Class: DataMapper::Migration
- Inherits:
-
Object
- Object
- DataMapper::Migration
- Includes:
- SQL
- Defined in:
- lib/dm-migrations/migration.rb
Instance Attribute Summary collapse
-
#name ⇒ Object
readonly
The name of the migration.
-
#position ⇒ Object
readonly
The position or version the migration belongs to.
-
#repository ⇒ Object
readonly
The repository the migration operates on.
Instance Method Summary collapse
-
#<=>(other) ⇒ Object
Orders migrations by position, so we know what order to run them in.
-
#adapter ⇒ DataMapper::Adapter
The adapter the migration will use.
- #create_index(table_name, *columns_and_options) ⇒ Object
- #create_migration_info_table_if_needed ⇒ Object
- #create_table(table_name, opts = {}, &block) ⇒ Object
-
#database ⇒ Symbol?
deprecated
Deprecated.
Use #repository instead.
-
#down(&block) ⇒ Object
define the actions that should be performed on a down migration.
- #drop_table(table_name, _opts = {}) ⇒ Object
-
#execute(sql, *bind_values) ⇒ Object
execute raw SQL.
-
#initialize(position, name, options = {}, &block) ⇒ Migration
constructor
Creates a new migration.
-
#migration_info_table ⇒ Object
Quoted table name, for the adapter.
- #migration_info_table_exists? ⇒ Boolean
-
#migration_name_column ⇒ Object
Quoted ‘migration_name` column, for the adapter.
-
#migration_record ⇒ Object
Fetch the record for this migration out of the migration_info table.
- #modify_table(table_name, opts = {}, &block) ⇒ Object
-
#needs_down? ⇒ Boolean
True if the migration has already been run.
-
#needs_up? ⇒ Boolean
True if the migration needs to be run.
-
#perform_down ⇒ Object
un-do the migration by running the code in the #down block.
-
#perform_up ⇒ Object
perform the migration by running the code in the #up block.
- #quote_column_name(column_name) ⇒ Object
- #quote_table_name(table_name) ⇒ Object
-
#quoted_name ⇒ Object
Quote the name of the migration for use in SQL.
-
#say(message, indent = 4) ⇒ Object
Output some text.
-
#say_with_time(message, indent = 2) ⇒ Object
Time how long the block takes to run, and output it with the message.
-
#select(sql, *bind_values) ⇒ Array<Struct>
Execute raw SQL and return a result set.
-
#up(&block) ⇒ Object
define the actions that should be performed on an up migration.
-
#update_migration_info(direction) ⇒ Object
Inserts or removes a row into the ‘migration_info` table, so we can mark this migration as run, or un-done.
-
#write(text = '') ⇒ Object
output the given text, but only if verbose mode is on.
Constructor Details
#initialize(position, name, options = {}, &block) ⇒ Migration
Creates a new migration.
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/dm-migrations/migration.rb', line 37 def initialize(position, name, = {}, &block) @position = position @name = name @options = @verbose = .fetch(:verbose, true) @up_action = nil @down_action = nil @repository = if .key?(:database) warn 'Using the :database option with migrations is deprecated, use :repository instead' [:database] else .fetch(:repository, :default) end instance_eval(&block) end |
Instance Attribute Details
#name ⇒ Object (readonly)
The name of the migration
14 15 16 |
# File 'lib/dm-migrations/migration.rb', line 14 def name @name end |
#position ⇒ Object (readonly)
The position or version the migration belongs to
11 12 13 |
# File 'lib/dm-migrations/migration.rb', line 11 def position @position end |
#repository ⇒ Object (readonly)
The repository the migration operates on
17 18 19 |
# File 'lib/dm-migrations/migration.rb', line 17 def repository @repository end |
Instance Method Details
#<=>(other) ⇒ Object
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.
193 194 195 196 197 198 199 |
# File 'lib/dm-migrations/migration.rb', line 193 def <=>(other) if position == other.position name.to_s <=> other.name.to_s else position <=> other.position end end |
#adapter ⇒ DataMapper::Adapter
The adapter the migration will use.
78 79 80 81 82 |
# File 'lib/dm-migrations/migration.rb', line 78 def adapter setup! unless setup? @adapter end |
#create_index(table_name, *columns_and_options) ⇒ Object
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
# File 'lib/dm-migrations/migration.rb', line 175 def create_index(table_name, *) opts = if .last.is_a?(Hash) .pop else {} end columns = .flatten opts[:name] ||= "#{opts[:unique] ? 'unique_' : ''}index_#{table_name}_#{columns.join('_')}" execute DataMapper::Ext::String.compress_lines(<<-SQL) CREATE #{opts[:unique] ? 'UNIQUE ' : ''}INDEX #{quote_column_name(opts[:name])} ON #{quote_table_name(table_name)} (#{columns.map { |c| quote_column_name(c) }.join(', ')}) SQL end |
#create_migration_info_table_if_needed ⇒ Object
235 236 237 238 239 240 |
# File 'lib/dm-migrations/migration.rb', line 235 def create_migration_info_table_if_needed save = @verbose @verbose = false execute("CREATE TABLE #{migration_info_table} (#{migration_name_column} VARCHAR(255) UNIQUE)") unless migration_info_table_exists? @verbose = save end |
#create_table(table_name, opts = {}, &block) ⇒ Object
161 162 163 |
# File 'lib/dm-migrations/migration.rb', line 161 def create_table(table_name, opts = {}, &block) execute TableCreator.new(adapter, table_name, opts, &block).to_sql end |
#database ⇒ Symbol?
Use #repository instead.
The repository the migration will operate on.
65 66 67 68 |
# File 'lib/dm-migrations/migration.rb', line 65 def database warn 'Using the DataMapper::Migration#database method is deprecated, use #repository instead' @repository end |
#down(&block) ⇒ Object
define the actions that should be performed on a down migration
90 91 92 |
# File 'lib/dm-migrations/migration.rb', line 90 def down(&block) @down_action = block end |
#drop_table(table_name, _opts = {}) ⇒ Object
165 166 167 |
# File 'lib/dm-migrations/migration.rb', line 165 def drop_table(table_name, _opts = {}) execute "DROP TABLE #{adapter.send(:quote_name, table_name.to_s)}" end |
#execute(sql, *bind_values) ⇒ Object
execute raw SQL
135 136 137 138 139 |
# 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 |
#migration_info_table ⇒ Object
Quoted table name, for the adapter
273 274 275 |
# File 'lib/dm-migrations/migration.rb', line 273 def migration_info_table @migration_info_table ||= quote_table_name('migration_info') end |
#migration_info_table_exists? ⇒ Boolean
247 248 249 |
# File 'lib/dm-migrations/migration.rb', line 247 def migration_info_table_exists? adapter.storage_exists?('migration_info') end |
#migration_name_column ⇒ Object
Quoted ‘migration_name` column, for the adapter
278 279 280 |
# File 'lib/dm-migrations/migration.rb', line 278 def migration_name_column @migration_name_column ||= quote_column_name('migration_name') end |
#migration_record ⇒ Object
Fetch the record for this migration out of the migration_info table
252 253 254 255 256 |
# File 'lib/dm-migrations/migration.rb', line 252 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 |
#modify_table(table_name, opts = {}, &block) ⇒ Object
169 170 171 172 173 |
# File 'lib/dm-migrations/migration.rb', line 169 def modify_table(table_name, opts = {}, &block) TableModifier.new(adapter, table_name, opts, &block).statements.each do |sql| execute(sql) end end |
#needs_down? ⇒ Boolean
True if the migration has already been run
266 267 268 269 270 |
# File 'lib/dm-migrations/migration.rb', line 266 def needs_down? return false unless migration_info_table_exists? !migration_record.empty? end |
#needs_up? ⇒ Boolean
True if the migration needs to be run
259 260 261 262 263 |
# File 'lib/dm-migrations/migration.rb', line 259 def needs_up? return true unless migration_info_table_exists? migration_record.empty? end |
#perform_down ⇒ Object
un-do the migration by running the code in the #down block
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# 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_up ⇒ Object
perform the migration by running the code in the #up block
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# 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 |
#quote_column_name(column_name) ⇒ Object
287 288 289 290 |
# File 'lib/dm-migrations/migration.rb', line 287 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 |
#quote_table_name(table_name) ⇒ Object
282 283 284 285 |
# File 'lib/dm-migrations/migration.rb', line 282 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 |
#quoted_name ⇒ Object
Quote the name of the migration for use in SQL
243 244 245 |
# File 'lib/dm-migrations/migration.rb', line 243 def quoted_name "'#{name}'" end |
#say(message, indent = 4) ⇒ Object
Output some text. Optional indent level
202 203 204 |
# File 'lib/dm-migrations/migration.rb', line 202 def say(, indent = 4) write "#{' ' * indent} #{}" end |
#say_with_time(message, indent = 2) ⇒ Object
Time how long the block takes to run, and output it with the message.
207 208 209 210 211 212 213 |
# File 'lib/dm-migrations/migration.rb', line 207 def say_with_time(, indent = 2) say(, indent) result = nil time = Benchmark.measure { result = yield } say('-> %.4fs' % time.real, indent) result end |
#select(sql, *bind_values) ⇒ Array<Struct>
Execute raw SQL and return a result set.
155 156 157 158 159 |
# File 'lib/dm-migrations/migration.rb', line 155 def select(sql, *bind_values) say_with_time(sql) do adapter.select(sql, *bind_values) end end |
#up(&block) ⇒ Object
define the actions that should be performed on an up migration
85 86 87 |
# File 'lib/dm-migrations/migration.rb', line 85 def up(&block) @up_action = block end |
#update_migration_info(direction) ⇒ Object
Inserts or removes a row into the ‘migration_info` table, so we can mark this migration as run, or un-done
221 222 223 224 225 226 227 228 229 230 231 232 233 |
# File 'lib/dm-migrations/migration.rb', line 221 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 |
#write(text = '') ⇒ Object
output the given text, but only if verbose mode is on
216 217 218 |
# File 'lib/dm-migrations/migration.rb', line 216 def write(text = '') puts text if @verbose end |