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 def initialize(position, name, options = {}, &block) @position = position @name = name @options = options @verbose = options.fetch(:verbose, true) @up_action = nil @down_action = nil @repository = if options.key?(:database) warn 'Using the :database option with migrations is deprecated, use :repository instead' options[:database] else options.fetch(:repository, :default) end instance_eval(&block) 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 def <=> other if self.position == other.position self.name.to_s <=> other.name.to_s else self.position <=> other.position end 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 def adapter setup! unless setup? @adapter end
# File lib/dm-migrations/migration.rb, line 155 def create_index(table_name, *columns_and_options) if columns_and_options.last.is_a?(Hash) opts = columns_and_options.pop else opts = {} end columns = columns_and_options.flatten opts[:name] ||= "#{opts[:unique] ? 'unique_' : ''}index_#{table_name}_#{columns.join('_')}" 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(', ') })) end
# File lib/dm-migrations/migration.rb, line 214 def create_migration_info_table_if_needed save, @verbose = @verbose, false unless migration_info_table_exists? execute("CREATE TABLE #{migration_info_table} (#{migration_name_column} VARCHAR(255) UNIQUE)") end @verbose = save end
# File lib/dm-migrations/migration.rb, line 141 def create_table(table_name, opts = {}, &block) execute TableCreator.new(adapter, table_name, opts, &block).to_sql end
The repository the migration will operate on.
@return [Symbol, nil]
The name of the DataMapper repository the migration will run against.
@deprecated Use {repository} instead.
@since 1.0.1.
# File lib/dm-migrations/migration.rb, line 65 def database warn "Using the DataMapper::Migration#database method is deprecated, use #repository instead" @repository end
define the actions that should be performed on a down migration
# File lib/dm-migrations/migration.rb, line 90 def down(&block) @down_action = block end
# File lib/dm-migrations/migration.rb, line 145 def drop_table(table_name, opts = {}) execute "DROP TABLE #{adapter.send(:quote_name, table_name.to_s)}" end
execute raw SQL
# File lib/dm-migrations/migration.rb, line 135 def execute(sql, *bind_values) say_with_time(sql) do adapter.execute(sql, *bind_values) end end
Quoted table name, for the adapter
# File lib/dm-migrations/migration.rb, line 250 def migration_info_table @migration_info_table ||= quote_table_name('migration_info') end
# File lib/dm-migrations/migration.rb, line 227 def migration_info_table_exists? adapter.storage_exists?('migration_info') end
Quoted `migration_name` column, for the adapter
# File lib/dm-migrations/migration.rb, line 255 def migration_name_column @migration_name_column ||= quote_column_name('migration_name') end
Fetch the record for this migration out of the migration_info table
# File lib/dm-migrations/migration.rb, line 232 def migration_record return [] unless migration_info_table_exists? adapter.select("SELECT #{migration_name_column} FROM #{migration_info_table} WHERE #{migration_name_column} = #{quoted_name}") end
# File lib/dm-migrations/migration.rb, line 149 def modify_table(table_name, opts = {}, &block) TableModifier.new(adapter, table_name, opts, &block).statements.each do |sql| execute(sql) end end
True if the migration has already been run
# File lib/dm-migrations/migration.rb, line 244 def needs_down? return false unless migration_info_table_exists? ! migration_record.empty? end
True if the migration needs to be run
# File lib/dm-migrations/migration.rb, line 238 def needs_up? return true unless migration_info_table_exists? migration_record.empty? end
un-do the migration by running the code in the down block
# File lib/dm-migrations/migration.rb, line 115 def perform_down result = nil if needs_down? # TODO: fix this so it only does transactions for databases that support create/drop # database.transaction.commit do if @down_action say_with_time "== Performing Down Migration ##{position}: #{name}", 0 do result = @down_action.call end end update_migration_info(:down) # end end result end
perform the migration by running the code in the up block
# File lib/dm-migrations/migration.rb, line 95 def perform_up result = nil if needs_up? # TODO: fix this so it only does transactions for databases that support create/drop # database.transaction.commit do if @up_action say_with_time "== Performing Up Migration ##{position}: #{name}", 0 do result = @up_action.call end end update_migration_info(:up) # end end result end
# File lib/dm-migrations/migration.rb, line 264 def quote_column_name(column_name) # TODO: Fix this for 1.9 - can't use this hack to access a private method adapter.send(:quote_name, column_name.to_s) end
# File lib/dm-migrations/migration.rb, line 259 def quote_table_name(table_name) # TODO: Fix this for 1.9 - can't use this hack to access a private method adapter.send(:quote_name, table_name.to_s) end
Quote the name of the migration for use in SQL
# File lib/dm-migrations/migration.rb, line 223 def quoted_name "'#{name}'" end
Output some text. Optional indent level
# File lib/dm-migrations/migration.rb, line 182 def say(message, indent = 4) write "#{" " * indent} #{message}" end
Time how long the block takes to run, and output it with the message.
# File lib/dm-migrations/migration.rb, line 187 def say_with_time(message, indent = 2) say(message, indent) result = nil time = Benchmark.measure { result = yield } say("-> %.4fs" % time.real, indent) result end
define the actions that should be performed on an up migration
# File lib/dm-migrations/migration.rb, line 85 def up(&block) @up_action = block 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 def update_migration_info(direction) save, @verbose = @verbose, false create_migration_info_table_if_needed if direction.to_sym == :up execute("INSERT INTO #{migration_info_table} (#{migration_name_column}) VALUES (#{quoted_name})") elsif direction.to_sym == :down execute("DELETE FROM #{migration_info_table} WHERE #{migration_name_column} = #{quoted_name}") end @verbose = save end
Sets up the migration.
@since 1.0.1
# File lib/dm-migrations/migration.rb, line 288 def setup! @adapter = DataMapper.repository(@repository).adapter case @adapter.class.name when /Sqlite/ then @adapter.extend(SQL::Sqlite) when /Mysql/ then @adapter.extend(SQL::Mysql) when /Postgres/ then @adapter.extend(SQL::Postgres) else raise(RuntimeError,"Unsupported Migration Adapter #{@adapter.class}",caller) end end
Generated with the Darkfish Rdoc Generator 2.