index-builder.vala 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. using Invercargill.DataStructures;
  2. using InvercargillSql.Orm;
  3. namespace InvercargillSql.Migrations {
  4. /**
  5. * Fluent builder for creating indexes within migrations.
  6. *
  7. * IndexBuilder is used within TableBuilder and AlterTableBuilder to
  8. * define indexes with a fluent API. It supports single and composite
  9. * indexes, as well as unique constraints.
  10. *
  11. * The index operation is added to the parent builder immediately upon
  12. * creation, and modifications (on_column, unique, etc.) update the
  13. * operation in place. This allows the fluent API to work without
  14. * requiring an explicit end() call.
  15. *
  16. * Example usage:
  17. * {{{
  18. * // Single column index
  19. * t.index("idx_email").on_column("email");
  20. *
  21. * // Composite unique index
  22. * t.index("idx_email_name").on_columns("email", "name").unique();
  23. * }}}
  24. */
  25. public class IndexBuilder : Object {
  26. private CreateIndexOperation _operation;
  27. private TableBuilder? _table_parent;
  28. private AlterTableBuilder? _alter_parent;
  29. /**
  30. * Creates a new IndexBuilder for use within TableBuilder.
  31. *
  32. * The index operation is automatically added to the parent builder,
  33. * and modifications (on_column, unique, etc.) update the operation in place.
  34. *
  35. * @param parent The parent TableBuilder
  36. * @param table_name The table name
  37. * @param index_name The name of the index
  38. */
  39. internal IndexBuilder.for_table(TableBuilder parent, string table_name, string index_name) {
  40. _table_parent = parent;
  41. _operation = new CreateIndexOperation() {
  42. index_name = index_name,
  43. table_name = table_name,
  44. is_unique = false
  45. };
  46. // Add the operation to the parent immediately - modifications
  47. // will update the operation in place
  48. parent.add_index_operation(_operation);
  49. }
  50. /**
  51. * Creates a new IndexBuilder for use within AlterTableBuilder.
  52. *
  53. * The index operation is automatically added to the parent builder,
  54. * and modifications (on_column, unique, etc.) update the operation in place.
  55. *
  56. * @param parent The parent AlterTableBuilder
  57. * @param table_name The table name
  58. * @param index_name The name of the index
  59. */
  60. internal IndexBuilder.for_alter(AlterTableBuilder parent, string table_name, string index_name) {
  61. _alter_parent = parent;
  62. _operation = new CreateIndexOperation() {
  63. index_name = index_name,
  64. table_name = table_name,
  65. is_unique = false
  66. };
  67. // Add the operation to the parent immediately
  68. parent.add_index_operation(_operation);
  69. }
  70. /**
  71. * Adds a single column to the index.
  72. *
  73. * @param column_name The name of the column to include in the index
  74. * @return This builder for method chaining
  75. */
  76. public IndexBuilder on_column(string column_name) {
  77. _operation.columns.add(column_name);
  78. return this;
  79. }
  80. /**
  81. * Adds multiple columns to the index using varargs.
  82. *
  83. * This method accepts a variable number of column names to create
  84. * a composite index.
  85. *
  86. * @param first_column The first column name (required)
  87. * @param ... Additional column names
  88. * @return This builder for method chaining
  89. *
  90. * Example:
  91. * {{{
  92. * t.index("idx_composite").on_columns("email", "name", "created_at");
  93. * }}}
  94. */
  95. public IndexBuilder on_columns(string first_column, ...) {
  96. _operation.columns.add(first_column);
  97. var args = va_list();
  98. while (true) {
  99. string? col = args.arg();
  100. if (col == null) {
  101. break;
  102. }
  103. _operation.columns.add(col);
  104. }
  105. return this;
  106. }
  107. /**
  108. * Marks the index as unique.
  109. *
  110. * A unique index ensures that all values in the indexed columns
  111. * are distinct from each other.
  112. *
  113. * @return This builder for method chaining
  114. */
  115. public IndexBuilder unique() {
  116. _operation.is_unique = true;
  117. return this;
  118. }
  119. /**
  120. * Returns to the parent TableBuilder.
  121. *
  122. * This method is optional - the index is automatically added to
  123. * the parent builder when this IndexBuilder is created.
  124. *
  125. * @return The parent TableBuilder
  126. */
  127. public TableBuilder end() {
  128. return _table_parent;
  129. }
  130. /**
  131. * Returns to the parent AlterTableBuilder.
  132. *
  133. * This method is optional - the index is automatically added to
  134. * the parent builder when this IndexBuilder is created.
  135. *
  136. * @return The parent AlterTableBuilder
  137. */
  138. public AlterTableBuilder end_alter() {
  139. return _alter_parent;
  140. }
  141. }
  142. }