Class: Lhm::Migrator

Inherits:
Object
  • Object
show all
Includes:
Command, SqlHelper
Defined in:
lib/lhm/migrator.rb

Overview

Copies existing schema and applies changes using alter on the empty table. ‘run` returns a Migration which can be used for the remaining process.

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from SqlHelper

#annotation, #idx_name, #idx_spec, #tagged, #version_string

Methods included from Command

#run

Constructor Details

#initialize(table, connection = nil) ⇒ Migrator

Returns a new instance of Migrator.



18
19
20
21
22
23
24
# File 'lib/lhm/migrator.rb', line 18

def initialize(table, connection = nil)
  @connection = connection
  @origin = table
  @name = table.destination_name
  @statements = []
  @renames = {}
end

Instance Attribute Details

#conditionsObject (readonly)

Returns the value of attribute conditions.



16
17
18
# File 'lib/lhm/migrator.rb', line 16

def conditions
  @conditions
end

#connectionObject (readonly)

Returns the value of attribute connection.



16
17
18
# File 'lib/lhm/migrator.rb', line 16

def connection
  @connection
end

#nameObject (readonly)

Returns the value of attribute name.



16
17
18
# File 'lib/lhm/migrator.rb', line 16

def name
  @name
end

#originObject (readonly)

Returns the value of attribute origin.



16
17
18
# File 'lib/lhm/migrator.rb', line 16

def origin
  @origin
end

#renamesObject (readonly)

Returns the value of attribute renames.



16
17
18
# File 'lib/lhm/migrator.rb', line 16

def renames
  @renames
end

#statementsObject (readonly)

Returns the value of attribute statements.



16
17
18
# File 'lib/lhm/migrator.rb', line 16

def statements
  @statements
end

Instance Method Details

#add_column(name, definition, algorithm: 'INPLACE') ⇒ Object

Add a column to a table

Examples:


Lhm.change_table(:users) do |m|
  m.add_column(:comment, "VARCHAR(12) DEFAULT '0'")
end

Parameters:

  • name (String)

    Name of the column to add

  • definition (String)

    Valid SQL column definition

  • algorithm (String) (defaults to: 'INPLACE')

    Algorithm that will be used in the DDL operation



58
59
60
# File 'lib/lhm/migrator.rb', line 58

def add_column(name, definition, algorithm: 'INPLACE')
  ddl('alter table `%s` add column `%s` %s' % [@name, name, definition], algorithm:)
end

#add_index(columns, index_name = nil) ⇒ Object

Add an index to a table

Examples:


Lhm.change_table(:users) do |m|
  m.add_index(:comment)
  m.add_index([:username, :created_at])
  m.add_index("comment(10)")
end

Parameters:

  • columns (String, Symbol, Array<String, Symbol>)

    A column name given as String or Symbol. An Array of Strings or Symbols for compound indexes. It’s possible to pass a length limit.

  • index_name (String, Symbol) (defaults to: nil)

    Optional name of the index to be created



134
135
136
# File 'lib/lhm/migrator.rb', line 134

def add_index(columns, index_name = nil)
  ddl(index_ddl(columns, false, index_name))
end

#add_unique_index(columns, index_name = nil) ⇒ Object

Add a unique index to a table

Examples:


Lhm.change_table(:users) do |m|
  m.add_unique_index(:comment)
  m.add_unique_index([:username, :created_at])
  m.add_unique_index("comment(10)")
end

Parameters:

  • columns (String, Symbol, Array<String, Symbol>)

    A column name given as String or Symbol. An Array of Strings or Symbols for compound indexes. It’s possible to pass a length limit.

  • index_name (String, Symbol) (defaults to: nil)

    Optional name of the index to be created



153
154
155
# File 'lib/lhm/migrator.rb', line 153

def add_unique_index(columns, index_name = nil)
  ddl(index_ddl(columns, true, index_name))
end

#change_column(name, definition) ⇒ Object

Change an existing column to a new definition

Examples:


Lhm.change_table(:users) do |m|
  m.change_column(:comment, "VARCHAR(12) DEFAULT '0' NOT NULL")
end

Parameters:

  • name (String)

    Name of the column to change

  • definition (String)

    Valid SQL column definition



72
73
74
75
76
77
78
# File 'lib/lhm/migrator.rb', line 72

def change_column(name, definition)
  if definition.match?(/^(DROP|SET) DEFAULT/i)
    ddl('alter table `%s` alter column `%s` %s' % [@name, name, definition])
  else
    ddl('alter table `%s` modify column `%s` %s' % [@name, name, definition])
  end
end

#ddl(statement, algorithm: nil) ⇒ Object

Note:

Don’t write the table name directly into the statement. Use the #name getter instead, because the alter statement will be executed against a temporary table.

Alter a table with a custom statement

Examples:


Lhm.change_table(:users) do |m|
  m.ddl("ALTER TABLE #{m.name} ADD COLUMN age INT(11)")
end

Parameters:

  • statement (String)

    SQL alter statement

  • algorithm (String) (defaults to: nil)

    Algorithm that will be used in the DDL operation



42
43
44
45
# File 'lib/lhm/migrator.rb', line 42

def ddl(statement, algorithm: nil)
  full_statement = algorithm ? "#{statement}, ALGORITHM=#{algorithm}" : statement
  statements << full_statement
end

#filter(sql) ⇒ String

Filter the data that is copied into the new table by the provided SQL. This SQL will be inserted into the copy directly after the “from” statement - so be sure to use inner/outer join syntax and not cross joins.

Examples:

Add a conditions filter to the migration.

Lhm.change_table(:sounds) do |m|
  m.filter("inner join users on users.`id` = sounds.`user_id` and sounds.`public` = 1")
end

Parameters:

  • sql (String)

    The sql filter.

Returns:

  • (String)

    The sql filter.



191
192
193
# File 'lib/lhm/migrator.rb', line 191

def filter(sql)
  @conditions = sql
end

#remove_column(name, algorithm: 'INPLACE') ⇒ Object

Remove a column from a table

Examples:


Lhm.change_table(:users) do |m|
  m.remove_column(:comment)
end

Parameters:

  • name (String)

    Name of the column to delete

  • algorithm (String) (defaults to: 'INPLACE')

    Algorithm that will be used in the DDL operation



115
116
117
# File 'lib/lhm/migrator.rb', line 115

def remove_column(name, algorithm: 'INPLACE')
  ddl('alter table `%s` drop `%s`' % [@name, name], algorithm:)
end

#remove_index(columns, index_name = nil) ⇒ Object

Remove an index from a table

Examples:


Lhm.change_table(:users) do |m|
  m.remove_index(:comment)
  m.remove_index([:username, :created_at])
end

Parameters:

  • columns (String, Symbol, Array<String, Symbol>)

    A column name given as String or Symbol. An Array of Strings or Symbols for compound indexes.

  • index_name (String, Symbol) (defaults to: nil)

    Optional name of the index to be removed



171
172
173
174
175
176
177
# File 'lib/lhm/migrator.rb', line 171

def remove_index(columns, index_name = nil)
  columns = [columns].flatten.map(&:to_sym)
  from_origin = @origin.indices.find { |_, cols| cols.map(&:to_sym) == columns }
  index_name ||= from_origin[0] unless from_origin.nil?
  index_name ||= idx_name(@origin.name, columns)
  ddl('drop index `%s` on `%s`' % [index_name, @name])
end

#rename_column(old, nu, algorithm: 'INPLACE') ⇒ Object

Rename an existing column.

Examples:


Lhm.change_table(:users) do |m|
  m.rename_column(:login, :username)
end

Parameters:

  • old (String)

    Name of the column to change

  • nu (String)

    New name to use for the column

  • algorithm (String) (defaults to: 'INPLACE')

    Algorithm that will be used in the DDL operation



91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/lhm/migrator.rb', line 91

def rename_column(old, nu, algorithm: 'INPLACE')
  col = @origin.columns[old.to_s]

  definition = col[:type]

  definition += ' NOT NULL' unless col[:is_nullable] == "YES"
  definition += " DEFAULT #{@connection.quote(col[:column_default])}" if col[:column_default]
  definition += " COMMENT #{@connection.quote(col[:comment])}" if col[:comment]
  definition += " COLLATE #{@connection.quote(col[:collate])}" if col[:collate]

  ddl('alter table `%s` change column `%s` `%s` %s' % [@name, old, nu, definition], algorithm:)
  @renames[old.to_s] = nu.to_s
end