PostgreSQLUpdateBuilder.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. namespace SqlSugar
  6. {
  7. public class PostgreSQLUpdateBuilder : UpdateBuilder
  8. {
  9. public override string SqlTemplateBatch
  10. {
  11. get
  12. {
  13. return @"UPDATE {1} {2} SET {0} FROM ${{0}} ";
  14. }
  15. }
  16. public override string SqlTemplateJoin
  17. {
  18. get
  19. {
  20. return @" (VALUES
  21. {0}
  22. ) AS T ({2}) WHERE {1}
  23. ";
  24. }
  25. }
  26. public override string SqlTemplateBatchUnion
  27. {
  28. get
  29. {
  30. return ",";
  31. }
  32. }
  33. public object FormatValue(object value,string name,int i,DbColumnInfo columnInfo)
  34. {
  35. if (value == null)
  36. {
  37. return "NULL";
  38. }
  39. else
  40. {
  41. var type =UtilMethods.GetUnderType(value.GetType());
  42. if (type == UtilConstants.DateType||columnInfo.IsArray||columnInfo.IsJson)
  43. {
  44. var parameterName = this.Builder.SqlParameterKeyWord + name + i;
  45. var paramter = new SugarParameter(parameterName, value);
  46. if (columnInfo.IsJson)
  47. {
  48. paramter.IsJson = true;
  49. }
  50. if (columnInfo.IsArray)
  51. {
  52. paramter.IsArray = true;
  53. }
  54. this.Parameters.Add(paramter);
  55. return parameterName;
  56. }
  57. else if (type == UtilConstants.DateTimeOffsetType)
  58. {
  59. return FormatDateTimeOffset(value);
  60. }
  61. else if (type == UtilConstants.ByteArrayType)
  62. {
  63. string bytesString = "0x" + BitConverter.ToString((byte[])value);
  64. return bytesString;
  65. }
  66. else if (type.IsEnum())
  67. {
  68. if (this.Context.CurrentConnectionConfig.MoreSettings?.TableEnumIsString == true)
  69. {
  70. return value.ToSqlValue();
  71. }
  72. else
  73. {
  74. return Convert.ToInt64(value);
  75. }
  76. }
  77. else if (type == UtilConstants.BoolType)
  78. {
  79. return value.ObjToBool() ? "1" : "0";
  80. }
  81. else if (type == UtilConstants.StringType || type == UtilConstants.ObjType)
  82. {
  83. return "'" + value.ToString().ToSqlFilter() + "'";
  84. }
  85. else
  86. {
  87. return "'" + value.ToString() + "'";
  88. }
  89. }
  90. }
  91. protected override string TomultipleSqlString(List<IGrouping<int, DbColumnInfo>> groupList)
  92. {
  93. Check.Exception(PrimaryKeys == null || PrimaryKeys.Count == 0, " Update List<T> need Primary key");
  94. int pageSize = 200;
  95. int pageIndex = 1;
  96. int totalRecord = groupList.Count;
  97. int pageCount = (totalRecord + pageSize - 1) / pageSize;
  98. StringBuilder batchUpdateSql = new StringBuilder();
  99. while (pageCount >= pageIndex)
  100. {
  101. StringBuilder updateTable = new StringBuilder();
  102. string setValues = string.Join(",", groupList.First().Where(it => it.IsPrimarykey == false && (it.IsIdentity == false || (IsOffIdentity && it.IsIdentity))).Select(it =>
  103. {
  104. if (SetValues.IsValuable())
  105. {
  106. var setValue = SetValues.Where(sv => sv.Key == Builder.GetTranslationColumnName(it.DbColumnName));
  107. if (setValue != null && setValue.Any())
  108. {
  109. return setValue.First().Value;
  110. }
  111. }
  112. var result = string.Format("{0}=T.{0}", Builder.GetTranslationColumnName(it.DbColumnName));
  113. return result;
  114. }));
  115. string tempColumnValue = string.Join(",", groupList.First().Select(it =>
  116. {
  117. if (SetValues.IsValuable())
  118. {
  119. var setValue = SetValues.Where(sv => sv.Key == Builder.GetTranslationColumnName(it.DbColumnName));
  120. if (setValue != null && setValue.Any())
  121. {
  122. return setValue.First().Value;
  123. }
  124. }
  125. var result = Builder.GetTranslationColumnName(it.DbColumnName);
  126. return result;
  127. }));
  128. batchUpdateSql.AppendFormat(SqlTemplateBatch.ToString(), setValues, GetTableNameStringNoWith, TableWithString);
  129. int i = 0;
  130. var tableColumnList = this.Context.DbMaintenance.GetColumnInfosByTableName(GetTableNameStringNoWith);
  131. foreach (var columns in groupList.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList())
  132. {
  133. var isFirst = i == 0;
  134. if (!isFirst)
  135. {
  136. updateTable.Append(SqlTemplateBatchUnion);
  137. }
  138. updateTable.Append("\r\n (" + string.Join(",", columns.Select(it =>
  139. {
  140. var columnInfo = tableColumnList.FirstOrDefault(x => x.DbColumnName.Equals(it.DbColumnName, StringComparison.OrdinalIgnoreCase));
  141. var dbType = columnInfo?.DataType;
  142. if (dbType == null) {
  143. var typeName = it.PropertyType.Name.ToLower();
  144. if (columnInfo==null&&it.PropertyType.IsEnum)
  145. {
  146. if (this.Context.CurrentConnectionConfig?.MoreSettings?.TableEnumIsString!=true)
  147. {
  148. typeName = "int";
  149. }
  150. }
  151. if (typeName == "int32")
  152. typeName = "int";
  153. if (typeName == "int64")
  154. typeName = "long";
  155. if (typeName == "int16")
  156. typeName = "short";
  157. if (typeName == "boolean")
  158. typeName = "bool";
  159. var isAnyType = PostgreSQLDbBind.MappingTypesConst.Where(x => x.Value.ToString().ToLower() == typeName).Any();
  160. if (isAnyType)
  161. {
  162. dbType = PostgreSQLDbBind.MappingTypesConst.Where(x => x.Value.ToString().ToLower() == typeName).FirstOrDefault().Key;
  163. }
  164. else {
  165. dbType = "varchar";
  166. }
  167. }
  168. return string.Format("CAST({0} AS {1})", base.GetDbColumn(it,FormatValue(it.Value,it.DbColumnName,i+(pageIndex-1)*100000,it)), dbType);
  169. })) + ")");
  170. ++i;
  171. }
  172. pageIndex++;
  173. updateTable.Append("\r\n");
  174. string whereString = null;
  175. if (this.WhereValues.HasValue())
  176. {
  177. foreach (var item in WhereValues)
  178. {
  179. var isFirst = whereString == null;
  180. whereString += (isFirst ? null : " AND ");
  181. whereString += item;
  182. }
  183. }
  184. else if (PrimaryKeys.HasValue())
  185. {
  186. foreach (var item in PrimaryKeys)
  187. {
  188. var isFirst = whereString == null;
  189. whereString += (isFirst ? null : " AND ");
  190. whereString += string.Format("{0}.{1}=T.{1}", GetTableNameStringNoWith, Builder.GetTranslationColumnName(item));
  191. }
  192. }
  193. var format = string.Format(SqlTemplateJoin, updateTable, whereString, tempColumnValue);
  194. batchUpdateSql.Replace("${0}", format);
  195. batchUpdateSql.Append(";");
  196. }
  197. batchUpdateSql = GetBatchUpdateSql(batchUpdateSql);
  198. return batchUpdateSql.ToString();
  199. }
  200. private StringBuilder GetBatchUpdateSql(StringBuilder batchUpdateSql)
  201. {
  202. if (ReSetValueBySqlExpListType == null && ReSetValueBySqlExpList != null)
  203. {
  204. var result = batchUpdateSql.ToString();
  205. foreach (var item in ReSetValueBySqlExpList)
  206. {
  207. var dbColumnName = item.Value.DbColumnName;
  208. if (item.Value.Type == ReSetValueBySqlExpListModelType.List)
  209. {
  210. result = result.Replace($"{dbColumnName}=T.{dbColumnName}", $"{dbColumnName}={GetTableNameString}.{dbColumnName}{item.Value.Sql}T.{dbColumnName}");
  211. }
  212. else
  213. {
  214. result = result.Replace($"{dbColumnName}=T.{dbColumnName}", $"{dbColumnName}={item.Value.Sql.Replace(dbColumnName, $"{Builder.GetTranslationColumnName(this.TableName)}.{dbColumnName}")}");
  215. }
  216. batchUpdateSql = new StringBuilder(result);
  217. }
  218. }
  219. return batchUpdateSql;
  220. }
  221. protected override string GetJoinUpdate(string columnsString, ref string whereString)
  222. {
  223. var formString = $" {Builder.GetTranslationColumnName(this.TableName)} AS {Builder.GetTranslationColumnName(this.ShortName)} ";
  224. var joinString = "";
  225. foreach (var item in this.JoinInfos)
  226. {
  227. whereString += " AND "+item.JoinWhere;
  228. joinString += $"\r\n FROM {Builder.GetTranslationColumnName(item.TableName)} {Builder.GetTranslationColumnName(item.ShortName)} ";
  229. }
  230. var tableName = formString + "\r\n ";
  231. columnsString = columnsString.Replace(Builder.GetTranslationColumnName(this.ShortName)+".","")+joinString;
  232. return string.Format(SqlTemplate, tableName, columnsString, whereString);
  233. }
  234. public override string FormatDateTimeOffset(object value)
  235. {
  236. return "'" + ((DateTimeOffset)value).ToString("o") + "'";
  237. }
  238. }
  239. }