activerecord 4.2.0 → 6.0.5.1

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 (373) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +852 -801
  3. data/MIT-LICENSE +4 -2
  4. data/README.rdoc +14 -13
  5. data/examples/performance.rb +33 -32
  6. data/examples/simple.rb +5 -4
  7. data/lib/active_record/advisory_lock_base.rb +18 -0
  8. data/lib/active_record/aggregations.rb +267 -249
  9. data/lib/active_record/association_relation.rb +26 -6
  10. data/lib/active_record/associations/alias_tracker.rb +29 -36
  11. data/lib/active_record/associations/association.rb +137 -55
  12. data/lib/active_record/associations/association_scope.rb +110 -132
  13. data/lib/active_record/associations/belongs_to_association.rb +67 -54
  14. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
  15. data/lib/active_record/associations/builder/association.rb +27 -40
  16. data/lib/active_record/associations/builder/belongs_to.rb +69 -55
  17. data/lib/active_record/associations/builder/collection_association.rb +10 -29
  18. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +58 -70
  19. data/lib/active_record/associations/builder/has_many.rb +8 -4
  20. data/lib/active_record/associations/builder/has_one.rb +46 -5
  21. data/lib/active_record/associations/builder/singular_association.rb +16 -10
  22. data/lib/active_record/associations/collection_association.rb +150 -275
  23. data/lib/active_record/associations/collection_proxy.rb +253 -152
  24. data/lib/active_record/associations/foreign_association.rb +20 -0
  25. data/lib/active_record/associations/has_many_association.rb +35 -84
  26. data/lib/active_record/associations/has_many_through_association.rb +62 -80
  27. data/lib/active_record/associations/has_one_association.rb +62 -49
  28. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  29. data/lib/active_record/associations/join_dependency/join_association.rb +43 -78
  30. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  31. data/lib/active_record/associations/join_dependency/join_part.rb +14 -14
  32. data/lib/active_record/associations/join_dependency.rb +159 -162
  33. data/lib/active_record/associations/preloader/association.rb +102 -113
  34. data/lib/active_record/associations/preloader/through_association.rb +85 -65
  35. data/lib/active_record/associations/preloader.rb +96 -95
  36. data/lib/active_record/associations/singular_association.rb +18 -45
  37. data/lib/active_record/associations/through_association.rb +49 -24
  38. data/lib/active_record/associations.rb +1737 -1596
  39. data/lib/active_record/attribute_assignment.rb +57 -185
  40. data/lib/active_record/attribute_decorators.rb +39 -17
  41. data/lib/active_record/attribute_methods/before_type_cast.rb +14 -5
  42. data/lib/active_record/attribute_methods/dirty.rb +174 -134
  43. data/lib/active_record/attribute_methods/primary_key.rb +90 -84
  44. data/lib/active_record/attribute_methods/query.rb +6 -5
  45. data/lib/active_record/attribute_methods/read.rb +20 -77
  46. data/lib/active_record/attribute_methods/serialization.rb +40 -21
  47. data/lib/active_record/attribute_methods/time_zone_conversion.rb +61 -37
  48. data/lib/active_record/attribute_methods/write.rb +33 -56
  49. data/lib/active_record/attribute_methods.rb +124 -143
  50. data/lib/active_record/attributes.rb +213 -74
  51. data/lib/active_record/autosave_association.rb +125 -54
  52. data/lib/active_record/base.rb +60 -49
  53. data/lib/active_record/callbacks.rb +101 -76
  54. data/lib/active_record/coders/json.rb +3 -1
  55. data/lib/active_record/coders/yaml_column.rb +36 -13
  56. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +810 -291
  57. data/lib/active_record/connection_adapters/abstract/database_limits.rb +26 -8
  58. data/lib/active_record/connection_adapters/abstract/database_statements.rb +253 -108
  59. data/lib/active_record/connection_adapters/abstract/query_cache.rb +83 -24
  60. data/lib/active_record/connection_adapters/abstract/quoting.rb +171 -53
  61. data/lib/active_record/connection_adapters/abstract/savepoints.rb +6 -4
  62. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +74 -47
  63. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +383 -239
  64. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +79 -36
  65. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +736 -235
  66. data/lib/active_record/connection_adapters/abstract/transaction.rb +190 -87
  67. data/lib/active_record/connection_adapters/abstract_adapter.rb +487 -192
  68. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +536 -600
  69. data/lib/active_record/connection_adapters/column.rb +56 -43
  70. data/lib/active_record/connection_adapters/connection_specification.rb +174 -153
  71. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +29 -0
  72. data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
  73. data/lib/active_record/connection_adapters/mysql/database_statements.rb +196 -0
  74. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +71 -0
  75. data/lib/active_record/connection_adapters/mysql/quoting.rb +81 -0
  76. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +71 -0
  77. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +95 -0
  78. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +88 -0
  79. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +268 -0
  80. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +31 -0
  81. data/lib/active_record/connection_adapters/mysql2_adapter.rb +59 -196
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +21 -11
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +71 -115
  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 +49 -57
  86. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +9 -8
  87. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +5 -2
  89. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +5 -1
  90. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +13 -1
  91. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +17 -13
  92. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  93. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +6 -3
  94. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +31 -20
  95. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  97. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +44 -0
  98. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -9
  99. data/lib/active_record/connection_adapters/postgresql/oid/{infinity.rb → oid.rb} +5 -3
  100. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +32 -11
  101. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +70 -34
  102. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
  103. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +67 -51
  104. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +9 -5
  105. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +3 -1
  106. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +3 -1
  107. data/lib/active_record/connection_adapters/postgresql/oid.rb +23 -25
  108. data/lib/active_record/connection_adapters/postgresql/quoting.rb +144 -47
  109. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +27 -14
  110. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
  111. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +178 -108
  112. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +49 -0
  113. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +465 -291
  114. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +36 -0
  115. data/lib/active_record/connection_adapters/postgresql/utils.rb +11 -8
  116. data/lib/active_record/connection_adapters/postgresql_adapter.rb +565 -363
  117. data/lib/active_record/connection_adapters/schema_cache.rb +72 -25
  118. data/lib/active_record/connection_adapters/sql_type_metadata.rb +37 -0
  119. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +119 -0
  120. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
  121. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +102 -0
  122. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +17 -0
  123. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  124. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  125. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +137 -0
  126. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +299 -364
  127. data/lib/active_record/connection_adapters/statement_pool.rb +33 -13
  128. data/lib/active_record/connection_handling.rb +167 -41
  129. data/lib/active_record/core.rb +277 -233
  130. data/lib/active_record/counter_cache.rb +71 -50
  131. data/lib/active_record/database_configurations/database_config.rb +37 -0
  132. data/lib/active_record/database_configurations/hash_config.rb +50 -0
  133. data/lib/active_record/database_configurations/url_config.rb +78 -0
  134. data/lib/active_record/database_configurations.rb +233 -0
  135. data/lib/active_record/define_callbacks.rb +22 -0
  136. data/lib/active_record/dynamic_matchers.rb +87 -106
  137. data/lib/active_record/enum.rb +172 -89
  138. data/lib/active_record/errors.rb +189 -53
  139. data/lib/active_record/explain.rb +22 -11
  140. data/lib/active_record/explain_registry.rb +4 -2
  141. data/lib/active_record/explain_subscriber.rb +11 -6
  142. data/lib/active_record/fixture_set/file.rb +35 -9
  143. data/lib/active_record/fixture_set/model_metadata.rb +33 -0
  144. data/lib/active_record/fixture_set/render_context.rb +17 -0
  145. data/lib/active_record/fixture_set/table_row.rb +152 -0
  146. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  147. data/lib/active_record/fixtures.rb +225 -497
  148. data/lib/active_record/gem_version.rb +6 -4
  149. data/lib/active_record/inheritance.rb +158 -115
  150. data/lib/active_record/insert_all.rb +179 -0
  151. data/lib/active_record/integration.rb +123 -29
  152. data/lib/active_record/internal_metadata.rb +53 -0
  153. data/lib/active_record/legacy_yaml_adapter.rb +48 -0
  154. data/lib/active_record/locale/en.yml +3 -2
  155. data/lib/active_record/locking/optimistic.rb +99 -98
  156. data/lib/active_record/locking/pessimistic.rb +18 -6
  157. data/lib/active_record/log_subscriber.rb +76 -33
  158. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  159. data/lib/active_record/middleware/database_selector/resolver.rb +87 -0
  160. data/lib/active_record/middleware/database_selector.rb +74 -0
  161. data/lib/active_record/migration/command_recorder.rb +166 -91
  162. data/lib/active_record/migration/compatibility.rb +244 -0
  163. data/lib/active_record/migration/join_table.rb +8 -7
  164. data/lib/active_record/migration.rb +636 -290
  165. data/lib/active_record/model_schema.rb +344 -112
  166. data/lib/active_record/nested_attributes.rb +265 -215
  167. data/lib/active_record/no_touching.rb +15 -2
  168. data/lib/active_record/null_relation.rb +24 -38
  169. data/lib/active_record/persistence.rb +559 -125
  170. data/lib/active_record/query_cache.rb +19 -23
  171. data/lib/active_record/querying.rb +44 -30
  172. data/lib/active_record/railtie.rb +166 -47
  173. data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
  174. data/lib/active_record/railties/console_sandbox.rb +2 -0
  175. data/lib/active_record/railties/controller_runtime.rb +34 -33
  176. data/lib/active_record/railties/databases.rake +341 -202
  177. data/lib/active_record/readonly_attributes.rb +5 -4
  178. data/lib/active_record/reflection.rb +461 -302
  179. data/lib/active_record/relation/batches/batch_enumerator.rb +69 -0
  180. data/lib/active_record/relation/batches.rb +206 -55
  181. data/lib/active_record/relation/calculations.rb +270 -249
  182. data/lib/active_record/relation/delegation.rb +76 -84
  183. data/lib/active_record/relation/finder_methods.rb +287 -255
  184. data/lib/active_record/relation/from_clause.rb +30 -0
  185. data/lib/active_record/relation/merger.rb +86 -68
  186. data/lib/active_record/relation/predicate_builder/array_handler.rb +27 -25
  187. data/lib/active_record/relation/predicate_builder/association_query_value.rb +43 -0
  188. data/lib/active_record/relation/predicate_builder/base_handler.rb +18 -0
  189. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +19 -0
  190. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +53 -0
  191. data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -0
  192. data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
  193. data/lib/active_record/relation/predicate_builder.rb +112 -92
  194. data/lib/active_record/relation/query_attribute.rb +50 -0
  195. data/lib/active_record/relation/query_methods.rb +612 -392
  196. data/lib/active_record/relation/record_fetch_warning.rb +51 -0
  197. data/lib/active_record/relation/spawn_methods.rb +18 -17
  198. data/lib/active_record/relation/where_clause.rb +189 -0
  199. data/lib/active_record/relation/where_clause_factory.rb +33 -0
  200. data/lib/active_record/relation.rb +533 -340
  201. data/lib/active_record/result.rb +79 -43
  202. data/lib/active_record/runtime_registry.rb +6 -4
  203. data/lib/active_record/sanitization.rb +144 -121
  204. data/lib/active_record/schema.rb +21 -24
  205. data/lib/active_record/schema_dumper.rb +112 -93
  206. data/lib/active_record/schema_migration.rb +24 -20
  207. data/lib/active_record/scoping/default.rb +98 -82
  208. data/lib/active_record/scoping/named.rb +91 -33
  209. data/lib/active_record/scoping.rb +45 -27
  210. data/lib/active_record/secure_token.rb +40 -0
  211. data/lib/active_record/serialization.rb +5 -5
  212. data/lib/active_record/statement_cache.rb +73 -36
  213. data/lib/active_record/store.rb +127 -42
  214. data/lib/active_record/suppressor.rb +61 -0
  215. data/lib/active_record/table_metadata.rb +90 -0
  216. data/lib/active_record/tasks/database_tasks.rb +309 -99
  217. data/lib/active_record/tasks/mysql_database_tasks.rb +58 -89
  218. data/lib/active_record/tasks/postgresql_database_tasks.rb +81 -31
  219. data/lib/active_record/tasks/sqlite_database_tasks.rb +37 -16
  220. data/lib/active_record/test_databases.rb +23 -0
  221. data/lib/active_record/test_fixtures.rb +243 -0
  222. data/lib/active_record/timestamp.rb +86 -41
  223. data/lib/active_record/touch_later.rb +65 -0
  224. data/lib/active_record/transactions.rb +222 -146
  225. data/lib/active_record/translation.rb +3 -1
  226. data/lib/active_record/type/adapter_specific_registry.rb +126 -0
  227. data/lib/active_record/type/date.rb +4 -41
  228. data/lib/active_record/type/date_time.rb +4 -38
  229. data/lib/active_record/type/decimal_without_scale.rb +6 -2
  230. data/lib/active_record/type/hash_lookup_type_map.rb +12 -5
  231. data/lib/active_record/type/internal/timezone.rb +17 -0
  232. data/lib/active_record/type/json.rb +30 -0
  233. data/lib/active_record/type/serialized.rb +29 -15
  234. data/lib/active_record/type/text.rb +2 -2
  235. data/lib/active_record/type/time.rb +21 -16
  236. data/lib/active_record/type/type_map.rb +16 -19
  237. data/lib/active_record/type/unsigned_integer.rb +9 -8
  238. data/lib/active_record/type.rb +77 -23
  239. data/lib/active_record/type_caster/connection.rb +34 -0
  240. data/lib/active_record/type_caster/map.rb +20 -0
  241. data/lib/active_record/type_caster.rb +9 -0
  242. data/lib/active_record/validations/absence.rb +25 -0
  243. data/lib/active_record/validations/associated.rb +12 -4
  244. data/lib/active_record/validations/length.rb +26 -0
  245. data/lib/active_record/validations/presence.rb +14 -13
  246. data/lib/active_record/validations/uniqueness.rb +43 -46
  247. data/lib/active_record/validations.rb +38 -35
  248. data/lib/active_record/version.rb +3 -1
  249. data/lib/active_record.rb +44 -21
  250. data/lib/arel/alias_predication.rb +9 -0
  251. data/lib/arel/attributes/attribute.rb +37 -0
  252. data/lib/arel/attributes.rb +22 -0
  253. data/lib/arel/collectors/bind.rb +24 -0
  254. data/lib/arel/collectors/composite.rb +31 -0
  255. data/lib/arel/collectors/plain_string.rb +20 -0
  256. data/lib/arel/collectors/sql_string.rb +20 -0
  257. data/lib/arel/collectors/substitute_binds.rb +28 -0
  258. data/lib/arel/crud.rb +42 -0
  259. data/lib/arel/delete_manager.rb +18 -0
  260. data/lib/arel/errors.rb +9 -0
  261. data/lib/arel/expressions.rb +29 -0
  262. data/lib/arel/factory_methods.rb +49 -0
  263. data/lib/arel/insert_manager.rb +49 -0
  264. data/lib/arel/math.rb +45 -0
  265. data/lib/arel/nodes/and.rb +32 -0
  266. data/lib/arel/nodes/ascending.rb +23 -0
  267. data/lib/arel/nodes/binary.rb +52 -0
  268. data/lib/arel/nodes/bind_param.rb +36 -0
  269. data/lib/arel/nodes/case.rb +55 -0
  270. data/lib/arel/nodes/casted.rb +50 -0
  271. data/lib/arel/nodes/comment.rb +29 -0
  272. data/lib/arel/nodes/count.rb +12 -0
  273. data/lib/arel/nodes/delete_statement.rb +45 -0
  274. data/lib/arel/nodes/descending.rb +23 -0
  275. data/lib/arel/nodes/equality.rb +18 -0
  276. data/lib/arel/nodes/extract.rb +24 -0
  277. data/lib/arel/nodes/false.rb +16 -0
  278. data/lib/arel/nodes/full_outer_join.rb +8 -0
  279. data/lib/arel/nodes/function.rb +44 -0
  280. data/lib/arel/nodes/grouping.rb +8 -0
  281. data/lib/arel/nodes/in.rb +8 -0
  282. data/lib/arel/nodes/infix_operation.rb +80 -0
  283. data/lib/arel/nodes/inner_join.rb +8 -0
  284. data/lib/arel/nodes/insert_statement.rb +37 -0
  285. data/lib/arel/nodes/join_source.rb +20 -0
  286. data/lib/arel/nodes/matches.rb +18 -0
  287. data/lib/arel/nodes/named_function.rb +23 -0
  288. data/lib/arel/nodes/node.rb +50 -0
  289. data/lib/arel/nodes/node_expression.rb +13 -0
  290. data/lib/arel/nodes/outer_join.rb +8 -0
  291. data/lib/arel/nodes/over.rb +15 -0
  292. data/lib/arel/nodes/regexp.rb +16 -0
  293. data/lib/arel/nodes/right_outer_join.rb +8 -0
  294. data/lib/arel/nodes/select_core.rb +67 -0
  295. data/lib/arel/nodes/select_statement.rb +41 -0
  296. data/lib/arel/nodes/sql_literal.rb +16 -0
  297. data/lib/arel/nodes/string_join.rb +11 -0
  298. data/lib/arel/nodes/table_alias.rb +27 -0
  299. data/lib/arel/nodes/terminal.rb +16 -0
  300. data/lib/arel/nodes/true.rb +16 -0
  301. data/lib/arel/nodes/unary.rb +45 -0
  302. data/lib/arel/nodes/unary_operation.rb +20 -0
  303. data/lib/arel/nodes/unqualified_column.rb +22 -0
  304. data/lib/arel/nodes/update_statement.rb +41 -0
  305. data/lib/arel/nodes/values_list.rb +9 -0
  306. data/lib/arel/nodes/window.rb +126 -0
  307. data/lib/arel/nodes/with.rb +11 -0
  308. data/lib/arel/nodes.rb +68 -0
  309. data/lib/arel/order_predications.rb +13 -0
  310. data/lib/arel/predications.rb +256 -0
  311. data/lib/arel/select_manager.rb +271 -0
  312. data/lib/arel/table.rb +110 -0
  313. data/lib/arel/tree_manager.rb +72 -0
  314. data/lib/arel/update_manager.rb +34 -0
  315. data/lib/arel/visitors/depth_first.rb +203 -0
  316. data/lib/arel/visitors/dot.rb +296 -0
  317. data/lib/arel/visitors/ibm_db.rb +34 -0
  318. data/lib/arel/visitors/informix.rb +62 -0
  319. data/lib/arel/visitors/mssql.rb +156 -0
  320. data/lib/arel/visitors/mysql.rb +83 -0
  321. data/lib/arel/visitors/oracle.rb +158 -0
  322. data/lib/arel/visitors/oracle12.rb +65 -0
  323. data/lib/arel/visitors/postgresql.rb +109 -0
  324. data/lib/arel/visitors/sqlite.rb +38 -0
  325. data/lib/arel/visitors/to_sql.rb +888 -0
  326. data/lib/arel/visitors/visitor.rb +45 -0
  327. data/lib/arel/visitors/where_sql.rb +22 -0
  328. data/lib/arel/visitors.rb +20 -0
  329. data/lib/arel/window_predications.rb +9 -0
  330. data/lib/arel.rb +62 -0
  331. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +26 -0
  332. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
  333. data/lib/rails/generators/active_record/migration/migration_generator.rb +42 -37
  334. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +24 -0
  335. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +11 -8
  336. data/lib/rails/generators/active_record/migration.rb +30 -1
  337. data/lib/rails/generators/active_record/model/model_generator.rb +18 -22
  338. data/lib/rails/generators/active_record/model/templates/model.rb.tt +22 -0
  339. data/lib/rails/generators/active_record.rb +7 -5
  340. metadata +174 -63
  341. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  342. data/lib/active_record/associations/preloader/collection_association.rb +0 -24
  343. data/lib/active_record/associations/preloader/has_many.rb +0 -17
  344. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  345. data/lib/active_record/associations/preloader/has_one.rb +0 -23
  346. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  347. data/lib/active_record/associations/preloader/singular_association.rb +0 -21
  348. data/lib/active_record/attribute.rb +0 -149
  349. data/lib/active_record/attribute_set/builder.rb +0 -86
  350. data/lib/active_record/attribute_set.rb +0 -77
  351. data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -491
  352. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
  353. data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
  354. data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +0 -11
  355. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -35
  356. data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
  357. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  358. data/lib/active_record/serializers/xml_serializer.rb +0 -193
  359. data/lib/active_record/type/big_integer.rb +0 -13
  360. data/lib/active_record/type/binary.rb +0 -50
  361. data/lib/active_record/type/boolean.rb +0 -30
  362. data/lib/active_record/type/decimal.rb +0 -40
  363. data/lib/active_record/type/decorator.rb +0 -14
  364. data/lib/active_record/type/float.rb +0 -19
  365. data/lib/active_record/type/integer.rb +0 -55
  366. data/lib/active_record/type/mutable.rb +0 -16
  367. data/lib/active_record/type/numeric.rb +0 -36
  368. data/lib/active_record/type/string.rb +0 -36
  369. data/lib/active_record/type/time_value.rb +0 -38
  370. data/lib/active_record/type/value.rb +0 -101
  371. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +0 -22
  372. data/lib/rails/generators/active_record/model/templates/model.rb +0 -10
  373. /data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
@@ -1,14 +1,16 @@
1
- require 'active_support/core_ext/string/filters'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_record/database_configurations"
2
4
 
3
5
  module ActiveRecord
4
6
  module Tasks # :nodoc:
5
7
  class DatabaseAlreadyExists < StandardError; end # :nodoc:
6
8
  class DatabaseNotSupported < StandardError; end # :nodoc:
7
9
 
8
- # <tt>ActiveRecord::Tasks::DatabaseTasks</tt> is a utility class, which encapsulates
10
+ # ActiveRecord::Tasks::DatabaseTasks is a utility class, which encapsulates
9
11
  # logic behind common tasks used to manage database and migrations.
10
12
  #
11
- # The tasks defined here are used with Rake tasks provided by Active Record.
13
+ # The tasks defined here are used with Rails commands provided by Active Record.
12
14
  #
13
15
  # In order to use DatabaseTasks, a few config values need to be set. All the needed
14
16
  # config values are set by Rails already, so it's necessary to do it only if you
@@ -18,15 +20,15 @@ module ActiveRecord
18
20
  #
19
21
  # The possible config values are:
20
22
  #
21
- # * +env+: current environment (like Rails.env).
22
- # * +database_configuration+: configuration of your databases (as in +config/database.yml+).
23
- # * +db_dir+: your +db+ directory.
24
- # * +fixtures_path+: a path to fixtures directory.
25
- # * +migrations_paths+: a list of paths to directories with migrations.
26
- # * +seed_loader+: an object which will load seeds, it needs to respond to the +load_seed+ method.
27
- # * +root+: a path to the root of the application.
23
+ # * +env+: current environment (like Rails.env).
24
+ # * +database_configuration+: configuration of your databases (as in +config/database.yml+).
25
+ # * +db_dir+: your +db+ directory.
26
+ # * +fixtures_path+: a path to fixtures directory.
27
+ # * +migrations_paths+: a list of paths to directories with migrations.
28
+ # * +seed_loader+: an object which will load seeds, it needs to respond to the +load_seed+ method.
29
+ # * +root+: a path to the root of the application.
28
30
  #
29
- # Example usage of +DatabaseTasks+ outside Rails could look as such:
31
+ # Example usage of DatabaseTasks outside Rails could look as such:
30
32
  #
31
33
  # include ActiveRecord::Tasks
32
34
  # DatabaseTasks.database_configuration = YAML.load_file('my_database_config.yml')
@@ -35,36 +37,62 @@ module ActiveRecord
35
37
  #
36
38
  # DatabaseTasks.create_current('production')
37
39
  module DatabaseTasks
40
+ ##
41
+ # :singleton-method:
42
+ # Extra flags passed to database CLI tool (mysqldump/pg_dump) when calling db:structure:dump
43
+ mattr_accessor :structure_dump_flags, instance_accessor: false
44
+
45
+ ##
46
+ # :singleton-method:
47
+ # Extra flags passed to database CLI tool when calling db:structure:load
48
+ mattr_accessor :structure_load_flags, instance_accessor: false
49
+
38
50
  extend self
39
51
 
40
52
  attr_writer :current_config, :db_dir, :migrations_paths, :fixtures_path, :root, :env, :seed_loader
41
53
  attr_accessor :database_configuration
42
54
 
43
- LOCAL_HOSTS = ['127.0.0.1', 'localhost']
55
+ LOCAL_HOSTS = ["127.0.0.1", "localhost"]
56
+
57
+ def check_protected_environments!
58
+ unless ENV["DISABLE_DATABASE_ENVIRONMENT_CHECK"]
59
+ current = ActiveRecord::Base.connection.migration_context.current_environment
60
+ stored = ActiveRecord::Base.connection.migration_context.last_stored_environment
61
+
62
+ if ActiveRecord::Base.connection.migration_context.protected_environment?
63
+ raise ActiveRecord::ProtectedEnvironmentError.new(stored)
64
+ end
65
+
66
+ if stored && stored != current
67
+ raise ActiveRecord::EnvironmentMismatchError.new(current: current, stored: stored)
68
+ end
69
+ end
70
+ rescue ActiveRecord::NoDatabaseError
71
+ end
44
72
 
45
73
  def register_task(pattern, task)
46
74
  @tasks ||= {}
47
75
  @tasks[pattern] = task
48
76
  end
49
77
 
50
- register_task(/mysql/, ActiveRecord::Tasks::MySQLDatabaseTasks)
51
- register_task(/postgresql/, ActiveRecord::Tasks::PostgreSQLDatabaseTasks)
52
- register_task(/sqlite/, ActiveRecord::Tasks::SQLiteDatabaseTasks)
78
+ register_task(/mysql/, "ActiveRecord::Tasks::MySQLDatabaseTasks")
79
+ register_task(/postgresql/, "ActiveRecord::Tasks::PostgreSQLDatabaseTasks")
80
+ register_task(/sqlite/, "ActiveRecord::Tasks::SQLiteDatabaseTasks")
53
81
 
54
82
  def db_dir
55
83
  @db_dir ||= Rails.application.config.paths["db"].first
56
84
  end
57
85
 
58
86
  def migrations_paths
59
- @migrations_paths ||= Rails.application.paths['db/migrate'].to_a
87
+ @migrations_paths ||= Rails.application.paths["db/migrate"].to_a
60
88
  end
61
89
 
62
90
  def fixtures_path
63
- @fixtures_path ||= if ENV['FIXTURES_PATH']
64
- File.join(root, ENV['FIXTURES_PATH'])
65
- else
66
- File.join(root, 'test', 'fixtures')
67
- end
91
+ @fixtures_path ||= if ENV["FIXTURES_PATH"]
92
+ File.join(root, ENV["FIXTURES_PATH"])
93
+ else
94
+ File.join(root, "test", "fixtures")
95
+ end
68
96
  end
69
97
 
70
98
  def root
@@ -75,35 +103,85 @@ module ActiveRecord
75
103
  @env ||= Rails.env
76
104
  end
77
105
 
106
+ def spec
107
+ @spec ||= "primary"
108
+ end
109
+
78
110
  def seed_loader
79
111
  @seed_loader ||= Rails.application
80
112
  end
81
113
 
82
114
  def current_config(options = {})
83
- options.reverse_merge! :env => env
115
+ options.reverse_merge! env: env
116
+ options[:spec] ||= "primary"
84
117
  if options.has_key?(:config)
85
118
  @current_config = options[:config]
86
119
  else
87
- @current_config ||= ActiveRecord::Base.configurations[options[:env]]
120
+ @current_config ||= ActiveRecord::Base.configurations.configs_for(env_name: options[:env], spec_name: options[:spec]).config
88
121
  end
89
122
  end
90
123
 
91
124
  def create(*arguments)
92
125
  configuration = arguments.first
93
- class_for_adapter(configuration['adapter']).new(*arguments).create
126
+ class_for_adapter(configuration["adapter"]).new(*arguments).create
127
+ $stdout.puts "Created database '#{configuration['database']}'" if verbose?
94
128
  rescue DatabaseAlreadyExists
95
- $stderr.puts "#{configuration['database']} already exists"
129
+ $stderr.puts "Database '#{configuration['database']}' already exists" if verbose?
96
130
  rescue Exception => error
97
- $stderr.puts error, *(error.backtrace)
98
- $stderr.puts "Couldn't create database for #{configuration.inspect}"
131
+ $stderr.puts error
132
+ $stderr.puts "Couldn't create '#{configuration['database']}' database. Please check your configuration."
133
+ raise
99
134
  end
100
135
 
101
136
  def create_all
137
+ old_pool = ActiveRecord::Base.connection_handler.retrieve_connection_pool(ActiveRecord::Base.connection_specification_name)
102
138
  each_local_configuration { |configuration| create configuration }
139
+ if old_pool
140
+ ActiveRecord::Base.connection_handler.establish_connection(old_pool.spec.to_hash)
141
+ end
103
142
  end
104
143
 
105
- def create_current(environment = env)
106
- each_current_configuration(environment) { |configuration|
144
+ def setup_initial_database_yaml
145
+ return {} unless defined?(Rails)
146
+
147
+ begin
148
+ Rails.application.config.load_database_yaml
149
+ rescue
150
+ $stderr.puts "Rails couldn't infer whether you are using multiple databases from your database.yml and can't generate the tasks for the non-primary databases. If you'd like to use this feature, please simplify your ERB."
151
+
152
+ {}
153
+ end
154
+ end
155
+
156
+ def for_each(databases)
157
+ return {} unless defined?(Rails)
158
+
159
+ database_configs = ActiveRecord::DatabaseConfigurations.new(databases).configs_for(env_name: Rails.env)
160
+
161
+ # if this is a single database application we don't want tasks for each primary database
162
+ return if database_configs.count == 1
163
+
164
+ database_configs.each do |db_config|
165
+ yield db_config.spec_name
166
+ end
167
+ end
168
+
169
+ def raise_for_multi_db(environment = env, command:)
170
+ db_configs = ActiveRecord::Base.configurations.configs_for(env_name: environment)
171
+
172
+ if db_configs.count > 1
173
+ dbs_list = []
174
+
175
+ db_configs.each do |db|
176
+ dbs_list << "#{command}:#{db.spec_name}"
177
+ end
178
+
179
+ raise "You're using a multiple database application. To use `#{command}` you must run the namespaced task with a VERSION. Available tasks are #{dbs_list.to_sentence}."
180
+ end
181
+ end
182
+
183
+ def create_current(environment = env, spec_name = nil)
184
+ each_current_configuration(environment, spec_name) { |configuration|
107
185
  create configuration
108
186
  }
109
187
  ActiveRecord::Base.establish_connection(environment.to_sym)
@@ -111,12 +189,14 @@ module ActiveRecord
111
189
 
112
190
  def drop(*arguments)
113
191
  configuration = arguments.first
114
- class_for_adapter(configuration['adapter']).new(*arguments).drop
192
+ class_for_adapter(configuration["adapter"]).new(*arguments).drop
193
+ $stdout.puts "Dropped database '#{configuration['database']}'" if verbose?
115
194
  rescue ActiveRecord::NoDatabaseError
116
195
  $stderr.puts "Database '#{configuration['database']}' does not exist"
117
196
  rescue Exception => error
118
- $stderr.puts error, *(error.backtrace)
119
- $stderr.puts "Couldn't drop #{configuration['database']}"
197
+ $stderr.puts error
198
+ $stderr.puts "Couldn't drop database '#{configuration['database']}'"
199
+ raise
120
200
  end
121
201
 
122
202
  def drop_all
@@ -129,38 +209,86 @@ module ActiveRecord
129
209
  }
130
210
  end
131
211
 
212
+ def truncate_tables(configuration)
213
+ ActiveRecord::Base.connected_to(database: { truncation: configuration }) do
214
+ conn = ActiveRecord::Base.connection
215
+ table_names = conn.tables
216
+ table_names -= [
217
+ conn.schema_migration.table_name,
218
+ InternalMetadata.table_name
219
+ ]
220
+
221
+ ActiveRecord::Base.connection.truncate_tables(*table_names)
222
+ end
223
+ end
224
+ private :truncate_tables
225
+
226
+ def truncate_all(environment = env)
227
+ ActiveRecord::Base.configurations.configs_for(env_name: environment).each do |db_config|
228
+ truncate_tables db_config.config
229
+ end
230
+ end
231
+
132
232
  def migrate
133
- verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true
134
- version = ENV["VERSION"] ? ENV["VERSION"].to_i : nil
135
- scope = ENV['SCOPE']
136
- verbose_was, Migration.verbose = Migration.verbose, verbose
137
- Migrator.migrate(Migrator.migrations_paths, version) do |migration|
233
+ check_target_version
234
+
235
+ scope = ENV["SCOPE"]
236
+ verbose_was, Migration.verbose = Migration.verbose, verbose?
237
+
238
+ Base.connection.migration_context.migrate(target_version) do |migration|
138
239
  scope.blank? || scope == migration.scope
139
240
  end
241
+
242
+ ActiveRecord::Base.clear_cache!
140
243
  ensure
141
244
  Migration.verbose = verbose_was
142
245
  end
143
246
 
144
- def charset_current(environment = env)
145
- charset ActiveRecord::Base.configurations[environment]
247
+ def migrate_status
248
+ unless ActiveRecord::Base.connection.schema_migration.table_exists?
249
+ Kernel.abort "Schema migrations table does not exist yet."
250
+ end
251
+
252
+ # output
253
+ puts "\ndatabase: #{ActiveRecord::Base.connection_config[:database]}\n\n"
254
+ puts "#{'Status'.center(8)} #{'Migration ID'.ljust(14)} Migration Name"
255
+ puts "-" * 50
256
+ ActiveRecord::Base.connection.migration_context.migrations_status.each do |status, version, name|
257
+ puts "#{status.center(8)} #{version.ljust(14)} #{name}"
258
+ end
259
+ puts
260
+ end
261
+
262
+ def check_target_version
263
+ if target_version && !(Migration::MigrationFilenameRegexp.match?(ENV["VERSION"]) || /\A\d+\z/.match?(ENV["VERSION"]))
264
+ raise "Invalid format of target version: `VERSION=#{ENV['VERSION']}`"
265
+ end
266
+ end
267
+
268
+ def target_version
269
+ ENV["VERSION"].to_i if ENV["VERSION"] && !ENV["VERSION"].empty?
270
+ end
271
+
272
+ def charset_current(environment = env, specification_name = spec)
273
+ charset ActiveRecord::Base.configurations.configs_for(env_name: environment, spec_name: specification_name).config
146
274
  end
147
275
 
148
276
  def charset(*arguments)
149
277
  configuration = arguments.first
150
- class_for_adapter(configuration['adapter']).new(*arguments).charset
278
+ class_for_adapter(configuration["adapter"]).new(*arguments).charset
151
279
  end
152
280
 
153
- def collation_current(environment = env)
154
- collation ActiveRecord::Base.configurations[environment]
281
+ def collation_current(environment = env, specification_name = spec)
282
+ collation ActiveRecord::Base.configurations.configs_for(env_name: environment, spec_name: specification_name).config
155
283
  end
156
284
 
157
285
  def collation(*arguments)
158
286
  configuration = arguments.first
159
- class_for_adapter(configuration['adapter']).new(*arguments).collation
287
+ class_for_adapter(configuration["adapter"]).new(*arguments).collation
160
288
  end
161
289
 
162
290
  def purge(configuration)
163
- class_for_adapter(configuration['adapter']).new(configuration).purge
291
+ class_for_adapter(configuration["adapter"]).new(configuration).purge
164
292
  end
165
293
 
166
294
  def purge_all
@@ -179,68 +307,130 @@ module ActiveRecord
179
307
  def structure_dump(*arguments)
180
308
  configuration = arguments.first
181
309
  filename = arguments.delete_at 1
182
- class_for_adapter(configuration['adapter']).new(*arguments).structure_dump(filename)
310
+ class_for_adapter(configuration["adapter"]).new(*arguments).structure_dump(filename, structure_dump_flags)
183
311
  end
184
312
 
185
313
  def structure_load(*arguments)
186
314
  configuration = arguments.first
187
315
  filename = arguments.delete_at 1
188
- class_for_adapter(configuration['adapter']).new(*arguments).structure_load(filename)
316
+ class_for_adapter(configuration["adapter"]).new(*arguments).structure_load(filename, structure_load_flags)
317
+ end
318
+
319
+ def load_schema(configuration, format = ActiveRecord::Base.schema_format, file = nil, environment = env, spec_name = "primary") # :nodoc:
320
+ file ||= dump_filename(spec_name, format)
321
+
322
+ verbose_was, Migration.verbose = Migration.verbose, verbose? && ENV["VERBOSE"]
323
+ check_schema_file(file)
324
+ ActiveRecord::Base.establish_connection(configuration)
325
+
326
+ case format
327
+ when :ruby
328
+ load(file)
329
+ when :sql
330
+ structure_load(configuration, file)
331
+ else
332
+ raise ArgumentError, "unknown format #{format.inspect}"
333
+ end
334
+ ActiveRecord::InternalMetadata.create_table
335
+ ActiveRecord::InternalMetadata[:environment] = environment
336
+ ActiveRecord::InternalMetadata[:schema_sha1] = schema_sha1(file)
337
+ ensure
338
+ Migration.verbose = verbose_was
189
339
  end
190
340
 
191
- def load_schema(format = ActiveRecord::Base.schema_format, file = nil)
192
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
193
- This method will act on a specific connection in the future.
194
- To act on the current connection, use `load_schema_current` instead.
195
- MSG
341
+ def schema_up_to_date?(configuration, format = ActiveRecord::Base.schema_format, file = nil, environment = env, spec_name = "primary")
342
+ file ||= dump_filename(spec_name, format)
343
+
344
+ return true unless File.exist?(file)
196
345
 
197
- load_schema_current(format, file)
346
+ ActiveRecord::Base.establish_connection(configuration)
347
+ return false unless ActiveRecord::InternalMetadata.table_exists?
348
+ ActiveRecord::InternalMetadata[:schema_sha1] == schema_sha1(file)
198
349
  end
199
350
 
200
- def schema_file(format = ActiveSupport::Base.schema_format)
351
+ def reconstruct_from_schema(configuration, format = ActiveRecord::Base.schema_format, file = nil, environment = env, spec_name = "primary") # :nodoc:
352
+ file ||= dump_filename(spec_name, format)
353
+
354
+ check_schema_file(file)
355
+
356
+ ActiveRecord::Base.establish_connection(configuration)
357
+
358
+ if schema_up_to_date?(configuration, format, file, environment, spec_name)
359
+ truncate_tables(configuration)
360
+ else
361
+ purge(configuration)
362
+ load_schema(configuration, format, file, environment, spec_name)
363
+ end
364
+ rescue ActiveRecord::NoDatabaseError
365
+ create(configuration)
366
+ load_schema(configuration, format, file, environment, spec_name)
367
+ end
368
+
369
+ def dump_schema(configuration, format = ActiveRecord::Base.schema_format, spec_name = "primary") # :nodoc:
370
+ require "active_record/schema_dumper"
371
+ filename = dump_filename(spec_name, format)
372
+ connection = ActiveRecord::Base.connection
373
+
201
374
  case format
202
375
  when :ruby
203
- File.join(db_dir, "schema.rb")
376
+ File.open(filename, "w:utf-8") do |file|
377
+ ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file)
378
+ end
204
379
  when :sql
205
- File.join(db_dir, "structure.sql")
380
+ structure_dump(configuration, filename)
381
+ if connection.schema_migration.table_exists?
382
+ File.open(filename, "a") do |f|
383
+ f.puts connection.dump_schema_information
384
+ f.print "\n"
385
+ end
386
+ end
206
387
  end
207
388
  end
208
389
 
209
- # This method is the successor of +load_schema+. We should rename it
210
- # after +load_schema+ went through a deprecation cycle. (Rails > 4.2)
211
- def load_schema_for(configuration, format = ActiveRecord::Base.schema_format, file = nil) # :nodoc:
212
- file ||= schema_file(format)
390
+ def schema_file(format = ActiveRecord::Base.schema_format)
391
+ File.join(db_dir, schema_file_type(format))
392
+ end
213
393
 
394
+ def schema_file_type(format = ActiveRecord::Base.schema_format)
214
395
  case format
215
396
  when :ruby
216
- check_schema_file(file)
217
- ActiveRecord::Base.establish_connection(configuration)
218
- load(file)
397
+ "schema.rb"
219
398
  when :sql
220
- check_schema_file(file)
221
- structure_load(configuration, file)
399
+ "structure.sql"
400
+ end
401
+ end
402
+
403
+ def dump_filename(namespace, format = ActiveRecord::Base.schema_format)
404
+ filename = if namespace == "primary"
405
+ schema_file_type(format)
222
406
  else
223
- raise ArgumentError, "unknown format #{format.inspect}"
407
+ "#{namespace}_#{schema_file_type(format)}"
224
408
  end
409
+
410
+ ENV["SCHEMA"] || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, filename)
225
411
  end
226
412
 
227
- def load_schema_current_if_exists(format = ActiveRecord::Base.schema_format, file = nil, environment = env)
228
- if File.exist?(file || schema_file(format))
229
- load_schema_current(format, file, environment)
413
+ def cache_dump_filename(namespace)
414
+ filename = if namespace == "primary"
415
+ "schema_cache.yml"
416
+ else
417
+ "#{namespace}_schema_cache.yml"
230
418
  end
419
+
420
+ ENV["SCHEMA_CACHE"] || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, filename)
231
421
  end
232
422
 
233
423
  def load_schema_current(format = ActiveRecord::Base.schema_format, file = nil, environment = env)
234
- each_current_configuration(environment) { |configuration|
235
- load_schema_for configuration, format, file
424
+ each_current_configuration(environment) { |configuration, spec_name, env|
425
+ load_schema(configuration, format, file, env, spec_name)
236
426
  }
237
427
  ActiveRecord::Base.establish_connection(environment.to_sym)
238
428
  end
239
429
 
240
430
  def check_schema_file(filename)
241
431
  unless File.exist?(filename)
242
- message = %{#{filename} doesn't exist yet. Run `rake db:migrate` to create it, then try again.}
243
- message << %{ 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.} if defined?(::Rails)
432
+ message = +%{#{filename} doesn't exist yet. Run `rails db:migrate` to create it, then try again.}
433
+ message << %{ 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.} if defined?(::Rails.root)
244
434
  Kernel.abort message
245
435
  end
246
436
  end
@@ -249,48 +439,68 @@ module ActiveRecord
249
439
  if seed_loader
250
440
  seed_loader.load_seed
251
441
  else
252
- raise "You tried to load seed data, but no seed loader is specified. Please specify seed " +
253
- "loader with ActiveRecord::Tasks::DatabaseTasks.seed_loader = your_seed_loader\n" +
442
+ raise "You tried to load seed data, but no seed loader is specified. Please specify seed " \
443
+ "loader with ActiveRecord::Tasks::DatabaseTasks.seed_loader = your_seed_loader\n" \
254
444
  "Seed loader should respond to load_seed method"
255
445
  end
256
446
  end
257
447
 
448
+ # Dumps the schema cache in YAML format for the connection into the file
449
+ #
450
+ # ==== Examples:
451
+ # ActiveRecord::Tasks::DatabaseTasks.dump_schema_cache(ActiveRecord::Base.connection, "tmp/schema_dump.yaml")
452
+ def dump_schema_cache(conn, filename)
453
+ conn.schema_cache.clear!
454
+ conn.data_sources.each { |table| conn.schema_cache.add(table) }
455
+ open(filename, "wb") { |f| f.write(YAML.dump(conn.schema_cache)) }
456
+ end
457
+
258
458
  private
459
+ def verbose?
460
+ ENV["VERBOSE"] ? ENV["VERBOSE"] != "false" : true
461
+ end
259
462
 
260
- def class_for_adapter(adapter)
261
- key = @tasks.keys.detect { |pattern| adapter[pattern] }
262
- unless key
263
- raise DatabaseNotSupported, "Rake tasks not supported by '#{adapter}' adapter"
463
+ def class_for_adapter(adapter)
464
+ _key, task = @tasks.each_pair.detect { |pattern, _task| adapter[pattern] }
465
+ unless task
466
+ raise DatabaseNotSupported, "Rake tasks not supported by '#{adapter}' adapter"
467
+ end
468
+ task.is_a?(String) ? task.constantize : task
264
469
  end
265
- @tasks[key]
266
- end
267
470
 
268
- def each_current_configuration(environment)
269
- environments = [environment]
270
- # add test environment only if no RAILS_ENV was specified.
271
- environments << 'test' if environment == 'development' && ENV['RAILS_ENV'].nil?
471
+ def each_current_configuration(environment, spec_name = nil)
472
+ environments = [environment]
473
+ environments << "test" if environment == "development"
474
+
475
+ environments.each do |env|
476
+ ActiveRecord::Base.configurations.configs_for(env_name: env).each do |db_config|
477
+ next if spec_name && spec_name != db_config.spec_name
272
478
 
273
- configurations = ActiveRecord::Base.configurations.values_at(*environments)
274
- configurations.compact.each do |configuration|
275
- yield configuration unless configuration['database'].blank?
479
+ yield db_config.config, db_config.spec_name, env
480
+ end
481
+ end
276
482
  end
277
- end
278
483
 
279
- def each_local_configuration
280
- ActiveRecord::Base.configurations.each_value do |configuration|
281
- next unless configuration['database']
484
+ def each_local_configuration
485
+ ActiveRecord::Base.configurations.configs_for.each do |db_config|
486
+ configuration = db_config.config
487
+ next unless configuration["database"]
282
488
 
283
- if local_database?(configuration)
284
- yield configuration
285
- else
286
- $stderr.puts "This task only modifies local databases. #{configuration['database']} is on a remote host."
489
+ if local_database?(configuration)
490
+ yield configuration
491
+ else
492
+ $stderr.puts "This task only modifies local databases. #{configuration['database']} is on a remote host."
493
+ end
287
494
  end
288
495
  end
289
- end
290
496
 
291
- def local_database?(configuration)
292
- configuration['host'].blank? || LOCAL_HOSTS.include?(configuration['host'])
293
- end
497
+ def local_database?(configuration)
498
+ configuration["host"].blank? || LOCAL_HOSTS.include?(configuration["host"])
499
+ end
500
+
501
+ def schema_sha1(file)
502
+ Digest::SHA1.hexdigest(File.read(file))
503
+ end
294
504
  end
295
505
  end
296
506
  end