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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.ruby-style.yml +2 -0
  4. data/.travis.yml +1 -1
  5. data/Appraisals +5 -5
  6. data/Changelog.md +6 -0
  7. data/Gemfile.rails5.2 +5 -0
  8. data/README.md +4 -10
  9. data/data_migrate.gemspec +1 -1
  10. data/gemfiles/rails_5.2.gemfile +7 -0
  11. data/lib/data_migrate.rb +19 -4
  12. data/lib/data_migrate/data_migrator.rb +5 -0
  13. data/lib/data_migrate/data_migrator_five.rb +84 -0
  14. data/lib/data_migrate/data_schema.rb +29 -9
  15. data/lib/data_migrate/data_schema_migration.rb +1 -0
  16. data/lib/data_migrate/database_tasks.rb +69 -0
  17. data/lib/data_migrate/migration.rb +1 -1
  18. data/lib/data_migrate/migration_context.rb +90 -0
  19. data/lib/data_migrate/schema_dumper.rb +1 -3
  20. data/lib/data_migrate/schema_migration.rb +31 -0
  21. data/lib/data_migrate/schema_migration_five.rb +31 -0
  22. data/lib/data_migrate/status_service.rb +1 -1
  23. data/lib/data_migrate/status_service_five.rb +48 -0
  24. data/lib/data_migrate/tasks/data_migrate_tasks.rb +25 -0
  25. data/lib/data_migrate/version.rb +1 -1
  26. data/lib/generators/data_migration/data_migration_generator.rb +3 -1
  27. data/spec/data_migrate/data_migrator_spec.rb +1 -13
  28. data/spec/data_migrate/{data_schema_spec.rb → data_spec.rb} +7 -5
  29. data/spec/data_migrate/database_tasks_spec.rb +96 -0
  30. data/spec/data_migrate/migration_context_spec.rb +107 -0
  31. data/spec/data_migrate/schema_dumper_spec.rb +5 -3
  32. data/spec/data_migrate/schema_migration_spec.rb +69 -0
  33. data/spec/data_migrate/status_service_spec.rb +15 -18
  34. data/spec/data_migrate/tasks/data_migrate_tasks_spec.rb +50 -0
  35. data/spec/db/4.2/20091231235959_some_name.rb +9 -0
  36. data/spec/db/4.2/20171231235959_super_update.rb +9 -0
  37. data/spec/db/5.0/20091231235959_some_name.rb +9 -0
  38. data/spec/db/5.0/20171231235959_super_update.rb +9 -0
  39. data/spec/db/data/20091231235959_some_name.rb +9 -0
  40. data/spec/db/data/20171231235959_super_update.rb +9 -0
  41. data/spec/db/migrate/4.2/20131111111111_late_migration.rb +9 -0
  42. data/spec/db/migrate/4.2/20202020202011_db_migration.rb +9 -0
  43. data/spec/db/migrate/5.0/20131111111111_late_migration.rb +9 -0
  44. data/spec/db/migrate/5.0/20202020202011_db_migration.rb +9 -0
  45. data/spec/db/migrate/5.2/20131111111111_late_migration.rb +9 -0
  46. data/spec/db/migrate/5.2/20202020202011_db_migration.rb +9 -0
  47. data/spec/spec_helper.rb +4 -0
  48. metadata +41 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 26625c3d1527400f57850a3ca1932d96f6416cbc
4
- data.tar.gz: 95a2a2d587eed28a7f228bb61b4d928f7a9205bb
3
+ metadata.gz: 513041c34e205e9f58b811e7b91a667d2383faaf
4
+ data.tar.gz: e33fbb5f528b37e747639225e7e05d9205ea4019
5
5
  SHA512:
6
- metadata.gz: a2ba6be64d1fe490b91cc2cf6511270747aba5ab363694b77503c272528ca81a60700d7c012c16eae748da5b9ba5153bd20b715e686032bde75e9ad8c415f8fb
7
- data.tar.gz: e58fc200e080c68b8dcc60e2430abccdf3065555df7edfedfbf66cef25e3406292a084648f9012242de16eb9cb266feee810d8d6327bbf2a6605a8aad63c0a8d
6
+ metadata.gz: 3352d4c800ad8cac090b0b4bb92e3fc646b16a54e871b88138f132b4f825581a42c1f3ff430563d6ed98c559129371e0dd0736466a328518405ddfd920204c3f
7
+ data.tar.gz: a93f9ed99ab3e6c346dacd1e3d5ce4ecfaf9c80cfa2d66ece9eb9177d72e2dccfdfacc60e0373f138582975bb3170a940e4974d2b5573e751a463d555e650e7d
data/.gitignore CHANGED
@@ -5,3 +5,4 @@ gemfiles/.bundle
5
5
  spec/db/test.db
6
6
  .vscode/
7
7
  tasks/databases.rake
8
+ .DS_Store
data/.ruby-style.yml CHANGED
@@ -1057,3 +1057,5 @@ Style/FrozenStringLiteralComment:
1057
1057
  Enabled: false
1058
1058
  Layout/SpaceBeforeFirstArg:
1059
1059
  Enabled: false
1060
+ Style/FormatStringToken:
1061
+ Enabled: false
data/.travis.yml CHANGED
@@ -4,10 +4,10 @@ rvm:
4
4
  - 2.3.4
5
5
  script: bundle exec rspec
6
6
  gemfile:
7
- - gemfiles/rails_4.1.gemfile
8
7
  - gemfiles/rails_4.2.gemfile
9
8
  - gemfiles/rails_5.0.gemfile
10
9
  - gemfiles/rails_5.1.gemfile
10
+ - gemfiles/rails_5.2.gemfile
11
11
  matrix:
12
12
  exclude:
13
13
  - rvm: 2.0.0-p648
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
@@ -1,6 +1,12 @@
1
1
  Changelog
2
2
  =========
3
3
 
4
+ ## 4.0.0
5
+
6
+ Support for Rails 5.2
7
+ Deprecated support for Rails 4.1
8
+ Internal changes to make data-migrate behavior more similar to Rails migrations
9
+
4
10
  ## 3.5.0
5
11
 
6
12
  Deprecated support for rails 4.0
data/Gemfile.rails5.2 ADDED
@@ -0,0 +1,5 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in data_migrate.gemspec
4
+ gemspec
5
+ gem 'rails', '~> 5.2'
data/README.md CHANGED
@@ -69,13 +69,7 @@ table to track all the goodness.
69
69
 
70
70
  ## Rails Support
71
71
 
72
- Rails 3.1: Version 1.2 supports Rails 3.1.0 and higher **but** is no longer maintained.
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.1')
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"
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "rails", "~> 5.2.0"
6
+
7
+ gemspec path: "../"
data/lib/data_migrate.rb CHANGED
@@ -1,15 +1,30 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require File.join(File.dirname(__FILE__), "data_migrate", "data_migrator")
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
- require File.join(File.dirname(__FILE__), "data_migrate", "status_service")
10
- if Rails::VERSION::MAJOR >= 5
11
- require File.join(File.dirname(__FILE__), "data_migrate", "migration_five")
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
@@ -1,5 +1,6 @@
1
1
  module DataMigrate
2
2
  class DataSchemaMigration < ::ActiveRecord::SchemaMigration
3
+
3
4
  class << self
4
5
  def table_name
5
6
  ActiveRecord::Base.table_name_prefix + 'data_migrations' + ActiveRecord::Base.table_name_suffix
@@ -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 + 'data_migrations' + ActiveRecord::Base.table_name_suffix
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