OscarDbMaintenance.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Data.Common;
  4. using System.Linq;
  5. using System.Text;
  6. namespace SqlSugar
  7. {
  8. public class OscarDbMaintenance : DbMaintenanceProvider
  9. {
  10. #region DML
  11. protected override string GetDataBaseSql
  12. {
  13. get
  14. {
  15. return "SELECT datname FROM sys_database ";
  16. }
  17. }
  18. protected override string GetColumnInfosByTableNameSql
  19. {
  20. get
  21. {
  22. string sql = @" SELECT
  23. A.COLUMN_NAME AS DbColumnName,
  24. A.TABLE_NAME AS TableName,
  25. A.DATA_TYPE AS DataType,
  26. case when DATA_DEFAULT like 'NEXTVAL%' then true else false end as IsIdentity,
  27. case when A.NULLABLE = 'Y' then true else false end as IsNullable ,
  28. A.DATA_LENGTH AS LENGTH,
  29. B.COMMENTS AS ColumnDescription,
  30. CASE WHEN K.COLUMN_NAME IS NULL THEN FALSE ELSE TRUE END AS IsPrimarykey,
  31. DATA_SCALE AS DecimalDigits,
  32. A.DATA_PRECISION AS SCALE,
  33. A.DATA_DEFAULT as DefaultValue
  34. FROM
  35. INFO_SCHEM.ALL_TAB_COLUMNS A
  36. LEFT JOIN INFO_SCHEM.SYS_CLASS T ON T.RELNAME=A.TABLE_NAME
  37. LEFT JOIN INFO_SCHEM.ALL_COL_COMMENTS B ON A.TABLE_NAME=B.TABLE_NAME AND A.COLUMN_NAME=B.COLUMN_NAME
  38. LEFT JOIN INFO_SCHEM.SYS_ATTRIBUTE C ON C.ATTNAME=A.COLUMN_NAME AND C.ATTRELID=T.OID
  39. LEFT JOIN INFO_SCHEM.V_SYS_PRIMARY_KEYS K ON A.TABLE_NAME=K.TABLE_NAME AND K.COLUMN_NAME=A.COLUMN_NAME
  40. WHERE upper(A.TABLE_NAME)=upper('{0}')
  41. ORDER BY c.ATTNUM
  42. ";
  43. return sql;
  44. }
  45. }
  46. protected override string GetTableInfoListSql
  47. {
  48. get
  49. {
  50. //AND t.relnamespace=1 表空间限制。
  51. return @" select cast(relname as varchar(500)) as Name , DESCRIPTION AS Description FROM sys_class t
  52. LEFT JOIN sys_description d ON t.OID=d.OBJOID AND d.OBJSUBID=0
  53. WHERE t.relvbase>0 AND t.relkind = 'r' AND t.relnamespace=(SELECT OID FROM sys_namespace WHERE nspname =USER)
  54. order by relname";
  55. }
  56. }
  57. protected override string GetViewInfoListSql
  58. {
  59. get
  60. {
  61. return @" select cast(relname as varchar(500)) as Name , DESCRIPTION AS Description FROM sys_class t
  62. LEFT JOIN sys_description d ON t.OID=d.OBJOID AND d.OBJSUBID=0
  63. WHERE t.relvbase>0 AND t.relkind = 'v' AND t.relnamespace=(SELECT OID FROM sys_namespace WHERE nspname =USER)
  64. order by relname";
  65. }
  66. }
  67. #endregion
  68. #region DDL
  69. protected override string CreateDataBaseSql
  70. {
  71. get
  72. {
  73. return "CREATE DATABASE {0}";
  74. }
  75. }
  76. protected override string AddPrimaryKeySql
  77. {
  78. get
  79. {
  80. return "ALTER TABLE {0} ADD PRIMARY KEY({2}) /*{1}*/";
  81. }
  82. }
  83. protected override string AddColumnToTableSql
  84. {
  85. get
  86. {
  87. return "ALTER TABLE {0} ADD COLUMN {1} {2}{3} {4} {5} {6}";
  88. }
  89. }
  90. protected override string AlterColumnToTableSql
  91. {
  92. get
  93. {
  94. return "alter table {0} ALTER COLUMN {1} {2}{3} {4} {5} {6}";
  95. }
  96. }
  97. protected override string BackupDataBaseSql
  98. {
  99. get
  100. {
  101. return "mysqldump.exe {0} -uroot -p > {1} ";
  102. }
  103. }
  104. protected override string CreateTableSql
  105. {
  106. get
  107. {
  108. return "CREATE TABLE {0}(\r\n{1} $PrimaryKey)";
  109. }
  110. }
  111. protected override string CreateTableColumn
  112. {
  113. get
  114. {
  115. return "{0} {1}{2} {3} {4} {5}";
  116. }
  117. }
  118. protected override string TruncateTableSql
  119. {
  120. get
  121. {
  122. return "TRUNCATE TABLE {0}";
  123. }
  124. }
  125. protected override string BackupTableSql
  126. {
  127. get
  128. {
  129. return "create table {0} as (select * from {1} limit {2} offset 0)";
  130. }
  131. }
  132. protected override string DropTableSql
  133. {
  134. get
  135. {
  136. return "DROP TABLE {0}";
  137. }
  138. }
  139. protected override string DropColumnToTableSql
  140. {
  141. get
  142. {
  143. return "ALTER TABLE {0} DROP COLUMN {1}";
  144. }
  145. }
  146. protected override string DropConstraintSql
  147. {
  148. get
  149. {
  150. return "ALTER TABLE {0} DROP CONSTRAINT {1}";
  151. }
  152. }
  153. protected override string RenameColumnSql
  154. {
  155. get
  156. {
  157. return "ALTER TABLE {0} RENAME {1} TO {2}";
  158. }
  159. }
  160. protected override string AddColumnRemarkSql => "comment on column {1}.{0} is '{2}'";
  161. protected override string DeleteColumnRemarkSql => "comment on column {1}.{0} is ''";
  162. protected override string IsAnyColumnRemarkSql { get { throw new NotSupportedException(); } }
  163. protected override string AddTableRemarkSql => "comment on table {0} is '{1}'";
  164. protected override string DeleteTableRemarkSql => "comment on table {0} is ''";
  165. protected override string IsAnyTableRemarkSql { get { throw new NotSupportedException(); } }
  166. protected override string RenameTableSql => "alter table 表名 {0} to {1}";
  167. protected override string CreateIndexSql
  168. {
  169. get
  170. {
  171. return "CREATE {3} INDEX Index_{0}_{2} ON {0} ({1})";
  172. }
  173. }
  174. protected override string AddDefaultValueSql
  175. {
  176. get
  177. {
  178. return "ALTER TABLE {0} ALTER COLUMN {1} SET DEFAULT {2}";
  179. }
  180. }
  181. protected override string IsAnyIndexSql
  182. {
  183. get
  184. {
  185. return " Select count(1) from (SELECT to_regclass('{0}') as c ) t where t.c is not null";
  186. }
  187. }
  188. protected override string IsAnyProcedureSql => throw new NotImplementedException();
  189. #endregion
  190. #region Check
  191. protected override string CheckSystemTablePermissionsSql
  192. {
  193. get
  194. {
  195. return "select 1 from INFO_SCHEM.ALL_TAB_COLUMNS limit 1 offset 0";
  196. }
  197. }
  198. #endregion
  199. #region Scattered
  200. protected override string CreateTableNull
  201. {
  202. get
  203. {
  204. return "DEFAULT NULL";
  205. }
  206. }
  207. protected override string CreateTableNotNull
  208. {
  209. get
  210. {
  211. return "NOT NULL";
  212. }
  213. }
  214. protected override string CreateTablePirmaryKey
  215. {
  216. get
  217. {
  218. return "PRIMARY KEY";
  219. }
  220. }
  221. protected override string CreateTableIdentity
  222. {
  223. get
  224. {
  225. return "serial";
  226. }
  227. }
  228. #endregion
  229. #region Methods
  230. public override bool UpdateColumn(string tableName, DbColumnInfo columnInfo)
  231. {
  232. tableName = this.SqlBuilder.GetTranslationTableName(tableName);
  233. var columnName= this.SqlBuilder.GetTranslationColumnName(columnInfo.DbColumnName);
  234. string type = GetType(tableName, columnInfo);
  235. //this.Context.Ado.ExecuteCommand(sql);
  236. string sql= @"ALTER TABLE {table} ALTER TYPE {column} {type};ALTER TABLE {table} ALTER COLUMN {column} {null}";
  237. var isnull = columnInfo.IsNullable?" DROP NOT NULL ": " SET NOT NULL ";
  238. sql = sql.Replace("{table}", tableName)
  239. .Replace("{type}", type)
  240. .Replace("{column}", columnName)
  241. .Replace("{null}", isnull);
  242. this.Context.Ado.ExecuteCommand(sql);
  243. return true;
  244. }
  245. protected string GetType(string tableName, DbColumnInfo columnInfo)
  246. {
  247. string columnName = this.SqlBuilder.GetTranslationColumnName(columnInfo.DbColumnName);
  248. tableName = this.SqlBuilder.GetTranslationTableName(tableName);
  249. string dataSize = GetSize(columnInfo);
  250. string dataType = columnInfo.DataType;
  251. //if (!string.IsNullOrEmpty(dataType))
  252. //{
  253. // dataType = dataType;
  254. //}
  255. return dataType +""+ dataSize;
  256. }
  257. protected override string GetUpdateColumnSql(string tableName, DbColumnInfo columnInfo)
  258. {
  259. string columnName = this.SqlBuilder.GetTranslationColumnName(columnInfo.DbColumnName);
  260. tableName = this.SqlBuilder.GetTranslationTableName(tableName);
  261. string dataSize = GetSize(columnInfo);
  262. string dataType = columnInfo.DataType;
  263. if (!string.IsNullOrEmpty(dataType))
  264. {
  265. dataType = " type " + dataType;
  266. }
  267. string nullType = "";
  268. string primaryKey = null;
  269. string identity = null;
  270. string result = string.Format(this.AlterColumnToTableSql, tableName, columnName, dataType, dataSize, nullType, primaryKey, identity);
  271. return result;
  272. }
  273. /// <summary>
  274. ///by current connection string
  275. /// </summary>
  276. /// <param name="databaseDirectory"></param>
  277. /// <returns></returns>
  278. public override bool CreateDatabase(string databaseName, string databaseDirectory = null)
  279. {
  280. throw new NotSupportedException("Not Supported CreateDatabase");
  281. }
  282. public override bool AddRemark(EntityInfo entity)
  283. {
  284. var db = this.Context;
  285. var columns = entity.Columns.Where(it => it.IsIgnore == false).ToList();
  286. foreach (var item in columns)
  287. {
  288. if (item.ColumnDescription != null)
  289. {
  290. db.DbMaintenance.AddColumnRemark(item.DbColumnName, item.DbTableName, item.ColumnDescription);
  291. }
  292. }
  293. //table remak
  294. if (entity.TableDescription != null)
  295. {
  296. db.DbMaintenance.AddTableRemark(entity.DbTableName, entity.TableDescription);
  297. }
  298. return true;
  299. }
  300. public override bool CreateTable(string tableName, List<DbColumnInfo> columns, bool isCreatePrimaryKey = true)
  301. {
  302. if (columns.HasValue())
  303. {
  304. foreach (var item in columns)
  305. {
  306. if (item.DbColumnName.Equals("GUID", StringComparison.CurrentCultureIgnoreCase) && item.Length == 0)
  307. {
  308. item.Length = 10;
  309. }
  310. }
  311. }
  312. string sql = GetCreateTableSql(tableName, columns);
  313. string primaryKeyInfo = null;
  314. if (columns.Any(it => it.IsPrimarykey) && isCreatePrimaryKey)
  315. {
  316. primaryKeyInfo = string.Format(", Primary key({0})", string.Join(",", columns.Where(it => it.IsPrimarykey).Select(it => this.SqlBuilder.GetTranslationColumnName(it.DbColumnName.ToLower()))));
  317. }
  318. sql = sql.Replace("$PrimaryKey", primaryKeyInfo);
  319. this.Context.Ado.ExecuteCommand(sql);
  320. return true;
  321. }
  322. protected override string GetCreateTableSql(string tableName, List<DbColumnInfo> columns)
  323. {
  324. List<string> columnArray = new List<string>();
  325. Check.Exception(columns.IsNullOrEmpty(), "No columns found ");
  326. foreach (var item in columns)
  327. {
  328. string columnName = item.DbColumnName;
  329. string dataType = item.DataType;
  330. if (dataType == "varchar" && item.Length == 0)
  331. {
  332. item.Length = 1;
  333. }
  334. if (dataType == "uuid")
  335. {
  336. item.Length = 50;
  337. dataType = "varchar";
  338. }
  339. string dataSize = item.Length > 0 ? string.Format("({0})", item.Length) : null;
  340. if (item.DecimalDigits > 0&&item.Length>0 && dataType == "numeric")
  341. {
  342. dataSize = $"({item.Length},{item.DecimalDigits})";
  343. }
  344. string nullType = item.IsNullable ? this.CreateTableNull : CreateTableNotNull;
  345. string primaryKey = null;
  346. string addItem = string.Format(this.CreateTableColumn, this.SqlBuilder.GetTranslationColumnName(columnName.ToLower()), dataType, dataSize, nullType, primaryKey, "");
  347. if (item.IsIdentity)
  348. {
  349. string length = dataType.Substring(dataType.Length - 1);
  350. string identityDataType = "serial" + length;
  351. addItem = addItem.Replace(dataType, identityDataType);
  352. }
  353. columnArray.Add(addItem);
  354. }
  355. string tableString = string.Format(this.CreateTableSql, this.SqlBuilder.GetTranslationTableName(tableName.ToLower()), string.Join(",\r\n", columnArray));
  356. return tableString;
  357. }
  358. public override bool IsAnyConstraint(string constraintName)
  359. {
  360. throw new NotSupportedException("PgSql IsAnyConstraint NotSupportedException");
  361. }
  362. public override bool BackupDataBase(string databaseName, string fullFileName)
  363. {
  364. Check.ThrowNotSupportedException("PgSql BackupDataBase NotSupported");
  365. return false;
  366. }
  367. public override List<DbColumnInfo> GetColumnInfosByTableName(string tableName, bool isCache = true)
  368. {
  369. var result= base.GetColumnInfosByTableName(tableName.TrimStart('"').TrimEnd('"'), isCache);
  370. foreach (var columnInfo in result)
  371. {
  372. if (columnInfo.IsIdentity && !columnInfo.DataType.ObjToString().ToLower().Contains("int"))
  373. {
  374. columnInfo.IsIdentity = false;
  375. }
  376. }
  377. string sql = "select * from " + SqlBuilder.GetTranslationTableName(tableName) + " WHERE 1=2 ";
  378. var oldIsEnableLog = this.Context.Ado.IsEnableLogEvent;
  379. this.Context.Ado.IsEnableLogEvent = false;
  380. using (DbDataReader reader = (DbDataReader)this.Context.Ado.GetDataReader(sql))
  381. {
  382. this.Context.Ado.IsEnableLogEvent = oldIsEnableLog;
  383. var schemaTable = reader.GetSchemaTable();
  384. foreach (System.Data.DataRow row in schemaTable.Rows)
  385. {
  386. var name = row["columnname"] + "";
  387. var data = result.First(it => it.DbColumnName.Equals(name, StringComparison.OrdinalIgnoreCase));
  388. data.IsPrimarykey= row["iskey"].ToString() =="True"? true : false;
  389. }
  390. }
  391. return result;
  392. }
  393. #endregion
  394. }
  395. }