using Invercargill.DataStructures; using InvercargillSql.Orm; namespace InvercargillSql.Migrations { /** * Fluent builder for creating indexes within migrations. * * IndexBuilder is used within TableBuilder and AlterTableBuilder to * define indexes with a fluent API. It supports single and composite * indexes, as well as unique constraints. * * The index operation is added to the parent builder immediately upon * creation, and modifications (on_column, unique, etc.) update the * operation in place. This allows the fluent API to work without * requiring an explicit end() call. * * Example usage: * {{{ * // Single column index * t.index("idx_email").on_column("email"); * * // Composite unique index * t.index("idx_email_name").on_columns("email", "name").unique(); * }}} */ public class IndexBuilder : Object { private CreateIndexOperation _operation; private TableBuilder? _table_parent; private AlterTableBuilder? _alter_parent; /** * Creates a new IndexBuilder for use within TableBuilder. * * The index operation is automatically added to the parent builder, * and modifications (on_column, unique, etc.) update the operation in place. * * @param parent The parent TableBuilder * @param table_name The table name * @param index_name The name of the index */ internal IndexBuilder.for_table(TableBuilder parent, string table_name, string index_name) { _table_parent = parent; _operation = new CreateIndexOperation() { index_name = index_name, table_name = table_name, is_unique = false }; // Add the operation to the parent immediately - modifications // will update the operation in place parent.add_index_operation(_operation); } /** * Creates a new IndexBuilder for use within AlterTableBuilder. * * The index operation is automatically added to the parent builder, * and modifications (on_column, unique, etc.) update the operation in place. * * @param parent The parent AlterTableBuilder * @param table_name The table name * @param index_name The name of the index */ internal IndexBuilder.for_alter(AlterTableBuilder parent, string table_name, string index_name) { _alter_parent = parent; _operation = new CreateIndexOperation() { index_name = index_name, table_name = table_name, is_unique = false }; // Add the operation to the parent immediately parent.add_index_operation(_operation); } /** * Adds a single column to the index. * * @param column_name The name of the column to include in the index * @return This builder for method chaining */ public IndexBuilder on_column(string column_name) { _operation.columns.add(column_name); return this; } /** * Adds multiple columns to the index using varargs. * * This method accepts a variable number of column names to create * a composite index. * * @param first_column The first column name (required) * @param ... Additional column names * @return This builder for method chaining * * Example: * {{{ * t.index("idx_composite").on_columns("email", "name", "created_at"); * }}} */ public IndexBuilder on_columns(string first_column, ...) { _operation.columns.add(first_column); var args = va_list(); while (true) { string? col = args.arg(); if (col == null) { break; } _operation.columns.add(col); } return this; } /** * Marks the index as unique. * * A unique index ensures that all values in the indexed columns * are distinct from each other. * * @return This builder for method chaining */ public IndexBuilder unique() { _operation.is_unique = true; return this; } /** * Returns to the parent TableBuilder. * * This method is optional - the index is automatically added to * the parent builder when this IndexBuilder is created. * * @return The parent TableBuilder */ public TableBuilder end() { return _table_parent; } /** * Returns to the parent AlterTableBuilder. * * This method is optional - the index is automatically added to * the parent builder when this IndexBuilder is created. * * @return The parent AlterTableBuilder */ public AlterTableBuilder end_alter() { return _alter_parent; } } }