Class: RubynCode::DB::Migrator
- Inherits:
-
Object
- Object
- RubynCode::DB::Migrator
- Defined in:
- lib/rubyn_code/db/migrator.rb
Overview
Reads migration files from db/migrations/, tracks applied versions in a schema_migrations table, and applies new migrations in order.
Supports two migration formats:
-
‘.sql` files: executed statement-by-statement inside a transaction
-
‘.rb` files: loaded and called via `ModuleName.up(connection)`
Constant Summary collapse
- MIGRATIONS_DIR =
Returns absolute path to the migrations directory.
File.('../../../db/migrations', __dir__).freeze
Instance Method Summary collapse
-
#applied_versions ⇒ Set<Integer>
Returns the set of already-applied migration versions.
-
#available_migrations ⇒ Array<Array(Integer, String)>
Lists all available migration files sorted by version.
-
#current_version ⇒ Integer?
Returns the current schema version (highest applied migration).
- #deduplicate_migrations(all) ⇒ Object
-
#initialize(connection) ⇒ Migrator
constructor
A new instance of Migrator.
-
#migrate! ⇒ Array<Integer>
Applies all pending migrations in version order.
-
#pending_migrations ⇒ Array<Array(Integer, String)>
Returns migration versions that have not yet been applied.
Constructor Details
#initialize(connection) ⇒ Migrator
Returns a new instance of Migrator.
16 17 18 19 |
# File 'lib/rubyn_code/db/migrator.rb', line 16 def initialize(connection) @connection = connection ensure_schema_migrations_table end |
Instance Method Details
#applied_versions ⇒ Set<Integer>
Returns the set of already-applied migration versions.
47 48 49 50 51 52 |
# File 'lib/rubyn_code/db/migrator.rb', line 47 def applied_versions rows = @connection.query( 'SELECT version FROM schema_migrations ORDER BY version' ).to_a rows.to_set { |row| row['version'] } end |
#available_migrations ⇒ Array<Array(Integer, String)>
Lists all available migration files sorted by version.
67 68 69 70 71 72 73 |
# File 'lib/rubyn_code/db/migrator.rb', line 67 def available_migrations all = Dir.glob(File.join(MIGRATIONS_DIR, '*')) .select { |path| path.end_with?('.sql', '.rb') } .filter_map { |path| parse_migration_file(path) } deduplicate_migrations(all) end |
#current_version ⇒ Integer?
Returns the current schema version (highest applied migration).
57 58 59 60 61 62 |
# File 'lib/rubyn_code/db/migrator.rb', line 57 def current_version row = @connection.query( 'SELECT MAX(version) AS max_version FROM schema_migrations' ).to_a.first row && row['max_version'] end |
#deduplicate_migrations(all) ⇒ Object
75 76 77 78 79 80 81 |
# File 'lib/rubyn_code/db/migrator.rb', line 75 def deduplicate_migrations(all) by_version = {} all.each do |version, path| by_version[version] = [version, path] if !by_version[version] || path.end_with?('.rb') end by_version.values.sort_by(&:first) end |
#migrate! ⇒ Array<Integer>
Applies all pending migrations in version order.
24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/rubyn_code/db/migrator.rb', line 24 def migrate! pending = pending_migrations return [] if pending.empty? applied = [] pending.each do |version, path| apply_migration(version, path) applied << version end applied end |
#pending_migrations ⇒ Array<Array(Integer, String)>
Returns migration versions that have not yet been applied.
39 40 41 42 |
# File 'lib/rubyn_code/db/migrator.rb', line 39 def pending_migrations applied = applied_versions available_migrations.reject { |version, _| applied.include?(version) } # rubocop:disable Style/HashExcept end |