mongration 0.0.3.pre.beta → 0.0.4.pre.beta
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.ruby-version +1 -1
- data/Gemfile +11 -4
- data/README.md +9 -2
- data/Rakefile +5 -0
- data/lib/mongration.rb +81 -26
- data/lib/mongration/configuration.rb +27 -4
- data/lib/mongration/create_migration.rb +11 -16
- data/lib/mongration/create_migration/migration_file_writer.rb +43 -0
- data/lib/mongration/file.rb +52 -9
- data/lib/mongration/migrate_all_up.rb +20 -0
- data/lib/mongration/migrate_down.rb +20 -0
- data/lib/mongration/migrate_up.rb +20 -0
- data/lib/mongration/migration.rb +37 -0
- data/lib/mongration/null_output.rb +6 -0
- data/lib/mongration/rake_tasks.rb +40 -0
- data/lib/mongration/rollback.rb +5 -16
- data/lib/mongration/status.rb +27 -0
- data/lib/mongration/version.rb +1 -1
- data/lib/os_check.rb +7 -0
- data/spec/fixtures/integration.rb +23 -27
- data/spec/integration/{template_spec.rb → create_migration_spec.rb} +5 -1
- data/spec/integration/migrate_spec.rb +76 -0
- data/spec/integration/migrate_with_version_spec.rb +38 -0
- data/spec/integration/{mongration_spec.rb → rollback_spec.rb} +11 -36
- data/spec/integration/status_spec.rb +61 -0
- data/spec/integration/version_spec.rb +20 -0
- data/spec/spec_helper.rb +16 -4
- data/spec/unit/mongration/{data_store/mongoid/migration_spec.rb → migration_spec.rb} +9 -3
- data/spec/unit/mongration/rake_tasks_spec.rb +95 -0
- metadata +40 -35
- data/lib/mongration/data_store/in_memory/store.rb +0 -32
- data/lib/mongration/data_store/mongoid/migration.rb +0 -24
- data/lib/mongration/data_store/mongoid/store.rb +0 -53
- data/lib/mongration/migrate.rb +0 -52
- data/lib/mongration/migration_file_writer.rb +0 -40
- data/lib/mongration/null_migration.rb +0 -16
- data/lib/mongration/rake_task.rb +0 -18
- data/spec/support/store_interface.rb +0 -18
- data/spec/unit/mongration/data_store/in_memory/store_spec.rb +0 -10
- data/spec/unit/mongration/data_store/mongoid/store_spec.rb +0 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 20730b095053fceae0d065822f9492a8e70eb89b
|
4
|
+
data.tar.gz: 4a57e71108a1453971fc04145a31b6ba1c2bf4eb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7ed9c54e2a8c160eb8ca9089e83c07310dd6b916e1e8b86f460e6f753892d6f0e43a7e5ab0b340b67ec3a6cd14a6a9b53c22e878e401dd695a81bdb538a995a3
|
7
|
+
data.tar.gz: 7708282338c9c5740a675c65f1f6ee836280f59c0e03cb95d030430353500c5bed606e6cf2c3bea99dc34c46ab6b616691f90832ad3aade93831275d96b09eb6
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.1.2
|
data/Gemfile
CHANGED
@@ -1,12 +1,19 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
|
+
gem 'rantly', github: 'hayeah/rantly'
|
4
|
+
|
3
5
|
group :test do
|
4
6
|
gem 'guard-rspec', '4.3.1', require: false
|
5
|
-
gem 'rantly', github: 'hayeah/rantly'
|
6
7
|
end
|
7
8
|
|
8
|
-
#
|
9
|
-
|
9
|
+
# debuggers
|
10
|
+
gem 'ruby-debug', platforms: :jruby
|
11
|
+
gem 'debugger', platforms: :mri_19
|
12
|
+
gem 'byebug', platforms: [:mri_20, :mri_21]
|
13
|
+
|
14
|
+
require './lib/os_check.rb'
|
15
|
+
if OsCheck.mac_osx?
|
16
|
+
gem 'rspec-nc'
|
17
|
+
end
|
10
18
|
|
11
|
-
# Specify your gem's dependencies in mongration.gemspec
|
12
19
|
gemspec
|
data/README.md
CHANGED
@@ -4,7 +4,14 @@
|
|
4
4
|
|
5
5
|
Mongration is a tool for migrating data. It is designed to have the same interface as [ActiveRecord](https://github.com/rails/rails/tree/master/activerecord)'s migrations but be used with [Mongoid](https://github.com/mongoid/mongoid) instead of an SQL database.
|
6
6
|
|
7
|
-
|
7
|
+
Mongration supports the following rake tasks:
|
8
|
+
* `db:migrate` - migrates all pending migrations
|
9
|
+
* `db:migrate VERSION=123` - moves to the specified version. If the version is greater than the current version, it will move up. If the version is lesser than the current version, it will move down.
|
10
|
+
* `db:rollback` - rolls back the most recent migration
|
11
|
+
* `db:rollback STEP=N` - rolls back the N most recent migrations
|
12
|
+
* `db:version` - outputs the numeric identifier for the most recent migration
|
13
|
+
* `db:migrate:create` - takes the place of the `rails generate migration` generator
|
14
|
+
* `db:migrate:status` - outputs a table of all files and their migration status
|
8
15
|
|
9
16
|
## Support
|
10
17
|
|
@@ -31,7 +38,7 @@ Or install it yourself as:
|
|
31
38
|
|
32
39
|
## Usage
|
33
40
|
|
34
|
-
The primary usage will be through the Rake tasks `db:migrate` and `db:
|
41
|
+
The primary usage will be through the Rake tasks `db:migrate` and `db:rollback`. Migrate will run all migrations that have not been run before. Rollback will rollback the previous migration.
|
35
42
|
|
36
43
|
Migration files have the following structure:
|
37
44
|
|
data/Rakefile
CHANGED
data/lib/mongration.rb
CHANGED
@@ -1,34 +1,67 @@
|
|
1
|
-
require '
|
1
|
+
require 'mongoid'
|
2
|
+
require 'rake'
|
2
3
|
|
4
|
+
require 'mongration/version'
|
3
5
|
require 'mongration/errors'
|
4
6
|
|
5
|
-
require 'mongration/configuration'
|
6
|
-
require 'mongration/create_migration'
|
7
7
|
require 'mongration/file'
|
8
|
-
require 'mongration/
|
9
|
-
require 'mongration/migration_file_writer'
|
10
|
-
require 'mongration/null_migration'
|
11
|
-
require 'mongration/rake_task'
|
12
|
-
require 'mongration/rollback'
|
8
|
+
require 'mongration/migration'
|
13
9
|
|
14
|
-
require 'mongration/
|
15
|
-
require 'mongration/
|
10
|
+
require 'mongration/rake_tasks'
|
11
|
+
require 'mongration/configuration'
|
16
12
|
|
17
13
|
module Mongration
|
18
14
|
extend self
|
19
15
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
16
|
+
autoload :CreateMigration, 'mongration/create_migration'
|
17
|
+
autoload :MigrateAllUp, 'mongration/migrate_all_up'
|
18
|
+
autoload :MigrateUp, 'mongration/migrate_up'
|
19
|
+
autoload :MigrateDown, 'mongration/migrate_down'
|
20
|
+
autoload :NullOutput, 'mongration/null_output'
|
21
|
+
autoload :Rollback, 'mongration/rollback'
|
22
|
+
autoload :Status, 'mongration/status'
|
23
|
+
|
24
|
+
# Performs the migrations. If no version is provided, all pending migrations will be run. If a version is provided, migrations will be run to that version (either up or down).
|
25
|
+
#
|
26
|
+
# @param [String, nil] version
|
27
|
+
#
|
28
|
+
# @return [Boolean] true if migration was successful, false otherwise
|
29
|
+
#
|
30
|
+
def migrate(version = nil)
|
31
|
+
pending = ->(_) { File.pending.map(&:version).include?(_) }
|
32
|
+
migrated = ->(_) { File.migrated.map(&:version).include?(_) }
|
33
|
+
|
34
|
+
case version
|
35
|
+
when nil
|
36
|
+
MigrateAllUp.perform
|
37
|
+
|
38
|
+
when pending
|
39
|
+
MigrateUp.new(version).perform
|
40
|
+
|
41
|
+
when migrated
|
42
|
+
MigrateDown.new(version).perform
|
43
|
+
|
44
|
+
else
|
45
|
+
out.puts("Invalid Version: #{version} does not exist.")
|
46
|
+
end
|
24
47
|
end
|
25
48
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
49
|
+
# Rolls back (calls `down`) on the most recent migration(s).
|
50
|
+
#
|
51
|
+
# @param [Integer] number of migrations to rollback
|
52
|
+
#
|
53
|
+
# @return [void]
|
54
|
+
#
|
55
|
+
def rollback(step = 1)
|
56
|
+
step.times do
|
57
|
+
Rollback.perform
|
58
|
+
end
|
30
59
|
end
|
31
60
|
|
61
|
+
# Creates a migration with the given name
|
62
|
+
#
|
63
|
+
# @return [String] name of the file created
|
64
|
+
#
|
32
65
|
def create_migration(name, options = {})
|
33
66
|
CreateMigration.perform(
|
34
67
|
name,
|
@@ -36,6 +69,34 @@ module Mongration
|
|
36
69
|
)
|
37
70
|
end
|
38
71
|
|
72
|
+
# Returns the version of most recently run migration. If there are no migrations that have run (all migrations are pending), it returns '0'.
|
73
|
+
#
|
74
|
+
# @return [String] version
|
75
|
+
#
|
76
|
+
def version
|
77
|
+
if File.migrated.any?
|
78
|
+
File.migrated.last.version
|
79
|
+
else
|
80
|
+
'0'
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# Returns the direction (up if it has been run, down otherwise), migration ID (version), and description of the migration.
|
85
|
+
#
|
86
|
+
# @return [Array] migration statuses
|
87
|
+
#
|
88
|
+
def status
|
89
|
+
Status.migrations
|
90
|
+
end
|
91
|
+
|
92
|
+
def out
|
93
|
+
if configuration.silent?
|
94
|
+
@null_output ||= NullOutput.new
|
95
|
+
else
|
96
|
+
$stdout
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
39
100
|
def configure
|
40
101
|
yield configuration if block_given?
|
41
102
|
end
|
@@ -43,12 +104,6 @@ module Mongration
|
|
43
104
|
def configuration
|
44
105
|
@configuration ||= Configuration.new
|
45
106
|
end
|
46
|
-
|
47
|
-
private
|
48
|
-
|
49
|
-
def latest_migration
|
50
|
-
configuration.data_store.migrations.max_by(&:version) || NullMigration.new
|
51
|
-
end
|
52
107
|
end
|
53
108
|
|
54
109
|
Mongration.configure do |config|
|
@@ -56,7 +111,7 @@ Mongration.configure do |config|
|
|
56
111
|
config.timestamps = true
|
57
112
|
|
58
113
|
begin
|
59
|
-
config.
|
60
|
-
rescue Mongration::
|
114
|
+
config.config_path = ::File.join('config', 'mongoid.yml')
|
115
|
+
rescue Mongration::Configuration::ConfigNotFound
|
61
116
|
end
|
62
117
|
end
|
@@ -2,22 +2,45 @@ module Mongration
|
|
2
2
|
|
3
3
|
# @private
|
4
4
|
class Configuration
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
|
6
|
+
class ConfigNotFound < Errors
|
7
|
+
def initialize(path)
|
8
|
+
super("#{path} cannot be found.")
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
attr_reader :dir, :config_path
|
13
|
+
attr_writer :err_out, :timestamps, :silent
|
8
14
|
|
9
15
|
def dir=(dir)
|
10
16
|
unless ::File.exists?(dir)
|
11
|
-
print_warning("Migration Directory #{dir} does not
|
17
|
+
print_warning("Migration Directory #{dir} does not exist.")
|
12
18
|
end
|
13
19
|
|
14
20
|
@dir = dir
|
15
21
|
end
|
16
22
|
|
23
|
+
def config_path=(config_path)
|
24
|
+
unless ::File.exists?(config_path)
|
25
|
+
raise ConfigNotFound.new(config_path)
|
26
|
+
end
|
27
|
+
|
28
|
+
env = if defined?(Rails)
|
29
|
+
Rails.env
|
30
|
+
else
|
31
|
+
:test
|
32
|
+
end
|
33
|
+
Mongoid.load!(config_path, env)
|
34
|
+
end
|
35
|
+
|
17
36
|
def timestamps?
|
18
37
|
@timestamps
|
19
38
|
end
|
20
39
|
|
40
|
+
def silent?
|
41
|
+
@silent
|
42
|
+
end
|
43
|
+
|
21
44
|
private
|
22
45
|
|
23
46
|
def print_warning(message)
|
@@ -1,36 +1,35 @@
|
|
1
|
+
require 'mongration/create_migration/migration_file_writer'
|
2
|
+
|
1
3
|
module Mongration
|
2
4
|
|
3
5
|
# @private
|
4
6
|
class CreateMigration
|
5
7
|
|
6
8
|
def self.perform(name, options = {})
|
7
|
-
new(name, options
|
9
|
+
new(name, options).perform
|
8
10
|
end
|
9
11
|
|
10
|
-
def initialize(name, options
|
11
|
-
@name = name
|
12
|
+
def initialize(name, options)
|
12
13
|
@options = options
|
13
|
-
|
14
|
+
|
15
|
+
snakecase = name.gsub(/([a-z])([A-Z0-9])/, '\1_\2').downcase
|
16
|
+
@file_name = "#{next_migration_number}_#{snakecase}.rb"
|
14
17
|
end
|
15
18
|
|
16
19
|
def perform
|
17
20
|
MigrationFileWriter.write(
|
18
|
-
file_name,
|
19
|
-
|
21
|
+
@file_name,
|
22
|
+
@options
|
20
23
|
)
|
21
24
|
end
|
22
25
|
|
23
26
|
private
|
24
27
|
|
25
|
-
def file_name
|
26
|
-
"#{next_migration_number}_#{snakecase}.rb"
|
27
|
-
end
|
28
|
-
|
29
28
|
def next_migration_number
|
30
|
-
if
|
29
|
+
if Mongration.configuration.timestamps?
|
31
30
|
Time.now.utc.strftime('%Y%m%d%H%M%S').to_i
|
32
31
|
else
|
33
|
-
latest_file =
|
32
|
+
latest_file = File.last
|
34
33
|
|
35
34
|
number = if latest_file
|
36
35
|
latest_file.number + 1
|
@@ -40,9 +39,5 @@ module Mongration
|
|
40
39
|
'%.3d' % number
|
41
40
|
end
|
42
41
|
end
|
43
|
-
|
44
|
-
def snakecase
|
45
|
-
@name.gsub(/([a-z])([A-Z0-9])/, '\1_\2').downcase
|
46
|
-
end
|
47
42
|
end
|
48
43
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Mongration
|
2
|
+
class CreateMigration
|
3
|
+
|
4
|
+
# @private
|
5
|
+
class MigrationFileWriter
|
6
|
+
|
7
|
+
def self.write(file_name, options = {})
|
8
|
+
new(file_name, options).write
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(file_name, options = {})
|
12
|
+
@file_name = file_name
|
13
|
+
@up = options[:up]
|
14
|
+
@down = options[:down]
|
15
|
+
end
|
16
|
+
|
17
|
+
def write
|
18
|
+
path = ::File.join(Mongration.configuration.dir, @file_name)
|
19
|
+
::File.open(path, 'w') do |file|
|
20
|
+
file.write(<<EOS
|
21
|
+
class #{class_name}
|
22
|
+
def self.up
|
23
|
+
#{@up}
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.down
|
27
|
+
#{@down}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
EOS
|
31
|
+
)
|
32
|
+
end
|
33
|
+
path
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def class_name
|
39
|
+
File.new(@file_name).class_name
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/lib/mongration/file.rb
CHANGED
@@ -4,16 +4,36 @@ module Mongration
|
|
4
4
|
class File
|
5
5
|
include Comparable
|
6
6
|
|
7
|
-
def self.
|
7
|
+
def self.all_file_names
|
8
8
|
Dir[::File.join(Mongration.configuration.dir, '*.rb')].map do |path|
|
9
9
|
path.pathmap('%f')
|
10
|
-
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.pending
|
14
|
+
wrap(all_file_names - migrated_file_names).sort
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.migrated
|
18
|
+
wrap(migrated_file_names).sort
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.migrated_file_names
|
22
|
+
Migration.file_names
|
11
23
|
end
|
12
24
|
|
13
|
-
def self.
|
25
|
+
def self.all
|
26
|
+
pending + migrated
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.last
|
14
30
|
all.max
|
15
31
|
end
|
16
32
|
|
33
|
+
def self.wrap(file_names)
|
34
|
+
file_names.map { |file_name| new(file_name) }
|
35
|
+
end
|
36
|
+
|
17
37
|
attr_reader :file_name
|
18
38
|
|
19
39
|
def initialize(file_name)
|
@@ -21,35 +41,58 @@ module Mongration
|
|
21
41
|
end
|
22
42
|
|
23
43
|
def up
|
44
|
+
Mongration.out.puts("#{version} #{class_name}: migrating")
|
45
|
+
|
24
46
|
load_file
|
25
47
|
klass.up
|
48
|
+
|
49
|
+
Migration.create_by_file_name(file_name)
|
50
|
+
Mongration.out.puts("#{version} #{class_name}: migrated")
|
51
|
+
true
|
52
|
+
|
53
|
+
rescue => e
|
54
|
+
Mongration.out.puts("#{e.class}: An error has occured, this and all later migrations cancelled")
|
55
|
+
false
|
26
56
|
end
|
27
57
|
|
28
58
|
def down
|
29
59
|
load_file
|
30
60
|
klass.down
|
61
|
+
Migration.destroy_by_file_name(file_name)
|
62
|
+
end
|
63
|
+
|
64
|
+
def name
|
65
|
+
underscored_name.gsub('_', ' ')
|
66
|
+
end
|
67
|
+
|
68
|
+
def class_name
|
69
|
+
underscored_name.camelize
|
70
|
+
end
|
71
|
+
|
72
|
+
def version
|
73
|
+
file_name.split('_').first
|
31
74
|
end
|
32
75
|
|
33
76
|
def number
|
34
|
-
|
77
|
+
version.to_i
|
35
78
|
end
|
36
79
|
|
37
80
|
def <=>(other)
|
38
81
|
number <=> other.number
|
39
82
|
end
|
40
83
|
|
41
|
-
def class_name
|
42
|
-
@file_name.chomp('.rb').gsub(/^\d+_/, '').camelize
|
43
|
-
end
|
44
|
-
|
45
84
|
private
|
46
85
|
|
47
86
|
def load_file
|
48
|
-
load(::File.join(
|
87
|
+
load(::File.join(Mongration.configuration.dir, @file_name))
|
49
88
|
end
|
50
89
|
|
51
90
|
def klass
|
52
91
|
class_name.constantize
|
53
92
|
end
|
93
|
+
|
94
|
+
def underscored_name
|
95
|
+
@file_name.chomp('.rb').gsub(/^\d+_/, '')
|
96
|
+
end
|
54
97
|
end
|
55
98
|
end
|