class CQL::AlterTable

Overview

Collects the changes to one table inside a Schema#alter block, which runs them as ALTER TABLE (and index) statements and updates the table's declaration.

Example

schema.alter :users do
  add_column :phone, String, null: true
  rename_column :phone, :mobile
  create_index :idx_users_mobile, [:mobile]
end

Defined in:

alter_table.cr

Constant Summary

Log = CQL.config.logger

Constructors

Instance Method Summary

Constructor Detail

def self.new(table : CQL::Table, schema : CQL::Schema) #

[View source]

Instance Method Detail

def add_column(name : Symbol, type : T.class, as as_name : String | Nil = nil, null : Bool = true, default : DB::Any = nil, unique : Bool = false, size : Int32 | Nil = nil, index : Bool = false) forall T #

Adds a new column to the table.

  • @param name [Symbol] the name of the column to be added
  • @param type [T.class] the Crystal type of the column
  • @param as [String, nil] an optional alias for the column
  • @param null [Bool] whether the column allows null values (default: true)
  • @param default [DB::Any, nil] the default value for the column (default: nil)
  • @param unique [Bool] whether the column should have a unique constraint (default: false)
  • @param size [Int32, nil] the size of the column (default: nil)
  • @param index [Bool] whether the column should be indexed (default: false)

Example Adding new columns

schema.alter :users do
  add_column :phone, String
  add_column :score, Int32, null: false, default: 0, index: true
end

[View source]
def change_column(name : Symbol, type : T.class) forall T #

Changes the type of a column in the table. Not on SQLite, which raises CQL::SQLiteUnsupportedFeatureError.

  • @param name [Symbol] the name of the column to be changed
  • @param type [T.class] the new Crystal type for the column

Example Changing the type of a column

schema.alter :users do
  change_column :age, Int64
end

[View source]
def create_index(name : Symbol, columns : Array(Symbol), unique : Bool = false) #

Creates an index on the table.

  • @param name [Symbol] the name of the index
  • @param columns [Array(Symbol)] the columns to be indexed
  • @param unique [Bool] whether the index should be unique (default: false)

Example Creating an index

schema.alter :users do
  create_index :index_users_on_email, [:email], unique: true
end

[View source]
def drop_column(column : Symbol) #

Drops a column from the table. The column need not be declared in the schema: the database reports a column it does not have.

  • @param column [Symbol] the name of the column to be dropped

Example Dropping a column

schema.alter :users do
  drop_column :age
end

[View source]
def drop_foreign_key(name : Symbol) #

Drops a foreign key from the table. Not on SQLite, which raises CQL::SQLiteUnsupportedFeatureError.

  • @param name [Symbol] the name of the foreign key to be dropped

Example Dropping a foreign key

schema.alter :posts do
  drop_foreign_key :fk_posts_user
end

[View source]
def drop_index(name : Symbol) #

Drops an index from the table.

  • @param name [Symbol] the name of the index to be dropped

Example Dropping an index

schema.alter :users do
  drop_index :index_users_on_email
end

[View source]
def foreign_key(columns local_columns : Array(Symbol), references references_table : Symbol, references_columns : Array(Symbol) | Symbol | Nil = nil, name : Symbol | Nil = nil, on_delete : Symbol = :no_action, on_update : Symbol = :no_action) #

Adds a foreign key to the table.

  • @param columns [Array(Symbol)] the columns in the current table
  • @param references [Symbol] the referenced table
  • @param references_columns [Array(Symbol), Symbol, nil] the columns in the referenced table (default: its primary key)
  • @param name [Symbol, nil] the optional name of the foreign key constraint
  • @param on_delete [Symbol] the action on delete (default: :no_action)
  • @param on_update [Symbol] the action on update (default: :no_action)

Not on SQLite, which raises CQL::SQLiteUnsupportedFeatureError: declare foreign keys in Schema#table there.

Example Adding a foreign key

schema.alter :posts do
  foreign_key [:user_id], references: :users, references_columns: [:id], name: :fk_posts_user, on_delete: :cascade
end

[View source]
def foreign_key(column local_column : Symbol, references references_table : Symbol, references_columns : Array(Symbol) | Symbol | Nil = nil, name : Symbol | Nil = nil, on_delete : Symbol = :no_action, on_update : Symbol = :no_action) #

Overload for single column case


[View source]
def rename_column(old_name : Symbol, new_name : Symbol) #

Renames a column in the table.

  • @param old_name [Symbol] the current name of the column
  • @param new_name [Symbol] the new name for the column

Example Renaming a column

schema.alter :users do
  rename_column :email, :user_email
end

[View source]
def rename_table(new_name : Symbol) #

Renames the table.

  • @param new_name [Symbol] the new name for the table

Example Renaming the table

schema.alter :users do
  rename_table :members
end

[View source]
def statements(visitor : Expression::Visitor) : Array(String) #

The SQL of each statement, in declaration order. Schema#alter runs them one by one, so a statement is never split on text inside it, such as a default value.

Example Generating SQL for alter table actions

alter_table = CQL::AlterTable.new(schema.users, schema)
alter_table.add_column :phone, String
alter_table.statements(schema.new_generator) # => ["ALTER TABLE users ADD COLUMN phone TEXT"]

[View source]
def to_sql(visitor : Expression::Visitor) : String #

The statements as one script, each ended by ; and a newline.


[View source]