data_migrate 3.0.1 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +6 -1
- data/.hound.yml +4 -0
- data/.overcommit.yml +21 -0
- data/.rspec +3 -0
- data/.rubocop.yml +2 -0
- data/.ruby-style.yml +1061 -0
- data/.travis.yml +16 -0
- data/Appraisals +17 -0
- data/Changelog.md +35 -0
- data/Gemfile.rails5 +5 -0
- data/Gemfile.rails5.1 +5 -0
- data/Gemfile.rails5.2 +5 -0
- data/README.md +58 -41
- data/data_migrate.gemspec +12 -1
- data/gemfiles/rails_4.1.gemfile +7 -0
- data/gemfiles/rails_4.2.gemfile +8 -0
- data/gemfiles/rails_5.0.gemfile +7 -0
- data/gemfiles/rails_5.1.gemfile +7 -0
- data/gemfiles/rails_5.2.gemfile +7 -0
- data/lib/data_migrate/data_migrator.rb +53 -8
- data/lib/data_migrate/data_migrator_five.rb +84 -0
- data/lib/data_migrate/data_schema.rb +63 -0
- data/lib/data_migrate/data_schema_migration.rb +1 -0
- data/lib/data_migrate/database_tasks.rb +82 -0
- data/lib/data_migrate/migration.rb +1 -1
- data/lib/data_migrate/migration_context.rb +90 -0
- data/lib/data_migrate/migration_five.rb +26 -0
- data/lib/data_migrate/railtie.rb +1 -1
- data/lib/data_migrate/schema_dumper.rb +42 -0
- 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 +65 -0
- 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/data_migrate.rb +30 -4
- data/lib/generators/data_migration/data_migration_generator.rb +17 -16
- data/lib/generators/data_migration/templates/data_migration.rb +4 -4
- data/screenshot.png +0 -0
- data/spec/data_migrate/data_migrator_spec.rb +50 -0
- data/spec/data_migrate/data_schema_migration_spec.rb +16 -0
- data/spec/data_migrate/data_spec.rb +87 -0
- data/spec/data_migrate/database_tasks_spec.rb +114 -0
- data/spec/data_migrate/migration.rb +19 -0
- data/spec/data_migrate/migration_context_spec.rb +107 -0
- data/spec/data_migrate/schema_dumper_spec.rb +46 -0
- data/spec/data_migrate/schema_migration_spec.rb +69 -0
- data/spec/data_migrate/status_service_spec.rb +93 -0
- 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/generators/data_migration/data_migration_generator_spec.rb +27 -0
- data/spec/spec_helper.rb +9 -0
- data/tasks/databases.rake +69 -62
- metadata +221 -6
@@ -0,0 +1,82 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DataMigrate
|
4
|
+
##
|
5
|
+
# This class extends DatabaseTasks to add a data_schema_file method.
|
6
|
+
class DatabaseTasks
|
7
|
+
extend ActiveRecord::Tasks::DatabaseTasks
|
8
|
+
|
9
|
+
def self.data_schema_file
|
10
|
+
File.join(db_dir, "data_schema.rb")
|
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
|
+
|
81
|
+
end
|
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
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module DataMigrate
|
2
|
+
class MigrationFive < ::ActiveRecord::Migration[5.0]
|
3
|
+
|
4
|
+
class << self
|
5
|
+
def check_pending!(connection = ::ActiveRecord::Base.connection)
|
6
|
+
raise ActiveRecord::PendingMigrationError if DataMigrator::Migrator.needs_migration?(connection)
|
7
|
+
end
|
8
|
+
|
9
|
+
def migrate(direction)
|
10
|
+
new.migrate direction
|
11
|
+
end
|
12
|
+
|
13
|
+
def table_name
|
14
|
+
ActiveRecord::Base.table_name_prefix + 'data_migrations' + ActiveRecord::Base.table_name_suffix
|
15
|
+
end
|
16
|
+
|
17
|
+
def index_name
|
18
|
+
"#{table_name_prefix}unique_data_migrations#{table_name_suffix}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize(name = self.class.name, version = nil)
|
23
|
+
super(name, version)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/data_migrate/railtie.rb
CHANGED
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DataMigrate
|
4
|
+
##
|
5
|
+
# Provides the capability to write the current data schema version to
|
6
|
+
# the data_schema file Based on ActiveRecord::SchemaDumper
|
7
|
+
class SchemaDumper
|
8
|
+
private_class_method :new
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def dump(connection = ActiveRecord::Base.connection, stream = STDOUT)
|
12
|
+
new(connection).dump(stream)
|
13
|
+
stream
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def dump(stream)
|
18
|
+
define_params = @version ? "version: #{@version}" : ""
|
19
|
+
|
20
|
+
if stream.respond_to?(:external_encoding) && stream.external_encoding
|
21
|
+
stream.puts "# encoding: #{stream.external_encoding.name}"
|
22
|
+
end
|
23
|
+
|
24
|
+
stream.puts "DataMigrate::Data.define(#{define_params})"
|
25
|
+
|
26
|
+
stream
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def initialize(connection)
|
32
|
+
@connection = connection
|
33
|
+
all_versions = DataSchemaMigration.normalized_versions
|
34
|
+
|
35
|
+
@version = begin
|
36
|
+
all_versions.max
|
37
|
+
rescue StandardError
|
38
|
+
0
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module DataMigrate
|
2
|
+
# Helper class to getting access to db schema
|
3
|
+
# to allow data/schema combiation tasks
|
4
|
+
class SchemaMigration
|
5
|
+
def self.pending_schema_migrations
|
6
|
+
all_migrations = DataMigrate::DataMigrator.migrations(migrations_paths)
|
7
|
+
sort_migrations(
|
8
|
+
ActiveRecord::Migrator.new(:up, all_migrations).
|
9
|
+
pending_migrations.
|
10
|
+
map {|m| { version: m.version, kind: :schema }}
|
11
|
+
)
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.run(direction, migration_paths, version)
|
15
|
+
ActiveRecord::Migrator.run(direction, migration_paths, version)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.sort_migrations(set1, set2 = nil)
|
19
|
+
migrations = set1 + (set2 || [])
|
20
|
+
migrations.sort {|a, b| sort_string(a) <=> sort_string(b)}
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.migrations_paths
|
24
|
+
Rails.application.config.paths["db/migrate"].to_a
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.sort_string(migration)
|
28
|
+
"#{migration[:version]}_#{migration[:kind] == :data ? 1 : 0}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module DataMigrate
|
2
|
+
# Helper class to getting access to db schema
|
3
|
+
# to allow data/schema combiation tasks
|
4
|
+
class SchemaMigration
|
5
|
+
def self.pending_schema_migrations
|
6
|
+
all_migrations = ActiveRecord::MigrationContext.new(migrations_paths).migrations
|
7
|
+
sort_migrations(
|
8
|
+
ActiveRecord::Migrator.new(:up, all_migrations).
|
9
|
+
pending_migrations.
|
10
|
+
map {|m| { version: m.version, kind: :schema }}
|
11
|
+
)
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.run(direction, migration_paths, version)
|
15
|
+
ActiveRecord::MigrationContext.new(migration_paths).run(direction, version)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.sort_migrations(set1, set2 = nil)
|
19
|
+
migrations = set1 + (set2 || [])
|
20
|
+
migrations.sort {|a, b| sort_string(a) <=> sort_string(b)}
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.migrations_paths
|
24
|
+
Rails.application.config.paths["db/migrate"].to_a
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.sort_string(migration)
|
28
|
+
"#{migration[:version]}_#{migration[:kind] == :data ? 1 : 0}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module DataMigrate
|
2
|
+
class StatusService
|
3
|
+
class << self
|
4
|
+
def dump(connection = ActiveRecord::Base.connection, stream = STDOUT)
|
5
|
+
new(connection).dump(stream)
|
6
|
+
stream
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(connection)
|
11
|
+
@connection = connection
|
12
|
+
end
|
13
|
+
|
14
|
+
def root_folder
|
15
|
+
Rails.root
|
16
|
+
end
|
17
|
+
|
18
|
+
def dump(stream)
|
19
|
+
unless @connection.table_exists?(table_name)
|
20
|
+
stream.puts "Data migrations table does not exist yet."
|
21
|
+
return
|
22
|
+
end
|
23
|
+
sql = "SELECT version FROM #{DataMigrate::DataMigrator.schema_migrations_table_name}"
|
24
|
+
db_list = ActiveRecord::Base.connection.select_values(sql)
|
25
|
+
output(stream, db_list)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def table_name
|
31
|
+
DataMigrate::DataMigrator.schema_migrations_table_name
|
32
|
+
end
|
33
|
+
|
34
|
+
def output(stream, db_list)
|
35
|
+
stream.puts "#{"Status".center(8)} #{"Migration ID".ljust(14)} Migration Name"
|
36
|
+
stream.puts "-" * 50
|
37
|
+
list = migration_files(db_list) + migration_list(db_list)
|
38
|
+
list.sort! {|line1, line2| line1[1] <=> line2[1]}
|
39
|
+
list.each do |file|
|
40
|
+
stream.puts "#{file[0].center(8)} #{file[1].ljust(14)} #{file[2]}"
|
41
|
+
end
|
42
|
+
stream.puts
|
43
|
+
end
|
44
|
+
|
45
|
+
def migration_list(db_list)
|
46
|
+
list = []
|
47
|
+
db_list.each do |version|
|
48
|
+
list << ["up", version, "********** NO FILE *************"]
|
49
|
+
end
|
50
|
+
list
|
51
|
+
end
|
52
|
+
|
53
|
+
def migration_files(db_list)
|
54
|
+
file_list = []
|
55
|
+
Dir.foreach(File.join(root_folder, "db", "data")) do |file|
|
56
|
+
# only files matching "20091231235959_some_name.rb" pattern
|
57
|
+
if match_data = DataMigrate::DataMigrator.match(file)
|
58
|
+
status = db_list.delete(match_data[1]) ? "up" : "down"
|
59
|
+
file_list << [status, match_data[1], match_data[2].humanize]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
file_list
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module DataMigrate
|
2
|
+
class StatusService
|
3
|
+
class << self
|
4
|
+
def dump(connection = ActiveRecord::Base.connection, stream = STDOUT)
|
5
|
+
new(connection).dump(stream)
|
6
|
+
stream
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(connection)
|
11
|
+
@connection = connection
|
12
|
+
end
|
13
|
+
|
14
|
+
def root_folder
|
15
|
+
Rails.root
|
16
|
+
end
|
17
|
+
|
18
|
+
def dump(stream)
|
19
|
+
output(stream)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def table_name
|
25
|
+
DataMigrate::DataSchemaMigration.table_name
|
26
|
+
end
|
27
|
+
|
28
|
+
def output(stream)
|
29
|
+
unless DataMigrate::DataSchemaMigration.table_exists?
|
30
|
+
stream.puts "Data migrations table does not exist yet."
|
31
|
+
return
|
32
|
+
end
|
33
|
+
|
34
|
+
# output
|
35
|
+
stream.puts "\ndatabase: #{ActiveRecord::Base.connection_config[:database]}\n\n"
|
36
|
+
stream.puts "#{'Status'.center(8)} #{'Migration ID'.ljust(14)} Migration Name"
|
37
|
+
stream.puts "-" * 50
|
38
|
+
db_list.each do |status, version, name|
|
39
|
+
stream.puts "#{status.center(8)} #{version.ljust(14)} #{name}"
|
40
|
+
end
|
41
|
+
stream.puts
|
42
|
+
end
|
43
|
+
|
44
|
+
def db_list
|
45
|
+
DataMigrate::DataMigrator.migrations_status
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module DataMigrate
|
2
|
+
module Tasks
|
3
|
+
module DataMigrateTasks
|
4
|
+
extend self
|
5
|
+
def migrations_paths
|
6
|
+
@migrations_paths ||= begin
|
7
|
+
if Rails.application && Rails.application.paths["data/migrate"]
|
8
|
+
Rails.application.paths["data/migrate"].to_a
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def migrate
|
14
|
+
DataMigrate::DataMigrator.assure_data_schema_table
|
15
|
+
target_version = ENV["VERSION"] ? ENV["VERSION"].to_i : nil
|
16
|
+
if Rails::VERSION::MAJOR == 5 && Rails::VERSION::MINOR == 2
|
17
|
+
DataMigrate::MigrationContext.new(migrations_paths).migrate(target_version)
|
18
|
+
else
|
19
|
+
paths = migrations_paths || "db/data/"
|
20
|
+
DataMigrate::DataMigrator.migrate(paths, ENV["VERSION"] ? ENV["VERSION"].to_i : nil)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/data_migrate/version.rb
CHANGED
data/lib/data_migrate.rb
CHANGED
@@ -1,4 +1,30 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
require File.join(File.dirname(__FILE__),
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
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
|
8
|
+
require File.join(File.dirname(__FILE__), "data_migrate",
|
9
|
+
"data_schema_migration")
|
10
|
+
require File.join(File.dirname(__FILE__), "data_migrate", "data_schema")
|
11
|
+
require File.join(File.dirname(__FILE__), "data_migrate", "database_tasks")
|
12
|
+
require File.join(File.dirname(__FILE__), "data_migrate", "schema_dumper")
|
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
|
26
|
+
else
|
27
|
+
require File.join(File.dirname(__FILE__), "data_migrate", "migration")
|
28
|
+
end
|
29
|
+
require File.join(File.dirname(__FILE__), "data_migrate", "railtie")
|
30
|
+
require File.join(File.dirname(__FILE__), "data_migrate", "tasks/data_migrate_tasks")
|
@@ -1,38 +1,39 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require "generators/data_migrate"
|
2
|
+
require "rails/generators"
|
3
|
+
require "rails/generators/active_record/migration"
|
4
|
+
require "rails/generators/migration"
|
4
5
|
|
5
6
|
module DataMigrate
|
6
7
|
module Generators
|
7
8
|
class DataMigrationGenerator < Rails::Generators::NamedBase
|
8
9
|
namespace "data_migration"
|
9
|
-
include
|
10
|
+
include ActiveRecord::Generators::Migration
|
10
11
|
|
11
|
-
argument :attributes, type: :array, default: [], banner:
|
12
|
+
argument :attributes, type: :array, default: [], banner: "field:type field:type"
|
12
13
|
|
13
14
|
def create_data_migration
|
14
15
|
set_local_assigns!
|
15
|
-
migration_template
|
16
|
+
migration_template "data_migration.rb", "db/data/#{file_name}.rb"
|
16
17
|
end
|
17
18
|
|
18
19
|
protected
|
19
20
|
|
20
|
-
attr_reader :migration_action
|
21
|
-
|
22
|
-
def self.next_migration_number(dirname)
|
23
|
-
if ActiveRecord::Base.timestamped_migrations
|
24
|
-
Time.new.utc.strftime("%Y%m%d%H%M%S")
|
25
|
-
else
|
26
|
-
"%.3d" % (current_migration_number(dirname) + 1)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
21
|
def set_local_assigns!
|
31
22
|
if file_name =~ /^(add|remove)_.*_(?:to|from)_(.*)/
|
32
23
|
@migration_action = $1
|
33
24
|
@table_name = $2.pluralize
|
34
25
|
end
|
35
26
|
end
|
27
|
+
|
28
|
+
def migration_base_class_name
|
29
|
+
if ActiveRecord.version >= Gem::Version.new("5.0")
|
30
|
+
"ActiveRecord::Migration[#{ActiveRecord::Migration.current_version}]"
|
31
|
+
elsif ActiveRecord.version >= Gem::Version.new("5.2")
|
32
|
+
"DataMigrate::MigrationContext"
|
33
|
+
else
|
34
|
+
"ActiveRecord::Migration"
|
35
|
+
end
|
36
|
+
end
|
36
37
|
end
|
37
38
|
end
|
38
39
|
end
|
data/screenshot.png
ADDED
Binary file
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DataMigrate::DataMigrator do
|
4
|
+
let(:subject) { DataMigrate::DataMigrator }
|
5
|
+
let(:db_config) do
|
6
|
+
{
|
7
|
+
adapter: "sqlite3",
|
8
|
+
database: "spec/db/test.db"
|
9
|
+
}
|
10
|
+
end
|
11
|
+
|
12
|
+
describe :assure_data_schema_table do
|
13
|
+
before do
|
14
|
+
allow(subject).to receive(:db_config) { db_config }.at_least(:once)
|
15
|
+
ActiveRecord::Base.establish_connection(db_config)
|
16
|
+
end
|
17
|
+
|
18
|
+
after do
|
19
|
+
ActiveRecord::Migration.drop_table("data_migrations")
|
20
|
+
end
|
21
|
+
|
22
|
+
it do
|
23
|
+
expect(
|
24
|
+
ActiveRecord::Base.connection.table_exists?("data_migrations")
|
25
|
+
).to eq false
|
26
|
+
subject.assure_data_schema_table
|
27
|
+
expect(
|
28
|
+
ActiveRecord::Base.connection.table_exists?("data_migrations")
|
29
|
+
).to eq true
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe :match do
|
34
|
+
context "when the file does not match" do
|
35
|
+
it "returns nil" do
|
36
|
+
expect(subject.match("not_a_data_migration_file")).to be_nil
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context "when the file matches" do
|
41
|
+
it "returns a valid MatchData object" do
|
42
|
+
match_data = subject.match("20091231235959_some_name.rb")
|
43
|
+
|
44
|
+
expect(match_data[0]).to eq "20091231235959_some_name.rb"
|
45
|
+
expect(match_data[1]).to eq "20091231235959"
|
46
|
+
expect(match_data[2]).to eq "some_name"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DataMigrate::DataSchemaMigration do
|
4
|
+
let(:subject) { DataMigrate::DataSchemaMigration }
|
5
|
+
describe :table_name do
|
6
|
+
it "returns correct table name" do
|
7
|
+
expect(subject.table_name).to eq("data_migrations")
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe :index_name do
|
12
|
+
it "returns correct index name" do
|
13
|
+
expect(subject.index_name).to eq("unique_data_migrations")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|