standalone_migrations 0.4.5 → 0.4.7

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