exodus 1.0.3 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,7 @@
1
+ ## v1.0.4
2
+
3
+ * Custom migrations now runs in the given order
4
+
1
5
  ## v1.0.3
2
6
 
3
7
  * Bug fix -- rake needs to be required in exodus.rake
data/README.md CHANGED
@@ -18,7 +18,7 @@ Exodus - a migration framework for MongoDb
18
18
 
19
19
  Add this line to your application's Gemfile:
20
20
 
21
- $ gem 'exodus'
21
+ gem 'exodus'
22
22
 
23
23
  And then execute bundle install:
24
24
 
@@ -37,7 +37,7 @@ Exodus - a migration framework for MongoDb
37
37
  Exodus.configure do |config|
38
38
  config.db = 'migration_db'
39
39
  config.connection = Mongo::MongoClient.new("127.0.0.1", 27017, :pool_size => 5, :pool_timeout => 5)
40
- config.config_file = File.dirname(__FILE__) + '/config/config.yml'
40
+ config.config_file = File.dirname(__FILE__) + '/config/migrations.yml'
41
41
  config.migrations_directory = File.dirname(__FILE__) + '/models/migrations'
42
42
  end
43
43
 
@@ -132,17 +132,17 @@ Exodus - a migration framework for MongoDb
132
132
  rake db:rollback
133
133
  rake db:rollback STEP=2
134
134
 
135
- ## db:migrate_custom
136
- Executes all custom migrations that haven't run yet. You can pass custom migrations in parameters, otherwise custom migrations will be loaded from config/migration.yml. You can use an extra parameter to run only the last x ones.
135
+ ## db:migrate:custom
136
+ Executes all custom migrations that haven't run yet. Custom migrations will be loaded from your config file. Custom migrations will run in order of appearence. You can set the STEP enviroment variable to rollback only the last x ones.
137
137
 
138
- rake db:migrate_custom
139
- rake db:migrate_custom STEP=2
138
+ rake db:migrate:custom
139
+ rake db:migrate:custom STEP=2
140
140
 
141
- ## db:rollback_custom
142
- Executes all custom migrations that haven't run yet. You can pass custom migrations in parameters, otherwise custom migrations will be loaded from config/migration.yml. You can use an extra parameter to run only the last x ones.
141
+ ## db:rollback:custom
142
+ Executes all custom migrations that haven't run yet. Custom migrations will be loaded from your config file. Custom migrations will run in order of appearence. You can set the STEP enviroment variable to rollback only the last x ones.
143
143
 
144
- rake db:rollback_custom
145
- rake db:rollback_custom STEP=2
144
+ rake db:rollback:custom
145
+ rake db:rollback:custom STEP=2
146
146
 
147
147
  ## db:migrate:list
148
148
  Lists all the migrations.
@@ -27,15 +27,24 @@ module Exodus
27
27
  File.dirname(__FILE__) + '/../tasks/exodus.rake'
28
28
  end
29
29
 
30
- # Executes a number of migrations equal to step (or all of them if step is nil)
31
- def run_migrations(direction, migrations, step = nil)
30
+ # Sorts and executes a number of migrations equal to step (or all of them if step is nil)
31
+ def run_sorted_migrations(direction, migrations, step = nil)
32
32
  if migrations
33
33
  sorted_migrations = order_with_direction(migrations, direction)
34
- sorted_migrations = sorted_migrations.shift(step.to_i) if step
34
+ run_migrations(direction, sorted_migrations, step)
35
+ else
36
+ raise StandardError, "no migrations given in argument!"
37
+ end
38
+ end
39
+
35
40
 
36
- run_each(direction, sorted_migrations)
41
+ # Executes a number of migrations equal to step (or all of them if step is nil)
42
+ def run_migrations(direction, migrations, step = nil)
43
+ if migrations
44
+ migrations = migrations.shift(step.to_i) if step
45
+ run_each(direction, migrations)
37
46
  else
38
- puts "no migrations given in argument!"
47
+ puts "Unable to find migrations!"
39
48
  end
40
49
  end
41
50
 
@@ -57,16 +66,13 @@ module Exodus
57
66
  end
58
67
  end
59
68
 
60
- # Looks up in the database if a migration with the same class and same arguments already exists
69
+
61
70
  # Otherwise instanciate a new one
62
71
  # Runs the migration if it is runnable
63
72
  def run_one_migration(migration_class, direction, args)
64
- # Going throught MRD because MM request returns nil for some reason
65
- current_migration = migration_class.load(migration_class.collection.find('status.arguments' => args).first)
66
- current_migration ||= migration_class.new(:status => {:arguments => args})
73
+ current_migration = find_existing_migration(migration_class, args) || migration_class.new(:status => {:arguments => args})
67
74
 
68
75
  if current_migration.is_runnable?(direction)
69
- # Make sure we save all info in case of a failure
70
76
  begin
71
77
  current_migration.run(direction)
72
78
  current_migration.status.error = nil
@@ -82,6 +88,16 @@ module Exodus
82
88
  end
83
89
  end
84
90
 
91
+ # Looks up in the database if a migration with the same class and same arguments already exists
92
+ # Returns nil or the migration if one is found
93
+ def find_existing_migration(migration_class, args)
94
+ existing_migrations = migration_class.collection.find('status.arguments' => args)
95
+ existing_migrations.detect do |migration|
96
+ existing_migration = migration_class.load(migration)
97
+ return existing_migration if existing_migration.is_a?(migration_class)
98
+ end
99
+ end
100
+
85
101
  private
86
102
 
87
103
  # Prints tabulation before execting a given block
@@ -1,3 +1,3 @@
1
1
  module Exodus
2
- VERSION = "1.0.3"
2
+ VERSION = "1.0.4"
3
3
  end
@@ -0,0 +1,236 @@
1
+ require "spec_helper"
2
+
3
+ describe Exodus do
4
+ describe "sort_migrations" do
5
+ before do
6
+ class Migration_test4 < Exodus::Migration; end
7
+ class Migration_test3 < Exodus::Migration; end
8
+
9
+ Migration_test3.migration_number = 3
10
+ Migration_test4.migration_number = 4
11
+ end
12
+
13
+ it "migrations should not be sorted by default" do
14
+ unsorted_migrations = Exodus::Migration.load_all([])
15
+ migrations_numbers = unsorted_migrations.map {|migration, args| migration.migration_number }
16
+
17
+ migrations_numbers.should_not == migrations_numbers.sort
18
+ end
19
+
20
+ it "should return the migrations sorted by migration number" do
21
+ unsorted_migrations = Exodus::Migration.load_all([])
22
+ migrations_numbers = unsorted_migrations.map {|migration, args| migration.migration_number }
23
+
24
+ sorted_migrations = Exodus::sort_migrations(unsorted_migrations)
25
+ sorted_migrations_numbers = sorted_migrations.map {|migration, args| migration.migration_number }
26
+ sorted_migrations_numbers.should == migrations_numbers.sort
27
+ end
28
+ end
29
+
30
+ describe "order_with_direction" do
31
+ before do
32
+ class Migration_test4 < Exodus::Migration; end
33
+ class Migration_test3 < Exodus::Migration; end
34
+ class Migration_test5 < Exodus::Migration; end
35
+
36
+ Migration_test3.migration_number = 3
37
+ Migration_test4.migration_number = 4
38
+ Migration_test5.migration_number = 5
39
+
40
+ unsorted_migrations = Exodus::Migration.load_all([])
41
+ @migrations_numbers = unsorted_migrations.map {|migration, args| migration.migration_number }
42
+
43
+ sorted_migrations = Exodus.order_with_direction(unsorted_migrations, 'up')
44
+ @ordered_up = sorted_migrations.map {|migration, args| migration.migration_number }
45
+
46
+ sorted_migrations = Exodus.order_with_direction(unsorted_migrations, 'down')
47
+ @ordered_down = sorted_migrations.map {|migration, args| migration.migration_number }
48
+ end
49
+
50
+ describe "when direction is UP" do
51
+ it "should be sorted ascendingly" do
52
+ @ordered_up.should == @migrations_numbers.sort
53
+ end
54
+ end
55
+
56
+ describe "when direction is UP" do
57
+ it "should be sorted ascendingly" do
58
+ @ordered_down.should == @migrations_numbers.sort.reverse
59
+ end
60
+ end
61
+ end
62
+
63
+ describe "tasks" do
64
+ it "should return the current path of exodus.rake" do
65
+ rake_file = Pathname.new(File.dirname(__FILE__) + '/../../tasks/exodus.rake')
66
+ Pathname.new(Exodus.tasks).realpath.to_s.should == rake_file.realpath.to_s
67
+ end
68
+ end
69
+
70
+ describe "run_one_migration" do
71
+ before do
72
+ class Migration_test6 < Exodus::Migration
73
+ def up
74
+ 'valid'
75
+ end
76
+ end
77
+ class Migration_test7 < Exodus::Migration
78
+ def up
79
+ raise StandardError, "the current migration failed"
80
+ end
81
+ end
82
+ end
83
+
84
+ before :each do
85
+ Exodus::Migration.collection.drop
86
+ end
87
+
88
+ describe "When the migration has not been ran" do
89
+ describe "with a valid migration" do
90
+ it "should successfully create the migration" do
91
+ lambda{ Exodus.run_one_migration(Migration_test6, 'up', {})}.should
92
+ change {Exodus::Migration}.by(1)
93
+ end
94
+ end
95
+
96
+ describe "with a failing migration" do
97
+ it "should raise an error" do
98
+ lambda{ Exodus.run_one_migration(Migration_test7, 'up', {})}.should
99
+ raise_error(StandardError)
100
+ end
101
+
102
+ it "should create the migration" do
103
+ lambda{ Exodus.run_one_migration(Migration_test7, 'up', {})}.should
104
+ change {Exodus::Migration}.by(1)
105
+ end
106
+ end
107
+ end
108
+
109
+ describe "When the migration has been ran" do
110
+ describe "with a valid migration" do
111
+ it "should not create a new migration" do
112
+ Exodus.run_one_migration(Migration_test6, 'up', {})
113
+
114
+ lambda{ Exodus.run_one_migration(Migration_test6, 'up', {})}.should
115
+ change {Exodus::Migration}.by(0)
116
+ end
117
+ end
118
+
119
+ describe "with a failing migration" do
120
+ it "should not create a new migration" do
121
+ Exodus.run_one_migration(Migration_test7, 'up', {}) rescue nil
122
+
123
+ lambda{ Exodus.run_one_migration(Migration_test7, 'up', {})}.should
124
+ change {Exodus::Migration}.by(0)
125
+ end
126
+ end
127
+ end
128
+ end
129
+
130
+ describe "find_existing_migration" do
131
+ before do
132
+ class Migration_test6 < Exodus::Migration
133
+ def up
134
+ 'valid'
135
+ end
136
+ end
137
+ class Migration_test8 < Exodus::Migration
138
+ def up
139
+ 'valid'
140
+ end
141
+ end
142
+ end
143
+
144
+ before :each do
145
+ Exodus::Migration.collection.drop
146
+ end
147
+
148
+ describe "When no migrations have been ran" do
149
+ it "should not find any migration" do
150
+ Exodus.find_existing_migration(Migration_test8, {}).should be_nil
151
+ end
152
+ end
153
+
154
+ describe "When a different migration has been ran" do
155
+ it "should not find any migration" do
156
+ Exodus.run_one_migration(Migration_test6, 'up', {})
157
+ Exodus.find_existing_migration(Migration_test8, {}).should be_nil
158
+ end
159
+ end
160
+
161
+ describe "When the migration has been ran" do
162
+ it "should find the migration" do
163
+ Exodus.run_one_migration(Migration_test8, 'up', {})
164
+ Exodus.find_existing_migration(Migration_test8, {}).class.should == Migration_test8
165
+ end
166
+ end
167
+
168
+ describe "When all migrations have been ran" do
169
+ it "should find the migration" do
170
+ Exodus.run_one_migration(Migration_test6, 'up', {})
171
+ Exodus.run_one_migration(Migration_test8, 'up', {})
172
+ Exodus.find_existing_migration(Migration_test8, {}).class.should == Migration_test8
173
+ end
174
+ end
175
+ end
176
+
177
+ describe "run_migrations and run_sorted_migrations" do
178
+ before do
179
+ class Migration_test9 < Exodus::Migration
180
+ @migration_number = 9
181
+ def up
182
+ UserSupport.create!({:name => "Thomas"})
183
+ end
184
+ end
185
+ class Migration_test10 < Exodus::Migration
186
+ @migration_number = 10
187
+ def up
188
+ UserSupport.create!({:name => "Tester"})
189
+ end
190
+ end
191
+ end
192
+
193
+ before :each do
194
+ UserSupport.collection.drop
195
+ Exodus::Migration.collection.drop
196
+ end
197
+
198
+ describe "running the same migration in a different order with run_migrations" do
199
+ it "should successfully run them in different order" do
200
+ migrations = [[Migration_test9, {}], [Migration_test10, {}]]
201
+ Exodus.run_migrations('up', migrations)
202
+ users = UserSupport.all
203
+
204
+ users.first.name.should == "Thomas"
205
+ users.last.name.should == "Tester"
206
+
207
+ UserSupport.collection.drop
208
+ Exodus::Migration.collection.drop
209
+ Exodus.run_migrations('up', migrations.reverse)
210
+ users = UserSupport.all
211
+
212
+ users.first.name.should == "Tester"
213
+ users.last.name.should == "Thomas"
214
+ end
215
+ end
216
+
217
+ describe "running the same migration in a different order with run_sorted_migrations" do
218
+ it "should successfully run them in the same order" do
219
+ migrations = [[Migration_test9, {}], [Migration_test10, {}]]
220
+ Exodus.run_sorted_migrations('up', migrations)
221
+ users = UserSupport.all
222
+
223
+ users.first.name.should == "Thomas"
224
+ users.last.name.should == "Tester"
225
+
226
+ UserSupport.collection.drop
227
+ Exodus::Migration.collection.drop
228
+ Exodus.run_sorted_migrations('up', migrations.reverse)
229
+ users = UserSupport.all
230
+
231
+ users.first.name.should == "Thomas"
232
+ users.last.name.should == "Tester"
233
+ end
234
+ end
235
+ end
236
+ end
@@ -1,5 +1,4 @@
1
1
  require "spec_helper"
2
- require File.dirname(__FILE__) + "/../../lib/exodus"
3
2
 
4
3
  describe Exodus::Migration do
5
4
 
@@ -173,15 +172,4 @@ describe Exodus::Migration do
173
172
  end
174
173
  end
175
174
  end
176
-
177
- describe "MigrationFramework" do
178
- describe "sort_migrations" do
179
- it "should return the migrations sorted by migration number" do
180
- CompleteNewMigration.migration_number = 10
181
- sorted_migrations = Exodus::sort_migrations(Exodus::Migration.load_all([]))
182
- migrations_number = sorted_migrations.map {|migration, args| migration.migration_number }
183
- migrations_number.should == migrations_number.sort
184
- end
185
- end
186
- end
187
175
  end
@@ -22,7 +22,7 @@ namespace :db do
22
22
  task :migrate => :require_env do
23
23
  time_it "db:migrate#{" step #{step}" if step}" do
24
24
  migrations = Exodus::Migration.load_all(Exodus.migrations_info.migrate)
25
- Exodus::run_migrations('up', migrations, step)
25
+ Exodus::run_sorted_migrations('up', migrations, step)
26
26
  end
27
27
  end
28
28
 
@@ -30,7 +30,7 @@ namespace :db do
30
30
  task :rollback => :require_env do
31
31
  time_it "db:rollback#{" step #{step}" if step}" do
32
32
  migrations = Exodus::Migration.load_all(Exodus.migrations_info.rollback)
33
- Exodus::run_migrations('down', migrations, step)
33
+ Exodus::run_sorted_migrations('down', migrations, step)
34
34
  end
35
35
  end
36
36
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: exodus
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 1.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-05-29 00:00:00.000000000 Z
12
+ date: 2013-06-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: mongo_mapper
@@ -99,6 +99,7 @@ files:
99
99
  - lib/exodus/migrations/migration_error.rb
100
100
  - lib/exodus/migrations/migration_status.rb
101
101
  - lib/exodus/version.rb
102
+ - spec/exodus/exodus_spec.rb
102
103
  - spec/exodus/migration_spec.rb
103
104
  - spec/spec_helper.rb
104
105
  - spec/support/config.yml
@@ -130,6 +131,7 @@ signing_key:
130
131
  specification_version: 3
131
132
  summary: Exodus uses mongomapper to provide a complete migration framework
132
133
  test_files:
134
+ - spec/exodus/exodus_spec.rb
133
135
  - spec/exodus/migration_spec.rb
134
136
  - spec/spec_helper.rb
135
137
  - spec/support/config.yml