activerecord 5.0.6 → 6.0.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 (358) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +638 -2023
  3. data/MIT-LICENSE +3 -1
  4. data/README.rdoc +8 -6
  5. data/examples/performance.rb +31 -29
  6. data/examples/simple.rb +5 -3
  7. data/lib/active_record/aggregations.rb +249 -246
  8. data/lib/active_record/association_relation.rb +24 -13
  9. data/lib/active_record/associations/alias_tracker.rb +24 -33
  10. data/lib/active_record/associations/association.rb +119 -56
  11. data/lib/active_record/associations/association_scope.rb +94 -94
  12. data/lib/active_record/associations/belongs_to_association.rb +58 -42
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
  14. data/lib/active_record/associations/builder/association.rb +18 -25
  15. data/lib/active_record/associations/builder/belongs_to.rb +43 -54
  16. data/lib/active_record/associations/builder/collection_association.rb +7 -18
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +42 -61
  18. data/lib/active_record/associations/builder/has_many.rb +4 -0
  19. data/lib/active_record/associations/builder/has_one.rb +37 -1
  20. data/lib/active_record/associations/builder/singular_association.rb +4 -0
  21. data/lib/active_record/associations/collection_association.rb +80 -252
  22. data/lib/active_record/associations/collection_proxy.rb +158 -121
  23. data/lib/active_record/associations/foreign_association.rb +9 -0
  24. data/lib/active_record/associations/has_many_association.rb +23 -29
  25. data/lib/active_record/associations/has_many_through_association.rb +58 -44
  26. data/lib/active_record/associations/has_one_association.rb +59 -54
  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 -90
  29. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  30. data/lib/active_record/associations/join_dependency/join_part.rb +12 -12
  31. data/lib/active_record/associations/join_dependency.rb +134 -176
  32. data/lib/active_record/associations/preloader/association.rb +84 -125
  33. data/lib/active_record/associations/preloader/through_association.rb +82 -75
  34. data/lib/active_record/associations/preloader.rb +90 -102
  35. data/lib/active_record/associations/singular_association.rb +12 -45
  36. data/lib/active_record/associations/through_association.rb +26 -14
  37. data/lib/active_record/associations.rb +1603 -1592
  38. data/lib/active_record/attribute_assignment.rb +54 -60
  39. data/lib/active_record/attribute_decorators.rb +38 -15
  40. data/lib/active_record/attribute_methods/before_type_cast.rb +12 -7
  41. data/lib/active_record/attribute_methods/dirty.rb +179 -109
  42. data/lib/active_record/attribute_methods/primary_key.rb +86 -91
  43. data/lib/active_record/attribute_methods/query.rb +4 -3
  44. data/lib/active_record/attribute_methods/read.rb +21 -49
  45. data/lib/active_record/attribute_methods/serialization.rb +30 -7
  46. data/lib/active_record/attribute_methods/time_zone_conversion.rb +39 -64
  47. data/lib/active_record/attribute_methods/write.rb +35 -33
  48. data/lib/active_record/attribute_methods.rb +66 -106
  49. data/lib/active_record/attributes.rb +38 -24
  50. data/lib/active_record/autosave_association.rb +53 -32
  51. data/lib/active_record/base.rb +27 -24
  52. data/lib/active_record/callbacks.rb +63 -33
  53. data/lib/active_record/coders/json.rb +2 -0
  54. data/lib/active_record/coders/yaml_column.rb +11 -11
  55. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +553 -321
  56. data/lib/active_record/connection_adapters/abstract/database_limits.rb +23 -5
  57. data/lib/active_record/connection_adapters/abstract/database_statements.rb +213 -94
  58. data/lib/active_record/connection_adapters/abstract/query_cache.rb +59 -28
  59. data/lib/active_record/connection_adapters/abstract/quoting.rb +119 -75
  60. data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
  61. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +33 -27
  62. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +207 -126
  63. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +68 -80
  64. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +369 -199
  65. data/lib/active_record/connection_adapters/abstract/transaction.rb +169 -78
  66. data/lib/active_record/connection_adapters/abstract_adapter.rb +363 -202
  67. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +405 -551
  68. data/lib/active_record/connection_adapters/column.rb +41 -13
  69. data/lib/active_record/connection_adapters/connection_specification.rb +172 -138
  70. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +11 -4
  71. data/lib/active_record/connection_adapters/mysql/column.rb +8 -31
  72. data/lib/active_record/connection_adapters/mysql/database_statements.rb +143 -49
  73. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +24 -22
  74. data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -20
  75. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +50 -45
  76. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +58 -56
  77. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +70 -36
  78. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +264 -0
  79. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +12 -13
  80. data/lib/active_record/connection_adapters/mysql2_adapter.rb +49 -30
  81. data/lib/active_record/connection_adapters/postgresql/column.rb +22 -7
  82. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +60 -54
  83. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +5 -3
  84. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +22 -10
  85. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +6 -5
  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 +2 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -1
  89. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
  90. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +4 -2
  91. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  92. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -3
  93. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +19 -17
  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 -5
  98. data/lib/active_record/connection_adapters/postgresql/oid/{json.rb → oid.rb} +6 -1
  99. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +31 -9
  100. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +34 -30
  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 +58 -54
  103. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +9 -4
  104. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
  105. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
  106. data/lib/active_record/connection_adapters/postgresql/oid.rb +24 -21
  107. data/lib/active_record/connection_adapters/postgresql/quoting.rb +95 -35
  108. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +19 -25
  109. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
  110. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +147 -105
  111. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +35 -32
  112. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +380 -300
  113. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +26 -25
  114. data/lib/active_record/connection_adapters/postgresql/utils.rb +10 -6
  115. data/lib/active_record/connection_adapters/postgresql_adapter.rb +382 -275
  116. data/lib/active_record/connection_adapters/schema_cache.rb +46 -12
  117. data/lib/active_record/connection_adapters/sql_type_metadata.rb +13 -8
  118. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +120 -0
  119. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +3 -1
  120. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +74 -19
  121. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +3 -8
  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 +254 -262
  126. data/lib/active_record/connection_adapters/statement_pool.rb +9 -7
  127. data/lib/active_record/connection_handling.rb +159 -40
  128. data/lib/active_record/core.rb +202 -162
  129. data/lib/active_record/counter_cache.rb +57 -28
  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 -86
  136. data/lib/active_record/enum.rb +60 -23
  137. data/lib/active_record/errors.rb +114 -18
  138. data/lib/active_record/explain.rb +4 -3
  139. data/lib/active_record/explain_registry.rb +3 -1
  140. data/lib/active_record/explain_subscriber.rb +9 -4
  141. data/lib/active_record/fixture_set/file.rb +13 -8
  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 +195 -502
  147. data/lib/active_record/gem_version.rb +4 -2
  148. data/lib/active_record/inheritance.rb +151 -97
  149. data/lib/active_record/insert_all.rb +179 -0
  150. data/lib/active_record/integration.rb +116 -25
  151. data/lib/active_record/internal_metadata.rb +15 -18
  152. data/lib/active_record/legacy_yaml_adapter.rb +4 -2
  153. data/lib/active_record/locking/optimistic.rb +78 -87
  154. data/lib/active_record/locking/pessimistic.rb +18 -6
  155. data/lib/active_record/log_subscriber.rb +48 -29
  156. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  157. data/lib/active_record/middleware/database_selector/resolver.rb +88 -0
  158. data/lib/active_record/middleware/database_selector.rb +75 -0
  159. data/lib/active_record/migration/command_recorder.rb +143 -97
  160. data/lib/active_record/migration/compatibility.rb +174 -56
  161. data/lib/active_record/migration/join_table.rb +8 -6
  162. data/lib/active_record/migration.rb +367 -300
  163. data/lib/active_record/model_schema.rb +145 -139
  164. data/lib/active_record/nested_attributes.rb +214 -201
  165. data/lib/active_record/no_touching.rb +10 -1
  166. data/lib/active_record/null_relation.rb +13 -34
  167. data/lib/active_record/persistence.rb +442 -72
  168. data/lib/active_record/query_cache.rb +15 -14
  169. data/lib/active_record/querying.rb +36 -23
  170. data/lib/active_record/railtie.rb +128 -36
  171. data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
  172. data/lib/active_record/railties/console_sandbox.rb +2 -0
  173. data/lib/active_record/railties/controller_runtime.rb +34 -33
  174. data/lib/active_record/railties/databases.rake +309 -177
  175. data/lib/active_record/readonly_attributes.rb +5 -4
  176. data/lib/active_record/reflection.rb +211 -249
  177. data/lib/active_record/relation/batches/batch_enumerator.rb +3 -1
  178. data/lib/active_record/relation/batches.rb +99 -52
  179. data/lib/active_record/relation/calculations.rb +211 -172
  180. data/lib/active_record/relation/delegation.rb +67 -65
  181. data/lib/active_record/relation/finder_methods.rb +208 -247
  182. data/lib/active_record/relation/from_clause.rb +2 -8
  183. data/lib/active_record/relation/merger.rb +78 -61
  184. data/lib/active_record/relation/predicate_builder/array_handler.rb +20 -14
  185. data/lib/active_record/relation/predicate_builder/association_query_value.rb +43 -0
  186. data/lib/active_record/relation/predicate_builder/base_handler.rb +4 -3
  187. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +6 -4
  188. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +53 -0
  189. data/lib/active_record/relation/predicate_builder/range_handler.rb +7 -18
  190. data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
  191. data/lib/active_record/relation/predicate_builder.rb +86 -104
  192. data/lib/active_record/relation/query_attribute.rb +33 -2
  193. data/lib/active_record/relation/query_methods.rb +458 -329
  194. data/lib/active_record/relation/record_fetch_warning.rb +5 -3
  195. data/lib/active_record/relation/spawn_methods.rb +8 -7
  196. data/lib/active_record/relation/where_clause.rb +111 -95
  197. data/lib/active_record/relation/where_clause_factory.rb +6 -11
  198. data/lib/active_record/relation.rb +429 -318
  199. data/lib/active_record/result.rb +69 -39
  200. data/lib/active_record/runtime_registry.rb +5 -3
  201. data/lib/active_record/sanitization.rb +83 -99
  202. data/lib/active_record/schema.rb +7 -14
  203. data/lib/active_record/schema_dumper.rb +71 -69
  204. data/lib/active_record/schema_migration.rb +15 -5
  205. data/lib/active_record/scoping/default.rb +93 -95
  206. data/lib/active_record/scoping/named.rb +45 -25
  207. data/lib/active_record/scoping.rb +20 -19
  208. data/lib/active_record/secure_token.rb +4 -2
  209. data/lib/active_record/serialization.rb +2 -0
  210. data/lib/active_record/statement_cache.rb +63 -28
  211. data/lib/active_record/store.rb +121 -41
  212. data/lib/active_record/suppressor.rb +4 -1
  213. data/lib/active_record/table_metadata.rb +26 -20
  214. data/lib/active_record/tasks/database_tasks.rb +276 -85
  215. data/lib/active_record/tasks/mysql_database_tasks.rb +54 -90
  216. data/lib/active_record/tasks/postgresql_database_tasks.rb +78 -47
  217. data/lib/active_record/tasks/sqlite_database_tasks.rb +34 -16
  218. data/lib/active_record/test_databases.rb +23 -0
  219. data/lib/active_record/test_fixtures.rb +224 -0
  220. data/lib/active_record/timestamp.rb +70 -35
  221. data/lib/active_record/touch_later.rb +7 -4
  222. data/lib/active_record/transactions.rb +133 -149
  223. data/lib/active_record/translation.rb +3 -1
  224. data/lib/active_record/type/adapter_specific_registry.rb +44 -45
  225. data/lib/active_record/type/date.rb +2 -0
  226. data/lib/active_record/type/date_time.rb +2 -0
  227. data/lib/active_record/type/decimal_without_scale.rb +15 -0
  228. data/lib/active_record/type/hash_lookup_type_map.rb +5 -3
  229. data/lib/active_record/type/internal/timezone.rb +2 -0
  230. data/lib/active_record/type/json.rb +30 -0
  231. data/lib/active_record/type/serialized.rb +16 -8
  232. data/lib/active_record/type/text.rb +11 -0
  233. data/lib/active_record/type/time.rb +2 -1
  234. data/lib/active_record/type/type_map.rb +13 -15
  235. data/lib/active_record/type/unsigned_integer.rb +17 -0
  236. data/lib/active_record/type.rb +23 -17
  237. data/lib/active_record/type_caster/connection.rb +17 -12
  238. data/lib/active_record/type_caster/map.rb +5 -4
  239. data/lib/active_record/type_caster.rb +4 -2
  240. data/lib/active_record/validations/absence.rb +2 -0
  241. data/lib/active_record/validations/associated.rb +3 -1
  242. data/lib/active_record/validations/length.rb +2 -0
  243. data/lib/active_record/validations/presence.rb +4 -2
  244. data/lib/active_record/validations/uniqueness.rb +29 -42
  245. data/lib/active_record/validations.rb +7 -4
  246. data/lib/active_record/version.rb +3 -1
  247. data/lib/active_record.rb +36 -22
  248. data/lib/arel/alias_predication.rb +9 -0
  249. data/lib/arel/attributes/attribute.rb +37 -0
  250. data/lib/arel/attributes.rb +22 -0
  251. data/lib/arel/collectors/bind.rb +24 -0
  252. data/lib/arel/collectors/composite.rb +31 -0
  253. data/lib/arel/collectors/plain_string.rb +20 -0
  254. data/lib/arel/collectors/sql_string.rb +20 -0
  255. data/lib/arel/collectors/substitute_binds.rb +28 -0
  256. data/lib/arel/crud.rb +42 -0
  257. data/lib/arel/delete_manager.rb +18 -0
  258. data/lib/arel/errors.rb +9 -0
  259. data/lib/arel/expressions.rb +29 -0
  260. data/lib/arel/factory_methods.rb +49 -0
  261. data/lib/arel/insert_manager.rb +49 -0
  262. data/lib/arel/math.rb +45 -0
  263. data/lib/arel/nodes/and.rb +32 -0
  264. data/lib/arel/nodes/ascending.rb +23 -0
  265. data/lib/arel/nodes/binary.rb +52 -0
  266. data/lib/arel/nodes/bind_param.rb +36 -0
  267. data/lib/arel/nodes/case.rb +55 -0
  268. data/lib/arel/nodes/casted.rb +50 -0
  269. data/lib/arel/nodes/comment.rb +29 -0
  270. data/lib/arel/nodes/count.rb +12 -0
  271. data/lib/arel/nodes/delete_statement.rb +45 -0
  272. data/lib/arel/nodes/descending.rb +23 -0
  273. data/lib/arel/nodes/equality.rb +18 -0
  274. data/lib/arel/nodes/extract.rb +24 -0
  275. data/lib/arel/nodes/false.rb +16 -0
  276. data/lib/arel/nodes/full_outer_join.rb +8 -0
  277. data/lib/arel/nodes/function.rb +44 -0
  278. data/lib/arel/nodes/grouping.rb +8 -0
  279. data/lib/arel/nodes/in.rb +8 -0
  280. data/lib/arel/nodes/infix_operation.rb +80 -0
  281. data/lib/arel/nodes/inner_join.rb +8 -0
  282. data/lib/arel/nodes/insert_statement.rb +37 -0
  283. data/lib/arel/nodes/join_source.rb +20 -0
  284. data/lib/arel/nodes/matches.rb +18 -0
  285. data/lib/arel/nodes/named_function.rb +23 -0
  286. data/lib/arel/nodes/node.rb +50 -0
  287. data/lib/arel/nodes/node_expression.rb +13 -0
  288. data/lib/arel/nodes/outer_join.rb +8 -0
  289. data/lib/arel/nodes/over.rb +15 -0
  290. data/lib/arel/nodes/regexp.rb +16 -0
  291. data/lib/arel/nodes/right_outer_join.rb +8 -0
  292. data/lib/arel/nodes/select_core.rb +67 -0
  293. data/lib/arel/nodes/select_statement.rb +41 -0
  294. data/lib/arel/nodes/sql_literal.rb +16 -0
  295. data/lib/arel/nodes/string_join.rb +11 -0
  296. data/lib/arel/nodes/table_alias.rb +27 -0
  297. data/lib/arel/nodes/terminal.rb +16 -0
  298. data/lib/arel/nodes/true.rb +16 -0
  299. data/lib/arel/nodes/unary.rb +45 -0
  300. data/lib/arel/nodes/unary_operation.rb +20 -0
  301. data/lib/arel/nodes/unqualified_column.rb +22 -0
  302. data/lib/arel/nodes/update_statement.rb +41 -0
  303. data/lib/arel/nodes/values_list.rb +9 -0
  304. data/lib/arel/nodes/window.rb +126 -0
  305. data/lib/arel/nodes/with.rb +11 -0
  306. data/lib/arel/nodes.rb +68 -0
  307. data/lib/arel/order_predications.rb +13 -0
  308. data/lib/arel/predications.rb +257 -0
  309. data/lib/arel/select_manager.rb +271 -0
  310. data/lib/arel/table.rb +110 -0
  311. data/lib/arel/tree_manager.rb +72 -0
  312. data/lib/arel/update_manager.rb +34 -0
  313. data/lib/arel/visitors/depth_first.rb +204 -0
  314. data/lib/arel/visitors/dot.rb +297 -0
  315. data/lib/arel/visitors/ibm_db.rb +34 -0
  316. data/lib/arel/visitors/informix.rb +62 -0
  317. data/lib/arel/visitors/mssql.rb +157 -0
  318. data/lib/arel/visitors/mysql.rb +83 -0
  319. data/lib/arel/visitors/oracle.rb +159 -0
  320. data/lib/arel/visitors/oracle12.rb +66 -0
  321. data/lib/arel/visitors/postgresql.rb +110 -0
  322. data/lib/arel/visitors/sqlite.rb +39 -0
  323. data/lib/arel/visitors/to_sql.rb +889 -0
  324. data/lib/arel/visitors/visitor.rb +46 -0
  325. data/lib/arel/visitors/where_sql.rb +23 -0
  326. data/lib/arel/visitors.rb +20 -0
  327. data/lib/arel/window_predications.rb +9 -0
  328. data/lib/arel.rb +58 -0
  329. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -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/migration_generator.rb +37 -35
  332. data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +1 -1
  333. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +4 -2
  334. data/lib/rails/generators/active_record/migration.rb +17 -2
  335. data/lib/rails/generators/active_record/model/model_generator.rb +9 -29
  336. data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +10 -1
  337. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
  338. data/lib/rails/generators/active_record.rb +7 -5
  339. metadata +133 -50
  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/user_provided_default.rb +0 -28
  348. data/lib/active_record/attribute.rb +0 -213
  349. data/lib/active_record/attribute_mutation_tracker.rb +0 -70
  350. data/lib/active_record/attribute_set/builder.rb +0 -130
  351. data/lib/active_record/attribute_set.rb +0 -110
  352. data/lib/active_record/collection_cache_key.rb +0 -50
  353. data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +0 -50
  354. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  355. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
  356. data/lib/active_record/relation/predicate_builder/class_handler.rb +0 -27
  357. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -57
  358. data/lib/active_record/type/internal/abstract_json.rb +0 -33
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  class SchemaCache
@@ -11,6 +13,7 @@ module ActiveRecord
11
13
  @columns_hash = {}
12
14
  @primary_keys = {}
13
15
  @data_sources = {}
16
+ @indexes = {}
14
17
  end
15
18
 
16
19
  def initialize_dup(other)
@@ -19,6 +22,27 @@ module ActiveRecord
19
22
  @columns_hash = @columns_hash.dup
20
23
  @primary_keys = @primary_keys.dup
21
24
  @data_sources = @data_sources.dup
25
+ @indexes = @indexes.dup
26
+ end
27
+
28
+ def encode_with(coder)
29
+ coder["columns"] = @columns
30
+ coder["columns_hash"] = @columns_hash
31
+ coder["primary_keys"] = @primary_keys
32
+ coder["data_sources"] = @data_sources
33
+ coder["indexes"] = @indexes
34
+ coder["version"] = connection.migration_context.current_version
35
+ coder["database_version"] = database_version
36
+ end
37
+
38
+ def init_with(coder)
39
+ @columns = coder["columns"]
40
+ @columns_hash = coder["columns_hash"]
41
+ @primary_keys = coder["primary_keys"]
42
+ @data_sources = coder["data_sources"]
43
+ @indexes = coder["indexes"] || {}
44
+ @version = coder["version"]
45
+ @database_version = coder["database_version"]
22
46
  end
23
47
 
24
48
  def primary_keys(table_name)
@@ -32,9 +56,6 @@ module ActiveRecord
32
56
 
33
57
  @data_sources[name] = connection.data_source_exists?(name)
34
58
  end
35
- alias table_exists? data_source_exists?
36
- deprecate :table_exists? => "use #data_source_exists? instead"
37
-
38
59
 
39
60
  # Add internal cache for table with +table_name+.
40
61
  def add(table_name)
@@ -42,14 +63,13 @@ module ActiveRecord
42
63
  primary_keys(table_name)
43
64
  columns(table_name)
44
65
  columns_hash(table_name)
66
+ indexes(table_name)
45
67
  end
46
68
  end
47
69
 
48
70
  def data_sources(name)
49
71
  @data_sources[name]
50
72
  end
51
- alias tables data_sources
52
- deprecate :tables => "use #data_sources instead"
53
73
 
54
74
  # Get the columns for a table
55
75
  def columns(table_name)
@@ -64,17 +84,32 @@ module ActiveRecord
64
84
  }]
65
85
  end
66
86
 
87
+ # Checks whether the columns hash is already cached for a table.
88
+ def columns_hash?(table_name)
89
+ @columns_hash.key?(table_name)
90
+ end
91
+
92
+ def indexes(table_name)
93
+ @indexes[table_name] ||= connection.indexes(table_name)
94
+ end
95
+
96
+ def database_version # :nodoc:
97
+ @database_version ||= connection.get_database_version
98
+ end
99
+
67
100
  # Clears out internal caches
68
101
  def clear!
69
102
  @columns.clear
70
103
  @columns_hash.clear
71
104
  @primary_keys.clear
72
105
  @data_sources.clear
106
+ @indexes.clear
73
107
  @version = nil
108
+ @database_version = nil
74
109
  end
75
110
 
76
111
  def size
77
- [@columns, @columns_hash, @primary_keys, @data_sources].map(&:size).inject :+
112
+ [@columns, @columns_hash, @primary_keys, @data_sources].sum(&:size)
78
113
  end
79
114
 
80
115
  # Clear out internal caches for the data source +name+.
@@ -83,22 +118,21 @@ module ActiveRecord
83
118
  @columns_hash.delete name
84
119
  @primary_keys.delete name
85
120
  @data_sources.delete name
121
+ @indexes.delete name
86
122
  end
87
- alias clear_table_cache! clear_data_source_cache!
88
- deprecate :clear_table_cache! => "use #clear_data_source_cache! instead"
89
123
 
90
124
  def marshal_dump
91
125
  # 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]
126
+ @version = connection.migration_context.current_version
127
+ [@version, @columns, @columns_hash, @primary_keys, @data_sources, @indexes, database_version]
94
128
  end
95
129
 
96
130
  def marshal_load(array)
97
- @version, @columns, @columns_hash, @primary_keys, @data_sources = array
131
+ @version, @columns, @columns_hash, @primary_keys, @data_sources, @indexes, @database_version = array
132
+ @indexes = @indexes || {}
98
133
  end
99
134
 
100
135
  private
101
-
102
136
  def prepare_data_sources
103
137
  connection.data_sources.each { |source| @data_sources[source] = true }
104
138
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  # :stopdoc:
3
5
  module ConnectionAdapters
@@ -14,18 +16,21 @@ module ActiveRecord
14
16
 
15
17
  def ==(other)
16
18
  other.is_a?(SqlTypeMetadata) &&
17
- attributes_for_hash == other.attributes_for_hash
19
+ sql_type == other.sql_type &&
20
+ type == other.type &&
21
+ limit == other.limit &&
22
+ precision == other.precision &&
23
+ scale == other.scale
18
24
  end
19
25
  alias eql? ==
20
26
 
21
27
  def hash
22
- attributes_for_hash.hash
23
- end
24
-
25
- protected
26
-
27
- def attributes_for_hash
28
- [self.class, sql_type, type, limit, precision, scale]
28
+ SqlTypeMetadata.hash ^
29
+ sql_type.hash ^
30
+ type.hash ^
31
+ limit.hash ^
32
+ precision.hash >> 1 ^
33
+ scale.hash >> 2
29
34
  end
30
35
  end
31
36
  end
@@ -0,0 +1,120 @@
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
+ :begin, :commit, :explain, :select, :pragma, :release, :savepoint, :rollback, :with
9
+ ) # :nodoc:
10
+ private_constant :READ_QUERY
11
+
12
+ def write_query?(sql) # :nodoc:
13
+ !READ_QUERY.match?(sql)
14
+ end
15
+
16
+ def execute(sql, name = nil) #:nodoc:
17
+ if preventing_writes? && write_query?(sql)
18
+ raise ActiveRecord::ReadOnlyError, "Write query attempted while in readonly mode: #{sql}"
19
+ end
20
+
21
+ materialize_transactions
22
+
23
+ log(sql, name) do
24
+ ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
25
+ @connection.execute(sql)
26
+ end
27
+ end
28
+ end
29
+
30
+ def exec_query(sql, name = nil, binds = [], prepare: false)
31
+ if preventing_writes? && write_query?(sql)
32
+ raise ActiveRecord::ReadOnlyError, "Write query attempted while in readonly mode: #{sql}"
33
+ end
34
+
35
+ materialize_transactions
36
+
37
+ type_casted_binds = type_casted_binds(binds)
38
+
39
+ log(sql, name, binds, type_casted_binds) do
40
+ ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
41
+ # Don't cache statements if they are not prepared
42
+ unless prepare
43
+ stmt = @connection.prepare(sql)
44
+ begin
45
+ cols = stmt.columns
46
+ unless without_prepared_statement?(binds)
47
+ stmt.bind_params(type_casted_binds)
48
+ end
49
+ records = stmt.to_a
50
+ ensure
51
+ stmt.close
52
+ end
53
+ else
54
+ stmt = @statements[sql] ||= @connection.prepare(sql)
55
+ cols = stmt.columns
56
+ stmt.reset!
57
+ stmt.bind_params(type_casted_binds)
58
+ records = stmt.to_a
59
+ end
60
+
61
+ ActiveRecord::Result.new(cols, records)
62
+ end
63
+ end
64
+ end
65
+
66
+ def exec_delete(sql, name = "SQL", binds = [])
67
+ exec_query(sql, name, binds)
68
+ @connection.changes
69
+ end
70
+ alias :exec_update :exec_delete
71
+
72
+ def begin_db_transaction #:nodoc:
73
+ log("begin transaction", nil) { @connection.transaction }
74
+ end
75
+
76
+ def commit_db_transaction #:nodoc:
77
+ log("commit transaction", nil) { @connection.commit }
78
+ end
79
+
80
+ def exec_rollback_db_transaction #:nodoc:
81
+ log("rollback transaction", nil) { @connection.rollback }
82
+ end
83
+
84
+
85
+ private
86
+ def execute_batch(sql, name = nil)
87
+ if preventing_writes? && write_query?(sql)
88
+ raise ActiveRecord::ReadOnlyError, "Write query attempted while in readonly mode: #{sql}"
89
+ end
90
+
91
+ materialize_transactions
92
+
93
+ log(sql, name) do
94
+ ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
95
+ @connection.execute_batch2(sql)
96
+ end
97
+ end
98
+ end
99
+
100
+ def last_inserted_id(result)
101
+ @connection.last_insert_row_id
102
+ end
103
+
104
+ def build_fixture_statements(fixture_set)
105
+ fixture_set.flat_map do |table_name, fixtures|
106
+ next if fixtures.empty?
107
+ fixtures.map { |fixture| build_fixture_sql([fixture], table_name) }
108
+ end.compact
109
+ end
110
+
111
+ def build_truncate_statements(*table_names)
112
+ truncate_tables = table_names.map do |table_name|
113
+ "DELETE FROM #{quote_table_name(table_name)}"
114
+ end
115
+ combine_multi_statements(truncate_tables)
116
+ end
117
+ end
118
+ end
119
+ end
120
+ 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,91 @@ 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)
18
- quoted_date(value)
24
+ value = value.change(year: 2000, month: 1, day: 1)
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"
34
+ end
35
+
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
29
50
  end
30
51
 
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))
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
+
86
+ def _type_cast(value)
87
+ case value
88
+ when BigDecimal
89
+ value.to_f
90
+ when String
91
+ if value.encoding == Encoding::ASCII_8BIT
92
+ super(value.encode(Encoding::UTF_8))
93
+ else
94
+ super
95
+ end
38
96
  else
39
97
  super
40
98
  end
41
- else
42
- super
43
99
  end
44
- end
45
100
  end
46
101
  end
47
102
  end
@@ -1,15 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module SQLite3
4
- class SchemaCreation < AbstractAdapter::SchemaCreation
6
+ class SchemaCreation < AbstractAdapter::SchemaCreation # :nodoc:
5
7
  private
6
-
7
- def column_options(o)
8
- options = super
9
- options[:null] = false if o.primary_key
10
- options
11
- end
12
-
13
8
  def add_column_options!(sql, options)
14
9
  if options[:collation]
15
10
  sql << " COLLATE \"#{options[:collation]}\""
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module ConnectionAdapters
5
+ module SQLite3
6
+ class TableDefinition < ActiveRecord::ConnectionAdapters::TableDefinition
7
+ def references(*args, **options)
8
+ super(*args, type: :integer, **options)
9
+ end
10
+ alias :belongs_to :references
11
+
12
+ private
13
+ def integer_like_primary_key_type(type, options)
14
+ :primary_key
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module ConnectionAdapters
5
+ module SQLite3
6
+ class SchemaDumper < ConnectionAdapters::SchemaDumper # :nodoc:
7
+ private
8
+ def default_primary_key?(column)
9
+ schema_type(column) == :integer
10
+ end
11
+
12
+ def explicit_primary_key_default?(column)
13
+ column.bigint?
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,137 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module ConnectionAdapters
5
+ module SQLite3
6
+ module SchemaStatements # :nodoc:
7
+ # Returns an array of indexes for the given table.
8
+ def indexes(table_name)
9
+ exec_query("PRAGMA index_list(#{quote_table_name(table_name)})", "SCHEMA").map do |row|
10
+ # Indexes SQLite creates implicitly for internal use start with "sqlite_".
11
+ # See https://www.sqlite.org/fileformat2.html#intschema
12
+ next if row["name"].starts_with?("sqlite_")
13
+
14
+ index_sql = query_value(<<~SQL, "SCHEMA")
15
+ SELECT sql
16
+ FROM sqlite_master
17
+ WHERE name = #{quote(row['name'])} AND type = 'index'
18
+ UNION ALL
19
+ SELECT sql
20
+ FROM sqlite_temp_master
21
+ WHERE name = #{quote(row['name'])} AND type = 'index'
22
+ SQL
23
+
24
+ /\bON\b\s*"?(\w+?)"?\s*\((?<expressions>.+?)\)(?:\s*WHERE\b\s*(?<where>.+))?\z/i =~ index_sql
25
+
26
+ columns = exec_query("PRAGMA index_info(#{quote(row['name'])})", "SCHEMA").map do |col|
27
+ col["name"]
28
+ end
29
+
30
+ orders = {}
31
+
32
+ if columns.any?(&:nil?) # index created with an expression
33
+ columns = expressions
34
+ else
35
+ # Add info on sort order for columns (only desc order is explicitly specified,
36
+ # asc is the default)
37
+ if index_sql # index_sql can be null in case of primary key indexes
38
+ index_sql.scan(/"(\w+)" DESC/).flatten.each { |order_column|
39
+ orders[order_column] = :desc
40
+ }
41
+ end
42
+ end
43
+
44
+ IndexDefinition.new(
45
+ table_name,
46
+ row["name"],
47
+ row["unique"] != 0,
48
+ columns,
49
+ where: where,
50
+ orders: orders
51
+ )
52
+ end.compact
53
+ end
54
+
55
+ def add_foreign_key(from_table, to_table, **options)
56
+ alter_table(from_table) do |definition|
57
+ to_table = strip_table_name_prefix_and_suffix(to_table)
58
+ definition.foreign_key(to_table, options)
59
+ end
60
+ end
61
+
62
+ def remove_foreign_key(from_table, to_table = nil, **options)
63
+ to_table ||= options[:to_table]
64
+ options = options.except(:name, :to_table)
65
+ foreign_keys = foreign_keys(from_table)
66
+
67
+ fkey = foreign_keys.detect do |fk|
68
+ table = to_table || begin
69
+ table = options[:column].to_s.delete_suffix("_id")
70
+ Base.pluralize_table_names ? table.pluralize : table
71
+ end
72
+ table = strip_table_name_prefix_and_suffix(table)
73
+ fk_to_table = strip_table_name_prefix_and_suffix(fk.to_table)
74
+ fk_to_table == table && options.all? { |k, v| fk.options[k].to_s == v.to_s }
75
+ end || raise(ArgumentError, "Table '#{from_table}' has no foreign key for #{to_table || options}")
76
+
77
+ foreign_keys.delete(fkey)
78
+ alter_table(from_table, foreign_keys)
79
+ end
80
+
81
+ def create_schema_dumper(options)
82
+ SQLite3::SchemaDumper.create(self, options)
83
+ end
84
+
85
+ private
86
+ def schema_creation
87
+ SQLite3::SchemaCreation.new(self)
88
+ end
89
+
90
+ def create_table_definition(*args)
91
+ SQLite3::TableDefinition.new(self, *args)
92
+ end
93
+
94
+ def new_column_from_field(table_name, field)
95
+ default = \
96
+ case field["dflt_value"]
97
+ when /^null$/i
98
+ nil
99
+ when /^'(.*)'$/m
100
+ $1.gsub("''", "'")
101
+ when /^"(.*)"$/m
102
+ $1.gsub('""', '"')
103
+ else
104
+ field["dflt_value"]
105
+ end
106
+
107
+ type_metadata = fetch_type_metadata(field["type"])
108
+ Column.new(field["name"], default, type_metadata, field["notnull"].to_i == 0, collation: field["collation"])
109
+ end
110
+
111
+ def data_source_sql(name = nil, type: nil)
112
+ scope = quoted_scope(name, type: type)
113
+ scope[:type] ||= "'table','view'"
114
+
115
+ sql = +"SELECT name FROM sqlite_master WHERE name <> 'sqlite_sequence'"
116
+ sql << " AND name = #{scope[:name]}" if scope[:name]
117
+ sql << " AND type IN (#{scope[:type]})"
118
+ sql
119
+ end
120
+
121
+ def quoted_scope(name = nil, type: nil)
122
+ type = \
123
+ case type
124
+ when "BASE TABLE"
125
+ "'table'"
126
+ when "VIEW"
127
+ "'view'"
128
+ end
129
+ scope = {}
130
+ scope[:name] = quote(name) if name
131
+ scope[:type] = type if type
132
+ scope
133
+ end
134
+ end
135
+ end
136
+ end
137
+ end