standalone_migrations 0.4.5 → 0.4.7

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/README.markdown CHANGED
@@ -12,6 +12,7 @@ Add to `Rakefile` in your projects base directory:
12
12
  # t.migrations = "db/migrations"
13
13
  # t.config = "db/config.yml"
14
14
  # t.schema = "db/schema.rb"
15
+ # t.sub_namespace = "dbname"
15
16
  # t.env = "DB"
16
17
  # t.default_env = "development"
17
18
  # t.verbose = true
@@ -77,6 +78,27 @@ If you're lazy and want to just execute raw SQL:
77
78
 
78
79
  rake db:migrate:up VERSION=20081220234130
79
80
 
81
+ ## Sub-namespacing
82
+
83
+ When working with multiple databases in a single application it is convenient
84
+ to have separate sets of tasks for each database. This is accomplished with
85
+ sub_namespace parameter - for example, given the following declaration:
86
+
87
+ MigratorTasks.new do |t|
88
+ t.migrations = "db/migrate/widgets"
89
+ t.sub_namespace = "widgets"
90
+ ...
91
+ end
92
+
93
+ The following tasks will be created:
94
+
95
+ db:widgets:new_migration
96
+ db:widgets:migrate
97
+ ...
98
+
99
+ And migrations for this database would be created in db/migrate/widgets
100
+ subdirectory.
101
+
80
102
  Contributors
81
103
  ============
82
104
  This work is based on [Lincoln Stoll's blog post](http://lstoll.net/2008/04/stand-alone-activerecord-migrations/) and [David Welton's post](http://journal.dedasys.com/2007/01/28/using-migrations-outside-of-rails).
@@ -86,4 +108,4 @@ This work is based on [Lincoln Stoll's blog post](http://lstoll.net/2008/04/stan
86
108
  - [Eric Lindvall](http://bitmonkey.net)
87
109
  - [Steve Hodgkiss](http://stevehodgkiss.com/)
88
110
  - [Rich Meyers](https://github.com/richmeyers)
89
- - [Wes Bailey](http://exposinggotchas.blogspot.com/)
111
+ - [Wes Bailey](http://exposinggotchas.blogspot.com/)
data/Rakefile CHANGED
@@ -1,12 +1,29 @@
1
1
  task :default => :spec
2
- require 'rspec/core/rake_task'
3
- RSpec::Core::RakeTask.new {|t| t.rspec_opts = ['--color']}
2
+
3
+ begin
4
+ require 'rspec/core/rake_task'
5
+ rescue LoadError => e
6
+ $stderr.puts "RSpec 2, or one of its dependencies, is not available:"
7
+ $stderr.puts "#{e.class}: #{e.message}"
8
+ $stderr.puts "Install it with: sudo gem install rspec"
9
+ $stderr.puts "Test-related tasks will not be available."
10
+ $stderr.puts "If you have RSpec 1 installed you can try running the tests with:"
11
+ $stderr.puts " spec spec"
12
+ $stderr.puts "However, RSpec 1 is not officially supported."
13
+ else
14
+ RSpec::Core::RakeTask.new {|t| t.rspec_opts = ['--color']}
15
+ end
4
16
 
5
17
  # rake install -> install gem locally (for tests)
6
18
  # rake release -> push to github and release to gemcutter
7
19
  # rake version:bump:patch -> increase version and add a git-tag
8
20
  begin
9
21
  require 'jeweler'
22
+ rescue LoadError => e
23
+ $stderr.puts "Jeweler, or one of its dependencies, is not available:"
24
+ $stderr.puts "#{e.class}: #{e.message}"
25
+ $stderr.puts "Install it with: sudo gem install jeweler"
26
+ else
10
27
  Jeweler::Tasks.new do |gem|
11
28
  gem.name = 'standalone_migrations'
12
29
  gem.summary = "A thin wrapper to use Rails Migrations in non Rails projects"
@@ -18,6 +35,4 @@ begin
18
35
  end
19
36
 
20
37
  Jeweler::GemcutterTasks.new
21
- rescue LoadError
22
- puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install jeweler"
23
38
  end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.5
1
+ 0.4.7
@@ -5,7 +5,8 @@ require 'logger'
5
5
  class MigratorTasks < ::Rake::TaskLib
6
6
  DefaultEnv = 'development'
7
7
 
8
- attr_accessor :name, :base, :vendor, :config, :schema, :env, :current_env, :verbose, :log_level, :logger
8
+ attr_accessor :name, :base, :vendor, :config, :schema, :env, :current_env
9
+ attr_accessor :verbose, :log_level, :logger, :sub_namespace
9
10
  attr_reader :migrations
10
11
 
11
12
  def initialize(name = :migrator)
@@ -32,266 +33,279 @@ class MigratorTasks < ::Rake::TaskLib
32
33
 
33
34
  def define
34
35
  namespace :db do
35
- def ar_init(connect = true)
36
- require 'active_record'
37
- self.current_env = ENV[@env] || DefaultEnv
38
-
39
- if @config.is_a?(Hash)
40
- ActiveRecord::Base.configurations = @config
41
- else
42
- require 'erb'
43
- ActiveRecord::Base.configurations = YAML::load(ERB.new(IO.read(@config)).result)
36
+ if sub_namespace
37
+ namespace sub_namespace do
38
+ define_tasks
44
39
  end
45
- ActiveRecord::Base.establish_connection(current_env) if connect
46
- if @logger
47
- logger = @logger
48
- else
49
- logger = Logger.new($stderr)
50
- logger.level = @log_level
51
- end
52
- ActiveRecord::Base.logger = logger
40
+ else
41
+ define_tasks
53
42
  end
43
+ end
44
+ end
54
45
 
55
- task :ar_init do
56
- ar_init
57
- end
46
+ def define_tasks
47
+ sub_namespace_with_separator = sub_namespace ? "#{sub_namespace}:" : ''
58
48
 
59
- desc "Migrate the database using the scripts in the migrations directory. Target specific version with VERSION=x. Turn off output with VERBOSE=false."
60
- task :migrate => :ar_init do
61
- require "#{@vendor}/migration_helpers/init"
62
- ActiveRecord::Migration.verbose = ENV['VERBOSE'] || @verbose
63
- @migrations.each do |path|
64
- ActiveRecord::Migrator.migrate(path, ENV["VERSION"] ? ENV["VERSION"].to_i : nil)
65
- end
66
- Rake::Task["db:schema:dump"].execute
49
+ def ar_init(connect = true)
50
+ require 'active_record'
51
+ self.current_env = ENV[@env] || DefaultEnv
52
+
53
+ if @config.is_a?(Hash)
54
+ ActiveRecord::Base.configurations = @config
55
+ else
56
+ require 'erb'
57
+ ActiveRecord::Base.configurations = YAML::load(ERB.new(IO.read(@config)).result)
67
58
  end
59
+ ActiveRecord::Base.establish_connection(current_env) if connect
60
+ if @logger
61
+ logger = @logger
62
+ else
63
+ logger = Logger.new($stderr)
64
+ logger.level = @log_level
65
+ end
66
+ ActiveRecord::Base.logger = logger
67
+ end
68
+
69
+ task :ar_init do
70
+ ar_init
71
+ end
68
72
 
69
- desc "Retrieves the current schema version number"
70
- task :version => :ar_init do
71
- puts "Current version: #{ActiveRecord::Migrator.current_version}"
73
+ desc "Migrate the database using the scripts in the migrations directory. Target specific version with VERSION=x. Turn off output with VERBOSE=false."
74
+ task :migrate => :ar_init do
75
+ require "#{@vendor}/migration_helpers/init"
76
+ ActiveRecord::Migration.verbose = ENV['VERBOSE'] || @verbose
77
+ @migrations.each do |path|
78
+ ActiveRecord::Migrator.migrate(path, ENV["VERSION"] ? ENV["VERSION"].to_i : nil)
72
79
  end
80
+ Rake::Task["db:#{sub_namespace_with_separator}schema:dump"].execute
81
+ end
73
82
 
83
+ desc "Retrieves the current schema version number"
84
+ task :version => :ar_init do
85
+ puts "Current version: #{ActiveRecord::Migrator.current_version}"
86
+ end
74
87
 
75
- def create_database(config)
76
- begin
77
- if config['adapter'] =~ /sqlite/
78
- if File.exist?(config['database'])
79
- $stderr.puts "#{config['database']} already exists"
80
- else
81
- begin
82
- # Create the SQLite database
83
- ActiveRecord::Base.establish_connection(config)
84
- ActiveRecord::Base.connection
85
- rescue Exception => e
86
- $stderr.puts e, *(e.backtrace)
87
- $stderr.puts "Couldn't create database for #{config.inspect}"
88
- end
89
- end
90
- return # Skip the else clause of begin/rescue
88
+
89
+ def create_database(config)
90
+ begin
91
+ if config['adapter'] =~ /sqlite/
92
+ if File.exist?(config['database'])
93
+ $stderr.puts "#{config['database']} already exists"
91
94
  else
92
- ActiveRecord::Base.establish_connection(config)
93
- ActiveRecord::Base.connection
94
- end
95
- rescue
96
- case config['adapter']
97
- when /mysql/
98
- @charset = ENV['CHARSET'] || 'utf8'
99
- @collation = ENV['COLLATION'] || 'utf8_unicode_ci'
100
- creation_options = {:charset => (config['charset'] || @charset), :collation => (config['collation'] || @collation)}
101
- error_class = config['adapter'] =~ /mysql2/ ? Mysql2::Error : Mysql::Error
102
- access_denied_error = 1045
103
- begin
104
- ActiveRecord::Base.establish_connection(config.merge('database' => nil))
105
- ActiveRecord::Base.connection.create_database(config['database'], creation_options)
106
- ActiveRecord::Base.establish_connection(config)
107
- rescue error_class => sqlerr
108
- if sqlerr.errno == access_denied_error
109
- print "#{sqlerr.error}. \nPlease provide the root password for your mysql installation\n>"
110
- root_password = $stdin.gets.strip
111
- grant_statement = "GRANT ALL PRIVILEGES ON #{config['database']}.* " \
112
- "TO '#{config['username']}'@'localhost' " \
113
- "IDENTIFIED BY '#{config['password']}' WITH GRANT OPTION;"
114
- ActiveRecord::Base.establish_connection(config.merge(
115
- 'database' => nil, 'username' => 'root', 'password' => root_password))
116
- ActiveRecord::Base.connection.create_database(config['database'], creation_options)
117
- ActiveRecord::Base.connection.execute grant_statement
118
- ActiveRecord::Base.establish_connection(config)
119
- else
120
- $stderr.puts sqlerr.error
121
- $stderr.puts "Couldn't create database for #{config.inspect}, charset: #{config['charset'] || @charset}, collation: #{config['collation'] || @collation}"
122
- $stderr.puts "(if you set the charset manually, make sure you have a matching collation)" if config['charset']
123
- end
124
- end
125
- when 'postgresql'
126
- @encoding = config['encoding'] || ENV['CHARSET'] || 'utf8'
127
- begin
128
- ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres', 'schema_search_path' => 'public'))
129
- ActiveRecord::Base.connection.create_database(config['database'], config.merge('encoding' => @encoding))
130
- ActiveRecord::Base.establish_connection(config)
131
- rescue Exception => e
132
- $stderr.puts e, *(e.backtrace)
133
- $stderr.puts "Couldn't create database for #{config.inspect}"
134
- end
95
+ begin
96
+ # Create the SQLite database
97
+ ActiveRecord::Base.establish_connection(config)
98
+ ActiveRecord::Base.connection
99
+ rescue Exception => e
100
+ $stderr.puts e, *(e.backtrace)
101
+ $stderr.puts "Couldn't create database for #{config.inspect}"
102
+ end
135
103
  end
104
+ return # Skip the else clause of begin/rescue
136
105
  else
137
- $stderr.puts "#{config['database']} already exists" unless config['adapter'] =~ /sqlite/
106
+ ActiveRecord::Base.establish_connection(config)
107
+ ActiveRecord::Base.connection
138
108
  end
139
- end
140
-
141
- desc 'Create the database from config/database.yml for the current DATABASE_ENV'
142
- task :create do
143
- ar_init(false)
144
- config = ActiveRecord::Base.configurations[self.current_env]
145
- create_database config
146
- end
147
-
148
- def drop_database(config)
109
+ rescue
149
110
  case config['adapter']
150
111
  when /mysql/
151
- ActiveRecord::Base.establish_connection(config)
152
- ActiveRecord::Base.connection.drop_database config['database']
153
- when /^sqlite/
154
- require 'pathname'
155
- path = Pathname.new(config['database'])
156
- file = path.absolute? ? path.to_s : File.join(@base, path)
157
- FileUtils.rm(file)
112
+ @charset = ENV['CHARSET'] || 'utf8'
113
+ @collation = ENV['COLLATION'] || 'utf8_unicode_ci'
114
+ creation_options = {:charset => (config['charset'] || @charset), :collation => (config['collation'] || @collation)}
115
+ error_class = config['adapter'] =~ /mysql2/ ? Mysql2::Error : Mysql::Error
116
+ access_denied_error = 1045
117
+ begin
118
+ ActiveRecord::Base.establish_connection(config.merge('database' => nil))
119
+ ActiveRecord::Base.connection.create_database(config['database'], creation_options)
120
+ ActiveRecord::Base.establish_connection(config)
121
+ rescue error_class => sqlerr
122
+ if sqlerr.errno == access_denied_error
123
+ print "#{sqlerr.error}. \nPlease provide the root password for your mysql installation\n>"
124
+ root_password = $stdin.gets.strip
125
+ grant_statement = "GRANT ALL PRIVILEGES ON #{config['database']}.* " \
126
+ "TO '#{config['username']}'@'localhost' " \
127
+ "IDENTIFIED BY '#{config['password']}' WITH GRANT OPTION;"
128
+ ActiveRecord::Base.establish_connection(config.merge(
129
+ 'database' => nil, 'username' => 'root', 'password' => root_password))
130
+ ActiveRecord::Base.connection.create_database(config['database'], creation_options)
131
+ ActiveRecord::Base.connection.execute grant_statement
132
+ ActiveRecord::Base.establish_connection(config)
133
+ else
134
+ $stderr.puts sqlerr.error
135
+ $stderr.puts "Couldn't create database for #{config.inspect}, charset: #{config['charset'] || @charset}, collation: #{config['collation'] || @collation}"
136
+ $stderr.puts "(if you set the charset manually, make sure you have a matching collation)" if config['charset']
137
+ end
138
+ end
158
139
  when 'postgresql'
159
- ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres', 'schema_search_path' => 'public'))
160
- ActiveRecord::Base.connection.drop_database config['database']
140
+ @encoding = config['encoding'] || ENV['CHARSET'] || 'utf8'
141
+ begin
142
+ ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres', 'schema_search_path' => 'public'))
143
+ ActiveRecord::Base.connection.create_database(config['database'], config.merge('encoding' => @encoding))
144
+ ActiveRecord::Base.establish_connection(config)
145
+ rescue Exception => e
146
+ $stderr.puts e, *(e.backtrace)
147
+ $stderr.puts "Couldn't create database for #{config.inspect}"
148
+ end
161
149
  end
150
+ else
151
+ $stderr.puts "#{config['database']} already exists" unless config['adapter'] =~ /sqlite/
162
152
  end
153
+ end
154
+
155
+ desc 'Create the database from config/database.yml for the current DATABASE_ENV'
156
+ task :create do
157
+ ar_init(false)
158
+ config = ActiveRecord::Base.configurations[self.current_env]
159
+ create_database config
160
+ end
163
161
 
164
- desc 'Drops the database for the current DATABASE_ENV'
165
- task :drop => :ar_init do
166
- config = ActiveRecord::Base.configurations[current_env]
167
- drop_database(config)
162
+ def drop_database(config)
163
+ case config['adapter']
164
+ when /mysql/
165
+ ActiveRecord::Base.establish_connection(config)
166
+ ActiveRecord::Base.connection.drop_database config['database']
167
+ when /^sqlite/
168
+ require 'pathname'
169
+ path = Pathname.new(config['database'])
170
+ file = path.absolute? ? path.to_s : File.join(@base, path)
171
+ FileUtils.rm(file)
172
+ when 'postgresql'
173
+ ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres', 'schema_search_path' => 'public'))
174
+ ActiveRecord::Base.connection.drop_database config['database']
168
175
  end
176
+ end
177
+
178
+ desc 'Drops the database for the current DATABASE_ENV'
179
+ task :drop => :ar_init do
180
+ config = ActiveRecord::Base.configurations[current_env]
181
+ drop_database(config)
182
+ end
169
183
 
170
- namespace :migrate do
171
- [:up, :down].each do |direction|
172
- desc "Runs the '#{direction}' for a given migration VERSION."
173
- task direction => :ar_init do
174
- ActiveRecord::Migration.verbose = @verbose
175
- version = ENV["VERSION"].to_i
176
- raise "VERSION is required (must be a number)" if version == 0
177
- migration_path = nil
178
- if @migrations.length == 1
179
- migration_path = @migrations.first
180
- else
181
- @migrations.each do |path|
182
- Dir[File.join(path, '*.rb')].each do |file|
183
- if File.basename(file).match(/^\d+/)[0] == version.to_s
184
- migration_path = path
185
- break
186
- end
184
+ namespace :migrate do
185
+ [:up, :down].each do |direction|
186
+ desc "Runs the '#{direction}' for a given migration VERSION."
187
+ task direction => :ar_init do
188
+ ActiveRecord::Migration.verbose = @verbose
189
+ version = ENV["VERSION"].to_i
190
+ raise "VERSION is required (must be a number)" if version == 0
191
+ migration_path = nil
192
+ if @migrations.length == 1
193
+ migration_path = @migrations.first
194
+ else
195
+ @migrations.each do |path|
196
+ Dir[File.join(path, '*.rb')].each do |file|
197
+ if File.basename(file).match(/^\d+/)[0] == version.to_s
198
+ migration_path = path
199
+ break
187
200
  end
188
201
  end
189
- raise "Migration #{version} wasn't found on paths #{@migrations.join(', ')}" if migration_path.nil?
190
202
  end
191
- ActiveRecord::Migrator.run(direction, migration_path, version)
192
- Rake::Task["db:schema:dump"].execute
203
+ raise "Migration #{version} wasn't found on paths #{@migrations.join(', ')}" if migration_path.nil?
193
204
  end
205
+ ActiveRecord::Migrator.run(direction, migration_path, version)
206
+ Rake::Task["db:#{sub_namespace_with_separator}schema:dump"].execute
194
207
  end
195
208
  end
209
+ end
196
210
 
197
- desc "Raises an error if there are pending migrations"
198
- task :abort_if_pending_migrations => :ar_init do
199
- @migrations.each do |path|
200
- pending_migrations = ActiveRecord::Migrator.new(:up, path).pending_migrations
211
+ desc "Raises an error if there are pending migrations"
212
+ task :abort_if_pending_migrations => :ar_init do
213
+ @migrations.each do |path|
214
+ pending_migrations = ActiveRecord::Migrator.new(:up, path).pending_migrations
201
215
 
202
- if pending_migrations.any?
203
- puts "You have #{pending_migrations.size} pending migrations:"
204
- pending_migrations.each do |pending_migration|
205
- puts ' %4d %s' % [pending_migration.version, pending_migration.name]
206
- end
207
- abort %{Run "rake db:migrate" to update your database then try again.}
216
+ if pending_migrations.any?
217
+ puts "You have #{pending_migrations.size} pending migrations:"
218
+ pending_migrations.each do |pending_migration|
219
+ puts ' %4d %s' % [pending_migration.version, pending_migration.name]
208
220
  end
221
+ abort %{Run "rake db:migrate" to update your database then try again.}
209
222
  end
210
223
  end
224
+ end
211
225
 
212
- namespace :schema do
213
- desc "Create schema.rb file that can be portably used against any DB supported by AR"
214
- task :dump => :ar_init do
215
- if schema_file = ENV['SCHEMA'] || @schema
216
- require 'active_record/schema_dumper'
217
- File.open(schema_file, "w") do |file|
218
- ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file)
219
- end
226
+ namespace :schema do
227
+ desc "Create schema.rb file that can be portably used against any DB supported by AR"
228
+ task :dump => :ar_init do
229
+ if schema_file = ENV['SCHEMA'] || @schema
230
+ require 'active_record/schema_dumper'
231
+ File.open(schema_file, "w") do |file|
232
+ ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file)
220
233
  end
221
234
  end
235
+ end
222
236
 
223
- desc "Load a ar_schema.rb file into the database"
224
- task :load => :ar_init do
225
- file = ENV['SCHEMA'] || @schema
226
- load(file)
227
- end
237
+ desc "Load a ar_schema.rb file into the database"
238
+ task :load => :ar_init do
239
+ file = ENV['SCHEMA'] || @schema
240
+ load(file)
228
241
  end
242
+ end
229
243
 
230
- namespace :test do
231
- desc "Recreate the test database from the current schema.rb"
232
- task :load => ['db:ar_init', 'db:test:purge'] do
233
- ActiveRecord::Base.establish_connection(:test)
234
- ActiveRecord::Schema.verbose = false
235
- Rake::Task["db:schema:load"].invoke
236
- end
244
+ namespace :test do
245
+ desc "Recreate the test database from the current schema.rb"
246
+ task :load => ["db:#{sub_namespace_with_separator}ar_init", "db:#{sub_namespace_with_separator}test:purge"] do
247
+ ActiveRecord::Base.establish_connection(:test)
248
+ ActiveRecord::Schema.verbose = false
249
+ Rake::Task["db:#{sub_namespace_with_separator}schema:load"].invoke
250
+ end
237
251
 
238
- desc "Empty the test database"
239
- task :purge => 'db:ar_init' do
240
- config = ActiveRecord::Base.configurations['test']
241
- case config["adapter"]
242
- when "mysql"
243
- ActiveRecord::Base.establish_connection(:test)
244
- ActiveRecord::Base.connection.recreate_database(config["database"], config)
245
- when "postgresql" #TODO i doubt this will work <-> methods are not defined
246
- ActiveRecord::Base.clear_active_connections!
247
- drop_database(config)
248
- create_database(config)
249
- when "sqlite", "sqlite3"
250
- db_file = config["database"] || config["dbfile"]
251
- File.delete(db_file) if File.exist?(db_file)
252
- when "sqlserver"
253
- drop_script = "#{config["host"]}.#{config["database"]}.DP1".gsub(/\\/, '-')
254
- `osql -E -S #{config["host"]} -d #{config["database"]} -i db\\#{drop_script}`
255
- `osql -E -S #{config["host"]} -d #{config["database"]} -i db\\test_structure.sql`
256
- when "oci", "oracle"
257
- ActiveRecord::Base.establish_connection(:test)
258
- ActiveRecord::Base.connection.structure_drop.split(";\n\n").each do |ddl|
259
- ActiveRecord::Base.connection.execute(ddl)
260
- end
261
- when "firebird"
262
- ActiveRecord::Base.establish_connection(:test)
263
- ActiveRecord::Base.connection.recreate_database!
264
- else
265
- raise "Task not supported by #{config["adapter"].inspect}"
266
- end
252
+ desc "Empty the test database"
253
+ task :purge => "db:#{sub_namespace_with_separator}ar_init" do
254
+ config = ActiveRecord::Base.configurations['test']
255
+ case config["adapter"]
256
+ when "mysql"
257
+ ActiveRecord::Base.establish_connection(:test)
258
+ ActiveRecord::Base.connection.recreate_database(config["database"], config)
259
+ when "postgresql" #TODO i doubt this will work <-> methods are not defined
260
+ ActiveRecord::Base.clear_active_connections!
261
+ drop_database(config)
262
+ create_database(config)
263
+ when "sqlite", "sqlite3"
264
+ db_file = config["database"] || config["dbfile"]
265
+ File.delete(db_file) if File.exist?(db_file)
266
+ when "sqlserver"
267
+ drop_script = "#{config["host"]}.#{config["database"]}.DP1".gsub(/\\/, '-')
268
+ `osql -E -S #{config["host"]} -d #{config["database"]} -i db\\#{drop_script}`
269
+ `osql -E -S #{config["host"]} -d #{config["database"]} -i db\\test_structure.sql`
270
+ when "oci", "oracle"
271
+ ActiveRecord::Base.establish_connection(:test)
272
+ ActiveRecord::Base.connection.structure_drop.split(";\n\n").each do |ddl|
273
+ ActiveRecord::Base.connection.execute(ddl)
274
+ end
275
+ when "firebird"
276
+ ActiveRecord::Base.establish_connection(:test)
277
+ ActiveRecord::Base.connection.recreate_database!
278
+ else
279
+ raise "Task not supported by #{config["adapter"].inspect}"
267
280
  end
268
-
269
- desc 'Check for pending migrations and load the test schema'
270
- task :prepare => ['db:abort_if_pending_migrations', 'db:test:load']
271
281
  end
272
282
 
273
- desc 'generate a model=name field="field1:type field2:type"'
274
- task :generate do
275
- ts = Time.now.strftime '%Y%m%d%H%%M%S'
283
+ desc 'Check for pending migrations and load the test schema'
284
+ task :prepare => ["db:#{sub_namespace_with_separator}abort_if_pending_migrations", "db:#{sub_namespace_with_separator}test:load"]
285
+ end
276
286
 
277
- if ENV['model']
278
- table_name = ENV['model']
279
- else
280
- print 'model name> '
281
- table_name = $stdin.gets.strip
282
- end
287
+ desc 'generate a model=name field="field1:type field2:type"'
288
+ task :generate do
289
+ ts = Time.now.strftime '%Y%m%d%H%%M%S'
290
+
291
+ if ENV['model']
292
+ table_name = ENV['model']
293
+ else
294
+ print 'model name> '
295
+ table_name = $stdin.gets.strip
296
+ end
283
297
 
284
- raise ArgumentError, 'must provide a name for the model to generate' if table_name.empty?
298
+ raise ArgumentError, 'must provide a name for the model to generate' if table_name.empty?
285
299
 
286
- create_table_str = "create_table :#{table_name} do |t|"
300
+ create_table_str = "create_table :#{table_name} do |t|"
287
301
 
288
- fields = ENV['fields'] if ENV['fields']
302
+ fields = ENV['fields'] if ENV['fields']
289
303
 
290
- columns = ENV.has_key?('fields') ? ENV['fields'].split.map { |v| "t.#{v.sub(/:/, ' :')}" }.join("\n#{' '*6}") : nil
304
+ columns = ENV.has_key?('fields') ? ENV['fields'].split.map { |v| "t.#{v.sub(/:/, ' :')}" }.join("\n#{' '*6}") : nil
291
305
 
292
- create_table_str << "\n #{columns}" if columns
306
+ create_table_str << "\n #{columns}" if columns
293
307
 
294
- contents = <<-MIGRATION
308
+ contents = <<-MIGRATION
295
309
  class Create#{class_name table_name} < ActiveRecord::Migration
296
310
  def self.up
297
311
  #{create_table_str}
@@ -305,18 +319,18 @@ class Create#{class_name table_name} < ActiveRecord::Migration
305
319
  end
306
320
  MIGRATION
307
321
 
308
- create_file @migrations.first, file_name("create_#{table_name}"), contents
309
- end
322
+ create_file @migrations.first, file_name("create_#{table_name}"), contents
323
+ end
310
324
 
311
- desc "Create a new migration"
312
- task :new_migration do |t|
313
- unless migration = ENV['name']
314
- puts "Error: must provide name of migration to generate."
315
- puts "For example: rake #{t.name} name=add_field_to_form"
316
- abort
317
- end
325
+ desc "Create a new migration"
326
+ task :new_migration do |t|
327
+ unless migration = ENV['name']
328
+ puts "Error: must provide name of migration to generate."
329
+ puts "For example: rake #{t.name} name=add_field_to_form"
330
+ abort
331
+ end
318
332
 
319
- file_contents = <<eof
333
+ file_contents = <<eof
320
334
  class #{class_name migration} < ActiveRecord::Migration
321
335
  def self.up
322
336
  end
@@ -327,10 +341,9 @@ class #{class_name migration} < ActiveRecord::Migration
327
341
  end
328
342
  eof
329
343
 
330
- create_file @migrations.first, file_name(migration), file_contents
344
+ create_file @migrations.first, file_name(migration), file_contents
331
345
 
332
- puts "Created migration #{file_name migration}"
333
- end
346
+ puts "Created migration #{file_name migration}"
334
347
  end
335
348
  end
336
349
 
@@ -28,8 +28,9 @@ describe 'Standalone migrations' do
28
28
  `cd spec/tmp && #{cmd} 2>&1`
29
29
  end
30
30
 
31
- def make_migration(name)
32
- migration = run("rake db:new_migration name=#{name}").match(%r{db/migrations/\d+.*.rb})[0]
31
+ def make_migration(name, options={})
32
+ task_name = options[:task_name] || 'db:new_migration'
33
+ migration = run("rake #{task_name} name=#{name}").match(%r{db/migrations/\d+.*.rb})[0]
33
34
  content = read(migration)
34
35
  content.sub!(/def self.down.*?\send/m, "def self.down;puts 'DOWN-#{name}';end")
35
36
  content.sub!(/def self.up.*?\send/m, "def self.up;puts 'UP-#{name}';end")
@@ -37,6 +38,11 @@ describe 'Standalone migrations' do
37
38
  migration.match(/\d{14}/)[0]
38
39
  end
39
40
 
41
+ def make_sub_namespaced_migration(namespace, name)
42
+ # specify complete task name here to avoid conditionals in make_migration
43
+ make_migration(name, :task_name => "db:#{namespace}:new_migration")
44
+ end
45
+
40
46
  def write_rakefile(config=nil)
41
47
  write 'Rakefile', <<-TXT
42
48
  $LOAD_PATH.unshift '#{File.expand_path('lib')}'
@@ -119,6 +125,24 @@ end
119
125
  run("rake db:new_migration name=test_abc").should =~ %r{Created migration .*db/migrations/\d+_test_abc\.rb}
120
126
  end
121
127
  end
128
+
129
+ context 'sub-namespaced task' do
130
+ before do
131
+ write_rakefile %{t.sub_namespace = "widgets"}
132
+ end
133
+ it "fails if i do not add a name" do
134
+ run("rake db:widgets:new_migration").should_not =~ /SUCCESS/
135
+ end
136
+
137
+ it "generates a new migration with this name and timestamp" do
138
+ run("rake db:widgets:new_migration name=test_widget").should =~ %r{Created migration .*spec/tmp/db/migrations/\d+_test_widget\.rb}
139
+ run("ls db/migrations").should =~ /^\d+_test_widget.rb$/
140
+ end
141
+
142
+ it 'does not create top level db:new_migration task' do
143
+ run('rake db:new_migration').should =~ /Don't know how to build task 'db:new_migration'/
144
+ end
145
+ end
122
146
  end
123
147
 
124
148
  describe 'db:version' do
@@ -151,6 +175,22 @@ end
151
175
  result.should =~ /Migrating to CreateTests2 \(2010/
152
176
  end
153
177
  end
178
+
179
+ context 'sub-namespaced task' do
180
+ before do
181
+ write_rakefile %{t.sub_namespace = "widgets"}
182
+ end
183
+ it 'runs the migrations' do
184
+ run("rake db:widgets:new_migration name=new_widget")
185
+ result = run("rake db:widgets:migrate")
186
+ result.should =~ /SUCCESS/
187
+ result.should =~ /Migrating to NewWidget \(#{Time.now.year}/
188
+ end
189
+
190
+ it 'does not create top level db:new_migration task' do
191
+ run('rake db:migrate').should =~ /Don't know how to build task 'db:migrate'/
192
+ end
193
+ end
154
194
  end
155
195
 
156
196
  describe 'db:migrate:down' do
@@ -193,6 +233,23 @@ end
193
233
  result.should =~ /wasn't found on path/
194
234
  end
195
235
  end
236
+
237
+ context 'sub-namespaced task' do
238
+ before do
239
+ write_rakefile %{t.sub_namespace = "widgets"}
240
+ end
241
+ it 'migrates down' do
242
+ make_sub_namespaced_migration('widgets', 'widget_xxx')
243
+ sleep 1
244
+ version = make_sub_namespaced_migration('widgets', 'widget_yyy')
245
+ run 'rake db:widgets:migrate'
246
+
247
+ result = run("rake db:widgets:migrate:down VERSION=#{version}")
248
+ result.should =~ /SUCCESS/
249
+ result.should_not =~ /DOWN-widget_xxx/
250
+ result.should =~ /DOWN-widget_yyy/
251
+ end
252
+ end
196
253
  end
197
254
 
198
255
  describe 'db:migrate:up' do
@@ -232,6 +289,22 @@ end
232
289
  result.should =~ /wasn't found on path/
233
290
  end
234
291
  end
292
+
293
+ context 'sub-namespaced task' do
294
+ before do
295
+ write_rakefile %{t.sub_namespace = "widgets"}
296
+ end
297
+ it 'migrates up' do
298
+ make_sub_namespaced_migration('widgets', 'widget_xxx')
299
+ run 'rake db:widgets:migrate'
300
+ sleep 1
301
+ version = make_sub_namespaced_migration('widgets', 'widget_yyy')
302
+ result = run("rake db:widgets:migrate:up VERSION=#{version}")
303
+ result.should =~ /SUCCESS/
304
+ result.should_not =~ /UP-widget_xxx/
305
+ result.should =~ /UP-widget_yyy/
306
+ end
307
+ end
235
308
  end
236
309
 
237
310
  describe 'schema:dump' do
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{standalone_migrations}
8
- s.version = "0.4.5"
8
+ s.version = "0.4.7"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Todd Huss", "Michael Grosser"]
12
- s.date = %q{2011-04-01}
12
+ s.date = %q{2011-04-19}
13
13
  s.email = %q{thuss@gabrito.com}
14
14
  s.extra_rdoc_files = [
15
15
  "README.markdown"
@@ -28,13 +28,14 @@ Gem::Specification.new do |s|
28
28
  ]
29
29
  s.homepage = %q{http://github.com/thuss/standalone-migrations}
30
30
  s.require_paths = ["lib"]
31
- s.rubygems_version = %q{1.6.2}
31
+ s.rubygems_version = %q{1.3.7}
32
32
  s.summary = %q{A thin wrapper to use Rails Migrations in non Rails projects}
33
33
  s.test_files = [
34
34
  "spec/standalone_migrations_spec.rb"
35
35
  ]
36
36
 
37
37
  if s.respond_to? :specification_version then
38
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
38
39
  s.specification_version = 3
39
40
 
40
41
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
metadata CHANGED
@@ -1,8 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: standalone_migrations
3
3
  version: !ruby/object:Gem::Version
4
- prerelease:
5
- version: 0.4.5
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 4
8
+ - 7
9
+ version: 0.4.7
6
10
  platform: ruby
7
11
  authors:
8
12
  - Todd Huss
@@ -11,7 +15,7 @@ autorequire:
11
15
  bindir: bin
12
16
  cert_chain: []
13
17
 
14
- date: 2011-04-01 00:00:00 -07:00
18
+ date: 2011-04-19 00:00:00 -07:00
15
19
  default_executable:
16
20
  dependencies:
17
21
  - !ruby/object:Gem::Dependency
@@ -22,6 +26,8 @@ dependencies:
22
26
  requirements:
23
27
  - - ">="
24
28
  - !ruby/object:Gem::Version
29
+ segments:
30
+ - 0
25
31
  version: "0"
26
32
  type: :runtime
27
33
  version_requirements: *id001
@@ -33,6 +39,8 @@ dependencies:
33
39
  requirements:
34
40
  - - ">="
35
41
  - !ruby/object:Gem::Version
42
+ segments:
43
+ - 0
36
44
  version: "0"
37
45
  type: :runtime
38
46
  version_requirements: *id002
@@ -69,17 +77,21 @@ required_ruby_version: !ruby/object:Gem::Requirement
69
77
  requirements:
70
78
  - - ">="
71
79
  - !ruby/object:Gem::Version
80
+ segments:
81
+ - 0
72
82
  version: "0"
73
83
  required_rubygems_version: !ruby/object:Gem::Requirement
74
84
  none: false
75
85
  requirements:
76
86
  - - ">="
77
87
  - !ruby/object:Gem::Version
88
+ segments:
89
+ - 0
78
90
  version: "0"
79
91
  requirements: []
80
92
 
81
93
  rubyforge_project:
82
- rubygems_version: 1.6.2
94
+ rubygems_version: 1.3.7
83
95
  signing_key:
84
96
  specification_version: 3
85
97
  summary: A thin wrapper to use Rails Migrations in non Rails projects