PageRenderTime 50ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/src/FluentMigrator.Runner/Generators/Postgres/PostgresGenerator.cs

http://github.com/schambers/fluentmigrator
C# | 320 lines | 264 code | 46 blank | 10 comment | 18 complexity | 0735492b407b896aae4c0cff2d89abc3 MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using FluentMigrator.Expressions;
  6. using FluentMigrator.Model;
  7. using FluentMigrator.Runner.Generators.Generic;
  8. namespace FluentMigrator.Runner.Generators.Postgres
  9. {
  10. public class PostgresGenerator : GenericGenerator
  11. {
  12. public PostgresGenerator() : base(new PostgresColumn(), new PostgresQuoter(), new PostgresDescriptionGenerator())
  13. {
  14. }
  15. public override string Generate(AlterTableExpression expression)
  16. {
  17. var alterStatement = new StringBuilder();
  18. var descriptionStatement = DescriptionGenerator.GenerateDescriptionStatement(expression);
  19. alterStatement.Append(base.Generate(expression));
  20. if (string.IsNullOrEmpty(descriptionStatement))
  21. {
  22. alterStatement.Append(descriptionStatement);
  23. }
  24. return alterStatement.ToString();
  25. }
  26. public override string Generate(CreateSchemaExpression expression)
  27. {
  28. return string.Format("CREATE SCHEMA {0};", Quoter.QuoteSchemaName(expression.SchemaName));
  29. }
  30. public override string Generate(DeleteSchemaExpression expression)
  31. {
  32. return string.Format("DROP SCHEMA {0};", Quoter.QuoteSchemaName(expression.SchemaName));
  33. }
  34. public override string Generate(CreateTableExpression expression)
  35. {
  36. var createStatement = new StringBuilder();
  37. var tableName = Quoter.QuoteTableName(expression.TableName);
  38. createStatement.Append(string.Format("CREATE TABLE {0}.{1} ({2})", Quoter.QuoteSchemaName(expression.SchemaName), tableName, Column.Generate(expression.Columns, tableName)));
  39. var descriptionStatement = DescriptionGenerator.GenerateDescriptionStatements(expression);
  40. createStatement.Append(";");
  41. if (descriptionStatement != null && descriptionStatement.Any())
  42. {
  43. createStatement.Append(string.Join(";", descriptionStatement.ToArray()));
  44. createStatement.Append(";");
  45. }
  46. return createStatement.ToString();
  47. }
  48. public override string Generate(AlterColumnExpression expression)
  49. {
  50. var alterStatement = new StringBuilder();
  51. alterStatement.Append(String.Format("ALTER TABLE {0}.{1} {2};", Quoter.QuoteSchemaName(expression.SchemaName), Quoter.QuoteTableName(expression.TableName), ((PostgresColumn)Column).GenerateAlterClauses(expression.Column)));
  52. var descriptionStatement = DescriptionGenerator.GenerateDescriptionStatement(expression);
  53. if (!string.IsNullOrEmpty(descriptionStatement))
  54. {
  55. alterStatement.Append(";");
  56. alterStatement.Append(descriptionStatement);
  57. }
  58. return alterStatement.ToString();
  59. }
  60. public override string Generate(CreateColumnExpression expression)
  61. {
  62. var createStatement = new StringBuilder();
  63. createStatement.Append(string.Format("ALTER TABLE {0}.{1} ADD {2};", Quoter.QuoteSchemaName(expression.SchemaName), Quoter.QuoteTableName(expression.TableName), Column.Generate(expression.Column)));
  64. var descriptionStatement = DescriptionGenerator.GenerateDescriptionStatement(expression);
  65. if (!string.IsNullOrEmpty(descriptionStatement))
  66. {
  67. createStatement.Append(";");
  68. createStatement.Append(descriptionStatement);
  69. }
  70. return createStatement.ToString();
  71. }
  72. public override string Generate(DeleteTableExpression expression)
  73. {
  74. return String.Format("DROP TABLE {0}.{1};", Quoter.QuoteSchemaName(expression.SchemaName), Quoter.QuoteTableName(expression.TableName));
  75. }
  76. public override string Generate(DeleteColumnExpression expression)
  77. {
  78. StringBuilder builder = new StringBuilder();
  79. foreach (string columnName in expression.ColumnNames) {
  80. if (expression.ColumnNames.First() != columnName) builder.AppendLine("");
  81. builder.AppendFormat("ALTER TABLE {0}.{1} DROP COLUMN {2};",
  82. Quoter.QuoteSchemaName(expression.SchemaName),
  83. Quoter.QuoteTableName(expression.TableName),
  84. Quoter.QuoteColumnName(columnName));
  85. }
  86. return builder.ToString();
  87. }
  88. public override string Generate(CreateForeignKeyExpression expression)
  89. {
  90. var primaryColumns = GetColumnList(expression.ForeignKey.PrimaryColumns);
  91. var foreignColumns = GetColumnList(expression.ForeignKey.ForeignColumns);
  92. const string sql = "ALTER TABLE {0}.{1} ADD CONSTRAINT {2} FOREIGN KEY ({3}) REFERENCES {4}.{5} ({6}){7}{8};";
  93. return string.Format(sql,
  94. Quoter.QuoteSchemaName(expression.ForeignKey.ForeignTableSchema),
  95. Quoter.QuoteTableName(expression.ForeignKey.ForeignTable),
  96. Quoter.Quote(expression.ForeignKey.Name),
  97. foreignColumns,
  98. Quoter.QuoteSchemaName(expression.ForeignKey.PrimaryTableSchema),
  99. Quoter.QuoteTableName(expression.ForeignKey.PrimaryTable),
  100. primaryColumns,
  101. FormatCascade("DELETE", expression.ForeignKey.OnDelete),
  102. FormatCascade("UPDATE", expression.ForeignKey.OnUpdate)
  103. );
  104. }
  105. public override string Generate(DeleteForeignKeyExpression expression)
  106. {
  107. return string.Format("ALTER TABLE {0}.{1} DROP CONSTRAINT {2};", Quoter.QuoteSchemaName(expression.ForeignKey.ForeignTableSchema), Quoter.QuoteTableName(expression.ForeignKey.ForeignTable), Quoter.Quote(expression.ForeignKey.Name));
  108. }
  109. public override string Generate(CreateIndexExpression expression)
  110. {
  111. var result = new StringBuilder("CREATE");
  112. if (expression.Index.IsUnique)
  113. result.Append(" UNIQUE");
  114. result.Append(" INDEX {0} ON {1}.{2} (");
  115. var first = true;
  116. foreach (var column in expression.Index.Columns)
  117. {
  118. if (first)
  119. first = false;
  120. else
  121. result.Append(",");
  122. result.Append("\"" + column.Name + "\"");
  123. result.Append(column.Direction == Direction.Ascending ? " ASC" : " DESC");
  124. }
  125. result.Append(");");
  126. return String.Format(result.ToString(), Quoter.QuoteIndexName(expression.Index.Name), Quoter.QuoteSchemaName(expression.Index.SchemaName), Quoter.QuoteTableName(expression.Index.TableName));
  127. /*
  128. var idx = String.Format(result.ToString(), expression.Index.Name, Quoter.QuoteSchemaName(expression.Index.SchemaName), expression.Index.TableName);
  129. if (!expression.Index.IsClustered)
  130. return idx;
  131. // Clustered indexes in Postgres do not cluster updates/inserts to the table after the initial cluster operation is applied.
  132. // To keep the clustered index up to date run CLUSTER TableName periodically
  133. return string.Format("{0}; CLUSTER {1}\"{2}\" ON \"{3}\"", idx, Quoter.QuoteSchemaName(expression.Index.SchemaName), expression.Index.TableName, expression.Index.Name);
  134. */
  135. }
  136. public override string Generate(DeleteIndexExpression expression)
  137. {
  138. return string.Format("DROP INDEX {0}.{1};", Quoter.QuoteSchemaName(expression.Index.SchemaName), Quoter.QuoteIndexName(expression.Index.Name));
  139. }
  140. public override string Generate(RenameTableExpression expression)
  141. {
  142. return string.Format("ALTER TABLE {0}.{1} RENAME TO {2};", Quoter.QuoteSchemaName(expression.SchemaName), Quoter.QuoteTableName(expression.OldName), Quoter.QuoteTableName(expression.NewName));
  143. }
  144. public override string Generate(RenameColumnExpression expression)
  145. {
  146. return string.Format("ALTER TABLE {0}.{1} RENAME COLUMN {2} TO {3};", Quoter.QuoteSchemaName(expression.SchemaName), Quoter.QuoteTableName(expression.TableName), Quoter.QuoteColumnName(expression.OldName), Quoter.QuoteColumnName(expression.NewName));
  147. }
  148. public override string Generate(InsertDataExpression expression)
  149. {
  150. var result = new StringBuilder();
  151. foreach (var row in expression.Rows)
  152. {
  153. var columnNames = new List<string>();
  154. var columnData = new List<object>();
  155. foreach (var item in row)
  156. {
  157. columnNames.Add(item.Key);
  158. columnData.Add(item.Value);
  159. }
  160. var columns = GetColumnList(columnNames);
  161. var data = GetDataList(columnData);
  162. result.Append(String.Format("INSERT INTO {0}.{1} ({2}) VALUES ({3});", Quoter.QuoteSchemaName(expression.SchemaName), Quoter.QuoteTableName(expression.TableName), columns, data));
  163. }
  164. return result.ToString();
  165. }
  166. public override string Generate(AlterDefaultConstraintExpression expression)
  167. {
  168. return String.Format("ALTER TABLE {0}.{1} ALTER {2} DROP DEFAULT, ALTER {2} {3};", Quoter.QuoteSchemaName(expression.SchemaName), Quoter.QuoteTableName(expression.TableName), Quoter.QuoteColumnName(expression.ColumnName), ((PostgresColumn)Column).FormatAlterDefaultValue(expression.ColumnName, expression.DefaultValue));
  169. }
  170. public override string Generate(DeleteDataExpression expression)
  171. {
  172. var result = new StringBuilder();
  173. if (expression.IsAllRows)
  174. {
  175. result.Append(String.Format("DELETE FROM {0}.{1};", Quoter.QuoteSchemaName(expression.SchemaName), Quoter.QuoteTableName(expression.TableName)));
  176. }
  177. else
  178. {
  179. foreach (var row in expression.Rows)
  180. {
  181. var where = String.Empty;
  182. var i = 0;
  183. foreach (var item in row)
  184. {
  185. if (i != 0)
  186. {
  187. where += " AND ";
  188. }
  189. where += String.Format("{0} {1} {2}", Quoter.QuoteColumnName(item.Key), item.Value == null ? "IS" : "=", Quoter.QuoteValue(item.Value));
  190. i++;
  191. }
  192. result.Append(String.Format("DELETE FROM {0}.{1} WHERE {2};", Quoter.QuoteSchemaName(expression.SchemaName), Quoter.QuoteTableName(expression.TableName), where));
  193. }
  194. }
  195. return result.ToString();
  196. }
  197. public override string Generate(UpdateDataExpression expression)
  198. {
  199. var updateItems = new List<string>();
  200. var whereClauses = new List<string>();
  201. foreach (var item in expression.Set)
  202. {
  203. updateItems.Add(string.Format("{0} = {1}", Quoter.QuoteColumnName(item.Key), Quoter.QuoteValue(item.Value)));
  204. }
  205. if (expression.IsAllRows)
  206. {
  207. whereClauses.Add("1 = 1");
  208. }
  209. else
  210. {
  211. foreach (var item in expression.Where)
  212. {
  213. whereClauses.Add(string.Format("{0} {1} {2}", Quoter.QuoteColumnName(item.Key),
  214. item.Value == null ? "IS" : "=", Quoter.QuoteValue(item.Value)));
  215. }
  216. }
  217. return String.Format("UPDATE {0}.{1} SET {2} WHERE {3};", Quoter.QuoteSchemaName(expression.SchemaName), Quoter.QuoteTableName(expression.TableName), String.Join(", ", updateItems.ToArray()), String.Join(" AND ", whereClauses.ToArray()));
  218. }
  219. public override string Generate(AlterSchemaExpression expression)
  220. {
  221. return string.Format("ALTER TABLE {0}.{1} SET SCHEMA {2};", Quoter.QuoteSchemaName(expression.SourceSchemaName), Quoter.QuoteTableName(expression.TableName), Quoter.QuoteSchemaName(expression.DestinationSchemaName));
  222. }
  223. public override string Generate(DeleteDefaultConstraintExpression expression)
  224. {
  225. return string.Format("ALTER TABLE {0}.{1} ALTER {2} DROP DEFAULT;", Quoter.QuoteSchemaName(expression.SchemaName), Quoter.QuoteTableName(expression.TableName), Quoter.Quote(expression.ColumnName));
  226. }
  227. public override string Generate(DeleteConstraintExpression expression)
  228. {
  229. return string.Format("ALTER TABLE {0}.{1} DROP CONSTRAINT {2};", Quoter.QuoteSchemaName(expression.Constraint.SchemaName), Quoter.QuoteTableName(expression.Constraint.TableName), Quoter.Quote(expression.Constraint.ConstraintName));
  230. }
  231. public override string Generate(CreateConstraintExpression expression)
  232. {
  233. var constraintType = (expression.Constraint.IsPrimaryKeyConstraint) ? "PRIMARY KEY" : "UNIQUE";
  234. string[] columns = new string[expression.Constraint.Columns.Count];
  235. for (int i = 0; i < expression.Constraint.Columns.Count; i++)
  236. {
  237. columns[i] = Quoter.QuoteColumnName(expression.Constraint.Columns.ElementAt(i));
  238. }
  239. return string.Format("ALTER TABLE {0}.{1} ADD CONSTRAINT {2} {3} ({4});", Quoter.QuoteSchemaName(expression.Constraint.SchemaName),
  240. Quoter.QuoteTableName(expression.Constraint.TableName),
  241. Quoter.QuoteConstraintName(expression.Constraint.ConstraintName),
  242. constraintType,
  243. String.Join(", ", columns));
  244. }
  245. protected string GetColumnList(IEnumerable<string> columns)
  246. {
  247. var result = "";
  248. foreach (var column in columns)
  249. {
  250. result += Quoter.QuoteColumnName(column) + ",";
  251. }
  252. return result.TrimEnd(',');
  253. }
  254. protected string GetDataList(List<object> data)
  255. {
  256. var result = "";
  257. foreach (var column in data)
  258. {
  259. result += Quoter.QuoteValue(column) + ",";
  260. }
  261. return result.TrimEnd(',');
  262. }
  263. public override string Generate(CreateSequenceExpression expression)
  264. {
  265. return String.Format("{0};", base.Generate(expression));
  266. }
  267. public override string Generate(DeleteSequenceExpression expression)
  268. {
  269. return String.Format("{0};", base.Generate(expression));
  270. }
  271. }
  272. }