| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291 |
- using Invercargill.DataStructures;
- using InvercargillSql.Orm;
- namespace InvercargillSql.Migrations {
-
- /**
- * Column builder for migrations that provides a fluent API for configuring column definitions.
- *
- * This builder is used within migration operations to configure column properties.
- * All configuration methods return this builder for method chaining.
- *
- * Example usage within a migration:
- * {{{
- * b.create_table("users")
- * .column<int64>("id", c => c.type_int().primary_key().auto_increment())
- * .column<string>("email", c => c.type_text().not_null().unique())
- * .execute();
- * }}}
- */
- public class MigrationColumnBuilder : Object {
- private MigrationBuilder? _migration_parent;
- private TableBuilder? _table_parent;
- private AlterTableBuilder? _alter_parent;
- private ColumnDefinition _column;
- private string? _table_name;
-
- // Index support
- private bool _should_create_index = false;
- private string? _index_name = null;
-
- // Foreign key support
- private ForeignKeyBuilder? _fk_builder = null;
-
- /**
- * Protected constructor for subclasses like ForeignKeyBuilder.
- */
- protected MigrationColumnBuilder.for_subclass() {
- _column = new ColumnDefinition();
- }
-
- /**
- * Creates a new MigrationColumnBuilder with a MigrationBuilder parent.
- *
- * @param parent the parent MigrationBuilder to return to after configuration
- * @param table_name the name of the table this column belongs to
- * @param column the column definition being configured
- */
- internal MigrationColumnBuilder(MigrationBuilder parent, string table_name, ColumnDefinition column) {
- _migration_parent = parent;
- _table_name = table_name;
- _column = column;
- }
-
- /**
- * Creates a new MigrationColumnBuilder with a TableBuilder parent.
- *
- * @param parent the parent TableBuilder to return to after configuration
- * @param column the column definition being configured
- */
- internal MigrationColumnBuilder.for_table(TableBuilder parent, ColumnDefinition column) {
- _table_parent = parent;
- _column = column;
- }
-
- /**
- * Creates a new MigrationColumnBuilder with an AlterTableBuilder parent.
- *
- * @param parent the parent AlterTableBuilder to return to after configuration
- * @param table_name the name of the table this column belongs to
- * @param column the column definition being configured
- */
- internal MigrationColumnBuilder.for_alter(AlterTableBuilder parent, string table_name, ColumnDefinition column) {
- _alter_parent = parent;
- _table_name = table_name;
- _column = column;
- }
-
- /**
- * Sets the column type to INTEGER.
- *
- * @return this builder for method chaining
- */
- public MigrationColumnBuilder type_int() {
- _column.column_type = ColumnType.INT_64;
- return this;
- }
-
- /**
- * Sets the column type to TEXT.
- *
- * @return this builder for method chaining
- */
- public MigrationColumnBuilder type_text() {
- _column.column_type = ColumnType.TEXT;
- return this;
- }
-
- /**
- * Sets the column type to REAL.
- *
- * @return this builder for method chaining
- */
- public MigrationColumnBuilder type_real() {
- _column.column_type = ColumnType.DECIMAL;
- return this;
- }
-
- /**
- * Sets the column type to BLOB.
- *
- * @return this builder for method chaining
- */
- public MigrationColumnBuilder type_blob() {
- _column.column_type = ColumnType.BINARY;
- return this;
- }
-
- /**
- * Sets the column type to DATETIME.
- *
- * @return this builder for method chaining
- */
- public MigrationColumnBuilder type_datetime() {
- _column.column_type = ColumnType.DATETIME;
- return this;
- }
-
- /**
- * Sets the column type to BOOLEAN.
- *
- * @return this builder for method chaining
- */
- public MigrationColumnBuilder type_boolean() {
- _column.column_type = ColumnType.BOOLEAN;
- return this;
- }
-
- /**
- * Marks this column as the primary key.
- *
- * Only one column per table should be marked as primary key.
- *
- * @return this builder for method chaining
- */
- public MigrationColumnBuilder primary_key() {
- _column.is_primary_key = true;
- return this;
- }
-
- /**
- * Marks this column as NOT NULL.
- *
- * @return this builder for method chaining
- */
- public MigrationColumnBuilder not_null() {
- _column.is_required = true;
- return this;
- }
-
- /**
- * Marks this column as UNIQUE.
- *
- * @return this builder for method chaining
- */
- public MigrationColumnBuilder unique() {
- _column.is_unique = true;
- return this;
- }
-
- /**
- * Marks this column as auto-incrementing.
- *
- * Typically used for integer primary keys.
- *
- * @return this builder for method chaining
- */
- public MigrationColumnBuilder auto_increment() {
- _column.auto_increment = true;
- return this;
- }
-
- /**
- * Sets a default value for this column.
- *
- * @param value the default value to use when inserting records
- * @return this builder for method chaining
- */
- public MigrationColumnBuilder default_value<T>(T value) {
- _column.default_value = new Invercargill.NativeElement<T>(value);
- return this;
- }
-
- /**
- * Marks this column to use the current timestamp as default.
- *
- * Only applicable to DATETIME columns.
- *
- * @return this builder for method chaining
- */
- public MigrationColumnBuilder default_now() {
- _column.default_now = true;
- return this;
- }
-
- /**
- * Adds a foreign key reference to another table.
- *
- * This method creates a ForeignKeyBuilder that allows configuring the FK
- * constraint with methods like .name(), .on_delete_cascade(), etc.
- * The ForeignKeyBuilder extends MigrationColumnBuilder, so column methods
- * can still be called after FK configuration.
- *
- * Example:
- * {{{
- * t.column<int64?>("user_id")
- * .not_null()
- * .references("users", "id")
- * .name("fk_orders_users")
- * .on_delete_cascade()
- * .indexed(); // Can continue with column methods
- * }}}
- *
- * @param table the referenced table name
- * @param column the referenced column name in the foreign table
- * @return a ForeignKeyBuilder for configuring the FK constraint
- */
- public ForeignKeyBuilder references(string table, string column) {
- _fk_builder = new ForeignKeyBuilder(this, table, column);
- return _fk_builder;
- }
-
- /**
- * Marks this column to have an index created for it.
- *
- * The index uniqueness is automatically inferred from the column's is_unique property.
- * If a custom index name is needed, pass it as the name parameter.
- *
- * Example:
- * {{{
- * // Basic index with auto-generated name (idx_{table}_{column})
- * t.column<string>("email").not_null().indexed();
- *
- * // Unique index - uniqueness inferred from column's unique() flag
- * t.column<string>("email").unique().indexed();
- *
- * // Index with custom name
- * t.column<string>("email").indexed("idx_users_email_address");
- * }}}
- *
- * @param name optional custom index name; if null, auto-generated as idx_{table}_{column}
- * @return this builder for method chaining
- */
- public MigrationColumnBuilder indexed(string? name = null) {
- _should_create_index = true;
- _index_name = name;
- return this;
- }
-
- /**
- * Whether an index should be created for this column.
- * TableBuilder uses this to determine if an index operation is needed.
- */
- public bool should_create_index { get { return _should_create_index; } }
-
- /**
- * The custom index name, or null if auto-generation should be used.
- * Auto-generated format: idx_{table}_{column}
- */
- public string? index_name { get { return _index_name; } }
-
- /**
- * The ForeignKeyBuilder if a foreign key was configured via references().
- * TableBuilder uses this to collect FK constraints from column definitions.
- */
- public ForeignKeyBuilder? fk_builder { get { return _fk_builder; } }
-
- /**
- * Returns to the parent MigrationBuilder.
- *
- * This method navigates through the parent chain to find the MigrationBuilder.
- *
- * @return the parent MigrationBuilder
- */
- internal virtual MigrationBuilder return_to_migration() {
- if (_migration_parent != null) return _migration_parent;
- if (_table_parent != null) return _table_parent.return_to_migration();
- if (_alter_parent != null) return _alter_parent.return_to_migration();
- assert_not_reached();
- }
- }
- }
|