data_migrate 3.5.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.ruby-style.yml +2 -0
- data/.travis.yml +1 -1
- data/Appraisals +5 -5
- data/Changelog.md +6 -0
- data/Gemfile.rails5.2 +5 -0
- data/README.md +4 -10
- data/data_migrate.gemspec +1 -1
- data/gemfiles/rails_5.2.gemfile +7 -0
- data/lib/data_migrate.rb +19 -4
- data/lib/data_migrate/data_migrator.rb +5 -0
- data/lib/data_migrate/data_migrator_five.rb +84 -0
- data/lib/data_migrate/data_schema.rb +29 -9
- data/lib/data_migrate/data_schema_migration.rb +1 -0
- data/lib/data_migrate/database_tasks.rb +69 -0
- data/lib/data_migrate/migration.rb +1 -1
- data/lib/data_migrate/migration_context.rb +90 -0
- data/lib/data_migrate/schema_dumper.rb +1 -3
- data/lib/data_migrate/schema_migration.rb +31 -0
- data/lib/data_migrate/schema_migration_five.rb +31 -0
- data/lib/data_migrate/status_service.rb +1 -1
- data/lib/data_migrate/status_service_five.rb +48 -0
- data/lib/data_migrate/tasks/data_migrate_tasks.rb +25 -0
- data/lib/data_migrate/version.rb +1 -1
- data/lib/generators/data_migration/data_migration_generator.rb +3 -1
- data/spec/data_migrate/data_migrator_spec.rb +1 -13
- data/spec/data_migrate/{data_schema_spec.rb → data_spec.rb} +7 -5
- data/spec/data_migrate/database_tasks_spec.rb +96 -0
- data/spec/data_migrate/migration_context_spec.rb +107 -0
- data/spec/data_migrate/schema_dumper_spec.rb +5 -3
- data/spec/data_migrate/schema_migration_spec.rb +69 -0
- data/spec/data_migrate/status_service_spec.rb +15 -18
- data/spec/data_migrate/tasks/data_migrate_tasks_spec.rb +50 -0
- data/spec/db/4.2/20091231235959_some_name.rb +9 -0
- data/spec/db/4.2/20171231235959_super_update.rb +9 -0
- data/spec/db/5.0/20091231235959_some_name.rb +9 -0
- data/spec/db/5.0/20171231235959_super_update.rb +9 -0
- data/spec/db/data/20091231235959_some_name.rb +9 -0
- data/spec/db/data/20171231235959_super_update.rb +9 -0
- data/spec/db/migrate/4.2/20131111111111_late_migration.rb +9 -0
- data/spec/db/migrate/4.2/20202020202011_db_migration.rb +9 -0
- data/spec/db/migrate/5.0/20131111111111_late_migration.rb +9 -0
- data/spec/db/migrate/5.0/20202020202011_db_migration.rb +9 -0
- data/spec/db/migrate/5.2/20131111111111_late_migration.rb +9 -0
- data/spec/db/migrate/5.2/20202020202011_db_migration.rb +9 -0
- data/spec/spec_helper.rb +4 -0
- metadata +41 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 513041c34e205e9f58b811e7b91a667d2383faaf
|
4
|
+
data.tar.gz: e33fbb5f528b37e747639225e7e05d9205ea4019
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3352d4c800ad8cac090b0b4bb92e3fc646b16a54e871b88138f132b4f825581a42c1f3ff430563d6ed98c559129371e0dd0736466a328518405ddfd920204c3f
|
7
|
+
data.tar.gz: a93f9ed99ab3e6c346dacd1e3d5ce4ecfaf9c80cfa2d66ece9eb9177d72e2dccfdfacc60e0373f138582975bb3170a940e4974d2b5573e751a463d555e650e7d
|
data/.gitignore
CHANGED
data/.ruby-style.yml
CHANGED
data/.travis.yml
CHANGED
data/Appraisals
CHANGED
@@ -1,7 +1,3 @@
|
|
1
|
-
appraise 'rails-4.1' do
|
2
|
-
gem 'rails', '4.1.16'
|
3
|
-
end
|
4
|
-
|
5
1
|
appraise 'rails-4.2' do
|
6
2
|
gem 'rails', '4.2.8'
|
7
3
|
# Nokogiri 1.7+ requires Ruby 2.1+
|
@@ -14,4 +10,8 @@ end
|
|
14
10
|
|
15
11
|
appraise 'rails-5.1' do
|
16
12
|
gem 'rails', '5.1'
|
17
|
-
end
|
13
|
+
end
|
14
|
+
|
15
|
+
appraise 'rails-5.2' do
|
16
|
+
gem 'rails', '~> 5.2.0'
|
17
|
+
end
|
data/Changelog.md
CHANGED
data/Gemfile.rails5.2
ADDED
data/README.md
CHANGED
@@ -69,13 +69,7 @@ table to track all the goodness.
|
|
69
69
|
|
70
70
|
## Rails Support
|
71
71
|
|
72
|
-
Rails
|
73
|
-
|
74
|
-
Rails 4: Version 2.0 supports Rails 4.0 and higher
|
75
|
-
|
76
|
-
Rails 5.0: Supported
|
77
|
-
|
78
|
-
Rails 5.1: Supported
|
72
|
+
Support Rails 4.2 through 5.2
|
79
73
|
|
80
74
|
### Important notes for older versions
|
81
75
|
|
@@ -164,9 +158,9 @@ From now on capistrano will run `rake db:migrate:with_data` in every deploy.
|
|
164
158
|
Run tests for a specific version of Rails
|
165
159
|
|
166
160
|
```
|
167
|
-
appraisal install
|
168
|
-
appraisal rails-4.2 rspec
|
169
|
-
appraisal rails-5.0 rspec
|
161
|
+
bundle exec appraisal install
|
162
|
+
bundle exec appraisal rails-4.2 rspec
|
163
|
+
bundle exec appraisal rails-5.0 rspec
|
170
164
|
```
|
171
165
|
|
172
166
|
## Thanks
|
data/data_migrate.gemspec
CHANGED
@@ -15,7 +15,7 @@ Gem::Specification.new do |s|
|
|
15
15
|
|
16
16
|
s.rubyforge_project = "data_migrate"
|
17
17
|
|
18
|
-
s.add_dependency('rails', '>= 4.
|
18
|
+
s.add_dependency('rails', '>= 4.2')
|
19
19
|
s.add_development_dependency "appraisal"
|
20
20
|
s.add_development_dependency "rake"
|
21
21
|
s.add_development_dependency "rspec"
|
data/lib/data_migrate.rb
CHANGED
@@ -1,15 +1,30 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
if Rails::VERSION::MAJOR == 5 && Rails::VERSION::MINOR == 2
|
4
|
+
require File.join(File.dirname(__FILE__), "data_migrate", "data_migrator_five")
|
5
|
+
else
|
6
|
+
require File.join(File.dirname(__FILE__), "data_migrate", "data_migrator")
|
7
|
+
end
|
4
8
|
require File.join(File.dirname(__FILE__), "data_migrate",
|
5
9
|
"data_schema_migration")
|
6
10
|
require File.join(File.dirname(__FILE__), "data_migrate", "data_schema")
|
7
11
|
require File.join(File.dirname(__FILE__), "data_migrate", "database_tasks")
|
8
12
|
require File.join(File.dirname(__FILE__), "data_migrate", "schema_dumper")
|
9
|
-
|
10
|
-
|
11
|
-
require File.join(File.dirname(__FILE__), "data_migrate", "
|
13
|
+
if Rails::VERSION::MAJOR == 5 && Rails::VERSION::MINOR == 2
|
14
|
+
require File.join(File.dirname(__FILE__), "data_migrate", "status_service_five")
|
15
|
+
require File.join(File.dirname(__FILE__), "data_migrate", "schema_migration_five")
|
16
|
+
else
|
17
|
+
require File.join(File.dirname(__FILE__), "data_migrate", "status_service")
|
18
|
+
require File.join(File.dirname(__FILE__), "data_migrate", "schema_migration")
|
19
|
+
end
|
20
|
+
if Rails::VERSION::MAJOR == 5
|
21
|
+
if Rails::VERSION::MINOR == 2
|
22
|
+
require File.join(File.dirname(__FILE__), "data_migrate", "migration_context")
|
23
|
+
else
|
24
|
+
require File.join(File.dirname(__FILE__), "data_migrate", "migration_five")
|
25
|
+
end
|
12
26
|
else
|
13
27
|
require File.join(File.dirname(__FILE__), "data_migrate", "migration")
|
14
28
|
end
|
15
29
|
require File.join(File.dirname(__FILE__), "data_migrate", "railtie")
|
30
|
+
require File.join(File.dirname(__FILE__), "data_migrate", "tasks/data_migrate_tasks")
|
@@ -16,7 +16,12 @@ module DataMigrate
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
+
|
19
20
|
class << self
|
21
|
+
def current_version(connection = ActiveRecord::Base.connection)
|
22
|
+
get_all_versions(connection).max || 0
|
23
|
+
end
|
24
|
+
|
20
25
|
def get_all_versions(connection = ActiveRecord::Base.connection)
|
21
26
|
if table_exists?(connection, schema_migrations_table_name)
|
22
27
|
# Certain versions of the gem wrote data migration versions into
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_record"
|
4
|
+
|
5
|
+
module DataMigrate
|
6
|
+
class DataMigrator < ActiveRecord::Migrator
|
7
|
+
self.migrations_paths = ["db/data"]
|
8
|
+
|
9
|
+
def self.assure_data_schema_table
|
10
|
+
DataMigrate::DataSchemaMigration.create_table
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(direction, migrations, target_version = nil)
|
14
|
+
@direction = direction
|
15
|
+
@target_version = target_version
|
16
|
+
@migrated_versions = nil
|
17
|
+
@migrations = migrations
|
18
|
+
|
19
|
+
validate(@migrations)
|
20
|
+
|
21
|
+
DataMigrate::DataSchemaMigration.create_table
|
22
|
+
ActiveRecord::InternalMetadata.create_table
|
23
|
+
end
|
24
|
+
|
25
|
+
def load_migrated
|
26
|
+
# Certain versions of the gem wrote data migration versions into
|
27
|
+
# schema_migrations table. After the fix, it was corrected to write into
|
28
|
+
# data_migrations. However, not to break anything we are going to
|
29
|
+
# get versions from both tables.
|
30
|
+
#
|
31
|
+
# This may cause some problems:
|
32
|
+
# Eg. rake data:versions will show version from the schema_migrations table
|
33
|
+
# which may be a version of actual schema migration and not data migration
|
34
|
+
@migrated_versions =
|
35
|
+
DataMigrate::DataSchemaMigration.normalized_versions.map(&:to_i).sort +
|
36
|
+
ActiveRecord::SchemaMigration.normalized_versions.map(&:to_i).sort
|
37
|
+
end
|
38
|
+
|
39
|
+
class << self
|
40
|
+
def current_version
|
41
|
+
DataMigrate::MigrationContext.new(migrations_paths).current_version
|
42
|
+
end
|
43
|
+
|
44
|
+
##
|
45
|
+
# Compares the given filename with what we expect data migration
|
46
|
+
# filenames to be, eg the "20091231235959_some_name.rb" pattern
|
47
|
+
# @param (String) filename
|
48
|
+
# @return (MatchData)
|
49
|
+
def match(filename)
|
50
|
+
/(\d{14})_(.+)\.rb/.match(filename)
|
51
|
+
end
|
52
|
+
|
53
|
+
def migrations_status
|
54
|
+
DataMigrate::MigrationContext.new(migrations_paths).migrations_status
|
55
|
+
end
|
56
|
+
|
57
|
+
#TODO: this was added to be backward compatible, need to re-evaluate
|
58
|
+
def migrations(_migrations_paths)
|
59
|
+
DataMigrate::MigrationContext.new(migrations_paths).migrations
|
60
|
+
end
|
61
|
+
|
62
|
+
#TODO: this was added to be backward compatible, need to re-evaluate
|
63
|
+
def run(direction, migration_paths, version)
|
64
|
+
DataMigrate::MigrationContext.new(migration_paths).run(direction, version)
|
65
|
+
end
|
66
|
+
|
67
|
+
def rollback(migrations_path, steps)
|
68
|
+
DataMigrate::MigrationContext.new(migrations_path).rollback(steps)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def record_version_state_after_migrating(version)
|
75
|
+
if down?
|
76
|
+
migrated.delete(version)
|
77
|
+
DataMigrate::DataSchemaMigration.where(version: version.to_s).delete_all
|
78
|
+
else
|
79
|
+
migrated << version
|
80
|
+
DataMigrate::DataSchemaMigration.create!(version: version.to_s)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -14,20 +14,32 @@ module DataMigrate
|
|
14
14
|
return if info[:version].blank?
|
15
15
|
|
16
16
|
version = info[:version].to_i
|
17
|
-
table_name = DataMigrate::DataMigrator.schema_migrations_table_name
|
18
|
-
sm_table = quote_table_name(table_name)
|
19
|
-
migrated = select_values("SELECT version FROM #{sm_table}").map(&:to_i)
|
20
|
-
|
21
|
-
versions = []
|
22
|
-
Dir.foreach(DataMigrate::DataMigrator.full_migrations_path) do |file|
|
23
|
-
match_data = DataMigrate::DataMigrator.match(file)
|
24
|
-
versions << match_data[1].to_i if match_data
|
25
|
-
end
|
26
17
|
|
27
18
|
unless migrated.include?(version)
|
28
19
|
execute "INSERT INTO #{sm_table} (version) VALUES ('#{version}')"
|
29
20
|
end
|
30
21
|
|
22
|
+
insert(version)
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def migrated
|
28
|
+
@migrated ||= select_values("SELECT version FROM #{sm_table}").map(&:to_i)
|
29
|
+
end
|
30
|
+
|
31
|
+
def versions
|
32
|
+
@versions ||= begin
|
33
|
+
versions = []
|
34
|
+
Dir.foreach(DataMigrate::DataMigrator.full_migrations_path) do |file|
|
35
|
+
match_data = DataMigrate::DataMigrator.match(file)
|
36
|
+
versions << match_data[1].to_i if match_data
|
37
|
+
end
|
38
|
+
versions
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def insert(version)
|
31
43
|
inserted = Set.new
|
32
44
|
(versions - migrated).each do |v|
|
33
45
|
if inserted.include?(v)
|
@@ -39,5 +51,13 @@ module DataMigrate
|
|
39
51
|
end
|
40
52
|
end
|
41
53
|
end
|
54
|
+
|
55
|
+
def sm_table
|
56
|
+
quote_table_name(table_name)
|
57
|
+
end
|
58
|
+
|
59
|
+
def table_name
|
60
|
+
DataMigrate::DataSchemaMigration.table_name
|
61
|
+
end
|
42
62
|
end
|
43
63
|
end
|
@@ -9,5 +9,74 @@ module DataMigrate
|
|
9
9
|
def self.data_schema_file
|
10
10
|
File.join(db_dir, "data_schema.rb")
|
11
11
|
end
|
12
|
+
|
13
|
+
def self.forward(step = 1)
|
14
|
+
DataMigrate::DataMigrator.assure_data_schema_table
|
15
|
+
migrations = pending_migrations.reverse.pop(step).reverse
|
16
|
+
migrations.each do | pending_migration |
|
17
|
+
if pending_migration[:kind] == :data
|
18
|
+
ActiveRecord::Migration.write("== %s %s" % ["Data", "=" * 71])
|
19
|
+
DataMigrate::DataMigrator.run(:up, data_migrations_path, pending_migration[:version])
|
20
|
+
elsif pending_migration[:kind] == :schema
|
21
|
+
ActiveRecord::Migration.write("== %s %s" % ["Schema", "=" * 69])
|
22
|
+
DataMigrate::SchemaMigration.run(:up, schema_migrations_path, pending_migration[:version])
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.data_migrations_path
|
28
|
+
"db/data/"
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.schema_migrations_path
|
32
|
+
"db/migrate/"
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.pending_migrations
|
36
|
+
sort_migrations(pending_schema_migrations, pending_data_migrations)
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.pending_data_migrations
|
40
|
+
data_migrations = DataMigrate::DataMigrator.migrations(data_migrations_path)
|
41
|
+
sort_migrations(DataMigrate::DataMigrator.new(:up, data_migrations ).
|
42
|
+
pending_migrations.map {|m| { version: m.version, kind: :data }})
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.pending_schema_migrations
|
46
|
+
::DataMigrate::SchemaMigration.pending_schema_migrations
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.sort_migrations(set1, set2 = nil)
|
50
|
+
migrations = set1 + (set2 || [])
|
51
|
+
migrations.sort {|a, b| sort_string(a) <=> sort_string(b)}
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.sort_string(migration)
|
55
|
+
"#{migration[:version]}_#{migration[:kind] == :data ? 1 : 0}"
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.past_migrations(sort = nil)
|
59
|
+
sort = sort.downcase if sort
|
60
|
+
db_list_data =
|
61
|
+
if DataMigrate::DataSchemaMigration.table_exists?
|
62
|
+
DataMigrate::DataSchemaMigration.normalized_versions.sort
|
63
|
+
else
|
64
|
+
[]
|
65
|
+
end
|
66
|
+
db_list_schema = ActiveRecord::SchemaMigration.normalized_versions.sort.sort
|
67
|
+
migrations = db_list_data.map do |d|
|
68
|
+
{
|
69
|
+
version: d.to_i, kind: :data
|
70
|
+
}
|
71
|
+
end +
|
72
|
+
db_list_schema.map do |d|
|
73
|
+
{
|
74
|
+
version: d.to_i, kind: :schema
|
75
|
+
}
|
76
|
+
end
|
77
|
+
|
78
|
+
sort == "asc" ? sort_migrations(migrations) : sort_migrations(migrations).reverse
|
79
|
+
end
|
80
|
+
|
12
81
|
end
|
13
82
|
end
|
@@ -11,7 +11,7 @@ module DataMigrate
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def table_name
|
14
|
-
ActiveRecord::Base.table_name_prefix +
|
14
|
+
ActiveRecord::Base.table_name_prefix + "data_migrations" + ActiveRecord::Base.table_name_suffix
|
15
15
|
end
|
16
16
|
|
17
17
|
def index_name
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module DataMigrate
|
2
|
+
class MigrationContext < ActiveRecord::MigrationContext
|
3
|
+
def initialize(migrations_paths = "db/data")
|
4
|
+
@migrations_paths = migrations_paths || "db/data"
|
5
|
+
end
|
6
|
+
|
7
|
+
def up(target_version = nil)
|
8
|
+
selected_migrations = if block_given?
|
9
|
+
migrations.select { |m| yield m }
|
10
|
+
else
|
11
|
+
migrations
|
12
|
+
end
|
13
|
+
|
14
|
+
DataMigrator.new(:up, selected_migrations, target_version).migrate
|
15
|
+
end
|
16
|
+
|
17
|
+
def down(target_version = nil)
|
18
|
+
selected_migrations =
|
19
|
+
if block_given?
|
20
|
+
migrations.select { |m| yield m }
|
21
|
+
else
|
22
|
+
migrations
|
23
|
+
end
|
24
|
+
|
25
|
+
DataMigrator.new(:down, selected_migrations, target_version).migrate
|
26
|
+
end
|
27
|
+
|
28
|
+
def run(direction, target_version)
|
29
|
+
DataMigrator.new(direction, migrations, target_version).run
|
30
|
+
end
|
31
|
+
|
32
|
+
def current_version
|
33
|
+
get_all_versions.max || 0
|
34
|
+
rescue ActiveRecord::NoDatabaseError
|
35
|
+
end
|
36
|
+
|
37
|
+
def migration_files
|
38
|
+
paths = Array(migrations_paths)
|
39
|
+
Dir[*paths.flat_map { |path| "#{path}/**/[0-9]*_*.rb" }]
|
40
|
+
end
|
41
|
+
|
42
|
+
def migrations_status
|
43
|
+
db_list = DataSchemaMigration.normalized_versions
|
44
|
+
|
45
|
+
file_list = migration_files.map do |file|
|
46
|
+
version, name, scope = parse_migration_filename(file)
|
47
|
+
raise ActiveRecord::IllegalMigrationNameError.new(file) unless version
|
48
|
+
version = ActiveRecord::SchemaMigration.normalize_migration_number(version)
|
49
|
+
status = db_list.delete(version) ? "up" : "down"
|
50
|
+
[status, version, (name + scope).humanize]
|
51
|
+
end.compact
|
52
|
+
|
53
|
+
db_list.map! do |version|
|
54
|
+
["up", version, "********** NO FILE **********"]
|
55
|
+
end
|
56
|
+
|
57
|
+
(db_list + file_list).sort_by { |_, version, _| version }
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def get_all_versions
|
63
|
+
if DataMigrate::DataSchemaMigration.table_exists?
|
64
|
+
DataSchemaMigration.normalized_versions.map(&:to_i)
|
65
|
+
else
|
66
|
+
[]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def move(direction, steps)
|
71
|
+
migrator = DataMigrator.new(direction, migrations)
|
72
|
+
|
73
|
+
if current_version != 0 && !migrator.current_migration
|
74
|
+
raise ActiveRecord::UnknownMigrationVersionError.new(current_version)
|
75
|
+
end
|
76
|
+
|
77
|
+
start_index =
|
78
|
+
if current_version.zero?
|
79
|
+
0
|
80
|
+
else
|
81
|
+
migrator.migrations.index(migrator.current_migration)
|
82
|
+
end
|
83
|
+
|
84
|
+
finish = migrator.migrations[start_index + steps]
|
85
|
+
version = finish ? finish.version : 0
|
86
|
+
send(direction, version)
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
end
|