mongoid_rails_migrations 0.0.1

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.
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ .DS_Store
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ # Use `bundle install` in order to install these gems
2
+ # Use `bundle exec rake` in order to run the specs using the bundle
3
+ source "http://gemcutter.org"
4
+
5
+ gem "rails", "3.0.0.beta3"
6
+ gem "railties", "3.0.0.beta3"
7
+ gem "activesupport", "3.0.0.beta3"
8
+ gem "mongoid", "2.0.0.beta4"
9
+ gem "bson_ext", '0.20.1' # this must be same version as mongo gem
data/README.rdoc ADDED
@@ -0,0 +1,34 @@
1
+ == SYNOPSIS
2
+ * Data migrations for Mongoid in Active Record style, minus column input. This allows for up and down migration methods.
3
+
4
+ == MIGRATE WHEN ...
5
+ * You need to rearrange or split data
6
+ * You have model instances which you leverage as schema data
7
+
8
+ == REQUIREMENTS
9
+ * rails 3.0.0.beta3 ( should be cake updating for rails 3 final )
10
+ * mongoid
11
+
12
+ == INSTALL
13
+ * gem install mongoid_rails_migrations
14
+ * In your Gemfile, include:
15
+ gem "mongoid_rails_migrations", ">=0.0.1" # or whatever the current version happens to be
16
+
17
+ == FEATURES AND HOW TO USE
18
+ * generator:
19
+ * rails generate mongoid:migration your_migration_name_here
20
+
21
+ * migrations (tested):
22
+ * db:migrate
23
+ * db:migrate:down
24
+ * db:migrate:up
25
+ * db:rollback
26
+
27
+ * migrations (untested):
28
+ * db:migrate:redo
29
+ * db:migrate:reset
30
+ * db:reseed (might be covered by mongoid)
31
+
32
+ == NOTES
33
+ * Currently, only timestamp generated migrations have been tested, but you should be able to toggle the value of Mongoid.timestamped_migrations to auto generate likewise migrations.
34
+ * Only tested with ruby 1.9.1
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ $:.unshift(File.dirname(__FILE__))
2
+
3
+ require File.dirname(__FILE__) + "/test/config"
4
+
5
+ namespace :test do
6
+ namespace :mongoid do
7
+ desc "Test mongoid rails migrations"
8
+ task :migrations do
9
+ require 'test/migration_test'
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ # Set up gems listed in the Gemfile.
5
+ if File.exist?(File.expand_path('../../Gemfile', __FILE__))
6
+ require 'bundler'
7
+ Bundler.setup
8
+ end
9
+
10
+ Bundler.require(:default) if defined?(Bundler)
11
+
12
+ # Add base to path incase not included as a gem
13
+ $:.unshift(File.dirname(__FILE__)) unless
14
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
15
+
16
+ require 'mongoid_rails_migrations/models/data_migration'
17
+ require 'mongoid_rails_migrations/mongoid_ext/mongoid'
18
+ require 'mongoid_rails_migrations/mongoid_ext/railtie'
19
+ require 'mongoid_rails_migrations/active_record_ext/migrations'
@@ -0,0 +1,405 @@
1
+ # encoding: utf-8
2
+
3
+ module Mongoid #:nodoc
4
+ # Exception that can be raised to stop migrations from going backwards.
5
+ class IrreversibleMigration < RuntimeError
6
+ end
7
+
8
+ class DuplicateMigrationVersionError < RuntimeError#:nodoc:
9
+ def initialize(version)
10
+ super("Multiple migrations have the version number #{version}")
11
+ end
12
+ end
13
+
14
+ class DuplicateMigrationNameError < RuntimeError#:nodoc:
15
+ def initialize(name)
16
+ super("Multiple migrations have the name #{name}")
17
+ end
18
+ end
19
+
20
+ class UnknownMigrationVersionError < RuntimeError#:nodoc:
21
+ def initialize(version)
22
+ super("No migration with version number #{version}")
23
+ end
24
+ end
25
+
26
+ class IllegalMigrationNameError < RuntimeError#:nodoc:
27
+ def initialize(name)
28
+ super("Illegal name for migration file: #{name}\n\t(only lower case letters, numbers, and '_' allowed)")
29
+ end
30
+ end
31
+
32
+ # Data migrations can manage the modification of data. It's a solution to the common problem of modifying
33
+ # data between code revisions within a document oriented database.
34
+ #
35
+ # Example of simple migration for a system dependency:
36
+ #
37
+ # class AddBaselineSurveySchema < Mongoid::Migration
38
+ # def self.up
39
+ # SurveySchema.create(:label => 'Baseline Survey')
40
+ # end
41
+ #
42
+ # def self.down
43
+ # SurveySchema.where(:label => 'Baseline Survey').first.destroy
44
+ # end
45
+ # end
46
+ #
47
+ # == Timestamped Migrations
48
+ #
49
+ # By default, Rails generates migrations that look like:
50
+ #
51
+ # 20080717013526_your_migration_name.rb
52
+ #
53
+ # The prefix is a generation timestamp (in UTC).
54
+ #
55
+ # If you'd prefer to use numeric prefixes, you can turn timestamped migrations
56
+ # off by setting:
57
+ #
58
+ # config.mongoid.timestamped_migrations = false
59
+ #
60
+ # In environment.rb.
61
+ #
62
+ class Migration
63
+ @@verbose = true
64
+ cattr_accessor :verbose
65
+
66
+ class << self
67
+ def up_with_benchmarks #:nodoc:
68
+ migrate(:up)
69
+ end
70
+
71
+ def down_with_benchmarks #:nodoc:
72
+ migrate(:down)
73
+ end
74
+
75
+ # Execute this migration in the named direction
76
+ def migrate(direction)
77
+ return unless respond_to?(direction)
78
+
79
+ case direction
80
+ when :up then announce "migrating"
81
+ when :down then announce "reverting"
82
+ end
83
+
84
+ result = nil
85
+ time = Benchmark.measure { result = send("#{direction}_without_benchmarks") }
86
+
87
+ case direction
88
+ when :up then announce "migrated (%.4fs)" % time.real; write
89
+ when :down then announce "reverted (%.4fs)" % time.real; write
90
+ end
91
+
92
+ result
93
+ end
94
+
95
+ # Because the method added may do an alias_method, it can be invoked
96
+ # recursively. We use @ignore_new_methods as a guard to indicate whether
97
+ # it is safe for the call to proceed.
98
+ def singleton_method_added(sym) #:nodoc:
99
+ return if defined?(@ignore_new_methods) && @ignore_new_methods
100
+
101
+ begin
102
+ @ignore_new_methods = true
103
+
104
+ case sym
105
+ when :up, :down
106
+ singleton_class.send(:alias_method_chain, sym, "benchmarks")
107
+ end
108
+ ensure
109
+ @ignore_new_methods = false
110
+ end
111
+ end
112
+
113
+ def write(text="")
114
+ puts(text) if verbose
115
+ end
116
+
117
+ def announce(message)
118
+ version = defined?(@version) ? @version : nil
119
+
120
+ text = "#{version} #{name}: #{message}"
121
+ length = [0, 75 - text.length].max
122
+ write "== %s %s" % [text, "=" * length]
123
+ end
124
+
125
+ def say(message, subitem=false)
126
+ write "#{subitem ? " ->" : "--"} #{message}"
127
+ end
128
+
129
+ def say_with_time(message)
130
+ say(message)
131
+ result = nil
132
+ time = Benchmark.measure { result = yield }
133
+ say "%.4fs" % time.real, :subitem
134
+ say("#{result} rows", :subitem) if result.is_a?(Integer)
135
+ result
136
+ end
137
+
138
+ def suppress_messages
139
+ save, self.verbose = verbose, false
140
+ yield
141
+ ensure
142
+ self.verbose = save
143
+ end
144
+
145
+ def connection
146
+ # ActiveRecord::Base.connection
147
+ Mongoid.database
148
+ end
149
+
150
+ def method_missing(method, *arguments, &block)
151
+ arg_list = arguments.map(&:inspect) * ', '
152
+
153
+ say_with_time "#{method}(#{arg_list})" do
154
+ # unless arguments.empty? || method == :execute
155
+ # arguments[0] = Migrator.proper_table_name(arguments.first)
156
+ # end
157
+ connection.send(method, *arguments, &block)
158
+ end
159
+ end
160
+ end
161
+ end
162
+
163
+ # MigrationProxy is used to defer loading of the actual migration classes
164
+ # until they are needed
165
+ class MigrationProxy
166
+
167
+ attr_accessor :name, :version, :filename
168
+
169
+ delegate :migrate, :announce, :write, :to=>:migration
170
+
171
+ private
172
+
173
+ def migration
174
+ @migration ||= load_migration
175
+ end
176
+
177
+ def load_migration
178
+ require(File.expand_path(filename))
179
+ name.constantize
180
+ end
181
+
182
+ end
183
+
184
+ class Migrator#:nodoc:
185
+ class << self
186
+ def migrate(migrations_path, target_version = nil)
187
+ case
188
+ when target_version.nil? then up(migrations_path, target_version)
189
+ when current_version > target_version then down(migrations_path, target_version)
190
+ else up(migrations_path, target_version)
191
+ end
192
+ end
193
+
194
+ def rollback(migrations_path, steps=1)
195
+ move(:down, migrations_path, steps)
196
+ end
197
+
198
+ def forward(migrations_path, steps=1)
199
+ move(:up, migrations_path, steps)
200
+ end
201
+
202
+ def up(migrations_path, target_version = nil)
203
+ self.new(:up, migrations_path, target_version).migrate
204
+ end
205
+
206
+ def down(migrations_path, target_version = nil)
207
+ self.new(:down, migrations_path, target_version).migrate
208
+ end
209
+
210
+ def run(direction, migrations_path, target_version)
211
+ self.new(direction, migrations_path, target_version).run
212
+ end
213
+
214
+ def migrations_path
215
+ 'db/migrate'
216
+ end
217
+
218
+ # def schema_migrations_table_name
219
+ # # Base.table_name_prefix + 'schema_migrations' + Base.table_name_suffix
220
+ # 'data_migrations'
221
+ # end
222
+
223
+ def get_all_versions
224
+ # table = Arel::Table.new(schema_migrations_table_name)
225
+ # Base.connection.select_values(table.project(table['version']).to_sql).map(&:to_i).sort
226
+ DataMigration.all.map {|datamigration| datamigration.version.to_i }.sort
227
+ end
228
+
229
+ def current_version
230
+ # sm_table = schema_migrations_table_name
231
+ # if Base.connection.table_exists?(sm_table)
232
+ # get_all_versions.max || 0
233
+ # else
234
+ # 0
235
+ # end
236
+ get_all_versions.max || 0
237
+ end
238
+
239
+ def proper_table_name(name)
240
+ # Use the Active Record objects own table_name, or pre/suffix from ActiveRecord::Base if name is a symbol/string
241
+ # name.table_name rescue "#{ActiveRecord::Base.table_name_prefix}#{name}#{ActiveRecord::Base.table_name_suffix}"
242
+ name
243
+ end
244
+
245
+ private
246
+
247
+ def move(direction, migrations_path, steps)
248
+ migrator = self.new(direction, migrations_path)
249
+ start_index = migrator.migrations.index(migrator.current_migration)
250
+
251
+ if start_index
252
+ finish = migrator.migrations[start_index + steps]
253
+ version = finish ? finish.version : 0
254
+ send(direction, migrations_path, version)
255
+ end
256
+ end
257
+ end
258
+
259
+ def initialize(direction, migrations_path, target_version = nil)
260
+ # raise StandardError.new("This database does not yet support migrations") unless Base.connection.supports_migrations?
261
+ # Base.connection.initialize_schema_migrations_table
262
+ @direction, @migrations_path, @target_version = direction, migrations_path, target_version
263
+ end
264
+
265
+ def current_version
266
+ migrated.last || 0
267
+ end
268
+
269
+ def current_migration
270
+ migrations.detect { |m| m.version == current_version }
271
+ end
272
+
273
+ def run
274
+ target = migrations.detect { |m| m.version == @target_version }
275
+ raise UnknownMigrationVersionError.new(@target_version) if target.nil?
276
+ unless (up? && migrated.include?(target.version.to_i)) || (down? && !migrated.include?(target.version.to_i))
277
+ target.migrate(@direction)
278
+ record_version_state_after_migrating(target.version)
279
+ end
280
+ end
281
+
282
+ def migrate
283
+ current = migrations.detect { |m| m.version == current_version }
284
+ target = migrations.detect { |m| m.version == @target_version }
285
+
286
+ if target.nil? && !@target_version.nil? && @target_version > 0
287
+ raise UnknownMigrationVersionError.new(@target_version)
288
+ end
289
+
290
+ start = up? ? 0 : (migrations.index(current) || 0)
291
+ finish = migrations.index(target) || migrations.size - 1
292
+ runnable = migrations[start..finish]
293
+
294
+ # skip the last migration if we're headed down, but not ALL the way down
295
+ runnable.pop if down? && !target.nil?
296
+
297
+ runnable.each do |migration|
298
+ Rails.logger.info "Migrating to #{migration.name} (#{migration.version})" if Rails.logger
299
+
300
+ # On our way up, we skip migrating the ones we've already migrated
301
+ next if up? && migrated.include?(migration.version.to_i)
302
+
303
+ # On our way down, we skip reverting the ones we've never migrated
304
+ if down? && !migrated.include?(migration.version.to_i)
305
+ migration.announce 'never migrated, skipping'; migration.write
306
+ next
307
+ end
308
+
309
+ # begin
310
+ # ddl_transaction do
311
+ # migration.migrate(@direction)
312
+ # record_version_state_after_migrating(migration.version)
313
+ # end
314
+ # rescue => e
315
+ # canceled_msg = Base.connection.supports_ddl_transactions? ? "this and " : ""
316
+ # raise StandardError, "An error has occurred, #{canceled_msg}all later migrations canceled:\n\n#{e}", e.backtrace
317
+ # end
318
+ begin
319
+ migration.migrate(@direction)
320
+ record_version_state_after_migrating(migration.version)
321
+ rescue => e
322
+ raise StandardError, "An error has occurred, #{migration.version} and all later migrations canceled:\n\n#{e}", e.backtrace
323
+ end
324
+ end
325
+ end
326
+
327
+ def migrations
328
+ @migrations ||= begin
329
+ files = Dir["#{@migrations_path}/[0-9]*_*.rb"]
330
+
331
+ migrations = files.inject([]) do |klasses, file|
332
+ version, name = file.scan(/([0-9]+)_([_a-z0-9]*).rb/).first
333
+
334
+ raise IllegalMigrationNameError.new(file) unless version
335
+ version = version.to_i
336
+
337
+ if klasses.detect { |m| m.version == version }
338
+ raise DuplicateMigrationVersionError.new(version)
339
+ end
340
+
341
+ if klasses.detect { |m| m.name == name.camelize }
342
+ raise DuplicateMigrationNameError.new(name.camelize)
343
+ end
344
+
345
+ migration = MigrationProxy.new
346
+ migration.name = name.camelize
347
+ migration.version = version
348
+ migration.filename = file
349
+ klasses << migration
350
+ end
351
+
352
+ migrations = migrations.sort_by(&:version)
353
+ down? ? migrations.reverse : migrations
354
+ end
355
+ end
356
+
357
+ def pending_migrations
358
+ already_migrated = migrated
359
+ migrations.reject { |m| already_migrated.include?(m.version.to_i) }
360
+ end
361
+
362
+ def migrated
363
+ @migrated_versions ||= self.class.get_all_versions
364
+ end
365
+
366
+ private
367
+ def record_version_state_after_migrating(version)
368
+ # table = Arel::Table.new(self.class.schema_migrations_table_name)
369
+
370
+ @migrated_versions ||= []
371
+ # if down?
372
+ # @migrated_versions.delete(version)
373
+ # table.where(table["version"].eq(version.to_s)).delete
374
+ # else
375
+ # @migrated_versions.push(version).sort!
376
+ # table.insert table["version"] => version.to_s
377
+ # end
378
+ if down?
379
+ @migrated_versions.delete(version)
380
+ DataMigration.where(:version => version.to_s).first.destroy
381
+ else
382
+ @migrated_versions.push(version).sort!
383
+ DataMigration.create(:version => version.to_s)
384
+ end
385
+ end
386
+
387
+ def up?
388
+ @direction == :up
389
+ end
390
+
391
+ def down?
392
+ @direction == :down
393
+ end
394
+
395
+ # Wrap the migration in a transaction only if supported by the adapter.
396
+ def ddl_transaction(&block)
397
+ # if Base.connection.supports_ddl_transactions?
398
+ # Base.transaction { block.call }
399
+ # else
400
+ # block.call
401
+ # end
402
+ block.call
403
+ end
404
+ end
405
+ end
@@ -0,0 +1,5 @@
1
+ class DataMigration
2
+ include Mongoid::Document
3
+
4
+ field :version
5
+ end
@@ -0,0 +1,8 @@
1
+ # encoding: utf-8
2
+
3
+ module Mongoid #:nodoc
4
+ class << self
5
+ # Specify whether or not to use timestamps for migration versions
6
+ cattr_accessor(:timestamped_migrations , :instance_writer => true) {|timestamped_migrations| timestamped_migrations = true }
7
+ end
8
+ end
@@ -0,0 +1,15 @@
1
+ # encoding: utf-8
2
+
3
+ if defined?(Rails::Railtie)
4
+ module Rails #:nodoc:
5
+ module Mongoid #:nodoc:
6
+ class Railtie < Rails::Railtie
7
+ config.generators.orm :mongoid, :migration => true
8
+
9
+ rake_tasks do
10
+ load "mongoid_rails_migrations/mongoid_ext/railties/database.rake"
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,78 @@
1
+ namespace :db do
2
+
3
+ desc 'Drops all the collections for the database for the current Rails.env'
4
+ task :drop => :environment do
5
+ Mongoid.master.collections.each{|col| col.drop unless col.name == 'system.users' }
6
+ end
7
+
8
+ desc 'Load the seed data from db/seeds.rb'
9
+ task :seed => :environment do
10
+ seed_file = File.join(Rails.root, 'db', 'seeds.rb')
11
+ load(seed_file) if File.exist?(seed_file)
12
+ end
13
+
14
+ desc 'Create the database, and initialize with the seed data'
15
+ task :setup => [ 'db:create', 'db:seed' ]
16
+
17
+ desc 'Delete data and seed'
18
+ task :reseed => [ 'db:drop', 'db:seed' ]
19
+
20
+ task :create => :environment do
21
+ # noop
22
+ end
23
+
24
+ desc "Migrate the database through scripts in db/migrate. Target specific version with VERSION=x. Turn off output with VERBOSE=false."
25
+ task :migrate => :environment do
26
+ Mongoid::Migration.verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true
27
+ Mongoid::Migrator.migrate("db/migrate/", ENV["VERSION"] ? ENV["VERSION"].to_i : nil)
28
+ end
29
+
30
+ namespace :migrate do
31
+ desc 'Rollback the database one migration and re migrate up. If you want to rollback more than one step, define STEP=x. Target specific version with VERSION=x.'
32
+ task :redo => :environment do
33
+ if ENV["VERSION"]
34
+ Rake::Task["db:migrate:down"].invoke
35
+ Rake::Task["db:migrate:up"].invoke
36
+ else
37
+ Rake::Task["db:rollback"].invoke
38
+ Rake::Task["db:migrate"].invoke
39
+ end
40
+ end
41
+
42
+ desc 'Resets your database using your migrations for the current environment'
43
+ # should db:create be changed to db:setup? It makes more sense wanting to seed
44
+ task :reset => ["db:drop", "db:create", "db:migrate"]
45
+
46
+ desc 'Runs the "up" for a given migration VERSION.'
47
+ task :up => :environment do
48
+ version = ENV["VERSION"] ? ENV["VERSION"].to_i : nil
49
+ raise "VERSION is required" unless version
50
+ Mongoid::Migrator.run(:up, "db/migrate/", version)
51
+ end
52
+
53
+ desc 'Runs the "down" for a given migration VERSION.'
54
+ task :down => :environment do
55
+ version = ENV["VERSION"] ? ENV["VERSION"].to_i : nil
56
+ raise "VERSION is required" unless version
57
+ Mongoid::Migrator.run(:down, "db/migrate/", version)
58
+ end
59
+ end
60
+
61
+ desc 'Rolls the database back to the previous migration. Specify the number of steps with STEP=n'
62
+ task :rollback => :environment do
63
+ step = ENV['STEP'] ? ENV['STEP'].to_i : 1
64
+ Mongoid::Migrator.rollback('db/migrate/', step)
65
+ end
66
+
67
+ namespace :schema do
68
+ task :load do
69
+ # noop
70
+ end
71
+ end
72
+
73
+ namespace :test do
74
+ task :prepare do
75
+ # Stub out for MongoDB
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,16 @@
1
+ require 'rails/generators/mongoid/mongoid_generator'
2
+
3
+ module Mongoid
4
+ module Generators
5
+ class MigrationGenerator < Base
6
+
7
+ def create_migration_file
8
+ migration_template "migration.rb", "db/migrate/#{file_name}.rb"
9
+ end
10
+
11
+ protected
12
+ attr_reader :migration_action
13
+
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,7 @@
1
+ class <%= migration_class_name %> < Mongoid::Migration
2
+ def self.up
3
+ end
4
+
5
+ def self.down
6
+ end
7
+ end
@@ -0,0 +1,26 @@
1
+ require 'rails/generators/migration'
2
+
3
+ module Mongoid #:nodoc:
4
+ module Generators #:nodoc:
5
+ class Base < ::Rails::Generators::NamedBase #:nodoc:
6
+ include Rails::Generators::Migration
7
+
8
+ # A simple redef is fine because rails caches this path on class.inherited
9
+ # mongoid uses @_mongoid_source_root ||=, but that's not necessary
10
+ def self.source_root
11
+ File.expand_path("../../#{base_name}/#{generator_name}/templates", __FILE__)
12
+ end
13
+
14
+ # Implement the required interface for Rails::Generators::Migration.
15
+ def self.next_migration_number(dirname) #:nodoc:
16
+ next_migration_number = current_migration_number(dirname) + 1
17
+ if Mongoid.timestamped_migrations
18
+ [Time.now.utc.strftime("%Y%m%d%H%M%S"), "%.14d" % next_migration_number].max
19
+ else
20
+ "%.3d" % next_migration_number
21
+ end
22
+ end
23
+
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,29 @@
1
+ Gem::Specification.new do |s|
2
+ s.platform = Gem::Platform::RUBY
3
+ s.name = 'mongoid_rails_migrations'
4
+ s.version = '0.0.1'
5
+ s.summary = 'Data migrations for Mongoid in Active Record style, minus column input.'
6
+ s.description = 'Sometimes you just need to migrate data.'
7
+
8
+ # only tested with 1.9.1, but let's go for it
9
+ s.required_ruby_version = '>= 1.8.6'
10
+ s.required_rubygems_version = ">= 1.3.6"
11
+
12
+ s.author = 'Alan Da Costa'
13
+ s.email = 'alandacosta@gmail.com.com'
14
+ s.date = %q{2010-05-12}
15
+ # s.homepage = ''
16
+
17
+ s.require_paths = ["lib"]
18
+ s.files = Dir['.gitignore', 'Gemfile', 'Rakefile', 'README.rdoc', 'mongoid_rails_migrations.gemspec', 'VERSION', 'lib/**/*']
19
+ s.test_files = Dir['test/**/*']
20
+ s.has_rdoc = false
21
+
22
+ rails_version = '>= 3.0.0.beta3'
23
+
24
+ s.add_dependency('bundler', '>= 0.9.19')
25
+ s.add_dependency('mongoid', '2.0.0.beta4')
26
+ s.add_dependency('rails', rails_version)
27
+ s.add_dependency('railties', rails_version)
28
+ s.add_dependency('activesupport', rails_version)
29
+ end
data/test/config.rb ADDED
@@ -0,0 +1,12 @@
1
+ require File.dirname(__FILE__) + '/../lib/mongoid_rails_migrations'
2
+
3
+ Mongoid.configure do |config|
4
+ name = "mongoid_test"
5
+ host = "localhost"
6
+ config.master = Mongo::Connection.new.db(name)
7
+ end
8
+
9
+ # require all models
10
+ Dir[File.dirname(__FILE__) + "/models/*.rb"].each {|file| require file }
11
+
12
+ MIGRATIONS_ROOT = File.dirname(__FILE__) + '/migrations'
data/test/helper.rb ADDED
@@ -0,0 +1,5 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ require 'config'
5
+ require 'test/unit'
@@ -0,0 +1,119 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class Mongoid::Migration
4
+ class <<self
5
+ attr_accessor :message_count
6
+ def puts(text="")
7
+ self.message_count ||= 0
8
+ self.message_count += 1
9
+ end
10
+ end
11
+ end
12
+
13
+ module Mongoid
14
+ class TestCase < ActiveSupport::TestCase #:nodoc:
15
+
16
+ def setup
17
+ Mongoid::Migration.verbose = true
18
+ end
19
+
20
+ def teardown
21
+ Mongoid.master.collections.each(&:drop)
22
+ end
23
+
24
+ def test_finds_migrations
25
+ assert Mongoid::Migrator.new(:up, MIGRATIONS_ROOT + "/valid").migrations.size == 2
26
+
27
+ assert_equal 2, Mongoid::Migrator.new(:up, MIGRATIONS_ROOT + "/valid").pending_migrations.size
28
+ end
29
+
30
+ def test_migrator
31
+ assert SurveySchema.first.nil?
32
+
33
+ Mongoid::Migrator.up(MIGRATIONS_ROOT + "/valid")
34
+
35
+ assert_equal 20100513063902, Mongoid::Migrator.current_version
36
+ assert !SurveySchema.first.nil?
37
+
38
+ Mongoid::Migrator.down(MIGRATIONS_ROOT + "/valid")
39
+ assert_equal 0, Mongoid::Migrator.current_version
40
+
41
+ assert SurveySchema.create(:label => 'Questionable Survey')
42
+ assert_equal 1, SurveySchema.all.size
43
+ end
44
+
45
+ def test_migrator_two_up_and_one_down
46
+ assert SurveySchema.where(:label => 'Baseline Survey').first.nil?
47
+ assert_equal 0, SurveySchema.all.size
48
+
49
+ Mongoid::Migrator.up(MIGRATIONS_ROOT + "/valid", 20100513054656)
50
+
51
+ assert !SurveySchema.where(:label => 'Baseline Survey').first.nil?
52
+ assert_equal 1, SurveySchema.all.size
53
+
54
+ assert SurveySchema.where(:label => 'Improvement Plan Survey').first.nil?
55
+
56
+ Mongoid::Migrator.up(MIGRATIONS_ROOT + "/valid", 20100513063902)
57
+ assert_equal 20100513063902, Mongoid::Migrator.current_version
58
+
59
+ assert !SurveySchema.where(:label => 'Improvement Plan Survey').first.nil?
60
+ assert_equal 2, SurveySchema.all.size
61
+
62
+ Mongoid::Migrator.down(MIGRATIONS_ROOT + "/valid", 20100513054656)
63
+ assert_equal 20100513054656, Mongoid::Migrator.current_version
64
+
65
+ assert SurveySchema.where(:label => 'Improvement Plan Survey').first.nil?
66
+ assert !SurveySchema.where(:label => 'Baseline Survey').first.nil?
67
+ assert_equal 1, SurveySchema.all.size
68
+ end
69
+
70
+ def test_finds_pending_migrations
71
+ Mongoid::Migrator.up(MIGRATIONS_ROOT + "/valid", 20100513054656)
72
+ pending_migrations = Mongoid::Migrator.new(:up, MIGRATIONS_ROOT + "/valid").pending_migrations
73
+
74
+ assert_equal 1, pending_migrations.size
75
+ assert_equal pending_migrations[0].version, 20100513063902
76
+ assert_equal pending_migrations[0].name, 'AddImprovementPlanSurveySchema'
77
+ end
78
+
79
+ def test_migrator_rollback
80
+ Mongoid::Migrator.migrate(MIGRATIONS_ROOT + "/valid")
81
+ assert_equal(20100513063902, Mongoid::Migrator.current_version)
82
+
83
+ Mongoid::Migrator.rollback(MIGRATIONS_ROOT + "/valid")
84
+ assert_equal(20100513054656, Mongoid::Migrator.current_version)
85
+
86
+ Mongoid::Migrator.rollback(MIGRATIONS_ROOT + "/valid")
87
+ assert_equal(0, Mongoid::Migrator.current_version)
88
+ end
89
+
90
+ def test_migrator_forward
91
+ Mongoid::Migrator.migrate(MIGRATIONS_ROOT + "/valid", 20100513054656)
92
+ assert_equal(20100513054656, Mongoid::Migrator.current_version)
93
+
94
+ Mongoid::Migrator.forward(MIGRATIONS_ROOT + "/valid", 20100513063902)
95
+ assert_equal(20100513063902, Mongoid::Migrator.current_version)
96
+ end
97
+
98
+ def test_migrator_with_duplicate_names
99
+ assert_raise(Mongoid::DuplicateMigrationNameError) do
100
+ Mongoid::Migrator.migrate(MIGRATIONS_ROOT + "/duplicate/names", nil)
101
+ end
102
+ end
103
+
104
+ def test_migrator_with_duplicate_versions
105
+ assert_raise(Mongoid::DuplicateMigrationVersionError) do
106
+ Mongoid::Migrator.migrate(MIGRATIONS_ROOT + "/duplicate/versions", nil)
107
+ end
108
+ end
109
+
110
+ def test_migrator_with_missing_version_numbers
111
+ assert_raise(Mongoid::UnknownMigrationVersionError) do
112
+ Mongoid::Migrator.migrate(MIGRATIONS_ROOT + "/valid", 500)
113
+ end
114
+ end
115
+
116
+ end
117
+ end
118
+
119
+ # migrations = ActiveRecord::Migrator.new(:up, MIGRATIONS_ROOT + "/interleaved/pass_2").pending_migrations
@@ -0,0 +1,9 @@
1
+ class AddDuplicateSurveySchema < Mongoid::Migration
2
+ def self.up
3
+ SurveySchema.create(:label => 'Duplicate Survey')
4
+ end
5
+
6
+ def self.down
7
+ SurveySchema.where(:label => 'Duplicate Survey').first.destroy
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ class AddDuplicateSurveySchema < Mongoid::Migration
2
+ def self.up
3
+ SurveySchema.create(:label => 'Duplicate Survey')
4
+ end
5
+
6
+ def self.down
7
+ SurveySchema.where(:label => 'Duplicate Survey').first.destroy
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ class AddDuplicateSurveySchema < Mongoid::Migration
2
+ def self.up
3
+ SurveySchema.create(:label => 'Duplicate Survey')
4
+ end
5
+
6
+ def self.down
7
+ SurveySchema.where(:label => 'Duplicate Survey').first.destroy
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ class AddDuplicateSurveySchema < Mongoid::Migration
2
+ def self.up
3
+ SurveySchema.create(:label => 'Duplicate Survey')
4
+ end
5
+
6
+ def self.down
7
+ SurveySchema.where(:label => 'Duplicate Survey').first.destroy
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ class AddBaselineSurveySchema < Mongoid::Migration
2
+ def self.up
3
+ SurveySchema.create(:label => 'Baseline Survey')
4
+ end
5
+
6
+ def self.down
7
+ SurveySchema.where(:label => 'Baseline Survey').first.destroy
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ class AddImprovementPlanSurveySchema < Mongoid::Migration
2
+ def self.up
3
+ SurveySchema.create(:label => 'Improvement Plan Survey')
4
+ end
5
+
6
+ def self.down
7
+ SurveySchema.where(:label => 'Improvement Plan Survey').first.destroy
8
+ end
9
+ end
@@ -0,0 +1,6 @@
1
+ class SurveySchema
2
+ include Mongoid::Document
3
+ include Mongoid::Timestamps
4
+
5
+ field :label
6
+ end
metadata ADDED
@@ -0,0 +1,161 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mongoid_rails_migrations
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - Alan Da Costa
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-05-12 00:00:00 -07:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: bundler
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ - 9
30
+ - 19
31
+ version: 0.9.19
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: mongoid
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 2
43
+ - 0
44
+ - 0
45
+ - beta4
46
+ version: 2.0.0.beta4
47
+ type: :runtime
48
+ version_requirements: *id002
49
+ - !ruby/object:Gem::Dependency
50
+ name: rails
51
+ prerelease: false
52
+ requirement: &id003 !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ segments:
57
+ - 3
58
+ - 0
59
+ - 0
60
+ - beta3
61
+ version: 3.0.0.beta3
62
+ type: :runtime
63
+ version_requirements: *id003
64
+ - !ruby/object:Gem::Dependency
65
+ name: railties
66
+ prerelease: false
67
+ requirement: &id004 !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ segments:
72
+ - 3
73
+ - 0
74
+ - 0
75
+ - beta3
76
+ version: 3.0.0.beta3
77
+ type: :runtime
78
+ version_requirements: *id004
79
+ - !ruby/object:Gem::Dependency
80
+ name: activesupport
81
+ prerelease: false
82
+ requirement: &id005 !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ segments:
87
+ - 3
88
+ - 0
89
+ - 0
90
+ - beta3
91
+ version: 3.0.0.beta3
92
+ type: :runtime
93
+ version_requirements: *id005
94
+ description: Sometimes you just need to migrate data.
95
+ email: alandacosta@gmail.com.com
96
+ executables: []
97
+
98
+ extensions: []
99
+
100
+ extra_rdoc_files: []
101
+
102
+ files:
103
+ - .gitignore
104
+ - Gemfile
105
+ - Rakefile
106
+ - README.rdoc
107
+ - mongoid_rails_migrations.gemspec
108
+ - lib/mongoid_rails_migrations/active_record_ext/migrations.rb
109
+ - lib/mongoid_rails_migrations/models/data_migration.rb
110
+ - lib/mongoid_rails_migrations/mongoid_ext/mongoid.rb
111
+ - lib/mongoid_rails_migrations/mongoid_ext/railtie.rb
112
+ - lib/mongoid_rails_migrations/mongoid_ext/railties/database.rake
113
+ - lib/mongoid_rails_migrations.rb
114
+ - lib/rails/generators/mongoid/migration/migration_generator.rb
115
+ - lib/rails/generators/mongoid/migration/templates/migration.rb
116
+ - lib/rails/generators/mongoid/mongoid_generator.rb
117
+ has_rdoc: true
118
+ homepage:
119
+ licenses: []
120
+
121
+ post_install_message:
122
+ rdoc_options: []
123
+
124
+ require_paths:
125
+ - lib
126
+ required_ruby_version: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ segments:
131
+ - 1
132
+ - 8
133
+ - 6
134
+ version: 1.8.6
135
+ required_rubygems_version: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ segments:
140
+ - 1
141
+ - 3
142
+ - 6
143
+ version: 1.3.6
144
+ requirements: []
145
+
146
+ rubyforge_project:
147
+ rubygems_version: 1.3.6
148
+ signing_key:
149
+ specification_version: 3
150
+ summary: Data migrations for Mongoid in Active Record style, minus column input.
151
+ test_files:
152
+ - test/config.rb
153
+ - test/helper.rb
154
+ - test/migration_test.rb
155
+ - test/migrations/duplicate/names/20100513073457_add_duplicate_survey_schema.rb
156
+ - test/migrations/duplicate/names/20100513073724_add_duplicate_survey_schema.rb
157
+ - test/migrations/duplicate/versions/20100513073457_add_another_duplicate_survey_schema.rb
158
+ - test/migrations/duplicate/versions/20100513073457_add_duplicate_survey_schema.rb
159
+ - test/migrations/valid/20100513054656_add_baseline_survey_schema.rb
160
+ - test/migrations/valid/20100513063902_add_improvement_plan_survey_schema.rb
161
+ - test/models/survey_schema.rb