activerecord 3.0.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activerecord might be problematic. Click here for more details.

Files changed (181) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +2102 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +35 -44
  5. data/examples/performance.rb +110 -100
  6. data/lib/active_record/aggregations.rb +59 -75
  7. data/lib/active_record/associations/alias_tracker.rb +76 -0
  8. data/lib/active_record/associations/association.rb +248 -0
  9. data/lib/active_record/associations/association_scope.rb +135 -0
  10. data/lib/active_record/associations/belongs_to_association.rb +60 -59
  11. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +16 -59
  12. data/lib/active_record/associations/builder/association.rb +108 -0
  13. data/lib/active_record/associations/builder/belongs_to.rb +98 -0
  14. data/lib/active_record/associations/builder/collection_association.rb +89 -0
  15. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +39 -0
  16. data/lib/active_record/associations/builder/has_many.rb +15 -0
  17. data/lib/active_record/associations/builder/has_one.rb +25 -0
  18. data/lib/active_record/associations/builder/singular_association.rb +32 -0
  19. data/lib/active_record/associations/collection_association.rb +608 -0
  20. data/lib/active_record/associations/collection_proxy.rb +986 -0
  21. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +40 -112
  22. data/lib/active_record/associations/has_many_association.rb +83 -76
  23. data/lib/active_record/associations/has_many_through_association.rb +147 -66
  24. data/lib/active_record/associations/has_one_association.rb +67 -108
  25. data/lib/active_record/associations/has_one_through_association.rb +21 -25
  26. data/lib/active_record/associations/join_dependency/join_association.rb +174 -0
  27. data/lib/active_record/associations/join_dependency/join_base.rb +24 -0
  28. data/lib/active_record/associations/join_dependency/join_part.rb +78 -0
  29. data/lib/active_record/associations/join_dependency.rb +235 -0
  30. data/lib/active_record/associations/join_helper.rb +45 -0
  31. data/lib/active_record/associations/preloader/association.rb +121 -0
  32. data/lib/active_record/associations/preloader/belongs_to.rb +17 -0
  33. data/lib/active_record/associations/preloader/collection_association.rb +24 -0
  34. data/lib/active_record/associations/preloader/has_and_belongs_to_many.rb +60 -0
  35. data/lib/active_record/associations/preloader/has_many.rb +17 -0
  36. data/lib/active_record/associations/preloader/has_many_through.rb +19 -0
  37. data/lib/active_record/associations/preloader/has_one.rb +23 -0
  38. data/lib/active_record/associations/preloader/has_one_through.rb +9 -0
  39. data/lib/active_record/associations/preloader/singular_association.rb +21 -0
  40. data/lib/active_record/associations/preloader/through_association.rb +63 -0
  41. data/lib/active_record/associations/preloader.rb +178 -0
  42. data/lib/active_record/associations/singular_association.rb +64 -0
  43. data/lib/active_record/associations/through_association.rb +87 -0
  44. data/lib/active_record/associations.rb +512 -1224
  45. data/lib/active_record/attribute_assignment.rb +201 -0
  46. data/lib/active_record/attribute_methods/before_type_cast.rb +49 -12
  47. data/lib/active_record/attribute_methods/dirty.rb +51 -28
  48. data/lib/active_record/attribute_methods/primary_key.rb +94 -22
  49. data/lib/active_record/attribute_methods/query.rb +5 -4
  50. data/lib/active_record/attribute_methods/read.rb +63 -72
  51. data/lib/active_record/attribute_methods/serialization.rb +162 -0
  52. data/lib/active_record/attribute_methods/time_zone_conversion.rb +39 -41
  53. data/lib/active_record/attribute_methods/write.rb +39 -13
  54. data/lib/active_record/attribute_methods.rb +362 -29
  55. data/lib/active_record/autosave_association.rb +132 -75
  56. data/lib/active_record/base.rb +83 -1627
  57. data/lib/active_record/callbacks.rb +69 -47
  58. data/lib/active_record/coders/yaml_column.rb +38 -0
  59. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +411 -138
  60. data/lib/active_record/connection_adapters/abstract/database_limits.rb +21 -11
  61. data/lib/active_record/connection_adapters/abstract/database_statements.rb +234 -173
  62. data/lib/active_record/connection_adapters/abstract/query_cache.rb +36 -22
  63. data/lib/active_record/connection_adapters/abstract/quoting.rb +82 -25
  64. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +176 -414
  65. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +70 -0
  66. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +562 -232
  67. data/lib/active_record/connection_adapters/abstract/transaction.rb +203 -0
  68. data/lib/active_record/connection_adapters/abstract_adapter.rb +281 -53
  69. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +782 -0
  70. data/lib/active_record/connection_adapters/column.rb +318 -0
  71. data/lib/active_record/connection_adapters/connection_specification.rb +96 -0
  72. data/lib/active_record/connection_adapters/mysql2_adapter.rb +273 -0
  73. data/lib/active_record/connection_adapters/mysql_adapter.rb +365 -450
  74. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +97 -0
  75. data/lib/active_record/connection_adapters/postgresql/cast.rb +152 -0
  76. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +242 -0
  77. data/lib/active_record/connection_adapters/postgresql/oid.rb +366 -0
  78. data/lib/active_record/connection_adapters/postgresql/quoting.rb +171 -0
  79. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +30 -0
  80. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +489 -0
  81. data/lib/active_record/connection_adapters/postgresql_adapter.rb +672 -752
  82. data/lib/active_record/connection_adapters/schema_cache.rb +129 -0
  83. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +588 -17
  84. data/lib/active_record/connection_adapters/statement_pool.rb +40 -0
  85. data/lib/active_record/connection_handling.rb +98 -0
  86. data/lib/active_record/core.rb +463 -0
  87. data/lib/active_record/counter_cache.rb +108 -101
  88. data/lib/active_record/dynamic_matchers.rb +131 -0
  89. data/lib/active_record/errors.rb +54 -13
  90. data/lib/active_record/explain.rb +38 -0
  91. data/lib/active_record/explain_registry.rb +30 -0
  92. data/lib/active_record/explain_subscriber.rb +29 -0
  93. data/lib/active_record/fixture_set/file.rb +55 -0
  94. data/lib/active_record/fixtures.rb +703 -785
  95. data/lib/active_record/inheritance.rb +200 -0
  96. data/lib/active_record/integration.rb +60 -0
  97. data/lib/active_record/locale/en.yml +8 -1
  98. data/lib/active_record/locking/optimistic.rb +69 -60
  99. data/lib/active_record/locking/pessimistic.rb +34 -12
  100. data/lib/active_record/log_subscriber.rb +40 -6
  101. data/lib/active_record/migration/command_recorder.rb +164 -0
  102. data/lib/active_record/migration/join_table.rb +15 -0
  103. data/lib/active_record/migration.rb +614 -216
  104. data/lib/active_record/model_schema.rb +345 -0
  105. data/lib/active_record/nested_attributes.rb +248 -119
  106. data/lib/active_record/null_relation.rb +65 -0
  107. data/lib/active_record/persistence.rb +275 -57
  108. data/lib/active_record/query_cache.rb +29 -9
  109. data/lib/active_record/querying.rb +62 -0
  110. data/lib/active_record/railtie.rb +135 -21
  111. data/lib/active_record/railties/console_sandbox.rb +5 -0
  112. data/lib/active_record/railties/controller_runtime.rb +17 -5
  113. data/lib/active_record/railties/databases.rake +249 -359
  114. data/lib/active_record/railties/jdbcmysql_error.rb +16 -0
  115. data/lib/active_record/readonly_attributes.rb +30 -0
  116. data/lib/active_record/reflection.rb +283 -103
  117. data/lib/active_record/relation/batches.rb +38 -34
  118. data/lib/active_record/relation/calculations.rb +252 -139
  119. data/lib/active_record/relation/delegation.rb +125 -0
  120. data/lib/active_record/relation/finder_methods.rb +182 -188
  121. data/lib/active_record/relation/merger.rb +161 -0
  122. data/lib/active_record/relation/predicate_builder.rb +86 -21
  123. data/lib/active_record/relation/query_methods.rb +917 -134
  124. data/lib/active_record/relation/spawn_methods.rb +53 -92
  125. data/lib/active_record/relation.rb +405 -143
  126. data/lib/active_record/result.rb +67 -0
  127. data/lib/active_record/runtime_registry.rb +17 -0
  128. data/lib/active_record/sanitization.rb +168 -0
  129. data/lib/active_record/schema.rb +20 -14
  130. data/lib/active_record/schema_dumper.rb +55 -46
  131. data/lib/active_record/schema_migration.rb +39 -0
  132. data/lib/active_record/scoping/default.rb +146 -0
  133. data/lib/active_record/scoping/named.rb +175 -0
  134. data/lib/active_record/scoping.rb +82 -0
  135. data/lib/active_record/serialization.rb +8 -46
  136. data/lib/active_record/serializers/xml_serializer.rb +21 -68
  137. data/lib/active_record/statement_cache.rb +26 -0
  138. data/lib/active_record/store.rb +156 -0
  139. data/lib/active_record/tasks/database_tasks.rb +203 -0
  140. data/lib/active_record/tasks/firebird_database_tasks.rb +56 -0
  141. data/lib/active_record/tasks/mysql_database_tasks.rb +143 -0
  142. data/lib/active_record/tasks/oracle_database_tasks.rb +45 -0
  143. data/lib/active_record/tasks/postgresql_database_tasks.rb +90 -0
  144. data/lib/active_record/tasks/sqlite_database_tasks.rb +51 -0
  145. data/lib/active_record/tasks/sqlserver_database_tasks.rb +48 -0
  146. data/lib/active_record/test_case.rb +57 -28
  147. data/lib/active_record/timestamp.rb +49 -18
  148. data/lib/active_record/transactions.rb +106 -63
  149. data/lib/active_record/translation.rb +22 -0
  150. data/lib/active_record/validations/associated.rb +25 -24
  151. data/lib/active_record/validations/presence.rb +65 -0
  152. data/lib/active_record/validations/uniqueness.rb +123 -83
  153. data/lib/active_record/validations.rb +29 -29
  154. data/lib/active_record/version.rb +7 -5
  155. data/lib/active_record.rb +83 -34
  156. data/lib/rails/generators/active_record/migration/migration_generator.rb +46 -9
  157. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +19 -0
  158. data/lib/rails/generators/active_record/migration/templates/migration.rb +30 -8
  159. data/lib/rails/generators/active_record/model/model_generator.rb +15 -5
  160. data/lib/rails/generators/active_record/model/templates/model.rb +7 -2
  161. data/lib/rails/generators/active_record/model/templates/module.rb +3 -1
  162. data/lib/rails/generators/active_record.rb +4 -8
  163. metadata +163 -121
  164. data/CHANGELOG +0 -6023
  165. data/examples/associations.png +0 -0
  166. data/lib/active_record/association_preload.rb +0 -403
  167. data/lib/active_record/associations/association_collection.rb +0 -562
  168. data/lib/active_record/associations/association_proxy.rb +0 -295
  169. data/lib/active_record/associations/through_association_scope.rb +0 -154
  170. data/lib/active_record/connection_adapters/abstract/connection_specification.rb +0 -113
  171. data/lib/active_record/connection_adapters/sqlite_adapter.rb +0 -401
  172. data/lib/active_record/dynamic_finder_match.rb +0 -53
  173. data/lib/active_record/dynamic_scope_match.rb +0 -32
  174. data/lib/active_record/named_scope.rb +0 -138
  175. data/lib/active_record/observer.rb +0 -140
  176. data/lib/active_record/session_store.rb +0 -340
  177. data/lib/rails/generators/active_record/model/templates/migration.rb +0 -16
  178. data/lib/rails/generators/active_record/observer/observer_generator.rb +0 -15
  179. data/lib/rails/generators/active_record/observer/templates/observer.rb +0 -2
  180. data/lib/rails/generators/active_record/session_migration/session_migration_generator.rb +0 -24
  181. data/lib/rails/generators/active_record/session_migration/templates/migration.rb +0 -16
@@ -1,314 +1,230 @@
1
- namespace :db do
2
- task :load_config => :rails_env do
3
- require 'active_record'
4
- ActiveRecord::Base.configurations = Rails.application.config.database_configuration
1
+ require 'active_record'
2
+
3
+ db_namespace = namespace :db do
4
+ task :load_config do
5
+ ActiveRecord::Base.configurations = ActiveRecord::Tasks::DatabaseTasks.database_configuration || {}
6
+ ActiveRecord::Migrator.migrations_paths = ActiveRecord::Tasks::DatabaseTasks.migrations_paths
5
7
  end
6
8
 
7
9
  namespace :create do
8
- # desc 'Create all the local databases defined in config/database.yml'
9
10
  task :all => :load_config do
10
- ActiveRecord::Base.configurations.each_value do |config|
11
- # Skip entries that don't have a database key, such as the first entry here:
12
- #
13
- # defaults: &defaults
14
- # adapter: mysql
15
- # username: root
16
- # password:
17
- # host: localhost
18
- #
19
- # development:
20
- # database: blog_development
21
- # <<: *defaults
22
- next unless config['database']
23
- # Only connect to local databases
24
- local_database?(config) { create_database(config) }
25
- end
26
- end
27
- end
28
-
29
- desc 'Create the database from config/database.yml for the current Rails.env (use db:create:all to create all dbs in the config)'
30
- task :create => :load_config do
31
- # Make the test database at the same time as the development one, if it exists
32
- if Rails.env.development? && ActiveRecord::Base.configurations['test']
33
- create_database(ActiveRecord::Base.configurations['test'])
11
+ ActiveRecord::Tasks::DatabaseTasks.create_all
34
12
  end
35
- create_database(ActiveRecord::Base.configurations[Rails.env])
36
13
  end
37
14
 
38
- def create_database(config)
39
- begin
40
- if config['adapter'] =~ /sqlite/
41
- if File.exist?(config['database'])
42
- $stderr.puts "#{config['database']} already exists"
43
- else
44
- begin
45
- # Create the SQLite database
46
- ActiveRecord::Base.establish_connection(config)
47
- ActiveRecord::Base.connection
48
- rescue
49
- $stderr.puts $!, *($!.backtrace)
50
- $stderr.puts "Couldn't create database for #{config.inspect}"
51
- end
52
- end
53
- return # Skip the else clause of begin/rescue
54
- else
55
- ActiveRecord::Base.establish_connection(config)
56
- ActiveRecord::Base.connection
57
- end
58
- rescue
59
- case config['adapter']
60
- when /mysql/
61
- @charset = ENV['CHARSET'] || 'utf8'
62
- @collation = ENV['COLLATION'] || 'utf8_unicode_ci'
63
- creation_options = {:charset => (config['charset'] || @charset), :collation => (config['collation'] || @collation)}
64
- error_class = config['adapter'] =~ /mysql2/ ? Mysql2::Error : Mysql::Error
65
- access_denied_error = 1045
66
- begin
67
- ActiveRecord::Base.establish_connection(config.merge('database' => nil))
68
- ActiveRecord::Base.connection.create_database(config['database'], creation_options)
69
- ActiveRecord::Base.establish_connection(config)
70
- rescue error_class => sqlerr
71
- if sqlerr.errno == access_denied_error
72
- print "#{sqlerr.error}. \nPlease provide the root password for your mysql installation\n>"
73
- root_password = $stdin.gets.strip
74
- grant_statement = "GRANT ALL PRIVILEGES ON #{config['database']}.* " \
75
- "TO '#{config['username']}'@'localhost' " \
76
- "IDENTIFIED BY '#{config['password']}' WITH GRANT OPTION;"
77
- ActiveRecord::Base.establish_connection(config.merge(
78
- 'database' => nil, 'username' => 'root', 'password' => root_password))
79
- ActiveRecord::Base.connection.create_database(config['database'], creation_options)
80
- ActiveRecord::Base.connection.execute grant_statement
81
- ActiveRecord::Base.establish_connection(config)
82
- else
83
- $stderr.puts sqlerr.error
84
- $stderr.puts "Couldn't create database for #{config.inspect}, charset: #{config['charset'] || @charset}, collation: #{config['collation'] || @collation}"
85
- $stderr.puts "(if you set the charset manually, make sure you have a matching collation)" if config['charset']
86
- end
87
- end
88
- when 'postgresql'
89
- @encoding = config[:encoding] || ENV['CHARSET'] || 'utf8'
90
- begin
91
- ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres', 'schema_search_path' => 'public'))
92
- ActiveRecord::Base.connection.create_database(config['database'], config.merge('encoding' => @encoding))
93
- ActiveRecord::Base.establish_connection(config)
94
- rescue
95
- $stderr.puts $!, *($!.backtrace)
96
- $stderr.puts "Couldn't create database for #{config.inspect}"
97
- end
98
- end
15
+ desc 'Create the database from DATABASE_URL or config/database.yml for the current Rails.env (use db:create:all to create all dbs in the config)'
16
+ task :create => [:load_config] do
17
+ if ENV['DATABASE_URL']
18
+ ActiveRecord::Tasks::DatabaseTasks.create_database_url
99
19
  else
100
- $stderr.puts "#{config['database']} already exists"
20
+ ActiveRecord::Tasks::DatabaseTasks.create_current
101
21
  end
102
22
  end
103
23
 
104
24
  namespace :drop do
105
- # desc 'Drops all the local databases defined in config/database.yml'
106
25
  task :all => :load_config do
107
- ActiveRecord::Base.configurations.each_value do |config|
108
- # Skip entries that don't have a database key
109
- next unless config['database']
110
- begin
111
- # Only connect to local databases
112
- local_database?(config) { drop_database(config) }
113
- rescue Exception => e
114
- $stderr.puts "Couldn't drop #{config['database']} : #{e.inspect}"
115
- end
116
- end
26
+ ActiveRecord::Tasks::DatabaseTasks.drop_all
117
27
  end
118
28
  end
119
29
 
120
- desc 'Drops the database for the current Rails.env (use db:drop:all to drop all databases)'
121
- task :drop => :load_config do
122
- config = ActiveRecord::Base.configurations[Rails.env || 'development']
123
- begin
124
- drop_database(config)
125
- rescue Exception => e
126
- $stderr.puts "Couldn't drop #{config['database']} : #{e.inspect}"
30
+ desc 'Drops the database using DATABASE_URL or the current Rails.env (use db:drop:all to drop all databases)'
31
+ task :drop => [:load_config] do
32
+ if ENV['DATABASE_URL']
33
+ ActiveRecord::Tasks::DatabaseTasks.drop_database_url
34
+ else
35
+ ActiveRecord::Tasks::DatabaseTasks.drop_current
127
36
  end
128
37
  end
129
38
 
130
- def local_database?(config, &block)
131
- if %w( 127.0.0.1 localhost ).include?(config['host']) || config['host'].blank?
132
- yield
133
- else
134
- $stderr.puts "This task only modifies local databases. #{config['database']} is on a remote host."
39
+ desc "Migrate the database (options: VERSION=x, VERBOSE=false, SCOPE=blog)."
40
+ task :migrate => [:environment, :load_config] do
41
+ ActiveRecord::Migration.verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true
42
+ ActiveRecord::Migrator.migrate(ActiveRecord::Migrator.migrations_paths, ENV["VERSION"] ? ENV["VERSION"].to_i : nil) do |migration|
43
+ ENV["SCOPE"].blank? || (ENV["SCOPE"] == migration.scope)
135
44
  end
45
+ db_namespace['_dump'].invoke
136
46
  end
137
47
 
138
-
139
- desc "Migrate the database (options: VERSION=x, VERBOSE=false)."
140
- task :migrate => :environment do
141
- ActiveRecord::Migration.verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true
142
- ActiveRecord::Migrator.migrate("db/migrate/", ENV["VERSION"] ? ENV["VERSION"].to_i : nil)
143
- Rake::Task["db:schema:dump"].invoke if ActiveRecord::Base.schema_format == :ruby
48
+ task :_dump do
49
+ case ActiveRecord::Base.schema_format
50
+ when :ruby then db_namespace["schema:dump"].invoke
51
+ when :sql then db_namespace["structure:dump"].invoke
52
+ else
53
+ raise "unknown schema format #{ActiveRecord::Base.schema_format}"
54
+ end
55
+ # Allow this task to be called as many times as required. An example is the
56
+ # migrate:redo task, which calls other two internally that depend on this one.
57
+ db_namespace['_dump'].reenable
144
58
  end
145
59
 
146
60
  namespace :migrate do
147
61
  # desc 'Rollbacks the database one migration and re migrate up (options: STEP=x, VERSION=x).'
148
- task :redo => :environment do
149
- if ENV["VERSION"]
150
- Rake::Task["db:migrate:down"].invoke
151
- Rake::Task["db:migrate:up"].invoke
62
+ task :redo => [:environment, :load_config] do
63
+ if ENV['VERSION']
64
+ db_namespace['migrate:down'].invoke
65
+ db_namespace['migrate:up'].invoke
152
66
  else
153
- Rake::Task["db:rollback"].invoke
154
- Rake::Task["db:migrate"].invoke
67
+ db_namespace['rollback'].invoke
68
+ db_namespace['migrate'].invoke
155
69
  end
156
70
  end
157
71
 
158
72
  # desc 'Resets your database using your migrations for the current environment'
159
- task :reset => ["db:drop", "db:create", "db:migrate"]
73
+ task :reset => ['db:drop', 'db:create', 'db:migrate']
160
74
 
161
75
  # desc 'Runs the "up" for a given migration VERSION.'
162
- task :up => :environment do
163
- version = ENV["VERSION"] ? ENV["VERSION"].to_i : nil
164
- raise "VERSION is required" unless version
165
- ActiveRecord::Migrator.run(:up, "db/migrate/", version)
166
- Rake::Task["db:schema:dump"].invoke if ActiveRecord::Base.schema_format == :ruby
76
+ task :up => [:environment, :load_config] do
77
+ version = ENV['VERSION'] ? ENV['VERSION'].to_i : nil
78
+ raise 'VERSION is required' unless version
79
+ ActiveRecord::Migrator.run(:up, ActiveRecord::Migrator.migrations_paths, version)
80
+ db_namespace['_dump'].invoke
167
81
  end
168
82
 
169
83
  # desc 'Runs the "down" for a given migration VERSION.'
170
- task :down => :environment do
171
- version = ENV["VERSION"] ? ENV["VERSION"].to_i : nil
172
- raise "VERSION is required" unless version
173
- ActiveRecord::Migrator.run(:down, "db/migrate/", version)
174
- Rake::Task["db:schema:dump"].invoke if ActiveRecord::Base.schema_format == :ruby
84
+ task :down => [:environment, :load_config] do
85
+ version = ENV['VERSION'] ? ENV['VERSION'].to_i : nil
86
+ raise 'VERSION is required' unless version
87
+ ActiveRecord::Migrator.run(:down, ActiveRecord::Migrator.migrations_paths, version)
88
+ db_namespace['_dump'].invoke
175
89
  end
176
90
 
177
- desc "Display status of migrations"
178
- task :status => :environment do
179
- config = ActiveRecord::Base.configurations[Rails.env || 'development']
180
- ActiveRecord::Base.establish_connection(config)
91
+ desc 'Display status of migrations'
92
+ task :status => [:environment, :load_config] do
181
93
  unless ActiveRecord::Base.connection.table_exists?(ActiveRecord::Migrator.schema_migrations_table_name)
182
94
  puts 'Schema migrations table does not exist yet.'
183
95
  next # means "return" for rake task
184
96
  end
185
97
  db_list = ActiveRecord::Base.connection.select_values("SELECT version FROM #{ActiveRecord::Migrator.schema_migrations_table_name}")
98
+ db_list.map! { |version| "%.3d" % version }
186
99
  file_list = []
187
- Dir.foreach(File.join(Rails.root, 'db', 'migrate')) do |file|
188
- # only files matching "20091231235959_some_name.rb" pattern
189
- if match_data = /(\d{14})_(.+)\.rb/.match(file)
190
- status = db_list.delete(match_data[1]) ? 'up' : 'down'
191
- file_list << [status, match_data[1], match_data[2]]
100
+ ActiveRecord::Migrator.migrations_paths.each do |path|
101
+ Dir.foreach(path) do |file|
102
+ # match "20091231235959_some_name.rb" and "001_some_name.rb" pattern
103
+ if match_data = /^(\d{3,})_(.+)\.rb$/.match(file)
104
+ status = db_list.delete(match_data[1]) ? 'up' : 'down'
105
+ file_list << [status, match_data[1], match_data[2].humanize]
106
+ end
192
107
  end
193
108
  end
109
+ db_list.map! do |version|
110
+ ['up', version, '********** NO FILE **********']
111
+ end
194
112
  # output
195
- puts "\ndatabase: #{config['database']}\n\n"
196
- puts "#{"Status".center(8)} #{"Migration ID".ljust(14)} Migration Name"
113
+ puts "\ndatabase: #{ActiveRecord::Base.connection_config[:database]}\n\n"
114
+ puts "#{'Status'.center(8)} #{'Migration ID'.ljust(14)} Migration Name"
197
115
  puts "-" * 50
198
- file_list.each do |file|
199
- puts "#{file[0].center(8)} #{file[1].ljust(14)} #{file[2].humanize}"
200
- end
201
- db_list.each do |version|
202
- puts "#{'up'.center(8)} #{version.ljust(14)} *** NO FILE ***"
116
+ (db_list + file_list).sort_by {|migration| migration[1]}.each do |migration|
117
+ puts "#{migration[0].center(8)} #{migration[1].ljust(14)} #{migration[2]}"
203
118
  end
204
119
  puts
205
120
  end
206
121
  end
207
122
 
208
123
  desc 'Rolls the schema back to the previous version (specify steps w/ STEP=n).'
209
- task :rollback => :environment do
124
+ task :rollback => [:environment, :load_config] do
210
125
  step = ENV['STEP'] ? ENV['STEP'].to_i : 1
211
- ActiveRecord::Migrator.rollback('db/migrate/', step)
212
- Rake::Task["db:schema:dump"].invoke if ActiveRecord::Base.schema_format == :ruby
126
+ ActiveRecord::Migrator.rollback(ActiveRecord::Migrator.migrations_paths, step)
127
+ db_namespace['_dump'].invoke
213
128
  end
214
129
 
215
130
  # desc 'Pushes the schema to the next version (specify steps w/ STEP=n).'
216
- task :forward => :environment do
131
+ task :forward => [:environment, :load_config] do
217
132
  step = ENV['STEP'] ? ENV['STEP'].to_i : 1
218
- ActiveRecord::Migrator.forward('db/migrate/', step)
219
- Rake::Task["db:schema:dump"].invoke if ActiveRecord::Base.schema_format == :ruby
133
+ ActiveRecord::Migrator.forward(ActiveRecord::Migrator.migrations_paths, step)
134
+ db_namespace['_dump'].invoke
220
135
  end
221
136
 
222
137
  # desc 'Drops and recreates the database from db/schema.rb for the current environment and loads the seeds.'
223
- task :reset => [ 'db:drop', 'db:setup' ]
138
+ task :reset => [:environment, :load_config] do
139
+ db_namespace["drop"].invoke
140
+ db_namespace["setup"].invoke
141
+ end
224
142
 
225
143
  # desc "Retrieves the charset for the current environment's database"
226
- task :charset => :environment do
227
- config = ActiveRecord::Base.configurations[Rails.env || 'development']
228
- case config['adapter']
229
- when /mysql/
230
- ActiveRecord::Base.establish_connection(config)
231
- puts ActiveRecord::Base.connection.charset
232
- when 'postgresql'
233
- ActiveRecord::Base.establish_connection(config)
234
- puts ActiveRecord::Base.connection.encoding
235
- when 'sqlite3'
236
- ActiveRecord::Base.establish_connection(config)
237
- puts ActiveRecord::Base.connection.encoding
238
- else
239
- $stderr.puts 'sorry, your database adapter is not supported yet, feel free to submit a patch'
240
- end
144
+ task :charset => [:environment, :load_config] do
145
+ puts ActiveRecord::Tasks::DatabaseTasks.charset_current
241
146
  end
242
147
 
243
148
  # desc "Retrieves the collation for the current environment's database"
244
- task :collation => :environment do
245
- config = ActiveRecord::Base.configurations[Rails.env || 'development']
246
- case config['adapter']
247
- when /mysql/
248
- ActiveRecord::Base.establish_connection(config)
249
- puts ActiveRecord::Base.connection.collation
250
- else
251
- $stderr.puts 'sorry, your database adapter is not supported yet, feel free to submit a patch'
149
+ task :collation => [:environment, :load_config] do
150
+ begin
151
+ puts ActiveRecord::Tasks::DatabaseTasks.collation_current
152
+ rescue NoMethodError
153
+ $stderr.puts 'Sorry, your database adapter is not supported yet. Feel free to submit a patch.'
252
154
  end
253
155
  end
254
156
 
255
- desc "Retrieves the current schema version number"
256
- task :version => :environment do
157
+ desc 'Retrieves the current schema version number'
158
+ task :version => [:environment, :load_config] do
257
159
  puts "Current version: #{ActiveRecord::Migrator.current_version}"
258
160
  end
259
161
 
260
162
  # desc "Raises an error if there are pending migrations"
261
163
  task :abort_if_pending_migrations => :environment do
262
- if defined? ActiveRecord
263
- pending_migrations = ActiveRecord::Migrator.new(:up, 'db/migrate').pending_migrations
164
+ pending_migrations = ActiveRecord::Migrator.open(ActiveRecord::Migrator.migrations_paths).pending_migrations
264
165
 
265
- if pending_migrations.any?
266
- puts "You have #{pending_migrations.size} pending migrations:"
267
- pending_migrations.each do |pending_migration|
268
- puts ' %4d %s' % [pending_migration.version, pending_migration.name]
269
- end
270
- abort %{Run "rake db:migrate" to update your database then try again.}
166
+ if pending_migrations.any?
167
+ puts "You have #{pending_migrations.size} pending #{pending_migrations.size > 1 ? 'migrations:' : 'migration:'}"
168
+ pending_migrations.each do |pending_migration|
169
+ puts ' %4d %s' % [pending_migration.version, pending_migration.name]
271
170
  end
171
+ abort %{Run `rake db:migrate` to update your database then try again.}
272
172
  end
273
173
  end
274
174
 
275
175
  desc 'Create the database, load the schema, and initialize with the seed data (use db:reset to also drop the db first)'
276
- task :setup => [ 'db:create', 'db:schema:load', 'db:seed' ]
176
+ task :setup => ['db:schema:load_if_ruby', 'db:structure:load_if_sql', :seed]
277
177
 
278
178
  desc 'Load the seed data from db/seeds.rb'
279
- task :seed => 'db:abort_if_pending_migrations' do
280
- seed_file = File.join(Rails.root, 'db', 'seeds.rb')
281
- load(seed_file) if File.exist?(seed_file)
179
+ task :seed do
180
+ db_namespace['abort_if_pending_migrations'].invoke
181
+ ActiveRecord::Tasks::DatabaseTasks.load_seed
282
182
  end
283
183
 
284
184
  namespace :fixtures do
285
- desc "Load fixtures into the current environment's database. Load specific fixtures using FIXTURES=x,y. Load from subdirectory in test/fixtures using FIXTURES_DIR=z. Specify an alternative path (eg. spec/fixtures) using FIXTURES_PATH=spec/fixtures."
286
- task :load => :environment do
185
+ desc "Load fixtures into the current environment's database. Load specific fixtures using FIXTURES=x,y. Load from subdirectory in test/fixtures using FIXTURES_DIR=z. Specify an alternative path (eg. spec/fixtures) using FIXTURES_PATH=spec/fixtures."
186
+ task :load => [:environment, :load_config] do
287
187
  require 'active_record/fixtures'
288
188
 
289
- ActiveRecord::Base.establish_connection(Rails.env)
290
- base_dir = ENV['FIXTURES_PATH'] ? File.join(Rails.root, ENV['FIXTURES_PATH']) : File.join(Rails.root, 'test', 'fixtures')
291
- fixtures_dir = ENV['FIXTURES_DIR'] ? File.join(base_dir, ENV['FIXTURES_DIR']) : base_dir
189
+ base_dir = if ENV['FIXTURES_PATH']
190
+ STDERR.puts "Using FIXTURES_PATH env variable is deprecated, please use " +
191
+ "ActiveRecord::Tasks::DatabaseTasks.fixtures_path = '/path/to/fixtures' " +
192
+ "instead."
193
+ File.join [Rails.root, ENV['FIXTURES_PATH'] || %w{test fixtures}].flatten
194
+ else
195
+ ActiveRecord::Tasks::DatabaseTasks.fixtures_path
196
+ end
292
197
 
293
- (ENV['FIXTURES'] ? ENV['FIXTURES'].split(/,/).map {|f| File.join(fixtures_dir, f) } : Dir["#{fixtures_dir}/**/*.{yml,csv}"]).each do |fixture_file|
294
- Fixtures.create_fixtures(fixtures_dir, fixture_file[(fixtures_dir.size + 1)..-5])
198
+ fixtures_dir = File.join [base_dir, ENV['FIXTURES_DIR']].compact
199
+
200
+ (ENV['FIXTURES'] ? ENV['FIXTURES'].split(/,/) : Dir["#{fixtures_dir}/**/*.yml"].map {|f| f[(fixtures_dir.size + 1)..-5] }).each do |fixture_file|
201
+ ActiveRecord::FixtureSet.create_fixtures(fixtures_dir, fixture_file)
295
202
  end
296
203
  end
297
204
 
298
205
  # desc "Search for a fixture given a LABEL or ID. Specify an alternative path (eg. spec/fixtures) using FIXTURES_PATH=spec/fixtures."
299
- task :identify => :environment do
206
+ task :identify => [:environment, :load_config] do
300
207
  require 'active_record/fixtures'
301
208
 
302
- label, id = ENV["LABEL"], ENV["ID"]
303
- raise "LABEL or ID required" if label.blank? && id.blank?
209
+ label, id = ENV['LABEL'], ENV['ID']
210
+ raise 'LABEL or ID required' if label.blank? && id.blank?
211
+
212
+ puts %Q(The fixture ID for "#{label}" is #{ActiveRecord::FixtureSet.identify(label)}.) if label
213
+
214
+ base_dir = if ENV['FIXTURES_PATH']
215
+ STDERR.puts "Using FIXTURES_PATH env variable is deprecated, please use " +
216
+ "ActiveRecord::Tasks::DatabaseTasks.fixtures_path = '/path/to/fixtures' " +
217
+ "instead."
218
+ File.join [Rails.root, ENV['FIXTURES_PATH'] || %w{test fixtures}].flatten
219
+ else
220
+ ActiveRecord::Tasks::DatabaseTasks.fixtures_path
221
+ end
304
222
 
305
- puts %Q(The fixture ID for "#{label}" is #{Fixtures.identify(label)}.) if label
306
223
 
307
- base_dir = ENV['FIXTURES_PATH'] ? File.join(Rails.root, ENV['FIXTURES_PATH']) : File.join(Rails.root, 'test', 'fixtures')
308
224
  Dir["#{base_dir}/**/*.yml"].each do |file|
309
225
  if data = YAML::load(ERB.new(IO.read(file)).result)
310
226
  data.keys.each do |key|
311
- key_id = Fixtures.identify(key)
227
+ key_id = ActiveRecord::FixtureSet.identify(key)
312
228
 
313
229
  if key == label || key_id == id.to_i
314
230
  puts "#{file}: #{key} (#{key_id})"
@@ -320,193 +236,167 @@ namespace :db do
320
236
  end
321
237
 
322
238
  namespace :schema do
323
- desc "Create a db/schema.rb file that can be portably used against any DB supported by AR"
324
- task :dump => :environment do
239
+ desc 'Create a db/schema.rb file that can be portably used against any DB supported by AR'
240
+ task :dump => [:environment, :load_config] do
325
241
  require 'active_record/schema_dumper'
326
- File.open(ENV['SCHEMA'] || "#{Rails.root}/db/schema.rb", "w") do |file|
242
+ filename = ENV['SCHEMA'] || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, 'schema.rb')
243
+ File.open(filename, "w:utf-8") do |file|
327
244
  ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file)
328
245
  end
329
- Rake::Task["db:schema:dump"].reenable
246
+ db_namespace['schema:dump'].reenable
330
247
  end
331
248
 
332
- desc "Load a schema.rb file into the database"
333
- task :load => :environment do
334
- file = ENV['SCHEMA'] || "#{Rails.root}/db/schema.rb"
249
+ desc 'Load a schema.rb file into the database'
250
+ task :load => [:environment, :load_config] do
251
+ file = ENV['SCHEMA'] || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, 'schema.rb')
335
252
  if File.exists?(file)
336
253
  load(file)
337
254
  else
338
- abort %{#{file} doesn't exist yet. Run "rake db:migrate" to create it then try again. If you do not intend to use a database, you should instead alter #{Rails.root}/config/boot.rb to limit the frameworks that will be loaded}
255
+ abort %{#{file} doesn't exist yet. Run `rake db:migrate` to create it, then try again. If you do not intend to use a database, you should instead alter #{Rails.root}/config/application.rb to limit the frameworks that will be loaded.}
256
+ end
257
+ end
258
+
259
+ task :load_if_ruby => ['db:create', :environment] do
260
+ db_namespace["schema:load"].invoke if ActiveRecord::Base.schema_format == :ruby
261
+ end
262
+
263
+ namespace :cache do
264
+ desc 'Create a db/schema_cache.dump file.'
265
+ task :dump => [:environment, :load_config] do
266
+ con = ActiveRecord::Base.connection
267
+ filename = File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, "schema_cache.dump")
268
+
269
+ con.schema_cache.clear!
270
+ con.tables.each { |table| con.schema_cache.add(table) }
271
+ open(filename, 'wb') { |f| f.write(Marshal.dump(con.schema_cache)) }
272
+ end
273
+
274
+ desc 'Clear a db/schema_cache.dump file.'
275
+ task :clear => [:environment, :load_config] do
276
+ filename = File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, "schema_cache.dump")
277
+ FileUtils.rm(filename) if File.exists?(filename)
339
278
  end
340
279
  end
280
+
341
281
  end
342
282
 
343
283
  namespace :structure do
344
- desc "Dump the database structure to an SQL file"
345
- task :dump => :environment do
346
- abcs = ActiveRecord::Base.configurations
347
- case abcs[Rails.env]["adapter"]
348
- when /mysql/, "oci", "oracle"
349
- ActiveRecord::Base.establish_connection(abcs[Rails.env])
350
- File.open("#{Rails.root}/db/#{Rails.env}_structure.sql", "w+") { |f| f << ActiveRecord::Base.connection.structure_dump }
351
- when "postgresql"
352
- ENV['PGHOST'] = abcs[Rails.env]["host"] if abcs[Rails.env]["host"]
353
- ENV['PGPORT'] = abcs[Rails.env]["port"].to_s if abcs[Rails.env]["port"]
354
- ENV['PGPASSWORD'] = abcs[Rails.env]["password"].to_s if abcs[Rails.env]["password"]
355
- search_path = abcs[Rails.env]["schema_search_path"]
356
- unless search_path.blank?
357
- search_path = search_path.split(",").map{|search_path| "--schema=#{search_path.strip}" }.join(" ")
358
- end
359
- `pg_dump -i -U "#{abcs[Rails.env]["username"]}" -s -x -O -f db/#{Rails.env}_structure.sql #{search_path} #{abcs[Rails.env]["database"]}`
360
- raise "Error dumping database" if $?.exitstatus == 1
361
- when "sqlite", "sqlite3"
362
- dbfile = abcs[Rails.env]["database"] || abcs[Rails.env]["dbfile"]
363
- `#{abcs[Rails.env]["adapter"]} #{dbfile} .schema > db/#{Rails.env}_structure.sql`
364
- when "sqlserver"
365
- `scptxfr /s #{abcs[Rails.env]["host"]} /d #{abcs[Rails.env]["database"]} /I /f db\\#{Rails.env}_structure.sql /q /A /r`
366
- `scptxfr /s #{abcs[Rails.env]["host"]} /d #{abcs[Rails.env]["database"]} /I /F db\ /q /A /r`
367
- when "firebird"
368
- set_firebird_env(abcs[Rails.env])
369
- db_string = firebird_db_string(abcs[Rails.env])
370
- sh "isql -a #{db_string} > #{Rails.root}/db/#{Rails.env}_structure.sql"
371
- else
372
- raise "Task not supported by '#{abcs["test"]["adapter"]}'"
373
- end
284
+ desc 'Dump the database structure to db/structure.sql. Specify another file with DB_STRUCTURE=db/my_structure.sql'
285
+ task :dump => [:environment, :load_config] do
286
+ filename = ENV['DB_STRUCTURE'] || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, "structure.sql")
287
+ current_config = ActiveRecord::Tasks::DatabaseTasks.current_config
288
+ ActiveRecord::Tasks::DatabaseTasks.structure_dump(current_config, filename)
374
289
 
375
290
  if ActiveRecord::Base.connection.supports_migrations?
376
- File.open("#{Rails.root}/db/#{Rails.env}_structure.sql", "a") { |f| f << ActiveRecord::Base.connection.dump_schema_information }
291
+ File.open(filename, "a") do |f|
292
+ f.puts ActiveRecord::Base.connection.dump_schema_information
293
+ end
377
294
  end
295
+ db_namespace['structure:dump'].reenable
296
+ end
297
+
298
+ # desc "Recreate the databases from the structure.sql file"
299
+ task :load => [:environment, :load_config] do
300
+ filename = ENV['DB_STRUCTURE'] || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, "structure.sql")
301
+ current_config = ActiveRecord::Tasks::DatabaseTasks.current_config
302
+ ActiveRecord::Tasks::DatabaseTasks.structure_load(current_config, filename)
303
+ end
304
+
305
+ task :load_if_sql => ['db:create', :environment] do
306
+ db_namespace["structure:load"].invoke if ActiveRecord::Base.schema_format == :sql
378
307
  end
379
308
  end
380
309
 
381
310
  namespace :test do
382
- # desc "Recreate the test database from the current schema.rb"
311
+
312
+ # desc "Recreate the test database from the current schema"
383
313
  task :load => 'db:test:purge' do
384
- ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['test'])
385
- ActiveRecord::Schema.verbose = false
386
- Rake::Task["db:schema:load"].invoke
314
+ case ActiveRecord::Base.schema_format
315
+ when :ruby
316
+ db_namespace["test:load_schema"].invoke
317
+ when :sql
318
+ db_namespace["test:load_structure"].invoke
319
+ end
387
320
  end
388
321
 
389
- # desc "Recreate the test database from the current environment's database schema"
390
- task :clone => %w(db:schema:dump db:test:load)
391
-
392
- # desc "Recreate the test databases from the development structure"
393
- task :clone_structure => [ "db:structure:dump", "db:test:purge" ] do
394
- abcs = ActiveRecord::Base.configurations
395
- case abcs["test"]["adapter"]
396
- when /mysql/
397
- ActiveRecord::Base.establish_connection(:test)
398
- ActiveRecord::Base.connection.execute('SET foreign_key_checks = 0')
399
- IO.readlines("#{Rails.root}/db/#{Rails.env}_structure.sql").join.split("\n\n").each do |table|
400
- ActiveRecord::Base.connection.execute(table)
401
- end
402
- when "postgresql"
403
- ENV['PGHOST'] = abcs["test"]["host"] if abcs["test"]["host"]
404
- ENV['PGPORT'] = abcs["test"]["port"].to_s if abcs["test"]["port"]
405
- ENV['PGPASSWORD'] = abcs["test"]["password"].to_s if abcs["test"]["password"]
406
- `psql -U "#{abcs["test"]["username"]}" -f #{Rails.root}/db/#{Rails.env}_structure.sql #{abcs["test"]["database"]}`
407
- when "sqlite", "sqlite3"
408
- dbfile = abcs["test"]["database"] || abcs["test"]["dbfile"]
409
- `#{abcs["test"]["adapter"]} #{dbfile} < #{Rails.root}/db/#{Rails.env}_structure.sql`
410
- when "sqlserver"
411
- `osql -E -S #{abcs["test"]["host"]} -d #{abcs["test"]["database"]} -i db\\#{Rails.env}_structure.sql`
412
- when "oci", "oracle"
413
- ActiveRecord::Base.establish_connection(:test)
414
- IO.readlines("#{Rails.root}/db/#{Rails.env}_structure.sql").join.split(";\n\n").each do |ddl|
415
- ActiveRecord::Base.connection.execute(ddl)
416
- end
417
- when "firebird"
418
- set_firebird_env(abcs["test"])
419
- db_string = firebird_db_string(abcs["test"])
420
- sh "isql -i #{Rails.root}/db/#{Rails.env}_structure.sql #{db_string}"
421
- else
422
- raise "Task not supported by '#{abcs["test"]["adapter"]}'"
322
+ # desc "Recreate the test database from an existent schema.rb file"
323
+ task :load_schema => 'db:test:purge' do
324
+ begin
325
+ ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['test'])
326
+ ActiveRecord::Schema.verbose = false
327
+ db_namespace["schema:load"].invoke
328
+ ensure
329
+ ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations[ActiveRecord::Tasks::DatabaseTasks.env])
423
330
  end
424
331
  end
425
332
 
426
- # desc "Empty the test database"
427
- task :purge => :environment do
428
- abcs = ActiveRecord::Base.configurations
429
- case abcs["test"]["adapter"]
430
- when /mysql/
431
- ActiveRecord::Base.establish_connection(:test)
432
- ActiveRecord::Base.connection.recreate_database(abcs["test"]["database"], abcs["test"])
433
- when "postgresql"
434
- ActiveRecord::Base.clear_active_connections!
435
- drop_database(abcs['test'])
436
- create_database(abcs['test'])
437
- when "sqlite","sqlite3"
438
- dbfile = abcs["test"]["database"] || abcs["test"]["dbfile"]
439
- File.delete(dbfile) if File.exist?(dbfile)
440
- when "sqlserver"
441
- dropfkscript = "#{abcs["test"]["host"]}.#{abcs["test"]["database"]}.DP1".gsub(/\\/,'-')
442
- `osql -E -S #{abcs["test"]["host"]} -d #{abcs["test"]["database"]} -i db\\#{dropfkscript}`
443
- `osql -E -S #{abcs["test"]["host"]} -d #{abcs["test"]["database"]} -i db\\#{Rails.env}_structure.sql`
444
- when "oci", "oracle"
445
- ActiveRecord::Base.establish_connection(:test)
446
- ActiveRecord::Base.connection.structure_drop.split(";\n\n").each do |ddl|
447
- ActiveRecord::Base.connection.execute(ddl)
448
- end
449
- when "firebird"
450
- ActiveRecord::Base.establish_connection(:test)
451
- ActiveRecord::Base.connection.recreate_database!
452
- else
453
- raise "Task not supported by '#{abcs["test"]["adapter"]}'"
333
+ # desc "Recreate the test database from an existent structure.sql file"
334
+ task :load_structure => 'db:test:purge' do
335
+ begin
336
+ ActiveRecord::Tasks::DatabaseTasks.current_config(:config => ActiveRecord::Base.configurations['test'])
337
+ db_namespace["structure:load"].invoke
338
+ ensure
339
+ ActiveRecord::Tasks::DatabaseTasks.current_config(:config => nil)
454
340
  end
455
341
  end
456
342
 
457
- # desc 'Check for pending migrations and load the test schema'
458
- task :prepare => 'db:abort_if_pending_migrations' do
459
- if defined?(ActiveRecord) && !ActiveRecord::Base.configurations.blank?
460
- Rake::Task[{ :sql => "db:test:clone_structure", :ruby => "db:test:load" }[ActiveRecord::Base.schema_format]].invoke
343
+ # desc "Recreate the test database from a fresh schema"
344
+ task :clone do
345
+ case ActiveRecord::Base.schema_format
346
+ when :ruby
347
+ db_namespace["test:clone_schema"].invoke
348
+ when :sql
349
+ db_namespace["test:clone_structure"].invoke
461
350
  end
462
351
  end
463
- end
464
352
 
465
- namespace :sessions do
466
- # desc "Creates a sessions migration for use with ActiveRecord::SessionStore"
467
- task :create => :environment do
468
- raise "Task unavailable to this database (no migration support)" unless ActiveRecord::Base.connection.supports_migrations?
469
- require 'rails/generators'
470
- Rails::Generators.configure!
471
- require 'rails/generators/rails/session_migration/session_migration_generator'
472
- Rails::Generators::SessionMigrationGenerator.start [ ENV["MIGRATION"] || "add_sessions_table" ]
353
+ # desc "Recreate the test database from a fresh schema.rb file"
354
+ task :clone_schema => ["db:schema:dump", "db:test:load_schema"]
355
+
356
+ # desc "Recreate the test database from a fresh structure.sql file"
357
+ task :clone_structure => [ "db:structure:dump", "db:test:load_structure" ]
358
+
359
+ # desc "Empty the test database"
360
+ task :purge => [:environment, :load_config] do
361
+ ActiveRecord::Tasks::DatabaseTasks.purge ActiveRecord::Base.configurations['test']
473
362
  end
474
363
 
475
- # desc "Clear the sessions table"
476
- task :clear => :environment do
477
- ActiveRecord::Base.connection.execute "DELETE FROM #{session_table_name}"
364
+ # desc 'Check for pending migrations and load the test schema'
365
+ task :prepare => :load_config do
366
+ unless ActiveRecord::Base.configurations.blank?
367
+ db_namespace['test:load'].invoke
368
+ end
478
369
  end
479
370
  end
480
371
  end
481
372
 
482
- task 'test:prepare' => 'db:test:prepare'
483
-
484
- def drop_database(config)
485
- case config['adapter']
486
- when /mysql/
487
- ActiveRecord::Base.establish_connection(config)
488
- ActiveRecord::Base.connection.drop_database config['database']
489
- when /^sqlite/
490
- require 'pathname'
491
- path = Pathname.new(config['database'])
492
- file = path.absolute? ? path.to_s : File.join(Rails.root, path)
493
-
494
- FileUtils.rm(file)
495
- when 'postgresql'
496
- ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres', 'schema_search_path' => 'public'))
497
- ActiveRecord::Base.connection.drop_database config['database']
498
- end
499
- end
373
+ namespace :railties do
374
+ namespace :install do
375
+ # desc "Copies missing migrations from Railties (e.g. engines). You can specify Railties to use with FROM=railtie1,railtie2"
376
+ task :migrations => :'db:load_config' do
377
+ to_load = ENV['FROM'].blank? ? :all : ENV['FROM'].split(",").map {|n| n.strip }
378
+ railties = {}
379
+ Rails.application.railties.each do |railtie|
380
+ next unless to_load == :all || to_load.include?(railtie.railtie_name)
381
+
382
+ if railtie.respond_to?(:paths) && (path = railtie.paths['db/migrate'].first)
383
+ railties[railtie.railtie_name] = path
384
+ end
385
+ end
500
386
 
501
- def session_table_name
502
- ActiveRecord::SessionStore::Session.table_name
503
- end
387
+ on_skip = Proc.new do |name, migration|
388
+ puts "NOTE: Migration #{migration.basename} from #{name} has been skipped. Migration with the same name already exists."
389
+ end
504
390
 
505
- def set_firebird_env(config)
506
- ENV["ISC_USER"] = config["username"].to_s if config["username"]
507
- ENV["ISC_PASSWORD"] = config["password"].to_s if config["password"]
508
- end
391
+ on_copy = Proc.new do |name, migration|
392
+ puts "Copied migration #{migration.basename} from #{name}"
393
+ end
509
394
 
510
- def firebird_db_string(config)
511
- FireRuby::Database.db_string_for(config.symbolize_keys)
395
+ ActiveRecord::Migration.copy(ActiveRecord::Migrator.migrations_paths.first, railties,
396
+ :on_skip => on_skip, :on_copy => on_copy)
397
+ end
398
+ end
512
399
  end
400
+
401
+ task 'test:prepare' => ['db:test:prepare', 'db:test:load', 'db:abort_if_pending_migrations']
402
+