activerecord 4.2.0 → 6.0.0

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

Potentially problematic release.


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

Files changed (372) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +612 -971
  3. data/MIT-LICENSE +4 -2
  4. data/README.rdoc +13 -12
  5. data/examples/performance.rb +33 -32
  6. data/examples/simple.rb +5 -4
  7. data/lib/active_record/aggregations.rb +267 -248
  8. data/lib/active_record/association_relation.rb +24 -6
  9. data/lib/active_record/associations/alias_tracker.rb +29 -35
  10. data/lib/active_record/associations/association.rb +135 -56
  11. data/lib/active_record/associations/association_scope.rb +103 -131
  12. data/lib/active_record/associations/belongs_to_association.rb +67 -54
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
  14. data/lib/active_record/associations/builder/association.rb +27 -40
  15. data/lib/active_record/associations/builder/belongs_to.rb +69 -55
  16. data/lib/active_record/associations/builder/collection_association.rb +10 -29
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +60 -70
  18. data/lib/active_record/associations/builder/has_many.rb +8 -4
  19. data/lib/active_record/associations/builder/has_one.rb +46 -5
  20. data/lib/active_record/associations/builder/singular_association.rb +16 -10
  21. data/lib/active_record/associations/collection_association.rb +138 -274
  22. data/lib/active_record/associations/collection_proxy.rb +252 -151
  23. data/lib/active_record/associations/foreign_association.rb +20 -0
  24. data/lib/active_record/associations/has_many_association.rb +35 -83
  25. data/lib/active_record/associations/has_many_through_association.rb +62 -80
  26. data/lib/active_record/associations/has_one_association.rb +62 -49
  27. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  28. data/lib/active_record/associations/join_dependency/join_association.rb +38 -80
  29. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  30. data/lib/active_record/associations/join_dependency/join_part.rb +14 -14
  31. data/lib/active_record/associations/join_dependency.rb +138 -162
  32. data/lib/active_record/associations/preloader/association.rb +90 -119
  33. data/lib/active_record/associations/preloader/through_association.rb +85 -65
  34. data/lib/active_record/associations/preloader.rb +92 -94
  35. data/lib/active_record/associations/singular_association.rb +18 -45
  36. data/lib/active_record/associations/through_association.rb +48 -23
  37. data/lib/active_record/associations.rb +1737 -1596
  38. data/lib/active_record/attribute_assignment.rb +56 -183
  39. data/lib/active_record/attribute_decorators.rb +39 -15
  40. data/lib/active_record/attribute_methods/before_type_cast.rb +15 -5
  41. data/lib/active_record/attribute_methods/dirty.rb +174 -134
  42. data/lib/active_record/attribute_methods/primary_key.rb +91 -83
  43. data/lib/active_record/attribute_methods/query.rb +6 -5
  44. data/lib/active_record/attribute_methods/read.rb +20 -76
  45. data/lib/active_record/attribute_methods/serialization.rb +40 -20
  46. data/lib/active_record/attribute_methods/time_zone_conversion.rb +62 -36
  47. data/lib/active_record/attribute_methods/write.rb +33 -55
  48. data/lib/active_record/attribute_methods.rb +124 -143
  49. data/lib/active_record/attributes.rb +214 -74
  50. data/lib/active_record/autosave_association.rb +115 -46
  51. data/lib/active_record/base.rb +60 -49
  52. data/lib/active_record/callbacks.rb +100 -74
  53. data/lib/active_record/coders/json.rb +3 -1
  54. data/lib/active_record/coders/yaml_column.rb +24 -12
  55. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +796 -290
  56. data/lib/active_record/connection_adapters/abstract/database_limits.rb +26 -8
  57. data/lib/active_record/connection_adapters/abstract/database_statements.rb +247 -108
  58. data/lib/active_record/connection_adapters/abstract/query_cache.rb +82 -23
  59. data/lib/active_record/connection_adapters/abstract/quoting.rb +171 -53
  60. data/lib/active_record/connection_adapters/abstract/savepoints.rb +6 -4
  61. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +74 -46
  62. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +366 -227
  63. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +79 -36
  64. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +706 -222
  65. data/lib/active_record/connection_adapters/abstract/transaction.rb +191 -87
  66. data/lib/active_record/connection_adapters/abstract_adapter.rb +468 -194
  67. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +535 -597
  68. data/lib/active_record/connection_adapters/column.rb +56 -43
  69. data/lib/active_record/connection_adapters/connection_specification.rb +174 -152
  70. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +29 -0
  71. data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
  72. data/lib/active_record/connection_adapters/mysql/database_statements.rb +200 -0
  73. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +72 -0
  74. data/lib/active_record/connection_adapters/mysql/quoting.rb +81 -0
  75. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +72 -0
  76. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +95 -0
  77. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +88 -0
  78. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +264 -0
  79. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +31 -0
  80. data/lib/active_record/connection_adapters/mysql2_adapter.rb +59 -195
  81. data/lib/active_record/connection_adapters/postgresql/column.rb +21 -11
  82. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +65 -115
  83. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
  84. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +50 -57
  85. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +9 -8
  86. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  87. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +5 -2
  88. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +5 -1
  89. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +13 -1
  90. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +9 -13
  91. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  92. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +7 -3
  93. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +31 -19
  94. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  95. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  96. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +45 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -9
  98. data/lib/active_record/connection_adapters/postgresql/oid/{integer.rb → oid.rb} +6 -2
  99. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +33 -11
  100. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +52 -34
  101. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
  102. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +67 -51
  103. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +10 -5
  104. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +3 -1
  105. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +3 -1
  106. data/lib/active_record/connection_adapters/postgresql/oid.rb +23 -25
  107. data/lib/active_record/connection_adapters/postgresql/quoting.rb +144 -47
  108. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +27 -14
  109. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
  110. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +178 -108
  111. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +50 -0
  112. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +474 -286
  113. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +36 -0
  114. data/lib/active_record/connection_adapters/postgresql/utils.rb +12 -8
  115. data/lib/active_record/connection_adapters/postgresql_adapter.rb +558 -363
  116. data/lib/active_record/connection_adapters/schema_cache.rb +72 -25
  117. data/lib/active_record/connection_adapters/sql_type_metadata.rb +37 -0
  118. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +118 -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 +103 -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 +137 -0
  125. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +288 -359
  126. data/lib/active_record/connection_adapters/statement_pool.rb +34 -13
  127. data/lib/active_record/connection_handling.rb +176 -41
  128. data/lib/active_record/core.rb +266 -233
  129. data/lib/active_record/counter_cache.rb +68 -50
  130. data/lib/active_record/database_configurations/database_config.rb +37 -0
  131. data/lib/active_record/database_configurations/hash_config.rb +50 -0
  132. data/lib/active_record/database_configurations/url_config.rb +79 -0
  133. data/lib/active_record/database_configurations.rb +233 -0
  134. data/lib/active_record/define_callbacks.rb +22 -0
  135. data/lib/active_record/dynamic_matchers.rb +87 -105
  136. data/lib/active_record/enum.rb +164 -88
  137. data/lib/active_record/errors.rb +189 -53
  138. data/lib/active_record/explain.rb +23 -11
  139. data/lib/active_record/explain_registry.rb +4 -2
  140. data/lib/active_record/explain_subscriber.rb +11 -6
  141. data/lib/active_record/fixture_set/file.rb +35 -9
  142. data/lib/active_record/fixture_set/model_metadata.rb +33 -0
  143. data/lib/active_record/fixture_set/render_context.rb +17 -0
  144. data/lib/active_record/fixture_set/table_row.rb +153 -0
  145. data/lib/active_record/fixture_set/table_rows.rb +47 -0
  146. data/lib/active_record/fixtures.rb +226 -495
  147. data/lib/active_record/gem_version.rb +4 -2
  148. data/lib/active_record/inheritance.rb +158 -112
  149. data/lib/active_record/insert_all.rb +179 -0
  150. data/lib/active_record/integration.rb +123 -29
  151. data/lib/active_record/internal_metadata.rb +53 -0
  152. data/lib/active_record/legacy_yaml_adapter.rb +48 -0
  153. data/lib/active_record/locale/en.yml +3 -2
  154. data/lib/active_record/locking/optimistic.rb +91 -98
  155. data/lib/active_record/locking/pessimistic.rb +18 -6
  156. data/lib/active_record/log_subscriber.rb +76 -33
  157. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  158. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  159. data/lib/active_record/middleware/database_selector.rb +75 -0
  160. data/lib/active_record/migration/command_recorder.rb +177 -90
  161. data/lib/active_record/migration/compatibility.rb +244 -0
  162. data/lib/active_record/migration/join_table.rb +8 -6
  163. data/lib/active_record/migration.rb +634 -288
  164. data/lib/active_record/model_schema.rb +314 -112
  165. data/lib/active_record/nested_attributes.rb +266 -214
  166. data/lib/active_record/no_touching.rb +15 -2
  167. data/lib/active_record/null_relation.rb +24 -37
  168. data/lib/active_record/persistence.rb +559 -124
  169. data/lib/active_record/query_cache.rb +19 -23
  170. data/lib/active_record/querying.rb +43 -29
  171. data/lib/active_record/railtie.rb +148 -47
  172. data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
  173. data/lib/active_record/railties/console_sandbox.rb +2 -0
  174. data/lib/active_record/railties/controller_runtime.rb +34 -33
  175. data/lib/active_record/railties/databases.rake +338 -202
  176. data/lib/active_record/readonly_attributes.rb +5 -4
  177. data/lib/active_record/reflection.rb +460 -299
  178. data/lib/active_record/relation/batches/batch_enumerator.rb +69 -0
  179. data/lib/active_record/relation/batches.rb +207 -55
  180. data/lib/active_record/relation/calculations.rb +269 -248
  181. data/lib/active_record/relation/delegation.rb +70 -80
  182. data/lib/active_record/relation/finder_methods.rb +279 -255
  183. data/lib/active_record/relation/from_clause.rb +26 -0
  184. data/lib/active_record/relation/merger.rb +83 -69
  185. data/lib/active_record/relation/predicate_builder/array_handler.rb +27 -25
  186. data/lib/active_record/relation/predicate_builder/association_query_value.rb +43 -0
  187. data/lib/active_record/relation/predicate_builder/base_handler.rb +18 -0
  188. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +19 -0
  189. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +53 -0
  190. data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -0
  191. data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
  192. data/lib/active_record/relation/predicate_builder.rb +116 -92
  193. data/lib/active_record/relation/query_attribute.rb +50 -0
  194. data/lib/active_record/relation/query_methods.rb +574 -391
  195. data/lib/active_record/relation/record_fetch_warning.rb +51 -0
  196. data/lib/active_record/relation/spawn_methods.rb +18 -16
  197. data/lib/active_record/relation/where_clause.rb +190 -0
  198. data/lib/active_record/relation/where_clause_factory.rb +33 -0
  199. data/lib/active_record/relation.rb +518 -340
  200. data/lib/active_record/result.rb +79 -42
  201. data/lib/active_record/runtime_registry.rb +6 -4
  202. data/lib/active_record/sanitization.rb +144 -121
  203. data/lib/active_record/schema.rb +21 -24
  204. data/lib/active_record/schema_dumper.rb +112 -93
  205. data/lib/active_record/schema_migration.rb +24 -20
  206. data/lib/active_record/scoping/default.rb +101 -84
  207. data/lib/active_record/scoping/named.rb +86 -33
  208. data/lib/active_record/scoping.rb +45 -26
  209. data/lib/active_record/secure_token.rb +40 -0
  210. data/lib/active_record/serialization.rb +5 -5
  211. data/lib/active_record/statement_cache.rb +73 -36
  212. data/lib/active_record/store.rb +127 -42
  213. data/lib/active_record/suppressor.rb +61 -0
  214. data/lib/active_record/table_metadata.rb +75 -0
  215. data/lib/active_record/tasks/database_tasks.rb +309 -99
  216. data/lib/active_record/tasks/mysql_database_tasks.rb +58 -88
  217. data/lib/active_record/tasks/postgresql_database_tasks.rb +82 -31
  218. data/lib/active_record/tasks/sqlite_database_tasks.rb +38 -16
  219. data/lib/active_record/test_databases.rb +23 -0
  220. data/lib/active_record/test_fixtures.rb +224 -0
  221. data/lib/active_record/timestamp.rb +86 -40
  222. data/lib/active_record/touch_later.rb +66 -0
  223. data/lib/active_record/transactions.rb +215 -139
  224. data/lib/active_record/translation.rb +3 -1
  225. data/lib/active_record/type/adapter_specific_registry.rb +129 -0
  226. data/lib/active_record/type/date.rb +4 -41
  227. data/lib/active_record/type/date_time.rb +4 -38
  228. data/lib/active_record/type/decimal_without_scale.rb +6 -2
  229. data/lib/active_record/type/hash_lookup_type_map.rb +13 -5
  230. data/lib/active_record/type/internal/timezone.rb +17 -0
  231. data/lib/active_record/type/json.rb +30 -0
  232. data/lib/active_record/type/serialized.rb +30 -15
  233. data/lib/active_record/type/text.rb +2 -2
  234. data/lib/active_record/type/time.rb +11 -16
  235. data/lib/active_record/type/type_map.rb +15 -17
  236. data/lib/active_record/type/unsigned_integer.rb +9 -7
  237. data/lib/active_record/type.rb +78 -23
  238. data/lib/active_record/type_caster/connection.rb +34 -0
  239. data/lib/active_record/type_caster/map.rb +20 -0
  240. data/lib/active_record/type_caster.rb +9 -0
  241. data/lib/active_record/validations/absence.rb +25 -0
  242. data/lib/active_record/validations/associated.rb +13 -4
  243. data/lib/active_record/validations/length.rb +26 -0
  244. data/lib/active_record/validations/presence.rb +14 -13
  245. data/lib/active_record/validations/uniqueness.rb +43 -46
  246. data/lib/active_record/validations.rb +39 -35
  247. data/lib/active_record/version.rb +3 -1
  248. data/lib/active_record.rb +43 -21
  249. data/lib/arel/alias_predication.rb +9 -0
  250. data/lib/arel/attributes/attribute.rb +37 -0
  251. data/lib/arel/attributes.rb +22 -0
  252. data/lib/arel/collectors/bind.rb +24 -0
  253. data/lib/arel/collectors/composite.rb +31 -0
  254. data/lib/arel/collectors/plain_string.rb +20 -0
  255. data/lib/arel/collectors/sql_string.rb +20 -0
  256. data/lib/arel/collectors/substitute_binds.rb +28 -0
  257. data/lib/arel/crud.rb +42 -0
  258. data/lib/arel/delete_manager.rb +18 -0
  259. data/lib/arel/errors.rb +9 -0
  260. data/lib/arel/expressions.rb +29 -0
  261. data/lib/arel/factory_methods.rb +49 -0
  262. data/lib/arel/insert_manager.rb +49 -0
  263. data/lib/arel/math.rb +45 -0
  264. data/lib/arel/nodes/and.rb +32 -0
  265. data/lib/arel/nodes/ascending.rb +23 -0
  266. data/lib/arel/nodes/binary.rb +52 -0
  267. data/lib/arel/nodes/bind_param.rb +36 -0
  268. data/lib/arel/nodes/case.rb +55 -0
  269. data/lib/arel/nodes/casted.rb +50 -0
  270. data/lib/arel/nodes/comment.rb +29 -0
  271. data/lib/arel/nodes/count.rb +12 -0
  272. data/lib/arel/nodes/delete_statement.rb +45 -0
  273. data/lib/arel/nodes/descending.rb +23 -0
  274. data/lib/arel/nodes/equality.rb +18 -0
  275. data/lib/arel/nodes/extract.rb +24 -0
  276. data/lib/arel/nodes/false.rb +16 -0
  277. data/lib/arel/nodes/full_outer_join.rb +8 -0
  278. data/lib/arel/nodes/function.rb +44 -0
  279. data/lib/arel/nodes/grouping.rb +8 -0
  280. data/lib/arel/nodes/in.rb +8 -0
  281. data/lib/arel/nodes/infix_operation.rb +80 -0
  282. data/lib/arel/nodes/inner_join.rb +8 -0
  283. data/lib/arel/nodes/insert_statement.rb +37 -0
  284. data/lib/arel/nodes/join_source.rb +20 -0
  285. data/lib/arel/nodes/matches.rb +18 -0
  286. data/lib/arel/nodes/named_function.rb +23 -0
  287. data/lib/arel/nodes/node.rb +50 -0
  288. data/lib/arel/nodes/node_expression.rb +13 -0
  289. data/lib/arel/nodes/outer_join.rb +8 -0
  290. data/lib/arel/nodes/over.rb +15 -0
  291. data/lib/arel/nodes/regexp.rb +16 -0
  292. data/lib/arel/nodes/right_outer_join.rb +8 -0
  293. data/lib/arel/nodes/select_core.rb +67 -0
  294. data/lib/arel/nodes/select_statement.rb +41 -0
  295. data/lib/arel/nodes/sql_literal.rb +16 -0
  296. data/lib/arel/nodes/string_join.rb +11 -0
  297. data/lib/arel/nodes/table_alias.rb +27 -0
  298. data/lib/arel/nodes/terminal.rb +16 -0
  299. data/lib/arel/nodes/true.rb +16 -0
  300. data/lib/arel/nodes/unary.rb +45 -0
  301. data/lib/arel/nodes/unary_operation.rb +20 -0
  302. data/lib/arel/nodes/unqualified_column.rb +22 -0
  303. data/lib/arel/nodes/update_statement.rb +41 -0
  304. data/lib/arel/nodes/values_list.rb +9 -0
  305. data/lib/arel/nodes/window.rb +126 -0
  306. data/lib/arel/nodes/with.rb +11 -0
  307. data/lib/arel/nodes.rb +68 -0
  308. data/lib/arel/order_predications.rb +13 -0
  309. data/lib/arel/predications.rb +257 -0
  310. data/lib/arel/select_manager.rb +271 -0
  311. data/lib/arel/table.rb +110 -0
  312. data/lib/arel/tree_manager.rb +72 -0
  313. data/lib/arel/update_manager.rb +34 -0
  314. data/lib/arel/visitors/depth_first.rb +204 -0
  315. data/lib/arel/visitors/dot.rb +297 -0
  316. data/lib/arel/visitors/ibm_db.rb +34 -0
  317. data/lib/arel/visitors/informix.rb +62 -0
  318. data/lib/arel/visitors/mssql.rb +157 -0
  319. data/lib/arel/visitors/mysql.rb +83 -0
  320. data/lib/arel/visitors/oracle.rb +159 -0
  321. data/lib/arel/visitors/oracle12.rb +66 -0
  322. data/lib/arel/visitors/postgresql.rb +110 -0
  323. data/lib/arel/visitors/sqlite.rb +39 -0
  324. data/lib/arel/visitors/to_sql.rb +889 -0
  325. data/lib/arel/visitors/visitor.rb +46 -0
  326. data/lib/arel/visitors/where_sql.rb +23 -0
  327. data/lib/arel/visitors.rb +20 -0
  328. data/lib/arel/window_predications.rb +9 -0
  329. data/lib/arel.rb +51 -0
  330. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
  331. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
  332. data/lib/rails/generators/active_record/migration/migration_generator.rb +42 -37
  333. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +24 -0
  334. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +11 -8
  335. data/lib/rails/generators/active_record/migration.rb +31 -1
  336. data/lib/rails/generators/active_record/model/model_generator.rb +19 -22
  337. data/lib/rails/generators/active_record/model/templates/model.rb.tt +22 -0
  338. data/lib/rails/generators/active_record.rb +7 -5
  339. metadata +166 -60
  340. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  341. data/lib/active_record/associations/preloader/collection_association.rb +0 -24
  342. data/lib/active_record/associations/preloader/has_many.rb +0 -17
  343. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  344. data/lib/active_record/associations/preloader/has_one.rb +0 -23
  345. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  346. data/lib/active_record/associations/preloader/singular_association.rb +0 -21
  347. data/lib/active_record/attribute.rb +0 -149
  348. data/lib/active_record/attribute_set/builder.rb +0 -86
  349. data/lib/active_record/attribute_set.rb +0 -77
  350. data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -491
  351. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
  352. data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
  353. data/lib/active_record/connection_adapters/postgresql/oid/infinity.rb +0 -13
  354. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -35
  355. data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
  356. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  357. data/lib/active_record/serializers/xml_serializer.rb +0 -193
  358. data/lib/active_record/type/big_integer.rb +0 -13
  359. data/lib/active_record/type/binary.rb +0 -50
  360. data/lib/active_record/type/boolean.rb +0 -30
  361. data/lib/active_record/type/decimal.rb +0 -40
  362. data/lib/active_record/type/decorator.rb +0 -14
  363. data/lib/active_record/type/float.rb +0 -19
  364. data/lib/active_record/type/integer.rb +0 -55
  365. data/lib/active_record/type/mutable.rb +0 -16
  366. data/lib/active_record/type/numeric.rb +0 -36
  367. data/lib/active_record/type/string.rb +0 -36
  368. data/lib/active_record/type/time_value.rb +0 -38
  369. data/lib/active_record/type/value.rb +0 -101
  370. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +0 -22
  371. data/lib/rails/generators/active_record/model/templates/model.rb +0 -10
  372. /data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
@@ -1,9 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module Tasks # :nodoc:
3
5
  class MySQLDatabaseTasks # :nodoc:
4
- DEFAULT_CHARSET = ENV['CHARSET'] || 'utf8'
5
- DEFAULT_COLLATION = ENV['COLLATION'] || 'utf8_unicode_ci'
6
- ACCESS_DENIED_ERROR = 1045
6
+ ER_DB_CREATE_EXISTS = 1007
7
7
 
8
8
  delegate :connection, :establish_connection, to: ActiveRecord::Base
9
9
 
@@ -13,38 +13,24 @@ module ActiveRecord
13
13
 
14
14
  def create
15
15
  establish_connection configuration_without_database
16
- connection.create_database configuration['database'], creation_options
16
+ connection.create_database configuration["database"], creation_options
17
17
  establish_connection configuration
18
18
  rescue ActiveRecord::StatementInvalid => error
19
- if /database exists/ === error.message
19
+ if connection.error_number(error.cause) == ER_DB_CREATE_EXISTS
20
20
  raise DatabaseAlreadyExists
21
21
  else
22
22
  raise
23
23
  end
24
- rescue error_class => error
25
- if error.respond_to?(:errno) && error.errno == ACCESS_DENIED_ERROR
26
- $stdout.print error.error
27
- establish_connection root_configuration_without_database
28
- connection.create_database configuration['database'], creation_options
29
- if configuration['username'] != 'root'
30
- connection.execute grant_statement.gsub(/\s+/, ' ').strip
31
- end
32
- establish_connection configuration
33
- else
34
- $stderr.puts error.inspect
35
- $stderr.puts "Couldn't create database for #{configuration.inspect}, #{creation_options.inspect}"
36
- $stderr.puts "(If you set the charset manually, make sure you have a matching collation)" if configuration['encoding']
37
- end
38
24
  end
39
25
 
40
26
  def drop
41
27
  establish_connection configuration
42
- connection.drop_database configuration['database']
28
+ connection.drop_database configuration["database"]
43
29
  end
44
30
 
45
31
  def purge
46
32
  establish_connection configuration
47
- connection.recreate_database configuration['database'], creation_options
33
+ connection.recreate_database configuration["database"], creation_options
48
34
  end
49
35
 
50
36
  def charset
@@ -55,91 +41,75 @@ module ActiveRecord
55
41
  connection.collation
56
42
  end
57
43
 
58
- def structure_dump(filename)
59
- args = prepare_command_options('mysqldump')
44
+ def structure_dump(filename, extra_flags)
45
+ args = prepare_command_options
60
46
  args.concat(["--result-file", "#{filename}"])
61
47
  args.concat(["--no-data"])
62
- args.concat(["#{configuration['database']}"])
63
- unless Kernel.system(*args)
64
- $stderr.puts "Could not dump the database structure. "\
65
- "Make sure `mysqldump` is in your PATH and check the command output for warnings."
66
- end
67
- end
48
+ args.concat(["--routines"])
49
+ args.concat(["--skip-comments"])
68
50
 
69
- def structure_load(filename)
70
- args = prepare_command_options('mysql')
71
- args.concat(['--execute', %{SET FOREIGN_KEY_CHECKS = 0; SOURCE #{filename}; SET FOREIGN_KEY_CHECKS = 1}])
72
- args.concat(["--database", "#{configuration['database']}"])
73
- Kernel.system(*args)
74
- end
51
+ ignore_tables = ActiveRecord::SchemaDumper.ignore_tables
52
+ if ignore_tables.any?
53
+ args += ignore_tables.map { |table| "--ignore-table=#{configuration['database']}.#{table}" }
54
+ end
75
55
 
76
- private
56
+ args.concat(["#{configuration['database']}"])
57
+ args.unshift(*extra_flags) if extra_flags
77
58
 
78
- def configuration
79
- @configuration
59
+ run_cmd("mysqldump", args, "dumping")
80
60
  end
81
61
 
82
- def configuration_without_database
83
- configuration.merge('database' => nil)
62
+ def structure_load(filename, extra_flags)
63
+ args = prepare_command_options
64
+ args.concat(["--execute", %{SET FOREIGN_KEY_CHECKS = 0; SOURCE #{filename}; SET FOREIGN_KEY_CHECKS = 1}])
65
+ args.concat(["--database", "#{configuration['database']}"])
66
+ args.unshift(*extra_flags) if extra_flags
67
+
68
+ run_cmd("mysql", args, "loading")
84
69
  end
85
70
 
86
- def creation_options
87
- Hash.new.tap do |options|
88
- options[:charset] = configuration['encoding'] if configuration.include? 'encoding'
89
- options[:collation] = configuration['collation'] if configuration.include? 'collation'
71
+ private
90
72
 
91
- # Set default charset only when collation isn't set.
92
- options[:charset] ||= DEFAULT_CHARSET unless options[:collation]
73
+ attr_reader :configuration
93
74
 
94
- # Set default collation only when charset is also default.
95
- options[:collation] ||= DEFAULT_COLLATION if options[:charset] == DEFAULT_CHARSET
75
+ def configuration_without_database
76
+ configuration.merge("database" => nil)
96
77
  end
97
- end
98
78
 
99
- def error_class
100
- if configuration['adapter'] =~ /jdbc/
101
- require 'active_record/railties/jdbcmysql_error'
102
- ArJdbcMySQL::Error
103
- elsif defined?(Mysql2)
104
- Mysql2::Error
105
- elsif defined?(Mysql)
106
- Mysql::Error
107
- else
108
- StandardError
79
+ def creation_options
80
+ Hash.new.tap do |options|
81
+ options[:charset] = configuration["encoding"] if configuration.include? "encoding"
82
+ options[:collation] = configuration["collation"] if configuration.include? "collation"
83
+ end
109
84
  end
110
- end
111
-
112
- def grant_statement
113
- <<-SQL
114
- GRANT ALL PRIVILEGES ON #{configuration['database']}.*
115
- TO '#{configuration['username']}'@'localhost'
116
- IDENTIFIED BY '#{configuration['password']}' WITH GRANT OPTION;
117
- SQL
118
- end
119
85
 
120
- def root_configuration_without_database
121
- configuration_without_database.merge(
122
- 'username' => 'root',
123
- 'password' => root_password
124
- )
125
- end
126
-
127
- def root_password
128
- $stdout.print "Please provide the root password for your MySQL installation\n>"
129
- $stdin.gets.strip
130
- end
86
+ def prepare_command_options
87
+ args = {
88
+ "host" => "--host",
89
+ "port" => "--port",
90
+ "socket" => "--socket",
91
+ "username" => "--user",
92
+ "password" => "--password",
93
+ "encoding" => "--default-character-set",
94
+ "sslca" => "--ssl-ca",
95
+ "sslcert" => "--ssl-cert",
96
+ "sslcapath" => "--ssl-capath",
97
+ "sslcipher" => "--ssl-cipher",
98
+ "sslkey" => "--ssl-key"
99
+ }.map { |opt, arg| "#{arg}=#{configuration[opt]}" if configuration[opt] }.compact
100
+
101
+ args
102
+ end
131
103
 
132
- def prepare_command_options(command)
133
- args = [command]
134
- args.concat(['--user', configuration['username']]) if configuration['username']
135
- args << "--password=#{configuration['password']}" if configuration['password']
136
- args.concat(['--default-character-set', configuration['encoding']]) if configuration['encoding']
137
- configuration.slice('host', 'port', 'socket').each do |k, v|
138
- args.concat([ "--#{k}", v.to_s ]) if v
104
+ def run_cmd(cmd, args, action)
105
+ fail run_cmd_error(cmd, args, action) unless Kernel.system(cmd, *args)
139
106
  end
140
107
 
141
- args
142
- end
108
+ def run_cmd_error(cmd, args, action)
109
+ msg = +"failed to execute: `#{cmd}`\n"
110
+ msg << "Please check the output above for any errors and make sure that `#{cmd}` is installed in your PATH and has proper permissions.\n\n"
111
+ msg
112
+ end
143
113
  end
144
114
  end
145
115
  end
@@ -1,9 +1,13 @@
1
- require 'shellwords'
1
+ # frozen_string_literal: true
2
+
3
+ require "tempfile"
2
4
 
3
5
  module ActiveRecord
4
6
  module Tasks # :nodoc:
5
7
  class PostgreSQLDatabaseTasks # :nodoc:
6
- DEFAULT_ENCODING = ENV['CHARSET'] || 'utf8'
8
+ DEFAULT_ENCODING = ENV["CHARSET"] || "utf8"
9
+ ON_ERROR_STOP_1 = "ON_ERROR_STOP=1"
10
+ SQL_COMMENT_BEGIN = "--"
7
11
 
8
12
  delegate :connection, :establish_connection, :clear_active_connections!,
9
13
  to: ActiveRecord::Base
@@ -14,11 +18,11 @@ module ActiveRecord
14
18
 
15
19
  def create(master_established = false)
16
20
  establish_master_connection unless master_established
17
- connection.create_database configuration['database'],
18
- configuration.merge('encoding' => encoding)
21
+ connection.create_database configuration["database"],
22
+ configuration.merge("encoding" => encoding)
19
23
  establish_connection configuration
20
24
  rescue ActiveRecord::StatementInvalid => error
21
- if /database .* already exists/ === error.message
25
+ if error.cause.is_a?(PG::DuplicateDatabase)
22
26
  raise DatabaseAlreadyExists
23
27
  else
24
28
  raise
@@ -27,7 +31,7 @@ module ActiveRecord
27
31
 
28
32
  def drop
29
33
  establish_master_connection
30
- connection.drop_database configuration['database']
34
+ connection.drop_database configuration["database"]
31
35
  end
32
36
 
33
37
  def charset
@@ -44,47 +48,94 @@ module ActiveRecord
44
48
  create true
45
49
  end
46
50
 
47
- def structure_dump(filename)
51
+ def structure_dump(filename, extra_flags)
48
52
  set_psql_env
49
- search_path = configuration['schema_search_path']
53
+
54
+ search_path = \
55
+ case ActiveRecord::Base.dump_schemas
56
+ when :schema_search_path
57
+ configuration["schema_search_path"]
58
+ when :all
59
+ nil
60
+ when String
61
+ ActiveRecord::Base.dump_schemas
62
+ end
63
+
64
+ args = ["-s", "-x", "-O", "-f", filename]
65
+ args.concat(Array(extra_flags)) if extra_flags
50
66
  unless search_path.blank?
51
- search_path = search_path.split(",").map{|search_path_part| "--schema=#{Shellwords.escape(search_path_part.strip)}" }.join(" ")
67
+ args += search_path.split(",").map do |part|
68
+ "--schema=#{part.strip}"
69
+ end
52
70
  end
53
71
 
54
- command = "pg_dump -i -s -x -O -f #{Shellwords.escape(filename)} #{search_path} #{Shellwords.escape(configuration['database'])}"
55
- raise 'Error dumping database' unless Kernel.system(command)
72
+ ignore_tables = ActiveRecord::SchemaDumper.ignore_tables
73
+ if ignore_tables.any?
74
+ args += ignore_tables.flat_map { |table| ["-T", table] }
75
+ end
56
76
 
77
+ args << configuration["database"]
78
+ run_cmd("pg_dump", args, "dumping")
79
+ remove_sql_header_comments(filename)
57
80
  File.open(filename, "a") { |f| f << "SET search_path TO #{connection.schema_search_path};\n\n" }
58
81
  end
59
82
 
60
- def structure_load(filename)
83
+ def structure_load(filename, extra_flags)
61
84
  set_psql_env
62
- Kernel.system("psql -q -f #{Shellwords.escape(filename)} #{configuration['database']}")
85
+ args = ["-v", ON_ERROR_STOP_1, "-q", "-X", "-f", filename]
86
+ args.concat(Array(extra_flags)) if extra_flags
87
+ args << configuration["database"]
88
+ run_cmd("psql", args, "loading")
63
89
  end
64
90
 
65
91
  private
66
92
 
67
- def configuration
68
- @configuration
69
- end
93
+ attr_reader :configuration
70
94
 
71
- def encoding
72
- configuration['encoding'] || DEFAULT_ENCODING
73
- end
95
+ def encoding
96
+ configuration["encoding"] || DEFAULT_ENCODING
97
+ end
74
98
 
75
- def establish_master_connection
76
- establish_connection configuration.merge(
77
- 'database' => 'postgres',
78
- 'schema_search_path' => 'public'
79
- )
80
- end
99
+ def establish_master_connection
100
+ establish_connection configuration.merge(
101
+ "database" => "postgres",
102
+ "schema_search_path" => "public"
103
+ )
104
+ end
81
105
 
82
- def set_psql_env
83
- ENV['PGHOST'] = configuration['host'] if configuration['host']
84
- ENV['PGPORT'] = configuration['port'].to_s if configuration['port']
85
- ENV['PGPASSWORD'] = configuration['password'].to_s if configuration['password']
86
- ENV['PGUSER'] = configuration['username'].to_s if configuration['username']
87
- end
106
+ def set_psql_env
107
+ ENV["PGHOST"] = configuration["host"] if configuration["host"]
108
+ ENV["PGPORT"] = configuration["port"].to_s if configuration["port"]
109
+ ENV["PGPASSWORD"] = configuration["password"].to_s if configuration["password"]
110
+ ENV["PGUSER"] = configuration["username"].to_s if configuration["username"]
111
+ end
112
+
113
+ def run_cmd(cmd, args, action)
114
+ fail run_cmd_error(cmd, args, action) unless Kernel.system(cmd, *args)
115
+ end
116
+
117
+ def run_cmd_error(cmd, args, action)
118
+ msg = +"failed to execute:\n"
119
+ msg << "#{cmd} #{args.join(' ')}\n\n"
120
+ msg << "Please check the output above for any errors and make sure that `#{cmd}` is installed in your PATH and has proper permissions.\n\n"
121
+ msg
122
+ end
123
+
124
+ def remove_sql_header_comments(filename)
125
+ removing_comments = true
126
+ tempfile = Tempfile.open("uncommented_structure.sql")
127
+ begin
128
+ File.foreach(filename) do |line|
129
+ unless removing_comments && (line.start_with?(SQL_COMMENT_BEGIN) || line.blank?)
130
+ tempfile << line
131
+ removing_comments = false
132
+ end
133
+ end
134
+ ensure
135
+ tempfile.close
136
+ end
137
+ FileUtils.cp(tempfile.path, filename)
138
+ end
88
139
  end
89
140
  end
90
141
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module Tasks # :nodoc:
3
5
  class SQLiteDatabaseTasks # :nodoc:
@@ -8,22 +10,26 @@ module ActiveRecord
8
10
  end
9
11
 
10
12
  def create
11
- raise DatabaseAlreadyExists if File.exist?(configuration['database'])
13
+ raise DatabaseAlreadyExists if File.exist?(configuration["database"])
12
14
 
13
15
  establish_connection configuration
14
16
  connection
15
17
  end
16
18
 
17
19
  def drop
18
- require 'pathname'
19
- path = Pathname.new configuration['database']
20
+ require "pathname"
21
+ path = Pathname.new configuration["database"]
20
22
  file = path.absolute? ? path.to_s : File.join(root, path)
21
23
 
22
- FileUtils.rm(file) if File.exist?(file)
24
+ FileUtils.rm(file)
25
+ rescue Errno::ENOENT => error
26
+ raise NoDatabaseError.new(error.message)
23
27
  end
24
28
 
25
29
  def purge
26
30
  drop
31
+ rescue NoDatabaseError
32
+ ensure
27
33
  create
28
34
  end
29
35
 
@@ -31,25 +37,41 @@ module ActiveRecord
31
37
  connection.encoding
32
38
  end
33
39
 
34
- def structure_dump(filename)
35
- dbfile = configuration['database']
36
- `sqlite3 #{dbfile} .schema > #{filename}`
40
+ def structure_dump(filename, extra_flags)
41
+ args = []
42
+ args.concat(Array(extra_flags)) if extra_flags
43
+ args << configuration["database"]
44
+
45
+ ignore_tables = ActiveRecord::SchemaDumper.ignore_tables
46
+ if ignore_tables.any?
47
+ condition = ignore_tables.map { |table| connection.quote(table) }.join(", ")
48
+ args << "SELECT sql FROM sqlite_master WHERE tbl_name NOT IN (#{condition}) ORDER BY tbl_name, type DESC, name"
49
+ else
50
+ args << ".schema"
51
+ end
52
+ run_cmd("sqlite3", args, filename)
37
53
  end
38
54
 
39
- def structure_load(filename)
40
- dbfile = configuration['database']
41
- `sqlite3 #{dbfile} < "#{filename}"`
55
+ def structure_load(filename, extra_flags)
56
+ dbfile = configuration["database"]
57
+ flags = extra_flags.join(" ") if extra_flags
58
+ `sqlite3 #{flags} #{dbfile} < "#{filename}"`
42
59
  end
43
60
 
44
61
  private
45
62
 
46
- def configuration
47
- @configuration
48
- end
63
+ attr_reader :configuration, :root
49
64
 
50
- def root
51
- @root
52
- end
65
+ def run_cmd(cmd, args, out)
66
+ fail run_cmd_error(cmd, args) unless Kernel.system(cmd, *args, out: out)
67
+ end
68
+
69
+ def run_cmd_error(cmd, args)
70
+ msg = +"failed to execute:\n"
71
+ msg << "#{cmd} #{args.join(' ')}\n\n"
72
+ msg << "Please check the output above for any errors and make sure that `#{cmd}` is installed in your PATH and has proper permissions.\n\n"
73
+ msg
74
+ end
53
75
  end
54
76
  end
55
77
  end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/testing/parallelization"
4
+
5
+ module ActiveRecord
6
+ module TestDatabases # :nodoc:
7
+ ActiveSupport::Testing::Parallelization.after_fork_hook do |i|
8
+ create_and_load_schema(i, env_name: Rails.env)
9
+ end
10
+
11
+ def self.create_and_load_schema(i, env_name:)
12
+ old, ENV["VERBOSE"] = ENV["VERBOSE"], "false"
13
+
14
+ ActiveRecord::Base.configurations.configs_for(env_name: env_name).each do |db_config|
15
+ db_config.config["database"] += "-#{i}"
16
+ ActiveRecord::Tasks::DatabaseTasks.reconstruct_from_schema(db_config.config, ActiveRecord::Base.schema_format, nil, env_name, db_config.spec_name)
17
+ end
18
+ ensure
19
+ ActiveRecord::Base.establish_connection(Rails.env.to_sym)
20
+ ENV["VERBOSE"] = old
21
+ end
22
+ end
23
+ end