Call migration script

Call migration script

Clear offers a migration system. Migration allow you to handle state update of your database.

Migration is a list of change going through a direction, up (commit changes) or down (rollback changes).

In clear, a migration is defined like this:

class MyMigration1
  include Clear::Migration

  def change(direction)
    direction.up do
      #do something on commit
    end

    direction.down do
      #do something on rollback
    end
  end
end

Executing custom SQL

The basic usage is to execute your own SQL (e.g. CREATE TABLE, ALTER, GRANT etc...).

To do it, just call execute into your direction block.

Example

class MyMigration1
  include Clear::Migration

  def change(direction)
    direction.up do
      execute("CREATE TABLE my_models...")
    end

    direction.down do
      execute("DROP TABLE my_models")
    end
  end
end

Built-in helpers

Clear offers helpers for simplify declaring your migration

Creating a table

Clear provides DSL looking like ActiveRecord for creating a table.

create_table(:users) do |t|
    t.column :first_name, :string, index: true
    t.column :last_name, :string, unique: true

    # Will create a "user_info_id" field of type longint with a foreign key constraint
    # This reference can be null, and if the user_info is deleted then the user is deleted too.
    t.references to: "user_infos", name: "user_info_id", on_delete: "cascade", null: true

    # Example of creating index on full name
    t.index "lower(first_name || ' ' || last_name)", using: :btree

    t.timestamps
end

Migration ordering

Migration should be ordered by a number. This number can be written in different way:

  • In case of mixing multiple classes into the same file, you can append the number at the end of the class name:

class Migration1
  include Clear::Migration

  def change(dir)
    #...
  end
end

If you're using one file per migration, you can prepend the ordering number at the start of the file name:

1234_migration.cr

Finally, if you feel more rock'n'roll and build a complex dynamic migration system on top of Clear, you can override the uid method:

class Migration1
  include Clear::Migration

  def uid
    123_i64 #Number must be a signed 64bits integer !
  end

  def change(dir)
    #...
  end
end

Calling your migration

Clear will offers soon a CLI; meanwhile, you can call migration update using methods in the Migration Manager:

# Activate all the migrations. Will call change with up direction for each down migrations
Clear::Migration::Manager.instance.apply_all
# Go to a specific migration. All migration with a number above than the version number will be downed if not yet down.
# All migrations with a version number below will be activated if not yet up.
Clear::Migration::Manager.instance.apply_to(version_number)

Last updated