Object
Creates a new migration.
@param [Symbol, String, Integer] position
The position or version the migration belongs to.
@param [Symbol] name
The name of the migration.
@param [Hash] options
Additional options for the migration.
@option options [Boolean] :verbose (true)
Enables or disables verbose output.
@option options [Symbol] :repository (:default)
The DataMapper repository the migration will operate on.
# File lib/dm-migrations/migration.rb, line 37 37: def initialize(position, name, options = {}, &block) 38: @position = position 39: @name = name 40: @options = options 41: @verbose = options.fetch(:verbose, true) 42: @up_action = nil 43: @down_action = nil 44: 45: @repository = if options.key?(:database) 46: warn 'Using the :database option with migrations is deprecated, use :repository instead' 47: options[:database] 48: else 49: options.fetch(:repository, :default) 50: end 51: 52: instance_eval(&block) 53: end
Orders migrations by position, so we know what order to run them in. First order by position, then by name, so at least the order is predictable.
# File lib/dm-migrations/migration.rb, line 173 173: def <=> other 174: if self.position == other.position 175: self.name.to_s <=> other.name.to_s 176: else 177: self.position <=> other.position 178: end 179: end
The adapter the migration will use.
@return [DataMapper::Adapter]
The adapter the migration will operate on.
@since 1.0.1
# File lib/dm-migrations/migration.rb, line 78 78: def adapter 79: setup! unless setup? 80: 81: @adapter 82: end
# File lib/dm-migrations/migration.rb, line 155 155: def create_index(table_name, *columns_and_options) 156: if columns_and_options.last.is_a?(Hash) 157: opts = columns_and_options.pop 158: else 159: opts = {} 160: end 161: columns = columns_and_options.flatten 162: 163: opts[:name] ||= "#{opts[:unique] ? 'unique_' : ''}index_#{table_name}_#{columns.join('_')}" 164: 165: execute DataMapper::Ext::String.compress_lines( CREATE #{opts[:unique] ? 'UNIQUE ' : '' }INDEX #{quote_column_name(opts[:name])} ON #{quote_table_name(table_name)} (#{columns.map { |c| quote_column_name(c) }.join(', ') })) 166: end
# File lib/dm-migrations/migration.rb, line 214 214: def create_migration_info_table_if_needed 215: save, @verbose = @verbose, false 216: unless migration_info_table_exists? 217: execute("CREATE TABLE #{migration_info_table} (#{migration_name_column} VARCHAR(255) UNIQUE)") 218: end 219: @verbose = save 220: end
# File lib/dm-migrations/migration.rb, line 141 141: def create_table(table_name, opts = {}, &block) 142: execute TableCreator.new(adapter, table_name, opts, &block).to_sql 143: end
The repository the migration will operate on.
@return [Symbol, nil]
The name of the DataMapper repository the migration will run against.
@deprecated Use {#} instead.
@since 1.0.1.
# File lib/dm-migrations/migration.rb, line 65 65: def database 66: warn "Using the DataMapper::Migration#database method is deprecated, use #repository instead" 67: @repository 68: end
define the actions that should be performed on a down migration
# File lib/dm-migrations/migration.rb, line 90 90: def down(&block) 91: @down_action = block 92: end
# File lib/dm-migrations/migration.rb, line 145 145: def drop_table(table_name, opts = {}) 146: execute "DROP TABLE #{adapter.send(:quote_name, table_name.to_s)}" 147: end
execute raw SQL
# File lib/dm-migrations/migration.rb, line 135 135: def execute(sql, *bind_values) 136: say_with_time(sql) do 137: adapter.execute(sql, *bind_values) 138: end 139: end
Quoted table name, for the adapter
# File lib/dm-migrations/migration.rb, line 250 250: def migration_info_table 251: @migration_info_table ||= quote_table_name('migration_info') 252: end
# File lib/dm-migrations/migration.rb, line 227 227: def migration_info_table_exists? 228: adapter.storage_exists?('migration_info') 229: end
Quoted `migration_name` column, for the adapter
# File lib/dm-migrations/migration.rb, line 255 255: def migration_name_column 256: @migration_name_column ||= quote_column_name('migration_name') 257: end
Fetch the record for this migration out of the migration_info table
# File lib/dm-migrations/migration.rb, line 232 232: def migration_record 233: return [] unless migration_info_table_exists? 234: adapter.select("SELECT #{migration_name_column} FROM #{migration_info_table} WHERE #{migration_name_column} = #{quoted_name}") 235: end
# File lib/dm-migrations/migration.rb, line 149 149: def modify_table(table_name, opts = {}, &block) 150: TableModifier.new(adapter, table_name, opts, &block).statements.each do |sql| 151: execute(sql) 152: end 153: end
True if the migration has already been run
# File lib/dm-migrations/migration.rb, line 244 244: def needs_down? 245: return false unless migration_info_table_exists? 246: ! migration_record.empty? 247: end
True if the migration needs to be run
# File lib/dm-migrations/migration.rb, line 238 238: def needs_up? 239: return true unless migration_info_table_exists? 240: migration_record.empty? 241: end
un-do the migration by running the code in the # block
# File lib/dm-migrations/migration.rb, line 115 115: def perform_down 116: result = nil 117: 118: if needs_down? 119: # TODO: fix this so it only does transactions for databases that support create/drop 120: # database.transaction.commit do 121: if @down_action 122: say_with_time "== Performing Down Migration ##{position}: #{name}", 0 do 123: result = @down_action.call 124: end 125: end 126: 127: update_migration_info(:down) 128: # end 129: end 130: 131: result 132: end
perform the migration by running the code in the # block
# File lib/dm-migrations/migration.rb, line 95 95: def perform_up 96: result = nil 97: 98: if needs_up? 99: # TODO: fix this so it only does transactions for databases that support create/drop 100: # database.transaction.commit do 101: if @up_action 102: say_with_time "== Performing Up Migration ##{position}: #{name}", 0 do 103: result = @up_action.call 104: end 105: end 106: 107: update_migration_info(:up) 108: # end 109: end 110: 111: result 112: end
# File lib/dm-migrations/migration.rb, line 264 264: def quote_column_name(column_name) 265: # TODO: Fix this for 1.9 - can't use this hack to access a private method 266: adapter.send(:quote_name, column_name.to_s) 267: end
# File lib/dm-migrations/migration.rb, line 259 259: def quote_table_name(table_name) 260: # TODO: Fix this for 1.9 - can't use this hack to access a private method 261: adapter.send(:quote_name, table_name.to_s) 262: end
Quote the name of the migration for use in SQL
# File lib/dm-migrations/migration.rb, line 223 223: def quoted_name 224: "'#{name}'" 225: end
Output some text. Optional indent level
# File lib/dm-migrations/migration.rb, line 182 182: def say(message, indent = 4) 183: write "#{" " * indent} #{message}" 184: end
Time how long the block takes to run, and output it with the message.
# File lib/dm-migrations/migration.rb, line 187 187: def say_with_time(message, indent = 2) 188: say(message, indent) 189: result = nil 190: time = Benchmark.measure { result = yield } 191: say("-> %.4fs" % time.real, indent) 192: result 193: end
define the actions that should be performed on an up migration
# File lib/dm-migrations/migration.rb, line 85 85: def up(&block) 86: @up_action = block 87: end
Inserts or removes a row into the `migration_info` table, so we can mark this migration as run, or un-done
# File lib/dm-migrations/migration.rb, line 201 201: def update_migration_info(direction) 202: save, @verbose = @verbose, false 203: 204: create_migration_info_table_if_needed 205: 206: if direction.to_sym == :up 207: execute("INSERT INTO #{migration_info_table} (#{migration_name_column}) VALUES (#{quoted_name})") 208: elsif direction.to_sym == :down 209: execute("DELETE FROM #{migration_info_table} WHERE #{migration_name_column} = #{quoted_name}") 210: end 211: @verbose = save 212: end
Sets up the migration.
@since 1.0.1
# File lib/dm-migrations/migration.rb, line 288 288: def setup! 289: @adapter = DataMapper.repository(@repository).adapter 290: 291: case @adapter.class.name 292: when /Sqlite/ then @adapter.extend(SQL::Sqlite) 293: when /Mysql/ then @adapter.extend(SQL::Mysql) 294: when /Postgres/ then @adapter.extend(SQL::Postgres) 295: else 296: raise(RuntimeError,"Unsupported Migration Adapter #{@adapter.class}",caller) 297: end 298: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.