data_migrate 3.0.1 → 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 (66) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +6 -1
  3. data/.hound.yml +4 -0
  4. data/.overcommit.yml +21 -0
  5. data/.rspec +3 -0
  6. data/.rubocop.yml +2 -0
  7. data/.ruby-style.yml +1061 -0
  8. data/.travis.yml +16 -0
  9. data/Appraisals +17 -0
  10. data/Changelog.md +35 -0
  11. data/Gemfile.rails5 +5 -0
  12. data/Gemfile.rails5.1 +5 -0
  13. data/Gemfile.rails5.2 +5 -0
  14. data/README.md +58 -41
  15. data/data_migrate.gemspec +12 -1
  16. data/gemfiles/rails_4.1.gemfile +7 -0
  17. data/gemfiles/rails_4.2.gemfile +8 -0
  18. data/gemfiles/rails_5.0.gemfile +7 -0
  19. data/gemfiles/rails_5.1.gemfile +7 -0
  20. data/gemfiles/rails_5.2.gemfile +7 -0
  21. data/lib/data_migrate/data_migrator.rb +53 -8
  22. data/lib/data_migrate/data_migrator_five.rb +84 -0
  23. data/lib/data_migrate/data_schema.rb +63 -0
  24. data/lib/data_migrate/data_schema_migration.rb +1 -0
  25. data/lib/data_migrate/database_tasks.rb +82 -0
  26. data/lib/data_migrate/migration.rb +1 -1
  27. data/lib/data_migrate/migration_context.rb +90 -0
  28. data/lib/data_migrate/migration_five.rb +26 -0
  29. data/lib/data_migrate/railtie.rb +1 -1
  30. data/lib/data_migrate/schema_dumper.rb +42 -0
  31. data/lib/data_migrate/schema_migration.rb +31 -0
  32. data/lib/data_migrate/schema_migration_five.rb +31 -0
  33. data/lib/data_migrate/status_service.rb +65 -0
  34. data/lib/data_migrate/status_service_five.rb +48 -0
  35. data/lib/data_migrate/tasks/data_migrate_tasks.rb +25 -0
  36. data/lib/data_migrate/version.rb +1 -1
  37. data/lib/data_migrate.rb +30 -4
  38. data/lib/generators/data_migration/data_migration_generator.rb +17 -16
  39. data/lib/generators/data_migration/templates/data_migration.rb +4 -4
  40. data/screenshot.png +0 -0
  41. data/spec/data_migrate/data_migrator_spec.rb +50 -0
  42. data/spec/data_migrate/data_schema_migration_spec.rb +16 -0
  43. data/spec/data_migrate/data_spec.rb +87 -0
  44. data/spec/data_migrate/database_tasks_spec.rb +114 -0
  45. data/spec/data_migrate/migration.rb +19 -0
  46. data/spec/data_migrate/migration_context_spec.rb +107 -0
  47. data/spec/data_migrate/schema_dumper_spec.rb +46 -0
  48. data/spec/data_migrate/schema_migration_spec.rb +69 -0
  49. data/spec/data_migrate/status_service_spec.rb +93 -0
  50. data/spec/data_migrate/tasks/data_migrate_tasks_spec.rb +50 -0
  51. data/spec/db/4.2/20091231235959_some_name.rb +9 -0
  52. data/spec/db/4.2/20171231235959_super_update.rb +9 -0
  53. data/spec/db/5.0/20091231235959_some_name.rb +9 -0
  54. data/spec/db/5.0/20171231235959_super_update.rb +9 -0
  55. data/spec/db/data/20091231235959_some_name.rb +9 -0
  56. data/spec/db/data/20171231235959_super_update.rb +9 -0
  57. data/spec/db/migrate/4.2/20131111111111_late_migration.rb +9 -0
  58. data/spec/db/migrate/4.2/20202020202011_db_migration.rb +9 -0
  59. data/spec/db/migrate/5.0/20131111111111_late_migration.rb +9 -0
  60. data/spec/db/migrate/5.0/20202020202011_db_migration.rb +9 -0
  61. data/spec/db/migrate/5.2/20131111111111_late_migration.rb +9 -0
  62. data/spec/db/migrate/5.2/20202020202011_db_migration.rb +9 -0
  63. data/spec/generators/data_migration/data_migration_generator_spec.rb +27 -0
  64. data/spec/spec_helper.rb +9 -0
  65. data/tasks/databases.rake +69 -62
  66. metadata +221 -6
data/.travis.yml ADDED
@@ -0,0 +1,16 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.6
4
+ - 2.3.4
5
+ script: bundle exec rspec
6
+ gemfile:
7
+ - gemfiles/rails_4.2.gemfile
8
+ - gemfiles/rails_5.0.gemfile
9
+ - gemfiles/rails_5.1.gemfile
10
+ - gemfiles/rails_5.2.gemfile
11
+ matrix:
12
+ exclude:
13
+ - rvm: 2.0.0-p648
14
+ gemfile: gemfiles/rails_5.0.gemfile
15
+ - rvm: 2.1.10
16
+ gemfile: gemfiles/rails_5.0.gemfile
data/Appraisals ADDED
@@ -0,0 +1,17 @@
1
+ appraise 'rails-4.2' do
2
+ gem 'rails', '4.2.8'
3
+ # Nokogiri 1.7+ requires Ruby 2.1+
4
+ gem 'nokogiri', '1.6.8.1'
5
+ end
6
+
7
+ appraise 'rails-5.0' do
8
+ gem 'rails', '5.0.3'
9
+ end
10
+
11
+ appraise 'rails-5.1' do
12
+ gem 'rails', '5.1'
13
+ end
14
+
15
+ appraise 'rails-5.2' do
16
+ gem 'rails', '~> 5.2.0'
17
+ end
data/Changelog.md CHANGED
@@ -1,6 +1,41 @@
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
+
10
+ ## 3.5.0
11
+
12
+ Deprecated support for rails 4.0
13
+ Improvements to timestamped migrations, thanks to [Pierre-Michard](https://github.com/Pierre-Michard)
14
+
15
+ ## 3.4.0
16
+ `rake data:migrate:status` to return result in chronological order
17
+ ## 3.3.1
18
+ Regression fix, thanks to [subakva](https://github.com/subakva)
19
+
20
+ ## 3.3.0
21
+ The concept of schema:dump to data migrations, thanks to
22
+ [tobyndockerill](https://github.com/tobyndockerill)
23
+
24
+ ## 3.2.1
25
+
26
+ data_migrate table into rails schema dump, thanks to
27
+ [jturkel](https://github.com/jturkel)
28
+
29
+
30
+ ## 3.2.0
31
+ - Add support for Rails 5.1
32
+ - No longer testing EOL rubies
33
+
34
+ ## 3.1.0
35
+
36
+ Rails 5.0 support thanks to
37
+ [jturkel](https://github.com/jturkel) and [abreckner](https://github.com/abreckner)
38
+
4
39
  ## 3.0.1
5
40
 
6
41
  ([gacha](https://github.com/gacha)) Capistrano fixes
data/Gemfile.rails5 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.0.0'
data/Gemfile.rails5.1 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.1'
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
@@ -3,6 +3,8 @@ Data Migrate
3
3
 
4
4
  - [![Version](http://img.shields.io/gem/v/data_migrate.svg?style=flat-square)](https://rubygems.org/gems/data_migrate)
5
5
  - [![License](http://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](http://opensource.org/licenses/MIT)
6
+ - [![Travis](https://img.shields.io/travis/ilyakatz/data-migrate.svg)](https://travis-ci.org/ilyakatz/data-migrate)
7
+
6
8
 
7
9
  Run data migrations alongside schema migrations.
8
10
 
@@ -11,8 +13,9 @@ migrations, except they should be reserved for data migrations. For
11
13
  instance, if you realize you need to titleize all your titles, this
12
14
  is the place to do it.
13
15
 
14
- Why should I use this?
15
- ----------------------
16
+ ![Travis](./screenshot.png)
17
+
18
+ # Why should I use this?
16
19
 
17
20
  Its seems when a project hits a certain size, I get to manipulate data
18
21
  outside the application itself. Changing defaults, new validations,
@@ -25,36 +28,37 @@ migration. It'd be much better to keep concerns separate. The benefit
25
28
  of having them separate has to do with your data model.
26
29
 
27
30
  For instance, lets take an absurd example, to illustrate: You have
28
- your infamous [Rails blog](http://media.rubyonrails.org/video/rails-0-5.mov)
29
- that has posts with many comments. After some use, you decide you are
30
- going to be a trend setter, and want only one comment per post, and
31
- just the text. "Frist!!1!1" rules the day. Given that you:
32
- - write a migration to add a comment column to Post
33
- - write a migration to move the contents of the first comments to the Post
34
- - drop the column_id column from Post
35
- - drop the Comment model
36
- - fix all your test/controller/view mojo.
31
+ a blog application that has posts with many comments.
32
+ After some use, you decide you are going to be a trend setter,
33
+ and want only one comment per post, and just the text.
34
+
35
+ Given that you:
36
+ - write a migration to add a comment column to `Post`
37
+ - write a migration to move the contents of the first comments to the `Post`
38
+ - drop the `column_id` column from `Post`
39
+ - drop the `Comment` model
40
+ - fix all your tests
37
41
 
38
42
  You've just got bit. When you `rake setup:development`, the mess gets
39
43
  mad at you after it creates your database, and starts cranking through
40
44
  migrations. It gets to the part where you iterate over the comments
41
- and it blows up. You don't have a comment model anymore for it to
45
+ and it blows up. You don't have a `Comment` model anymore for it to
42
46
  even try and get 'all' from. You think you are smarter, and wrap the
43
- AR call in a conditional based on the environment. That's fine until
44
- you get that QA gal, and she wants her own thing. Then the UI people
45
- get tired of waiting for the full stack to load on page refreshes, so
46
- you have to edit past migrations...
47
+ ActiveRecord call in a conditional based on the environment.
48
+
49
+ That's fine until you get that QA gal, and she wants her own thing.
50
+ Then the UI people get tired of waiting for the full stack to load on page
51
+ refreshes, so you have to edit past migrations...
47
52
 
48
53
  With Data Migrate, you have the control. You can generate your
49
54
  migrations as schema or data as you would as your work flow. For
50
55
  setting tasks that don't require any intermediate AR activity, like
51
- dev and test, you stick with db:migrate. For your prod, and qa, you
56
+ dev and test, you stick with `db:migrate`. For production and QA, you
52
57
  change their scripts to `db:migrate:with_data`. Of course you want to
53
58
  test your migration, so you have the choice of `db:migrate:with_data` or
54
59
  `data:migrate` to just capture that data change.
55
60
 
56
- What's it do?
57
- -------------
61
+ ## What does it do?
58
62
 
59
63
  Data migrations are stored in `db/data`. They act like schema
60
64
  migrations, except they should be reserved for data migrations. For
@@ -63,16 +67,13 @@ is the place to do it. Running any of the provided rake tasks also
63
67
  creates a data schema table to mirror the usual schema migrations
64
68
  table to track all the goodness.
65
69
 
66
- Rails Support
67
- --------------------
70
+ ## Rails Support
68
71
 
69
- Rails 3.1: Version 1.2 supports Rails 3.1.0 and higher **but** is no longer maintained.
72
+ Support Rails 4.2 through 5.2
70
73
 
71
- Rails 4: Version 2.0 supports Rails 4.0 and higher
74
+ ### Important notes for older versions
72
75
 
73
- Rails 5: Not tested
74
-
75
- ### Important note
76
+ #### v2
76
77
 
77
78
  If you upgraded to Rails 4 while using `data_migrate` prior to version 2,
78
79
  the gem wrote data migration versions into
@@ -81,8 +82,12 @@ the gem wrote data migration versions into
81
82
 
82
83
  This may cause some unintended consequences. See [#22](https://github.com/ilyakatz/data-migrate/issues/22)
83
84
 
84
- Installation
85
- ------------
85
+ #### v1
86
+
87
+ If you've installed previous to v1.1.0, you'll want to delete the
88
+ `create_data_migrations_table` migration.
89
+
90
+ ## Installation
86
91
  Add the gem to your project
87
92
 
88
93
  # Gemfile
@@ -91,13 +96,11 @@ Add the gem to your project
91
96
  Then `bundle install` and you are ready to go.
92
97
 
93
98
  So you know, when you use one of the provide rake tasks, a table
94
- called 'data_migrations' will be created in your database. This
95
- is to mirror the way the standard 'db' rake tasks work. If you've
96
- installed previous to v1.1.0, you'll want to delete the
97
- 'create\_data\_migrations_table' migration.
99
+ called `data_migrations` will be created in your database. This
100
+ is to mirror the way the standard `db` rake tasks work.
98
101
 
99
- Usage
100
- -----
102
+
103
+ ## Usage
101
104
 
102
105
  ### Generating Migrations
103
106
 
@@ -108,31 +111,35 @@ You can generate a data migration as you would a schema migration:
108
111
  ### Rake Tasks
109
112
 
110
113
  $> rake -T data
114
+ rake data:dump # Create a db/data_schema.rb file that stores the current data version
111
115
  rake data:forward # Pushes the schema to the next version (specify steps w/ STEP=n)
112
116
  rake data:migrate # Migrate data migrations (options: VERSION=x, VERBOSE=false)
113
117
  rake data:migrate:down # Runs the "down" for a given migration VERSION
114
- rake data:migrate:redo # Rollbacks the database one migration and re migrate up (options: STEP=x, VERSIO...
118
+ rake data:migrate:redo # Rollbacks the database one migration and re migrate up (options: STEP=x, VERSION=x)
115
119
  rake data:migrate:status # Display status of data migrations
116
120
  rake data:migrate:up # Runs the "up" for a given migration VERSION
117
121
  rake data:rollback # Rolls the schema back to the previous version (specify steps w/ STEP=n)
118
122
  rake data:version # Retrieves the current schema version number for data migrations
119
123
  rake db:forward:with_data # Pushes the schema to the next version (specify steps w/ STEP=n)
120
124
  rake db:migrate:down:with_data # Runs the "down" for a given migration VERSION
121
- rake db:migrate:redo:with_data # Rollbacks the database one migration and re migrate up (options: STEP=x, VERSIO...
125
+ rake db:migrate:redo:with_data # Rollbacks the database one migration and re migrate up (options: STEP=x, VERSION=x)
122
126
  rake db:migrate:status:with_data # Display status of data and schema migrations
123
127
  rake db:migrate:up:with_data # Runs the "up" for a given migration VERSION
124
128
  rake db:migrate:with_data # Migrate the database data and schema (options: VERSION=x, VERBOSE=false)
125
129
  rake db:rollback:with_data # Rolls the schema back to the previous version (specify steps w/ STEP=n)
130
+ rake db:schema:load:with_data # Load both schema.rb and data_schema.rb file into the database
126
131
  rake db:version:with_data # Retrieves the current schema version numbers for data and schema migrations
127
132
 
128
- Tasks work as they would with the 'vanilla' db version. The 'with_data' addition to the 'db' tasks will run the task in the context of both the data and schema migrations. That is, `rake db:rollback:with_data` will check to see if it was a schema or data migration invoked last, and do that. Tasks invoked in that space also have an additional line of output, indicating if the action is performed on data or schema.
133
+ Tasks work as they would with the 'vanilla' db version. The 'with_data' addition to the 'db' tasks will run the task in the context of both the data and schema migrations. That is, rake db:rollback:with_data will check to see if it was a schema or data migration invoked last, and do that. Tasks invoked in that space also have an additional line of output, indicating if the action is performed on data or schema.
129
134
 
130
135
  With 'up' and 'down', you can specify the option 'BOTH', which defaults to false. Using true, will migrate both the data and schema (in the desired direction) if they both match the version provided. Again, going up, schema is given precedence. Down its data.
131
136
 
132
137
  `rake db:migrate:status:with_data` provides and additional column to indicate which type of migration.
138
+ ### Configuration
139
+
140
+ `data_migrate` respects `ActiveRecord::Base.dump_schema_after_migration`. If it is set to `false`, data schema file will not be generated
133
141
 
134
- Capistrano Support
135
- ------------------
142
+ ## Capistrano Support
136
143
 
137
144
  The gem comes with a capistrano task that can be used instead of `capistrano/rails/migrations`.
138
145
 
@@ -144,9 +151,19 @@ require 'capistrano/data_migrate'
144
151
 
145
152
  From now on capistrano will run `rake db:migrate:with_data` in every deploy.
146
153
 
154
+ ### Contributing
155
+
156
+ ## Testing
157
+
158
+ Run tests for a specific version of Rails
159
+
160
+ ```
161
+ bundle exec appraisal install
162
+ bundle exec appraisal rails-4.2 rspec
163
+ bundle exec appraisal rails-5.0 rspec
164
+ ```
147
165
 
148
- Thanks
149
- ------
166
+ ## Thanks
150
167
  [Andrew J Vargo](http://github.com/ajvargo) Andrew was the original creator and maintainer of this project!
151
168
 
152
169
  [Jeremy Durham](http://jeremydurham.com/) for fleshing out the idea with me, and providing guidance.
data/data_migrate.gemspec CHANGED
@@ -15,7 +15,18 @@ Gem::Specification.new do |s|
15
15
 
16
16
  s.rubyforge_project = "data_migrate"
17
17
 
18
- s.add_dependency('rails', '>= 4.0')
18
+ s.add_dependency('rails', '>= 4.2')
19
+ s.add_development_dependency "appraisal"
20
+ s.add_development_dependency "rake"
21
+ s.add_development_dependency "rspec"
22
+ s.add_development_dependency "rspec-core"
23
+ s.add_development_dependency "pry"
24
+ s.add_development_dependency "rb-readline"
25
+ s.add_development_dependency "sqlite3"
26
+ s.add_development_dependency "timecop"
27
+ s.add_development_dependency "rubocop"
28
+ s.add_development_dependency "overcommit"
29
+
19
30
 
20
31
  s.files = `git ls-files`.split("\n")
21
32
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "rails", "4.1.16"
6
+
7
+ gemspec path: "../"
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "rails", "4.2.8"
6
+ gem "nokogiri", "1.6.8.1"
7
+
8
+ gemspec path: "../"
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "rails", "5.0.3"
6
+
7
+ gemspec path: "../"
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "rails", "5.1"
6
+
7
+ gemspec path: "../"
@@ -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: "../"
@@ -1,4 +1,6 @@
1
- require 'active_record'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_record"
2
4
 
3
5
  module DataMigrate
4
6
 
@@ -14,9 +16,14 @@ module DataMigrate
14
16
  end
15
17
  end
16
18
 
19
+
17
20
  class << self
21
+ def current_version(connection = ActiveRecord::Base.connection)
22
+ get_all_versions(connection).max || 0
23
+ end
24
+
18
25
  def get_all_versions(connection = ActiveRecord::Base.connection)
19
- if connection.table_exists?(schema_migrations_table_name)
26
+ if table_exists?(connection, schema_migrations_table_name)
20
27
  # Certain versions of the gem wrote data migration versions into
21
28
  # schema_migrations table. After the fix, it was corrected to write into
22
29
  # data_migrations. However, not to break anything we are going to
@@ -33,20 +40,43 @@ module DataMigrate
33
40
  end
34
41
 
35
42
  def schema_migrations_table_name
36
- ActiveRecord::Base.table_name_prefix + 'data_migrations' + ActiveRecord::Base.table_name_suffix
43
+ ActiveRecord::Base.table_name_prefix + "data_migrations" +
44
+ ActiveRecord::Base.table_name_suffix
37
45
  end
38
46
 
39
47
  def migrations_path
40
- 'db/data'
48
+ "db/data"
49
+ end
50
+
51
+ ##
52
+ # Provides the full migrations_path filepath
53
+ # @return (String)
54
+ def full_migrations_path
55
+ File.join(Rails.root, *migrations_path.split(File::SEPARATOR))
41
56
  end
42
57
 
43
58
  def assure_data_schema_table
44
- config = ActiveRecord::Base.configurations[Rails.env || 'development'] || ENV["DATABASE_URL"]
45
- ActiveRecord::Base.establish_connection(config)
59
+ ActiveRecord::Base.establish_connection(db_config)
46
60
  sm_table = DataMigrate::DataMigrator.schema_migrations_table_name
47
61
 
48
- unless ActiveRecord::Base.connection.table_exists?(sm_table)
49
- ActiveRecord::Base.connection.create_table(sm_table, :id => false) do |schema_migrations_table|
62
+ unless table_exists?(ActiveRecord::Base.connection, sm_table)
63
+ create_table(sm_table)
64
+ end
65
+ end
66
+
67
+ ##
68
+ # Compares the given filename with what we expect data migration
69
+ # filenames to be, eg the "20091231235959_some_name.rb" pattern
70
+ # @param (String) filename
71
+ # @return (MatchData)
72
+ def match(filename)
73
+ /(\d{14})_(.+)\.rb/.match(filename)
74
+ end
75
+
76
+ private
77
+
78
+ def create_table(sm_table)
79
+ ActiveRecord::Base.connection.create_table(sm_table, :id => false) do |schema_migrations_table|
50
80
  schema_migrations_table.column :version, :string, :null => false
51
81
  end
52
82
 
@@ -57,9 +87,24 @@ module DataMigrate
57
87
  ActiveRecord::Base.connection.add_index sm_table, :version,
58
88
  :unique => true,
59
89
  :name => index_name
90
+ end
91
+
92
+ def table_exists?(connection, table_name)
93
+ # Avoid the warning that table_exists? prints in Rails 5.0 due a
94
+ # change in behavior between Rails 5.0 and Rails 5.1 of this method
95
+ # with respect to database views.
96
+ if ActiveRecord.version >= Gem::Version.new("5.0") &&
97
+ ActiveRecord.version < Gem::Version.new("5.1")
98
+ connection.data_source_exists?(table_name)
99
+ else
100
+ connection.table_exists?(schema_migrations_table_name)
60
101
  end
61
102
  end
62
103
 
104
+ def db_config
105
+ ActiveRecord::Base.configurations[Rails.env || "development"] ||
106
+ ENV["DATABASE_URL"]
107
+ end
63
108
  end
64
109
  end
65
110
  end
@@ -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
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DataMigrate
4
+ ##
5
+ # Provides the definition method for data_schema.rb
6
+ class Data < ActiveRecord::Schema
7
+ # This method is based on the following two methods
8
+ # ActiveRecord::Schema#define
9
+ # ActiveRecord::ConnectionAdapters::SchemaStatements
10
+ # #assume_migrated_upto_version
11
+ def define(info)
12
+ DataMigrate::DataMigrator.assure_data_schema_table
13
+
14
+ return if info[:version].blank?
15
+
16
+ version = info[:version].to_i
17
+
18
+ unless migrated.include?(version)
19
+ execute "INSERT INTO #{sm_table} (version) VALUES ('#{version}')"
20
+ end
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)
43
+ inserted = Set.new
44
+ (versions - migrated).each do |v|
45
+ if inserted.include?(v)
46
+ raise "Duplicate data migration #{v}. Please renumber your data " \
47
+ "migrations to resolve the conflict."
48
+ elsif v < version
49
+ execute "INSERT INTO #{sm_table} (version) VALUES ('#{v}')"
50
+ inserted << v
51
+ end
52
+ end
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
62
+ end
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