activerecord 3.2.22.5 → 5.2.8

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