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,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,74 @@ 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)
84
- end
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
85
67
 
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'
68
+ run_cmd("mysql", args, "loading")
69
+ end
90
70
 
91
- # Set default charset only when collation isn't set.
92
- options[:charset] ||= DEFAULT_CHARSET unless options[:collation]
71
+ private
72
+ attr_reader :configuration
93
73
 
94
- # Set default collation only when charset is also default.
95
- options[:collation] ||= DEFAULT_COLLATION if options[:charset] == DEFAULT_CHARSET
74
+ def configuration_without_database
75
+ configuration.merge("database" => nil)
96
76
  end
97
- end
98
77
 
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
78
+ def creation_options
79
+ Hash.new.tap do |options|
80
+ options[:charset] = configuration["encoding"] if configuration.include? "encoding"
81
+ options[:collation] = configuration["collation"] if configuration.include? "collation"
82
+ end
109
83
  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
-
120
- def root_configuration_without_database
121
- configuration_without_database.merge(
122
- 'username' => 'root',
123
- 'password' => root_password
124
- )
125
- end
126
84
 
127
- def root_password
128
- $stdout.print "Please provide the root password for your MySQL installation\n>"
129
- $stdin.gets.strip
130
- end
85
+ def prepare_command_options
86
+ args = {
87
+ "host" => "--host",
88
+ "port" => "--port",
89
+ "socket" => "--socket",
90
+ "username" => "--user",
91
+ "password" => "--password",
92
+ "encoding" => "--default-character-set",
93
+ "sslca" => "--ssl-ca",
94
+ "sslcert" => "--ssl-cert",
95
+ "sslcapath" => "--ssl-capath",
96
+ "sslcipher" => "--ssl-cipher",
97
+ "sslkey" => "--ssl-key"
98
+ }.map { |opt, arg| "#{arg}=#{configuration[opt]}" if configuration[opt] }.compact
99
+
100
+ args
101
+ end
131
102
 
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
103
+ def run_cmd(cmd, args, action)
104
+ fail run_cmd_error(cmd, args, action) unless Kernel.system(cmd, *args)
139
105
  end
140
106
 
141
- args
142
- end
107
+ def run_cmd_error(cmd, args, action)
108
+ msg = +"failed to execute: `#{cmd}`\n"
109
+ 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"
110
+ msg
111
+ end
143
112
  end
144
113
  end
145
114
  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,93 @@ 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
92
+ attr_reader :configuration
66
93
 
67
- def configuration
68
- @configuration
69
- end
94
+ def encoding
95
+ configuration["encoding"] || DEFAULT_ENCODING
96
+ end
70
97
 
71
- def encoding
72
- configuration['encoding'] || DEFAULT_ENCODING
73
- end
98
+ def establish_master_connection
99
+ establish_connection configuration.merge(
100
+ "database" => "postgres",
101
+ "schema_search_path" => "public"
102
+ )
103
+ end
74
104
 
75
- def establish_master_connection
76
- establish_connection configuration.merge(
77
- 'database' => 'postgres',
78
- 'schema_search_path' => 'public'
79
- )
80
- end
105
+ def set_psql_env
106
+ ENV["PGHOST"] = configuration["host"] if configuration["host"]
107
+ ENV["PGPORT"] = configuration["port"].to_s if configuration["port"]
108
+ ENV["PGPASSWORD"] = configuration["password"].to_s if configuration["password"]
109
+ ENV["PGUSER"] = configuration["username"].to_s if configuration["username"]
110
+ end
81
111
 
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
112
+ def run_cmd(cmd, args, action)
113
+ fail run_cmd_error(cmd, args, action) unless Kernel.system(cmd, *args)
114
+ end
115
+
116
+ def run_cmd_error(cmd, args, action)
117
+ msg = +"failed to execute:\n"
118
+ msg << "#{cmd} #{args.join(' ')}\n\n"
119
+ 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"
120
+ msg
121
+ end
122
+
123
+ def remove_sql_header_comments(filename)
124
+ removing_comments = true
125
+ tempfile = Tempfile.open("uncommented_structure.sql")
126
+ begin
127
+ File.foreach(filename) do |line|
128
+ unless removing_comments && (line.start_with?(SQL_COMMENT_BEGIN) || line.blank?)
129
+ tempfile << line
130
+ removing_comments = false
131
+ end
132
+ end
133
+ ensure
134
+ tempfile.close
135
+ end
136
+ FileUtils.cp(tempfile.path, filename)
137
+ end
88
138
  end
89
139
  end
90
140
  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,40 @@ 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
62
+ attr_reader :configuration, :root
45
63
 
46
- def configuration
47
- @configuration
48
- end
64
+ def run_cmd(cmd, args, out)
65
+ fail run_cmd_error(cmd, args) unless Kernel.system(cmd, *args, out: out)
66
+ end
49
67
 
50
- def root
51
- @root
52
- end
68
+ def run_cmd_error(cmd, args)
69
+ msg = +"failed to execute:\n"
70
+ msg << "#{cmd} #{args.join(' ')}\n\n"
71
+ 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"
72
+ msg
73
+ end
53
74
  end
54
75
  end
55
76
  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