懒人记时 代码仓库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

136 line
3.7 KiB

  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Data;
  5. using System.Data.Common;
  6. using System.Data.OleDb;
  7. using System.Data.SQLite;
  8. using System.Dynamic;
  9. using System.IO;
  10. using System.Linq;
  11. using System.Text;
  12. using System.Windows.Forms;
  13. namespace AppTime
  14. {
  15. class DB
  16. {
  17. public readonly static DB Instance = new DB();
  18. DbConnection conn;
  19. DbProviderFactory factory = SQLiteFactory.Instance;
  20. public DB()
  21. {
  22. var connectionString = new SQLiteConnectionStringBuilder()
  23. {
  24. DataSource= Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "data.db")
  25. }.ToString();
  26. conn = new SQLiteConnection
  27. {
  28. ConnectionString = connectionString
  29. };
  30. }
  31. T execute<T>(Func<DbCommand, T> handler, string sql, params object[] args)
  32. {
  33. lock (this)
  34. {
  35. conn.Open();
  36. using var cmd = conn.CreateCommand();
  37. cmd.CommandText = sql;
  38. for (var i = 0; i < args.Length; i++)
  39. {
  40. var arg = args[i];
  41. if (!(arg is DbParameter param))
  42. {
  43. param = factory.CreateParameter();
  44. param.ParameterName = $"@v{i}";
  45. param.Value = arg;
  46. }
  47. cmd.Parameters.Add(param);
  48. }
  49. var result = handler(cmd);
  50. conn.Close();
  51. return result;
  52. }
  53. }
  54. public int Execute(string sql, params object[] args)
  55. {
  56. return execute(cmd => cmd.ExecuteNonQuery(), sql, args) ;
  57. }
  58. public List<object[]> ExecuteData(string sql, params object[] args)
  59. {
  60. return execute(cmd =>
  61. {
  62. var result = new List<object[]>();
  63. using var reader = cmd.ExecuteReader();
  64. while (reader.Read())
  65. {
  66. var row = new object[reader.FieldCount];
  67. reader.GetValues(row);
  68. result.Add(row);
  69. }
  70. return result;
  71. }, sql, args);
  72. }
  73. public T ExecuteValue<T>(string sql, params object[] args)
  74. {
  75. return (T)Convert.ChangeType(ExecuteData(sql, args)[0][0], typeof(T));
  76. }
  77. public T[] ExecuteColumn<T>(string sql, params object[] args)
  78. {
  79. var data = ExecuteData(sql, args);
  80. var result = new T[data.Count];
  81. for(var i = 0;i<data.Count;i++)
  82. {
  83. result[i] = (T)Convert.ChangeType(data[i][0], typeof(T));
  84. }
  85. return result;
  86. }
  87. public DataTable ExecuteTable(string sql, params object[] args)
  88. {
  89. return execute(cmd =>
  90. {
  91. using var adapter = factory.CreateDataAdapter();
  92. adapter.SelectCommand = cmd;
  93. var result = new DataTable();
  94. adapter.Fill(result);
  95. return result;
  96. }, sql, args);
  97. }
  98. public IEnumerable<dynamic> ExecuteDynamic(string sql, params object[] args)
  99. {
  100. return from r in ExecuteTable(sql, args).AsEnumerable() select new DynamicDataRow(r);
  101. }
  102. }
  103. class DynamicDataRow : DynamicObject
  104. {
  105. DataRow row;
  106. public DynamicDataRow(DataRow row)
  107. {
  108. this.row = row;
  109. }
  110. public override bool TryGetMember(GetMemberBinder binder, out object result)
  111. {
  112. result = row[binder.Name];
  113. return true;
  114. }
  115. }
  116. }