activerecord 3.1.10 → 4.2.11

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.

Potentially problematic release.


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

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