activerecord 5.0.7.2 → 6.1.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 (363) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +829 -2015
  3. data/MIT-LICENSE +3 -1
  4. data/README.rdoc +11 -9
  5. data/examples/performance.rb +31 -29
  6. data/examples/simple.rb +5 -3
  7. data/lib/active_record.rb +37 -29
  8. data/lib/active_record/aggregations.rb +249 -247
  9. data/lib/active_record/association_relation.rb +30 -18
  10. data/lib/active_record/associations.rb +1714 -1596
  11. data/lib/active_record/associations/alias_tracker.rb +36 -42
  12. data/lib/active_record/associations/association.rb +143 -68
  13. data/lib/active_record/associations/association_scope.rb +98 -94
  14. data/lib/active_record/associations/belongs_to_association.rb +76 -46
  15. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +13 -12
  16. data/lib/active_record/associations/builder/association.rb +27 -28
  17. data/lib/active_record/associations/builder/belongs_to.rb +52 -60
  18. data/lib/active_record/associations/builder/collection_association.rb +12 -22
  19. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +40 -62
  20. data/lib/active_record/associations/builder/has_many.rb +10 -2
  21. data/lib/active_record/associations/builder/has_one.rb +35 -2
  22. data/lib/active_record/associations/builder/singular_association.rb +5 -1
  23. data/lib/active_record/associations/collection_association.rb +104 -259
  24. data/lib/active_record/associations/collection_proxy.rb +169 -125
  25. data/lib/active_record/associations/foreign_association.rb +22 -0
  26. data/lib/active_record/associations/has_many_association.rb +46 -31
  27. data/lib/active_record/associations/has_many_through_association.rb +66 -46
  28. data/lib/active_record/associations/has_one_association.rb +71 -52
  29. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  30. data/lib/active_record/associations/join_dependency.rb +169 -180
  31. data/lib/active_record/associations/join_dependency/join_association.rb +53 -79
  32. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  33. data/lib/active_record/associations/join_dependency/join_part.rb +14 -14
  34. data/lib/active_record/associations/preloader.rb +97 -104
  35. data/lib/active_record/associations/preloader/association.rb +109 -97
  36. data/lib/active_record/associations/preloader/through_association.rb +77 -76
  37. data/lib/active_record/associations/singular_association.rb +12 -45
  38. data/lib/active_record/associations/through_association.rb +27 -15
  39. data/lib/active_record/attribute_assignment.rb +55 -60
  40. data/lib/active_record/attribute_methods.rb +111 -141
  41. data/lib/active_record/attribute_methods/before_type_cast.rb +17 -9
  42. data/lib/active_record/attribute_methods/dirty.rb +172 -112
  43. data/lib/active_record/attribute_methods/primary_key.rb +88 -91
  44. data/lib/active_record/attribute_methods/query.rb +6 -8
  45. data/lib/active_record/attribute_methods/read.rb +18 -50
  46. data/lib/active_record/attribute_methods/serialization.rb +38 -10
  47. data/lib/active_record/attribute_methods/time_zone_conversion.rb +38 -66
  48. data/lib/active_record/attribute_methods/write.rb +25 -32
  49. data/lib/active_record/attributes.rb +69 -31
  50. data/lib/active_record/autosave_association.rb +102 -66
  51. data/lib/active_record/base.rb +16 -25
  52. data/lib/active_record/callbacks.rb +202 -43
  53. data/lib/active_record/coders/json.rb +2 -0
  54. data/lib/active_record/coders/yaml_column.rb +11 -12
  55. data/lib/active_record/connection_adapters.rb +50 -0
  56. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +661 -375
  57. data/lib/active_record/connection_adapters/abstract/database_limits.rb +14 -38
  58. data/lib/active_record/connection_adapters/abstract/database_statements.rb +269 -105
  59. data/lib/active_record/connection_adapters/abstract/query_cache.rb +54 -35
  60. data/lib/active_record/connection_adapters/abstract/quoting.rb +137 -93
  61. data/lib/active_record/connection_adapters/abstract/savepoints.rb +5 -3
  62. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +155 -113
  63. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +328 -162
  64. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +68 -80
  65. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +591 -259
  66. data/lib/active_record/connection_adapters/abstract/transaction.rb +229 -91
  67. data/lib/active_record/connection_adapters/abstract_adapter.rb +392 -244
  68. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +457 -582
  69. data/lib/active_record/connection_adapters/column.rb +55 -13
  70. data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
  71. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +31 -0
  72. data/lib/active_record/connection_adapters/mysql/column.rb +8 -31
  73. data/lib/active_record/connection_adapters/mysql/database_statements.rb +135 -49
  74. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +24 -23
  75. data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -20
  76. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +79 -49
  77. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +66 -56
  78. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +70 -36
  79. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +268 -0
  80. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +20 -12
  81. data/lib/active_record/connection_adapters/mysql2_adapter.rb +74 -37
  82. data/lib/active_record/connection_adapters/pool_config.rb +63 -0
  83. data/lib/active_record/connection_adapters/pool_manager.rb +43 -0
  84. data/lib/active_record/connection_adapters/postgresql/column.rb +39 -28
  85. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +70 -101
  86. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +5 -3
  87. data/lib/active_record/connection_adapters/postgresql/oid.rb +26 -21
  88. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +22 -11
  89. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +6 -5
  90. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
  92. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +6 -6
  93. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
  94. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +14 -4
  95. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  96. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -4
  97. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +19 -18
  98. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  99. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  101. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +44 -0
  102. data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
  103. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -5
  104. data/lib/active_record/connection_adapters/postgresql/oid/{json.rb → oid.rb} +6 -1
  105. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +30 -9
  106. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +52 -30
  107. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
  108. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
  109. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +18 -4
  110. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
  111. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
  112. data/lib/active_record/connection_adapters/postgresql/quoting.rb +98 -38
  113. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +21 -27
  114. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +80 -0
  115. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +147 -105
  116. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +34 -32
  117. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +426 -324
  118. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +32 -23
  119. data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -6
  120. data/lib/active_record/connection_adapters/postgresql_adapter.rb +418 -293
  121. data/lib/active_record/connection_adapters/schema_cache.rb +135 -18
  122. data/lib/active_record/connection_adapters/sql_type_metadata.rb +22 -7
  123. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +144 -0
  124. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +3 -1
  125. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +72 -18
  126. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -6
  127. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  128. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  129. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +170 -0
  130. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +282 -290
  131. data/lib/active_record/connection_adapters/statement_pool.rb +9 -8
  132. data/lib/active_record/connection_handling.rb +287 -45
  133. data/lib/active_record/core.rb +385 -181
  134. data/lib/active_record/counter_cache.rb +60 -28
  135. data/lib/active_record/database_configurations.rb +272 -0
  136. data/lib/active_record/database_configurations/connection_url_resolver.rb +98 -0
  137. data/lib/active_record/database_configurations/database_config.rb +80 -0
  138. data/lib/active_record/database_configurations/hash_config.rb +96 -0
  139. data/lib/active_record/database_configurations/url_config.rb +53 -0
  140. data/lib/active_record/delegated_type.rb +209 -0
  141. data/lib/active_record/destroy_association_async_job.rb +36 -0
  142. data/lib/active_record/dynamic_matchers.rb +87 -87
  143. data/lib/active_record/enum.rb +122 -47
  144. data/lib/active_record/errors.rb +153 -22
  145. data/lib/active_record/explain.rb +13 -8
  146. data/lib/active_record/explain_registry.rb +3 -1
  147. data/lib/active_record/explain_subscriber.rb +9 -4
  148. data/lib/active_record/fixture_set/file.rb +20 -22
  149. data/lib/active_record/fixture_set/model_metadata.rb +32 -0
  150. data/lib/active_record/fixture_set/render_context.rb +17 -0
  151. data/lib/active_record/fixture_set/table_row.rb +152 -0
  152. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  153. data/lib/active_record/fixtures.rb +246 -507
  154. data/lib/active_record/gem_version.rb +6 -4
  155. data/lib/active_record/inheritance.rb +168 -95
  156. data/lib/active_record/insert_all.rb +208 -0
  157. data/lib/active_record/integration.rb +114 -25
  158. data/lib/active_record/internal_metadata.rb +30 -24
  159. data/lib/active_record/legacy_yaml_adapter.rb +11 -5
  160. data/lib/active_record/locking/optimistic.rb +81 -85
  161. data/lib/active_record/locking/pessimistic.rb +22 -6
  162. data/lib/active_record/log_subscriber.rb +68 -31
  163. data/lib/active_record/middleware/database_selector.rb +77 -0
  164. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  165. data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
  166. data/lib/active_record/migration.rb +439 -342
  167. data/lib/active_record/migration/command_recorder.rb +152 -98
  168. data/lib/active_record/migration/compatibility.rb +229 -60
  169. data/lib/active_record/migration/join_table.rb +8 -7
  170. data/lib/active_record/model_schema.rb +230 -122
  171. data/lib/active_record/nested_attributes.rb +213 -203
  172. data/lib/active_record/no_touching.rb +11 -2
  173. data/lib/active_record/null_relation.rb +12 -34
  174. data/lib/active_record/persistence.rb +471 -97
  175. data/lib/active_record/query_cache.rb +23 -12
  176. data/lib/active_record/querying.rb +43 -25
  177. data/lib/active_record/railtie.rb +155 -43
  178. data/lib/active_record/railties/console_sandbox.rb +2 -0
  179. data/lib/active_record/railties/controller_runtime.rb +34 -33
  180. data/lib/active_record/railties/databases.rake +507 -195
  181. data/lib/active_record/readonly_attributes.rb +9 -4
  182. data/lib/active_record/reflection.rb +245 -269
  183. data/lib/active_record/relation.rb +475 -324
  184. data/lib/active_record/relation/batches.rb +125 -72
  185. data/lib/active_record/relation/batches/batch_enumerator.rb +28 -10
  186. data/lib/active_record/relation/calculations.rb +267 -171
  187. data/lib/active_record/relation/delegation.rb +73 -69
  188. data/lib/active_record/relation/finder_methods.rb +238 -248
  189. data/lib/active_record/relation/from_clause.rb +7 -9
  190. data/lib/active_record/relation/merger.rb +95 -77
  191. data/lib/active_record/relation/predicate_builder.rb +109 -110
  192. data/lib/active_record/relation/predicate_builder/array_handler.rb +22 -17
  193. data/lib/active_record/relation/predicate_builder/association_query_value.rb +42 -0
  194. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +6 -4
  195. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +55 -0
  196. data/lib/active_record/relation/predicate_builder/range_handler.rb +7 -18
  197. data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
  198. data/lib/active_record/relation/query_attribute.rb +33 -2
  199. data/lib/active_record/relation/query_methods.rb +654 -374
  200. data/lib/active_record/relation/record_fetch_warning.rb +8 -6
  201. data/lib/active_record/relation/spawn_methods.rb +15 -14
  202. data/lib/active_record/relation/where_clause.rb +171 -109
  203. data/lib/active_record/result.rb +88 -51
  204. data/lib/active_record/runtime_registry.rb +5 -3
  205. data/lib/active_record/sanitization.rb +73 -100
  206. data/lib/active_record/schema.rb +7 -14
  207. data/lib/active_record/schema_dumper.rb +101 -69
  208. data/lib/active_record/schema_migration.rb +16 -12
  209. data/lib/active_record/scoping.rb +20 -20
  210. data/lib/active_record/scoping/default.rb +92 -95
  211. data/lib/active_record/scoping/named.rb +39 -30
  212. data/lib/active_record/secure_token.rb +19 -9
  213. data/lib/active_record/serialization.rb +7 -3
  214. data/lib/active_record/signed_id.rb +116 -0
  215. data/lib/active_record/statement_cache.rb +80 -29
  216. data/lib/active_record/store.rb +122 -42
  217. data/lib/active_record/suppressor.rb +6 -3
  218. data/lib/active_record/table_metadata.rb +51 -39
  219. data/lib/active_record/tasks/database_tasks.rb +332 -115
  220. data/lib/active_record/tasks/mysql_database_tasks.rb +66 -104
  221. data/lib/active_record/tasks/postgresql_database_tasks.rb +84 -56
  222. data/lib/active_record/tasks/sqlite_database_tasks.rb +40 -19
  223. data/lib/active_record/test_databases.rb +24 -0
  224. data/lib/active_record/test_fixtures.rb +246 -0
  225. data/lib/active_record/timestamp.rb +70 -38
  226. data/lib/active_record/touch_later.rb +26 -24
  227. data/lib/active_record/transactions.rb +121 -184
  228. data/lib/active_record/translation.rb +3 -1
  229. data/lib/active_record/type.rb +29 -17
  230. data/lib/active_record/type/adapter_specific_registry.rb +44 -48
  231. data/lib/active_record/type/date.rb +2 -0
  232. data/lib/active_record/type/date_time.rb +2 -0
  233. data/lib/active_record/type/decimal_without_scale.rb +15 -0
  234. data/lib/active_record/type/hash_lookup_type_map.rb +5 -4
  235. data/lib/active_record/type/internal/timezone.rb +2 -0
  236. data/lib/active_record/type/json.rb +30 -0
  237. data/lib/active_record/type/serialized.rb +20 -9
  238. data/lib/active_record/type/text.rb +11 -0
  239. data/lib/active_record/type/time.rb +12 -1
  240. data/lib/active_record/type/type_map.rb +14 -17
  241. data/lib/active_record/type/unsigned_integer.rb +16 -0
  242. data/lib/active_record/type_caster.rb +4 -2
  243. data/lib/active_record/type_caster/connection.rb +17 -13
  244. data/lib/active_record/type_caster/map.rb +10 -6
  245. data/lib/active_record/validations.rb +8 -5
  246. data/lib/active_record/validations/absence.rb +2 -0
  247. data/lib/active_record/validations/associated.rb +4 -3
  248. data/lib/active_record/validations/length.rb +2 -0
  249. data/lib/active_record/validations/numericality.rb +35 -0
  250. data/lib/active_record/validations/presence.rb +4 -2
  251. data/lib/active_record/validations/uniqueness.rb +52 -45
  252. data/lib/active_record/version.rb +3 -1
  253. data/lib/arel.rb +54 -0
  254. data/lib/arel/alias_predication.rb +9 -0
  255. data/lib/arel/attributes/attribute.rb +41 -0
  256. data/lib/arel/collectors/bind.rb +29 -0
  257. data/lib/arel/collectors/composite.rb +39 -0
  258. data/lib/arel/collectors/plain_string.rb +20 -0
  259. data/lib/arel/collectors/sql_string.rb +27 -0
  260. data/lib/arel/collectors/substitute_binds.rb +35 -0
  261. data/lib/arel/crud.rb +42 -0
  262. data/lib/arel/delete_manager.rb +18 -0
  263. data/lib/arel/errors.rb +9 -0
  264. data/lib/arel/expressions.rb +29 -0
  265. data/lib/arel/factory_methods.rb +49 -0
  266. data/lib/arel/insert_manager.rb +49 -0
  267. data/lib/arel/math.rb +45 -0
  268. data/lib/arel/nodes.rb +70 -0
  269. data/lib/arel/nodes/and.rb +32 -0
  270. data/lib/arel/nodes/ascending.rb +23 -0
  271. data/lib/arel/nodes/binary.rb +126 -0
  272. data/lib/arel/nodes/bind_param.rb +44 -0
  273. data/lib/arel/nodes/case.rb +55 -0
  274. data/lib/arel/nodes/casted.rb +62 -0
  275. data/lib/arel/nodes/comment.rb +29 -0
  276. data/lib/arel/nodes/count.rb +12 -0
  277. data/lib/arel/nodes/delete_statement.rb +45 -0
  278. data/lib/arel/nodes/descending.rb +23 -0
  279. data/lib/arel/nodes/equality.rb +15 -0
  280. data/lib/arel/nodes/extract.rb +24 -0
  281. data/lib/arel/nodes/false.rb +16 -0
  282. data/lib/arel/nodes/full_outer_join.rb +8 -0
  283. data/lib/arel/nodes/function.rb +44 -0
  284. data/lib/arel/nodes/grouping.rb +11 -0
  285. data/lib/arel/nodes/homogeneous_in.rb +72 -0
  286. data/lib/arel/nodes/in.rb +15 -0
  287. data/lib/arel/nodes/infix_operation.rb +92 -0
  288. data/lib/arel/nodes/inner_join.rb +8 -0
  289. data/lib/arel/nodes/insert_statement.rb +37 -0
  290. data/lib/arel/nodes/join_source.rb +20 -0
  291. data/lib/arel/nodes/matches.rb +18 -0
  292. data/lib/arel/nodes/named_function.rb +23 -0
  293. data/lib/arel/nodes/node.rb +51 -0
  294. data/lib/arel/nodes/node_expression.rb +13 -0
  295. data/lib/arel/nodes/ordering.rb +27 -0
  296. data/lib/arel/nodes/outer_join.rb +8 -0
  297. data/lib/arel/nodes/over.rb +15 -0
  298. data/lib/arel/nodes/regexp.rb +16 -0
  299. data/lib/arel/nodes/right_outer_join.rb +8 -0
  300. data/lib/arel/nodes/select_core.rb +67 -0
  301. data/lib/arel/nodes/select_statement.rb +41 -0
  302. data/lib/arel/nodes/sql_literal.rb +19 -0
  303. data/lib/arel/nodes/string_join.rb +11 -0
  304. data/lib/arel/nodes/table_alias.rb +31 -0
  305. data/lib/arel/nodes/terminal.rb +16 -0
  306. data/lib/arel/nodes/true.rb +16 -0
  307. data/lib/arel/nodes/unary.rb +44 -0
  308. data/lib/arel/nodes/unary_operation.rb +20 -0
  309. data/lib/arel/nodes/unqualified_column.rb +22 -0
  310. data/lib/arel/nodes/update_statement.rb +41 -0
  311. data/lib/arel/nodes/values_list.rb +9 -0
  312. data/lib/arel/nodes/window.rb +126 -0
  313. data/lib/arel/nodes/with.rb +11 -0
  314. data/lib/arel/order_predications.rb +13 -0
  315. data/lib/arel/predications.rb +250 -0
  316. data/lib/arel/select_manager.rb +270 -0
  317. data/lib/arel/table.rb +118 -0
  318. data/lib/arel/tree_manager.rb +72 -0
  319. data/lib/arel/update_manager.rb +34 -0
  320. data/lib/arel/visitors.rb +13 -0
  321. data/lib/arel/visitors/dot.rb +308 -0
  322. data/lib/arel/visitors/mysql.rb +93 -0
  323. data/lib/arel/visitors/postgresql.rb +120 -0
  324. data/lib/arel/visitors/sqlite.rb +38 -0
  325. data/lib/arel/visitors/to_sql.rb +899 -0
  326. data/lib/arel/visitors/visitor.rb +45 -0
  327. data/lib/arel/window_predications.rb +9 -0
  328. data/lib/rails/generators/active_record.rb +7 -5
  329. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +26 -0
  330. data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
  331. data/lib/rails/generators/active_record/migration.rb +22 -3
  332. data/lib/rails/generators/active_record/migration/migration_generator.rb +38 -35
  333. data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +3 -1
  334. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +7 -5
  335. data/lib/rails/generators/active_record/model/model_generator.rb +41 -25
  336. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
  337. data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +10 -1
  338. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
  339. metadata +141 -57
  340. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  341. data/lib/active_record/associations/preloader/collection_association.rb +0 -17
  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 -15
  345. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  346. data/lib/active_record/associations/preloader/singular_association.rb +0 -20
  347. data/lib/active_record/attribute.rb +0 -213
  348. data/lib/active_record/attribute/user_provided_default.rb +0 -28
  349. data/lib/active_record/attribute_decorators.rb +0 -67
  350. data/lib/active_record/attribute_mutation_tracker.rb +0 -70
  351. data/lib/active_record/attribute_set.rb +0 -110
  352. data/lib/active_record/attribute_set/builder.rb +0 -132
  353. data/lib/active_record/collection_cache_key.rb +0 -50
  354. data/lib/active_record/connection_adapters/connection_specification.rb +0 -263
  355. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -22
  356. data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +0 -50
  357. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  358. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
  359. data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -17
  360. data/lib/active_record/relation/predicate_builder/class_handler.rb +0 -27
  361. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -57
  362. data/lib/active_record/relation/where_clause_factory.rb +0 -38
  363. data/lib/active_record/type/internal/abstract_json.rb +0 -33
@@ -1,6 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/file/atomic"
4
+
1
5
  module ActiveRecord
2
6
  module ConnectionAdapters
3
7
  class SchemaCache
8
+ def self.load_from(filename)
9
+ return unless File.file?(filename)
10
+
11
+ read(filename) do |file|
12
+ filename.include?(".dump") ? Marshal.load(file) : YAML.load(file)
13
+ end
14
+ end
15
+
16
+ def self.read(filename, &block)
17
+ if File.extname(filename) == ".gz"
18
+ Zlib::GzipReader.open(filename) { |gz|
19
+ yield gz.read
20
+ }
21
+ else
22
+ yield File.read(filename)
23
+ end
24
+ end
25
+ private_class_method :read
26
+
4
27
  attr_reader :version
5
28
  attr_accessor :connection
6
29
 
@@ -11,6 +34,7 @@ module ActiveRecord
11
34
  @columns_hash = {}
12
35
  @primary_keys = {}
13
36
  @data_sources = {}
37
+ @indexes = {}
14
38
  end
15
39
 
16
40
  def initialize_dup(other)
@@ -19,10 +43,37 @@ module ActiveRecord
19
43
  @columns_hash = @columns_hash.dup
20
44
  @primary_keys = @primary_keys.dup
21
45
  @data_sources = @data_sources.dup
46
+ @indexes = @indexes.dup
47
+ end
48
+
49
+ def encode_with(coder)
50
+ reset_version!
51
+
52
+ coder["columns"] = @columns
53
+ coder["primary_keys"] = @primary_keys
54
+ coder["data_sources"] = @data_sources
55
+ coder["indexes"] = @indexes
56
+ coder["version"] = @version
57
+ coder["database_version"] = database_version
58
+ end
59
+
60
+ def init_with(coder)
61
+ @columns = coder["columns"]
62
+ @primary_keys = coder["primary_keys"]
63
+ @data_sources = coder["data_sources"]
64
+ @indexes = coder["indexes"] || {}
65
+ @version = coder["version"]
66
+ @database_version = coder["database_version"]
67
+
68
+ derive_columns_hash_and_deduplicate_values
22
69
  end
23
70
 
24
71
  def primary_keys(table_name)
25
- @primary_keys[table_name] ||= data_source_exists?(table_name) ? connection.primary_key(table_name) : nil
72
+ @primary_keys.fetch(table_name) do
73
+ if data_source_exists?(table_name)
74
+ @primary_keys[deep_deduplicate(table_name)] = deep_deduplicate(connection.primary_key(table_name))
75
+ end
76
+ end
26
77
  end
27
78
 
28
79
  # A cached lookup for table existence.
@@ -30,11 +81,8 @@ module ActiveRecord
30
81
  prepare_data_sources if @data_sources.empty?
31
82
  return @data_sources[name] if @data_sources.key? name
32
83
 
33
- @data_sources[name] = connection.data_source_exists?(name)
84
+ @data_sources[deep_deduplicate(name)] = connection.data_source_exists?(name)
34
85
  end
35
- alias table_exists? data_source_exists?
36
- deprecate :table_exists? => "use #data_source_exists? instead"
37
-
38
86
 
39
87
  # Add internal cache for table with +table_name+.
40
88
  def add(table_name)
@@ -42,26 +90,42 @@ module ActiveRecord
42
90
  primary_keys(table_name)
43
91
  columns(table_name)
44
92
  columns_hash(table_name)
93
+ indexes(table_name)
45
94
  end
46
95
  end
47
96
 
48
97
  def data_sources(name)
49
98
  @data_sources[name]
50
99
  end
51
- alias tables data_sources
52
- deprecate :tables => "use #data_sources instead"
53
100
 
54
101
  # Get the columns for a table
55
102
  def columns(table_name)
56
- @columns[table_name] ||= connection.columns(table_name)
103
+ @columns.fetch(table_name) do
104
+ @columns[deep_deduplicate(table_name)] = deep_deduplicate(connection.columns(table_name))
105
+ end
57
106
  end
58
107
 
59
108
  # Get the columns for a table as a hash, key is the column name
60
109
  # value is the column object.
61
110
  def columns_hash(table_name)
62
- @columns_hash[table_name] ||= Hash[columns(table_name).map { |col|
63
- [col.name, col]
64
- }]
111
+ @columns_hash.fetch(table_name) do
112
+ @columns_hash[deep_deduplicate(table_name)] = columns(table_name).index_by(&:name).freeze
113
+ end
114
+ end
115
+
116
+ # Checks whether the columns hash is already cached for a table.
117
+ def columns_hash?(table_name)
118
+ @columns_hash.key?(table_name)
119
+ end
120
+
121
+ def indexes(table_name)
122
+ @indexes.fetch(table_name) do
123
+ @indexes[deep_deduplicate(table_name)] = deep_deduplicate(connection.indexes(table_name))
124
+ end
125
+ end
126
+
127
+ def database_version # :nodoc:
128
+ @database_version ||= connection.get_database_version
65
129
  end
66
130
 
67
131
  # Clears out internal caches
@@ -70,11 +134,13 @@ module ActiveRecord
70
134
  @columns_hash.clear
71
135
  @primary_keys.clear
72
136
  @data_sources.clear
137
+ @indexes.clear
73
138
  @version = nil
139
+ @database_version = nil
74
140
  end
75
141
 
76
142
  def size
77
- [@columns, @columns_hash, @primary_keys, @data_sources].map(&:size).inject :+
143
+ [@columns, @columns_hash, @primary_keys, @data_sources].sum(&:size)
78
144
  end
79
145
 
80
146
  # Clear out internal caches for the data source +name+.
@@ -83,25 +149,76 @@ module ActiveRecord
83
149
  @columns_hash.delete name
84
150
  @primary_keys.delete name
85
151
  @data_sources.delete name
152
+ @indexes.delete name
153
+ end
154
+
155
+ def dump_to(filename)
156
+ clear!
157
+ connection.data_sources.each { |table| add(table) }
158
+ open(filename) { |f|
159
+ if filename.include?(".dump")
160
+ f.write(Marshal.dump(self))
161
+ else
162
+ f.write(YAML.dump(self))
163
+ end
164
+ }
86
165
  end
87
- alias clear_table_cache! clear_data_source_cache!
88
- deprecate :clear_table_cache! => "use #clear_data_source_cache! instead"
89
166
 
90
167
  def marshal_dump
91
- # if we get current version during initialization, it happens stack over flow.
92
- @version = ActiveRecord::Migrator.current_version
93
- [@version, @columns, @columns_hash, @primary_keys, @data_sources]
168
+ reset_version!
169
+
170
+ [@version, @columns, {}, @primary_keys, @data_sources, @indexes, database_version]
94
171
  end
95
172
 
96
173
  def marshal_load(array)
97
- @version, @columns, @columns_hash, @primary_keys, @data_sources = array
174
+ @version, @columns, _columns_hash, @primary_keys, @data_sources, @indexes, @database_version = array
175
+ @indexes ||= {}
176
+
177
+ derive_columns_hash_and_deduplicate_values
98
178
  end
99
179
 
100
180
  private
181
+ def reset_version!
182
+ @version = connection.migration_context.current_version
183
+ end
184
+
185
+ def derive_columns_hash_and_deduplicate_values
186
+ @columns = deep_deduplicate(@columns)
187
+ @columns_hash = @columns.transform_values { |columns| columns.index_by(&:name) }
188
+ @primary_keys = deep_deduplicate(@primary_keys)
189
+ @data_sources = deep_deduplicate(@data_sources)
190
+ @indexes = deep_deduplicate(@indexes)
191
+ end
192
+
193
+ def deep_deduplicate(value)
194
+ case value
195
+ when Hash
196
+ value.transform_keys { |k| deep_deduplicate(k) }.transform_values { |v| deep_deduplicate(v) }
197
+ when Array
198
+ value.map { |i| deep_deduplicate(i) }
199
+ when String, Deduplicable
200
+ -value
201
+ else
202
+ value
203
+ end
204
+ end
101
205
 
102
206
  def prepare_data_sources
103
207
  connection.data_sources.each { |source| @data_sources[source] = true }
104
208
  end
209
+
210
+ def open(filename)
211
+ File.atomic_write(filename) do |file|
212
+ if File.extname(filename) == ".gz"
213
+ zipper = Zlib::GzipWriter.new file
214
+ yield zipper
215
+ zipper.flush
216
+ zipper.close
217
+ else
218
+ yield file
219
+ end
220
+ end
221
+ end
105
222
  end
106
223
  end
107
224
  end
@@ -1,7 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_record/connection_adapters/deduplicable"
4
+
1
5
  module ActiveRecord
2
6
  # :stopdoc:
3
7
  module ConnectionAdapters
4
8
  class SqlTypeMetadata
9
+ include Deduplicable
10
+
5
11
  attr_reader :sql_type, :type, :limit, :precision, :scale
6
12
 
7
13
  def initialize(sql_type: nil, type: nil, limit: nil, precision: nil, scale: nil)
@@ -14,19 +20,28 @@ module ActiveRecord
14
20
 
15
21
  def ==(other)
16
22
  other.is_a?(SqlTypeMetadata) &&
17
- attributes_for_hash == other.attributes_for_hash
23
+ sql_type == other.sql_type &&
24
+ type == other.type &&
25
+ limit == other.limit &&
26
+ precision == other.precision &&
27
+ scale == other.scale
18
28
  end
19
29
  alias eql? ==
20
30
 
21
31
  def hash
22
- attributes_for_hash.hash
32
+ SqlTypeMetadata.hash ^
33
+ sql_type.hash ^
34
+ type.hash ^
35
+ limit.hash ^
36
+ precision.hash >> 1 ^
37
+ scale.hash >> 2
23
38
  end
24
39
 
25
- protected
26
-
27
- def attributes_for_hash
28
- [self.class, sql_type, type, limit, precision, scale]
29
- end
40
+ private
41
+ def deduplicated
42
+ @sql_type = -sql_type
43
+ super
44
+ end
30
45
  end
31
46
  end
32
47
  end
@@ -0,0 +1,144 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module ConnectionAdapters
5
+ module SQLite3
6
+ module DatabaseStatements
7
+ READ_QUERY = ActiveRecord::ConnectionAdapters::AbstractAdapter.build_read_query_regexp(
8
+ :pragma
9
+ ) # :nodoc:
10
+ private_constant :READ_QUERY
11
+
12
+ def write_query?(sql) # :nodoc:
13
+ !READ_QUERY.match?(sql)
14
+ end
15
+
16
+ def explain(arel, binds = [])
17
+ sql = "EXPLAIN QUERY PLAN #{to_sql(arel, binds)}"
18
+ SQLite3::ExplainPrettyPrinter.new.pp(exec_query(sql, "EXPLAIN", []))
19
+ end
20
+
21
+ def execute(sql, name = nil) #:nodoc:
22
+ if preventing_writes? && write_query?(sql)
23
+ raise ActiveRecord::ReadOnlyError, "Write query attempted while in readonly mode: #{sql}"
24
+ end
25
+
26
+ materialize_transactions
27
+ mark_transaction_written_if_write(sql)
28
+
29
+ log(sql, name) do
30
+ ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
31
+ @connection.execute(sql)
32
+ end
33
+ end
34
+ end
35
+
36
+ def exec_query(sql, name = nil, binds = [], prepare: false)
37
+ if preventing_writes? && write_query?(sql)
38
+ raise ActiveRecord::ReadOnlyError, "Write query attempted while in readonly mode: #{sql}"
39
+ end
40
+
41
+ materialize_transactions
42
+ mark_transaction_written_if_write(sql)
43
+
44
+ type_casted_binds = type_casted_binds(binds)
45
+
46
+ log(sql, name, binds, type_casted_binds) do
47
+ ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
48
+ # Don't cache statements if they are not prepared
49
+ unless prepare
50
+ stmt = @connection.prepare(sql)
51
+ begin
52
+ cols = stmt.columns
53
+ unless without_prepared_statement?(binds)
54
+ stmt.bind_params(type_casted_binds)
55
+ end
56
+ records = stmt.to_a
57
+ ensure
58
+ stmt.close
59
+ end
60
+ else
61
+ stmt = @statements[sql] ||= @connection.prepare(sql)
62
+ cols = stmt.columns
63
+ stmt.reset!
64
+ stmt.bind_params(type_casted_binds)
65
+ records = stmt.to_a
66
+ end
67
+
68
+ build_result(columns: cols, rows: records)
69
+ end
70
+ end
71
+ end
72
+
73
+ def exec_delete(sql, name = "SQL", binds = [])
74
+ exec_query(sql, name, binds)
75
+ @connection.changes
76
+ end
77
+ alias :exec_update :exec_delete
78
+
79
+ def begin_isolated_db_transaction(isolation) #:nodoc
80
+ raise TransactionIsolationError, "SQLite3 only supports the `read_uncommitted` transaction isolation level" if isolation != :read_uncommitted
81
+ raise StandardError, "You need to enable the shared-cache mode in SQLite mode before attempting to change the transaction isolation level" unless shared_cache?
82
+
83
+ Thread.current.thread_variable_set("read_uncommitted", @connection.get_first_value("PRAGMA read_uncommitted"))
84
+ @connection.read_uncommitted = true
85
+ begin_db_transaction
86
+ end
87
+
88
+ def begin_db_transaction #:nodoc:
89
+ log("begin transaction", "TRANSACTION") { @connection.transaction }
90
+ end
91
+
92
+ def commit_db_transaction #:nodoc:
93
+ log("commit transaction", "TRANSACTION") { @connection.commit }
94
+ reset_read_uncommitted
95
+ end
96
+
97
+ def exec_rollback_db_transaction #:nodoc:
98
+ log("rollback transaction", "TRANSACTION") { @connection.rollback }
99
+ reset_read_uncommitted
100
+ end
101
+
102
+ private
103
+ def reset_read_uncommitted
104
+ read_uncommitted = Thread.current.thread_variable_get("read_uncommitted")
105
+ return unless read_uncommitted
106
+
107
+ @connection.read_uncommitted = read_uncommitted
108
+ end
109
+
110
+ def execute_batch(statements, name = nil)
111
+ sql = combine_multi_statements(statements)
112
+
113
+ if preventing_writes? && write_query?(sql)
114
+ raise ActiveRecord::ReadOnlyError, "Write query attempted while in readonly mode: #{sql}"
115
+ end
116
+
117
+ materialize_transactions
118
+ mark_transaction_written_if_write(sql)
119
+
120
+ log(sql, name) do
121
+ ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
122
+ @connection.execute_batch2(sql)
123
+ end
124
+ end
125
+ end
126
+
127
+ def last_inserted_id(result)
128
+ @connection.last_insert_row_id
129
+ end
130
+
131
+ def build_fixture_statements(fixture_set)
132
+ fixture_set.flat_map do |table_name, fixtures|
133
+ next if fixtures.empty?
134
+ fixtures.map { |fixture| build_fixture_sql([fixture], table_name) }
135
+ end.compact
136
+ end
137
+
138
+ def build_truncate_statement(table_name)
139
+ "DELETE FROM #{quote_table_name(table_name)}"
140
+ end
141
+ end
142
+ end
143
+ end
144
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module SQLite3
@@ -10,7 +12,7 @@ module ActiveRecord
10
12
  #
11
13
  def pp(result)
12
14
  result.rows.map do |row|
13
- row.join('|')
15
+ row.join("|")
14
16
  end.join("\n") + "\n"
15
17
  end
16
18
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module SQLite3
@@ -10,38 +12,90 @@ module ActiveRecord
10
12
  quote_column_name(attr)
11
13
  end
12
14
 
15
+ def quote_table_name(name)
16
+ self.class.quoted_table_names[name] ||= super.gsub(".", "\".\"").freeze
17
+ end
18
+
13
19
  def quote_column_name(name)
14
- @quoted_column_names[name] ||= %Q("#{super.gsub('"', '""')}")
20
+ self.class.quoted_column_names[name] ||= %Q("#{super.gsub('"', '""')}")
15
21
  end
16
22
 
17
23
  def quoted_time(value)
24
+ value = value.change(year: 2000, month: 1, day: 1)
18
25
  quoted_date(value).sub(/\A\d\d\d\d-\d\d-\d\d /, "2000-01-01 ")
19
26
  end
20
27
 
21
- private
28
+ def quoted_binary(value)
29
+ "x'#{value.hex}'"
30
+ end
22
31
 
23
- def _quote(value)
24
- if value.is_a?(Type::Binary::Data)
25
- "x'#{value.hex}'"
26
- else
27
- super
28
- end
32
+ def quoted_true
33
+ "1"
29
34
  end
30
35
 
31
- def _type_cast(value)
32
- case value
33
- when BigDecimal
34
- value.to_f
35
- when String
36
- if value.encoding == Encoding::ASCII_8BIT
37
- super(value.encode(Encoding::UTF_8))
36
+ def unquoted_true
37
+ 1
38
+ end
39
+
40
+ def quoted_false
41
+ "0"
42
+ end
43
+
44
+ def unquoted_false
45
+ 0
46
+ end
47
+
48
+ def column_name_matcher
49
+ COLUMN_NAME
50
+ end
51
+
52
+ def column_name_with_order_matcher
53
+ COLUMN_NAME_WITH_ORDER
54
+ end
55
+
56
+ COLUMN_NAME = /
57
+ \A
58
+ (
59
+ (?:
60
+ # "table_name"."column_name" | function(one or no argument)
61
+ ((?:\w+\.|"\w+"\.)?(?:\w+|"\w+")) | \w+\((?:|\g<2>)\)
62
+ )
63
+ (?:(?:\s+AS)?\s+(?:\w+|"\w+"))?
64
+ )
65
+ (?:\s*,\s*\g<1>)*
66
+ \z
67
+ /ix
68
+
69
+ COLUMN_NAME_WITH_ORDER = /
70
+ \A
71
+ (
72
+ (?:
73
+ # "table_name"."column_name" | function(one or no argument)
74
+ ((?:\w+\.|"\w+"\.)?(?:\w+|"\w+")) | \w+\((?:|\g<2>)\)
75
+ )
76
+ (?:\s+ASC|\s+DESC)?
77
+ )
78
+ (?:\s*,\s*\g<1>)*
79
+ \z
80
+ /ix
81
+
82
+ private_constant :COLUMN_NAME, :COLUMN_NAME_WITH_ORDER
83
+
84
+ private
85
+ def _type_cast(value)
86
+ case value
87
+ when BigDecimal
88
+ value.to_f
89
+ when String
90
+ if value.encoding == Encoding::ASCII_8BIT
91
+ super(value.encode(Encoding::UTF_8))
92
+ else
93
+ super
94
+ end
38
95
  else
39
96
  super
40
97
  end
41
- else
42
- super
43
98
  end
44
- end
45
99
  end
46
100
  end
47
101
  end