Module: Migratrix::ActiveRecordMigrationHelpers
- Defined in:
- lib/migratrix/active_record_migration_helpers.rb
Instance Method Summary collapse
-
#execute(query, msg = nil) ⇒ Object
Executes a query on this class’ connection, and logs the query or an optional message to Migratrix.log.
-
#mysql_truncate(table) ⇒ Object
MySQL ONLY: truncates a table using TRUNCATE, which drops the data very quickly and resets any autoindexing primary key to 1.
-
#psql_truncate(table) ⇒ Object
PostGreSQL ONLY: truncates a table by deleting all its rows and restarting its id sequence at 1.
-
#with_mysql_indexes_disabled_on(table, *read_locked_tables, &block) ⇒ Object
MySQL ONLY: Disables indexes on a table and locks it for writing, optionally read-locks another list of tables, then yields to the given block before unlocking.
Instance Method Details
#execute(query, msg = nil) ⇒ Object
Executes a query on this class’ connection, and logs the query or an optional message to Migratrix.log.
6 7 8 9 |
# File 'lib/migratrix/active_record_migration_helpers.rb', line 6 def execute(query, msg=nil) Migratrix.log(msg || query) unless msg == false connection.execute query end |
#mysql_truncate(table) ⇒ Object
MySQL ONLY: truncates a table using TRUNCATE, which drops the data very quickly and resets any autoindexing primary key to 1.
13 14 15 |
# File 'lib/migratrix/active_record_migration_helpers.rb', line 13 def mysql_truncate(table) execute("TRUNCATE #{table}") end |
#psql_truncate(table) ⇒ Object
PostGreSQL ONLY: truncates a table by deleting all its rows and restarting its id sequence at 1.
Note: TRUNCATE was added to PostGreSQL in version 8.3, which at the time of this writing is still poorly adopted. This code works on earlier versions, is MVCC-safe, and will trigger cascading deletes.
It does NOT, however, actually look up the table’s sequence definition. It assumes the sequence for a is named a_id_seq and that it should be reset to 1. (A tiny dash of extra cleverness is all that would be needed to read start_value from the sequence, but for now this is a pure-SQL, stateless call.)
30 31 32 |
# File 'lib/migratrix/active_record_migration_helpers.rb', line 30 def psql_truncate(table) execute("DELETE FROM #{table}; ALTER SEQUENCE #{table}_id_seq RESTART WITH 1") end |
#with_mysql_indexes_disabled_on(table, *read_locked_tables, &block) ⇒ Object
MySQL ONLY: Disables indexes on a table and locks it for writing, optionally read-locks another list of tables, then yields to the given block before unlocking. This prevents MySQL from indexing the migrated data until the block is complete. This produces a significant speedup on InnoDB tables with multiple indexes. (The plural of anecdote is not data, but on one heavily-indexed table, migrating 10 million records took 38 hours with indexes enabled and under 2 hours with them disabled.)
43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/migratrix/active_record_migration_helpers.rb', line 43 def with_mysql_indexes_disabled_on(table, *read_locked_tables, &block) log "Locking table '#{table}' and disabling indexes..." lock_cmd = "LOCK TABLES `#{table}` WRITE" if read_locked_tables.andand.size > 0 lock_cmd += ', ' + (read_locked_tables.map {|t| "#{t} READ"} * ", ") end execute lock_cmd execute("/*!40000 ALTER TABLE `#{table}` DISABLE KEYS */") yield log "Unlocking table '#{table}' and re-enabling indexes..." execute("/*!40000 ALTER TABLE `#{table}` ENABLE KEYS */") execute("UNLOCK TABLES") end |