Skip to content

Commit

Permalink
Support Rails 7.1
Browse files Browse the repository at this point in the history
  • Loading branch information
wildmaples committed Jul 21, 2023
1 parent 7cb5ad5 commit f9b1cfc
Show file tree
Hide file tree
Showing 7 changed files with 208 additions and 4 deletions.
1 change: 1 addition & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ jobs:
gemfile:
- gemfiles/rails_6.1.gemfile
- gemfiles/rails_7.0.gemfile
- gemfiles/rails_7.1.0.alpha.gemfile
runs-on: ubuntu-latest
env:
BUNDLE_GEMFILE: ${{ matrix.gemfile }}
Expand Down
4 changes: 4 additions & 0 deletions Appraisals
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@ end
appraise 'rails-7.0' do
gem 'rails', '~> 7.0'
end

appraise 'rails-7.1.0.alpha' do
gem 'rails', git: "https://github.com/rails/rails.git", branch: "main"
end
8 changes: 8 additions & 0 deletions gemfiles/rails_7.1.0.alpha.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# This file was generated by Appraisal

source "http://rubygems.org"

gem "sqlite3", "~> 1.4"
gem "rails", git: "https://github.com/rails/rails.git", branch: "main"

gemspec path: "../"
15 changes: 11 additions & 4 deletions lib/data_migrate.rb
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
# frozen_string_literal: true

require File.join(File.dirname(__FILE__), "data_migrate", "data_migrator")
require File.join(File.dirname(__FILE__), "data_migrate", "data_schema_migration")
require 'active_record'
require File.join(File.dirname(__FILE__), "data_migrate", "data_schema")
require File.join(File.dirname(__FILE__), "data_migrate", "database_tasks")
require File.join(File.dirname(__FILE__), "data_migrate", "schema_dumper")
require File.join(File.dirname(__FILE__), "data_migrate", "status_service")
require File.join(File.dirname(__FILE__), "data_migrate", "migration_context")
require File.join(File.dirname(__FILE__), "data_migrate", "railtie")
require File.join(File.dirname(__FILE__), "data_migrate", "tasks/data_migrate_tasks")
require File.join(File.dirname(__FILE__), "data_migrate", "legacy_migrator")
require File.join(File.dirname(__FILE__), "data_migrate", "config")
require File.join(File.dirname(__FILE__), "data_migrate", "schema_migration")

if Gem::Dependency.new("railties", "~> 7.1").match?("railties", Gem.loaded_specs["railties"].version)
require File.join(File.dirname(__FILE__), "data_migrate", "schema_migration_seven_one")
require File.join(File.dirname(__FILE__), "data_migrate", "data_migrator_seven_one")
require File.join(File.dirname(__FILE__), "data_migrate", "data_schema_migration_seven_one")
else
require File.join(File.dirname(__FILE__), "data_migrate", "schema_migration")
require File.join(File.dirname(__FILE__), "data_migrate", "data_migrator")
require File.join(File.dirname(__FILE__), "data_migrate", "data_schema_migration")
end

module DataMigrate
def self.root
Expand Down
97 changes: 97 additions & 0 deletions lib/data_migrate/data_migrator_seven_one.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# frozen_string_literal: true

require "data_migrate/config"

module DataMigrate
class DataMigrator < ActiveRecord::Migrator
def self.migrations_paths
[DataMigrate.config.data_migrations_path]
end

def self.assure_data_schema_table
ActiveRecord::Base.establish_connection(db_config)
DataMigrate::DataSchemaMigration.create_table
end

def initialize(direction, migrations, target_version = nil)
@direction = direction
@target_version = target_version
@migrated_versions = nil
@migrations = migrations
@schema_migration = ActiveRecord::Base.connection.schema_migration
@internal_metadata = ActiveRecord::Base.connection.internal_metadata

validate(@migrations)

DataMigrate::DataSchemaMigration.create_table
@internal_metadata.create_table
end

def load_migrated
@migrated_versions =
DataMigrate::DataSchemaMigration.normalized_versions.map(&:to_i).sort
end

class << self
def current_version
DataMigrate::MigrationContext.new(migrations_paths).current_version
end

##
# Compares the given filename with what we expect data migration
# filenames to be, eg the "20091231235959_some_name.rb" pattern
# @param (String) filename
# @return (MatchData)
def match(filename)
/(\d{14})_(.+)\.rb$/.match(filename)
end

def needs_migration?
DataMigrate::DatabaseTasks.pending_migrations.count.positive?
end
##
# Provides the full migrations_path filepath
# @return (String)
def full_migrations_path
File.join(Rails.root, *migrations_paths.split(File::SEPARATOR))
end

def migrations_status
DataMigrate::MigrationContext.new(migrations_paths).migrations_status
end

# TODO: this was added to be backward compatible, need to re-evaluate
def migrations(_migrations_paths)
#DataMigrate::MigrationContext.new(migrations_paths).migrations
DataMigrate::MigrationContext.new(_migrations_paths).migrations
end

#TODO: this was added to be backward compatible, need to re-evaluate
def run(direction, migration_paths, version)
DataMigrate::MigrationContext.new(migration_paths).run(direction, version)
end

def rollback(migrations_path, steps)
DataMigrate::MigrationContext.new(migrations_path).rollback(steps)
end

def db_config
env = Rails.env || "development"
ar_config = ActiveRecord::Base.configurations.configs_for(env_name: env).first
ar_config || ENV["DATABASE_URL"]
end
end

private

def record_version_state_after_migrating(version)
if down?
migrated.delete(version)
DataMigrate::DataSchemaMigration.delete_version(version: version.to_s)
else
migrated << version
DataMigrate::DataSchemaMigration.create!(version: version.to_s)
end
end
end
end
26 changes: 26 additions & 0 deletions lib/data_migrate/data_schema_migration_seven_one.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
module DataMigrate
class DataSchemaMigration
class << self
delegate :table_name, :primary_key, :create_table, :normalized_versions, :create_version, :create!, :table_exists?, :exists?, :where, to: :instance

def instance
@instance ||= Class.new(::ActiveRecord::SchemaMigration) do
define_method(:table_name) { ActiveRecord::Base.table_name_prefix + 'data_migrations' + ActiveRecord::Base.table_name_suffix }
define_method(:primary_key) { "version" }
end.new(ActiveRecord::Base.connection)
end

def delete_version(version:)
instance.delete_version(version)
end

def create(version:)
instance.create_version(version)
end

def create!(version:)
instance.create_version(version)
end
end
end
end
61 changes: 61 additions & 0 deletions lib/data_migrate/schema_migration_seven_one.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
module DataMigrate
# Helper class to getting access to db schema
# to allow data/schema combination tasks
class SchemaMigration
def self.pending_schema_migrations
all_migrations = DataMigrate::MigrationContext.new(migrations_paths).migrations
sort_migrations(
ActiveRecord::Migrator.new(:up, all_migrations, ActiveRecord::Base.connection.schema_migration, ActiveRecord::Base.connection.internal_metadata).
pending_migrations.
map {|m| { version: m.version, kind: :schema }}
)
end

def self.run(direction, migration_paths, version)
ActiveRecord::MigrationContext.new(migration_paths, ActiveRecord::Base.connection.schema_migration).run(direction, version)
end

def self.sort_migrations(set1, set2 = nil)
migrations = set1 + (set2 || [])
migrations.sort {|a, b| sort_string(a) <=> sort_string(b)}
end

def self.migrations_paths
spec_name = DataMigrate.config.spec_name
if spec_name
ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, name: spec_name).migrations_paths
else
Rails.application.config.paths["db/migrate"].to_a
end
end

def self.sort_string(migration)
"#{migration[:version]}_#{migration[:kind] == :data ? 1 : 0}"
end
end
end

# ActiveRecord::SchemaMigration no longer inherits from ActiveRecord::Base in Rails 7.1
# and now has updated method names. See: https://github.com/rails/rails/pull/45908
# This patch delegates SchemaMigration calls to the updated connection instance.
class ActiveRecord::SchemaMigration
class << self
delegate :create_table, :table_exists?, :normalized_versions, to: :schema_migration

def schema_migration
ActiveRecord::Base.connection.schema_migration
end
end

def self.schema_migrations_table_name
ActiveRecord::Base.connection.schema_migration.table_name
end

def self.create(version:)
ActiveRecord::Base.connection.schema_migration.create_version(version)
end

def self.normalize_migration_number(version)
ActiveRecord::Base.connection.schema_migration.normalize_migration_number(version)
end
end

0 comments on commit f9b1cfc

Please sign in to comment.