class Mimi::DB::Dictate::Migrator
Constants
- DEFAULTS
Attributes
from_schema[R]
options[R]
table_name[R]
to_schema[R]
Public Class Methods
db_schema_definition(table_name)
click to toggle source
# File lib/mimi/db/dictate/migrator.rb, line 65 def self.db_schema_definition(table_name) db_schema_definitions[table_name] ||= Mimi::DB::Dictate::Explorer.discover_schema(table_name) end
db_schema_definitions()
click to toggle source
# File lib/mimi/db/dictate/migrator.rb, line 70 def self.db_schema_definitions @db_schema_definitions ||= {} end
new(table_name, options)
click to toggle source
Creates a migrator to update table schema from DB
state to defined state
@param table_name
[String,Symbol] table name @param options [Hash]
# File lib/mimi/db/dictate/migrator.rb, line 24 def initialize(table_name, options) @table_name = table_name.to_sym @options = DEFAULTS.merge(options.dup) @from_schema = self.class.db_schema_definition(@table_name) @to_schema = Mimi::DB::Dictate.schema_definitions[@table_name] if from_schema.nil? && to_schema.nil? raise "Failed to migrate '#{@table_name}', no DB or target schema found" end end
reset_db_schema_definition!(table_name)
click to toggle source
# File lib/mimi/db/dictate/migrator.rb, line 74 def self.reset_db_schema_definition!(table_name) db_schema_definitions[table_name] = nil end
Public Instance Methods
db_connection()
click to toggle source
# File lib/mimi/db/dictate/migrator.rb, line 38 def db_connection Mimi::DB.connection end
destructive?(key)
click to toggle source
Returns true if the Migrator
is permitted to do destructive operations (DROP …) on resources identified by :key
# File lib/mimi/db/dictate/migrator.rb, line 51 def destructive?(key) options[:destructive] == true || (options[:destructive].is_a?(Hash) && options[:destructive][key]) end
dry_run?()
click to toggle source
logger()
click to toggle source
# File lib/mimi/db/dictate/migrator.rb, line 34 def logger @logger ||= options[:logger] || ActiveRecord::Base.logger end
run!()
click to toggle source
# File lib/mimi/db/dictate/migrator.rb, line 56 def run! db_ddl_transaction do run_drop_table! if from_schema && to_schema.nil? run_change_table! if from_schema && to_schema run_create_table! if from_schema.nil? && to_schema end self.class.reset_db_schema_definition!(table_name) end
Private Instance Methods
add_column!(table_name, column)
click to toggle source
# File lib/mimi/db/dictate/migrator.rb, line 150 def add_column!(table_name, column) logger.info "-- add column: #{table_name}.#{column}" return if dry_run? db_connection.add_column(table_name, column.name, column.sequel_type, column.to_sequel_params) end
add_index!(table_name, idx)
click to toggle source
# File lib/mimi/db/dictate/migrator.rb, line 166 def add_index!(table_name, idx) params = idx.params.select { |_, v| v }.map { |k, v| "#{k}: #{v.inspect}" }.join(', ') idx_column_names = idx.columns.join(', ') logger.info "-- add index: #{idx.name} on #{table_name}(#{idx_column_names}), #{params}" return if dry_run? db_connection.add_index(table_name, idx.columns, idx.params) end
change_column!(table_name, column)
click to toggle source
# File lib/mimi/db/dictate/migrator.rb, line 136 def change_column!(table_name, column) logger.info "-- change column: #{table_name}.#{column}" return if dry_run? db_connection.alter_table(table_name) do set_column_type column.name, column.sequel_type, column.to_sequel_params.except(:default, :null) set_column_default column.name, column.params[:default] if column.to_sequel_params[:null] set_column_allow_null column.name else set_column_not_null column.name end end end
db_ddl_transaction() { || ... }
click to toggle source
# File lib/mimi/db/dictate/migrator.rb, line 174 def db_ddl_transaction(&_block) supports_transactional_ddl = db_connection.respond_to?(:supports_transactional_ddl?) && db_connection.supports_transactional_ddl? return yield unless supports_transactional_ddl db_connection.transaction { yield } end
drop_column!(table_name, column_name)
click to toggle source
# File lib/mimi/db/dictate/migrator.rb, line 130 def drop_column!(table_name, column_name) logger.info "-- drop column: #{table_name}.#{column_name}" return if dry_run? || !destructive?(:columns) db_connection.drop_column(table_name, column_name) end
drop_index!(table_name, idx)
click to toggle source
# File lib/mimi/db/dictate/migrator.rb, line 156 def drop_index!(table_name, idx) idx_column_names = idx.columns.join(', ') logger.info "-- drop index: #{idx.name} on #{table_name}(#{idx_column_names})" return if dry_run? drop_index_params = {} drop_index_params[:name] = idx.name if idx.name drop_index_params[:cascade] = true # TODO: always cascade? db_connection.drop_index(table_name, idx.columns, drop_index_params) end
run_change_table!()
click to toggle source
# File lib/mimi/db/dictate/migrator.rb, line 86 def run_change_table! diff = Mimi::DB::Dictate::SchemaDiff.diff(from_schema, to_schema) if diff[:columns].empty? && diff[:indexes].empty? logger.info "- no changes: #{table_name}" return end logger.info "- ALTER TABLE: #{table_name}" run_change_table_columns!(diff[:columns]) unless diff[:columns].empty? run_change_table_indexes!(diff[:indexes]) unless diff[:indexes].empty? end
run_change_table_columns!(diff_columns)
click to toggle source
# File lib/mimi/db/dictate/migrator.rb, line 97 def run_change_table_columns!(diff_columns) diff_columns.each do |c, diff| drop_column!(table_name, c) if diff[:from] && diff[:to].nil? change_column!(table_name, diff[:to]) if diff[:from] && diff[:to] add_column!(table_name, diff[:to]) if diff[:from].nil? && diff[:to] end end
run_change_table_indexes!(diff_indexes)
click to toggle source
# File lib/mimi/db/dictate/migrator.rb, line 105 def run_change_table_indexes!(diff_indexes) diff_indexes.each do |i, diff| drop_index!(table_name, diff[:from]) if diff[:from] && diff[:to].nil? add_index!(table_name, diff[:to]) if diff[:from].nil? && diff[:to] end end
run_create_table!()
click to toggle source
# File lib/mimi/db/dictate/migrator.rb, line 112 def run_create_table! columns = to_schema.columns.values column_pk = to_schema.primary_key # issue CREATE TABLE with primary key field logger.info "- CREATE TABLE: #{table_name}" logger.info "-- add column: #{table_name}.#{column_pk}" unless dry_run? db_connection.create_table(table_name) do |_| column column_pk.name, column_pk.sequel_type, column_pk.to_sequel_params end end # create rest of the columns and indexes (columns - [column_pk]).each { |c| add_column!(table_name, c) } to_schema.indexes.each { |i| add_index!(table_name, i) } end
run_drop_table!()
click to toggle source
# File lib/mimi/db/dictate/migrator.rb, line 80 def run_drop_table! logger.info "- DROP TABLE: #{table_name}" return if dry_run? || !destructive?(:tables) db_connection.drop_table(table_name) end