mongoid_rails_migrations 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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