omg-activerecord 8.0.0.alpha1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (412) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +355 -0
  3. data/MIT-LICENSE +22 -0
  4. data/README.rdoc +219 -0
  5. data/examples/performance.rb +185 -0
  6. data/examples/simple.rb +15 -0
  7. data/lib/active_record/aggregations.rb +287 -0
  8. data/lib/active_record/association_relation.rb +50 -0
  9. data/lib/active_record/associations/alias_tracker.rb +90 -0
  10. data/lib/active_record/associations/association.rb +417 -0
  11. data/lib/active_record/associations/association_scope.rb +175 -0
  12. data/lib/active_record/associations/belongs_to_association.rb +163 -0
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +50 -0
  14. data/lib/active_record/associations/builder/association.rb +170 -0
  15. data/lib/active_record/associations/builder/belongs_to.rb +160 -0
  16. data/lib/active_record/associations/builder/collection_association.rb +80 -0
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +107 -0
  18. data/lib/active_record/associations/builder/has_many.rb +23 -0
  19. data/lib/active_record/associations/builder/has_one.rb +61 -0
  20. data/lib/active_record/associations/builder/singular_association.rb +48 -0
  21. data/lib/active_record/associations/collection_association.rb +535 -0
  22. data/lib/active_record/associations/collection_proxy.rb +1163 -0
  23. data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
  24. data/lib/active_record/associations/errors.rb +265 -0
  25. data/lib/active_record/associations/foreign_association.rb +40 -0
  26. data/lib/active_record/associations/has_many_association.rb +167 -0
  27. data/lib/active_record/associations/has_many_through_association.rb +232 -0
  28. data/lib/active_record/associations/has_one_association.rb +142 -0
  29. data/lib/active_record/associations/has_one_through_association.rb +45 -0
  30. data/lib/active_record/associations/join_dependency/join_association.rb +106 -0
  31. data/lib/active_record/associations/join_dependency/join_base.rb +23 -0
  32. data/lib/active_record/associations/join_dependency/join_part.rb +71 -0
  33. data/lib/active_record/associations/join_dependency.rb +301 -0
  34. data/lib/active_record/associations/nested_error.rb +47 -0
  35. data/lib/active_record/associations/preloader/association.rb +316 -0
  36. data/lib/active_record/associations/preloader/batch.rb +48 -0
  37. data/lib/active_record/associations/preloader/branch.rb +153 -0
  38. data/lib/active_record/associations/preloader/through_association.rb +150 -0
  39. data/lib/active_record/associations/preloader.rb +135 -0
  40. data/lib/active_record/associations/singular_association.rb +76 -0
  41. data/lib/active_record/associations/through_association.rb +132 -0
  42. data/lib/active_record/associations.rb +1897 -0
  43. data/lib/active_record/asynchronous_queries_tracker.rb +64 -0
  44. data/lib/active_record/attribute_assignment.rb +82 -0
  45. data/lib/active_record/attribute_methods/before_type_cast.rb +106 -0
  46. data/lib/active_record/attribute_methods/composite_primary_key.rb +84 -0
  47. data/lib/active_record/attribute_methods/dirty.rb +262 -0
  48. data/lib/active_record/attribute_methods/primary_key.rb +158 -0
  49. data/lib/active_record/attribute_methods/query.rb +50 -0
  50. data/lib/active_record/attribute_methods/read.rb +46 -0
  51. data/lib/active_record/attribute_methods/serialization.rb +232 -0
  52. data/lib/active_record/attribute_methods/time_zone_conversion.rb +94 -0
  53. data/lib/active_record/attribute_methods/write.rb +49 -0
  54. data/lib/active_record/attribute_methods.rb +542 -0
  55. data/lib/active_record/attributes.rb +307 -0
  56. data/lib/active_record/autosave_association.rb +586 -0
  57. data/lib/active_record/base.rb +338 -0
  58. data/lib/active_record/callbacks.rb +452 -0
  59. data/lib/active_record/coders/column_serializer.rb +61 -0
  60. data/lib/active_record/coders/json.rb +15 -0
  61. data/lib/active_record/coders/yaml_column.rb +95 -0
  62. data/lib/active_record/connection_adapters/abstract/connection_handler.rb +290 -0
  63. data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +210 -0
  64. data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +78 -0
  65. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +923 -0
  66. data/lib/active_record/connection_adapters/abstract/database_limits.rb +31 -0
  67. data/lib/active_record/connection_adapters/abstract/database_statements.rb +747 -0
  68. data/lib/active_record/connection_adapters/abstract/query_cache.rb +319 -0
  69. data/lib/active_record/connection_adapters/abstract/quoting.rb +239 -0
  70. data/lib/active_record/connection_adapters/abstract/savepoints.rb +24 -0
  71. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +190 -0
  72. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +961 -0
  73. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +106 -0
  74. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +1883 -0
  75. data/lib/active_record/connection_adapters/abstract/transaction.rb +676 -0
  76. data/lib/active_record/connection_adapters/abstract_adapter.rb +1218 -0
  77. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +1016 -0
  78. data/lib/active_record/connection_adapters/column.rb +122 -0
  79. data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
  80. data/lib/active_record/connection_adapters/mysql/column.rb +28 -0
  81. data/lib/active_record/connection_adapters/mysql/database_statements.rb +95 -0
  82. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +71 -0
  83. data/lib/active_record/connection_adapters/mysql/quoting.rb +114 -0
  84. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +106 -0
  85. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +106 -0
  86. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +97 -0
  87. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +300 -0
  88. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +40 -0
  89. data/lib/active_record/connection_adapters/mysql2/database_statements.rb +96 -0
  90. data/lib/active_record/connection_adapters/mysql2_adapter.rb +196 -0
  91. data/lib/active_record/connection_adapters/pool_config.rb +83 -0
  92. data/lib/active_record/connection_adapters/pool_manager.rb +57 -0
  93. data/lib/active_record/connection_adapters/postgresql/column.rb +82 -0
  94. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +231 -0
  95. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +91 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +53 -0
  98. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +15 -0
  99. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +17 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +54 -0
  101. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +31 -0
  102. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +36 -0
  103. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +15 -0
  104. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +20 -0
  105. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +109 -0
  106. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +15 -0
  107. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
  108. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +15 -0
  109. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +44 -0
  110. data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
  111. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +42 -0
  112. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +15 -0
  113. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +74 -0
  114. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +124 -0
  115. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +18 -0
  116. data/lib/active_record/connection_adapters/postgresql/oid/timestamp.rb +15 -0
  117. data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +30 -0
  118. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +125 -0
  119. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +45 -0
  120. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +28 -0
  121. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +30 -0
  122. data/lib/active_record/connection_adapters/postgresql/oid.rb +38 -0
  123. data/lib/active_record/connection_adapters/postgresql/quoting.rb +238 -0
  124. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +71 -0
  125. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +169 -0
  126. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +392 -0
  127. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +127 -0
  128. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +1162 -0
  129. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +44 -0
  130. data/lib/active_record/connection_adapters/postgresql/utils.rb +79 -0
  131. data/lib/active_record/connection_adapters/postgresql_adapter.rb +1182 -0
  132. data/lib/active_record/connection_adapters/schema_cache.rb +478 -0
  133. data/lib/active_record/connection_adapters/sql_type_metadata.rb +45 -0
  134. data/lib/active_record/connection_adapters/sqlite3/column.rb +62 -0
  135. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +145 -0
  136. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
  137. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +116 -0
  138. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +37 -0
  139. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +39 -0
  140. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +47 -0
  141. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +221 -0
  142. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +843 -0
  143. data/lib/active_record/connection_adapters/statement_pool.rb +67 -0
  144. data/lib/active_record/connection_adapters/trilogy/database_statements.rb +69 -0
  145. data/lib/active_record/connection_adapters/trilogy_adapter.rb +212 -0
  146. data/lib/active_record/connection_adapters.rb +176 -0
  147. data/lib/active_record/connection_handling.rb +413 -0
  148. data/lib/active_record/core.rb +836 -0
  149. data/lib/active_record/counter_cache.rb +230 -0
  150. data/lib/active_record/database_configurations/connection_url_resolver.rb +105 -0
  151. data/lib/active_record/database_configurations/database_config.rb +104 -0
  152. data/lib/active_record/database_configurations/hash_config.rb +172 -0
  153. data/lib/active_record/database_configurations/url_config.rb +78 -0
  154. data/lib/active_record/database_configurations.rb +309 -0
  155. data/lib/active_record/delegated_type.rb +289 -0
  156. data/lib/active_record/deprecator.rb +7 -0
  157. data/lib/active_record/destroy_association_async_job.rb +38 -0
  158. data/lib/active_record/disable_joins_association_relation.rb +39 -0
  159. data/lib/active_record/dynamic_matchers.rb +121 -0
  160. data/lib/active_record/encryption/auto_filtered_parameters.rb +66 -0
  161. data/lib/active_record/encryption/cipher/aes256_gcm.rb +101 -0
  162. data/lib/active_record/encryption/cipher.rb +53 -0
  163. data/lib/active_record/encryption/config.rb +70 -0
  164. data/lib/active_record/encryption/configurable.rb +60 -0
  165. data/lib/active_record/encryption/context.rb +42 -0
  166. data/lib/active_record/encryption/contexts.rb +76 -0
  167. data/lib/active_record/encryption/derived_secret_key_provider.rb +18 -0
  168. data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
  169. data/lib/active_record/encryption/encryptable_record.rb +230 -0
  170. data/lib/active_record/encryption/encrypted_attribute_type.rb +184 -0
  171. data/lib/active_record/encryption/encrypted_fixtures.rb +38 -0
  172. data/lib/active_record/encryption/encrypting_only_encryptor.rb +12 -0
  173. data/lib/active_record/encryption/encryptor.rb +177 -0
  174. data/lib/active_record/encryption/envelope_encryption_key_provider.rb +55 -0
  175. data/lib/active_record/encryption/errors.rb +15 -0
  176. data/lib/active_record/encryption/extended_deterministic_queries.rb +159 -0
  177. data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +28 -0
  178. data/lib/active_record/encryption/key.rb +28 -0
  179. data/lib/active_record/encryption/key_generator.rb +53 -0
  180. data/lib/active_record/encryption/key_provider.rb +46 -0
  181. data/lib/active_record/encryption/message.rb +33 -0
  182. data/lib/active_record/encryption/message_pack_message_serializer.rb +76 -0
  183. data/lib/active_record/encryption/message_serializer.rb +96 -0
  184. data/lib/active_record/encryption/null_encryptor.rb +25 -0
  185. data/lib/active_record/encryption/properties.rb +76 -0
  186. data/lib/active_record/encryption/read_only_null_encryptor.rb +28 -0
  187. data/lib/active_record/encryption/scheme.rb +107 -0
  188. data/lib/active_record/encryption.rb +58 -0
  189. data/lib/active_record/enum.rb +424 -0
  190. data/lib/active_record/errors.rb +614 -0
  191. data/lib/active_record/explain.rb +63 -0
  192. data/lib/active_record/explain_registry.rb +37 -0
  193. data/lib/active_record/explain_subscriber.rb +34 -0
  194. data/lib/active_record/fixture_set/file.rb +89 -0
  195. data/lib/active_record/fixture_set/model_metadata.rb +42 -0
  196. data/lib/active_record/fixture_set/render_context.rb +19 -0
  197. data/lib/active_record/fixture_set/table_row.rb +208 -0
  198. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  199. data/lib/active_record/fixtures.rb +850 -0
  200. data/lib/active_record/future_result.rb +182 -0
  201. data/lib/active_record/gem_version.rb +17 -0
  202. data/lib/active_record/inheritance.rb +366 -0
  203. data/lib/active_record/insert_all.rb +328 -0
  204. data/lib/active_record/integration.rb +209 -0
  205. data/lib/active_record/internal_metadata.rb +164 -0
  206. data/lib/active_record/legacy_yaml_adapter.rb +15 -0
  207. data/lib/active_record/locale/en.yml +48 -0
  208. data/lib/active_record/locking/optimistic.rb +228 -0
  209. data/lib/active_record/locking/pessimistic.rb +102 -0
  210. data/lib/active_record/log_subscriber.rb +149 -0
  211. data/lib/active_record/marshalling.rb +56 -0
  212. data/lib/active_record/message_pack.rb +124 -0
  213. data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
  214. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  215. data/lib/active_record/middleware/database_selector.rb +87 -0
  216. data/lib/active_record/middleware/shard_selector.rb +62 -0
  217. data/lib/active_record/migration/command_recorder.rb +406 -0
  218. data/lib/active_record/migration/compatibility.rb +490 -0
  219. data/lib/active_record/migration/default_strategy.rb +22 -0
  220. data/lib/active_record/migration/execution_strategy.rb +19 -0
  221. data/lib/active_record/migration/join_table.rb +16 -0
  222. data/lib/active_record/migration/pending_migration_connection.rb +21 -0
  223. data/lib/active_record/migration.rb +1626 -0
  224. data/lib/active_record/model_schema.rb +635 -0
  225. data/lib/active_record/nested_attributes.rb +633 -0
  226. data/lib/active_record/no_touching.rb +65 -0
  227. data/lib/active_record/normalization.rb +163 -0
  228. data/lib/active_record/persistence.rb +968 -0
  229. data/lib/active_record/promise.rb +84 -0
  230. data/lib/active_record/query_cache.rb +56 -0
  231. data/lib/active_record/query_logs.rb +247 -0
  232. data/lib/active_record/query_logs_formatter.rb +30 -0
  233. data/lib/active_record/querying.rb +122 -0
  234. data/lib/active_record/railtie.rb +440 -0
  235. data/lib/active_record/railties/console_sandbox.rb +5 -0
  236. data/lib/active_record/railties/controller_runtime.rb +65 -0
  237. data/lib/active_record/railties/databases.rake +641 -0
  238. data/lib/active_record/railties/job_runtime.rb +23 -0
  239. data/lib/active_record/readonly_attributes.rb +66 -0
  240. data/lib/active_record/reflection.rb +1287 -0
  241. data/lib/active_record/relation/batches/batch_enumerator.rb +115 -0
  242. data/lib/active_record/relation/batches.rb +491 -0
  243. data/lib/active_record/relation/calculations.rb +679 -0
  244. data/lib/active_record/relation/delegation.rb +154 -0
  245. data/lib/active_record/relation/finder_methods.rb +661 -0
  246. data/lib/active_record/relation/from_clause.rb +30 -0
  247. data/lib/active_record/relation/merger.rb +192 -0
  248. data/lib/active_record/relation/predicate_builder/array_handler.rb +48 -0
  249. data/lib/active_record/relation/predicate_builder/association_query_value.rb +76 -0
  250. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +19 -0
  251. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +60 -0
  252. data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -0
  253. data/lib/active_record/relation/predicate_builder/relation_handler.rb +24 -0
  254. data/lib/active_record/relation/predicate_builder.rb +181 -0
  255. data/lib/active_record/relation/query_attribute.rb +68 -0
  256. data/lib/active_record/relation/query_methods.rb +2235 -0
  257. data/lib/active_record/relation/record_fetch_warning.rb +52 -0
  258. data/lib/active_record/relation/spawn_methods.rb +78 -0
  259. data/lib/active_record/relation/where_clause.rb +218 -0
  260. data/lib/active_record/relation.rb +1495 -0
  261. data/lib/active_record/result.rb +249 -0
  262. data/lib/active_record/runtime_registry.rb +82 -0
  263. data/lib/active_record/sanitization.rb +254 -0
  264. data/lib/active_record/schema.rb +77 -0
  265. data/lib/active_record/schema_dumper.rb +364 -0
  266. data/lib/active_record/schema_migration.rb +106 -0
  267. data/lib/active_record/scoping/default.rb +205 -0
  268. data/lib/active_record/scoping/named.rb +202 -0
  269. data/lib/active_record/scoping.rb +136 -0
  270. data/lib/active_record/secure_password.rb +60 -0
  271. data/lib/active_record/secure_token.rb +66 -0
  272. data/lib/active_record/serialization.rb +29 -0
  273. data/lib/active_record/signed_id.rb +137 -0
  274. data/lib/active_record/statement_cache.rb +164 -0
  275. data/lib/active_record/store.rb +299 -0
  276. data/lib/active_record/suppressor.rb +59 -0
  277. data/lib/active_record/table_metadata.rb +85 -0
  278. data/lib/active_record/tasks/database_tasks.rb +681 -0
  279. data/lib/active_record/tasks/mysql_database_tasks.rb +120 -0
  280. data/lib/active_record/tasks/postgresql_database_tasks.rb +147 -0
  281. data/lib/active_record/tasks/sqlite_database_tasks.rb +89 -0
  282. data/lib/active_record/test_databases.rb +24 -0
  283. data/lib/active_record/test_fixtures.rb +321 -0
  284. data/lib/active_record/testing/query_assertions.rb +121 -0
  285. data/lib/active_record/timestamp.rb +177 -0
  286. data/lib/active_record/token_for.rb +123 -0
  287. data/lib/active_record/touch_later.rb +70 -0
  288. data/lib/active_record/transaction.rb +132 -0
  289. data/lib/active_record/transactions.rb +523 -0
  290. data/lib/active_record/translation.rb +22 -0
  291. data/lib/active_record/type/adapter_specific_registry.rb +144 -0
  292. data/lib/active_record/type/date.rb +9 -0
  293. data/lib/active_record/type/date_time.rb +9 -0
  294. data/lib/active_record/type/decimal_without_scale.rb +15 -0
  295. data/lib/active_record/type/hash_lookup_type_map.rb +57 -0
  296. data/lib/active_record/type/internal/timezone.rb +22 -0
  297. data/lib/active_record/type/json.rb +30 -0
  298. data/lib/active_record/type/serialized.rb +76 -0
  299. data/lib/active_record/type/text.rb +11 -0
  300. data/lib/active_record/type/time.rb +35 -0
  301. data/lib/active_record/type/type_map.rb +58 -0
  302. data/lib/active_record/type/unsigned_integer.rb +16 -0
  303. data/lib/active_record/type.rb +83 -0
  304. data/lib/active_record/type_caster/connection.rb +33 -0
  305. data/lib/active_record/type_caster/map.rb +23 -0
  306. data/lib/active_record/type_caster.rb +9 -0
  307. data/lib/active_record/validations/absence.rb +25 -0
  308. data/lib/active_record/validations/associated.rb +65 -0
  309. data/lib/active_record/validations/length.rb +26 -0
  310. data/lib/active_record/validations/numericality.rb +36 -0
  311. data/lib/active_record/validations/presence.rb +45 -0
  312. data/lib/active_record/validations/uniqueness.rb +295 -0
  313. data/lib/active_record/validations.rb +101 -0
  314. data/lib/active_record/version.rb +10 -0
  315. data/lib/active_record.rb +616 -0
  316. data/lib/arel/alias_predication.rb +9 -0
  317. data/lib/arel/attributes/attribute.rb +33 -0
  318. data/lib/arel/collectors/bind.rb +31 -0
  319. data/lib/arel/collectors/composite.rb +46 -0
  320. data/lib/arel/collectors/plain_string.rb +20 -0
  321. data/lib/arel/collectors/sql_string.rb +27 -0
  322. data/lib/arel/collectors/substitute_binds.rb +35 -0
  323. data/lib/arel/crud.rb +48 -0
  324. data/lib/arel/delete_manager.rb +32 -0
  325. data/lib/arel/errors.rb +19 -0
  326. data/lib/arel/expressions.rb +29 -0
  327. data/lib/arel/factory_methods.rb +53 -0
  328. data/lib/arel/filter_predications.rb +9 -0
  329. data/lib/arel/insert_manager.rb +48 -0
  330. data/lib/arel/math.rb +45 -0
  331. data/lib/arel/nodes/ascending.rb +23 -0
  332. data/lib/arel/nodes/binary.rb +125 -0
  333. data/lib/arel/nodes/bind_param.rb +44 -0
  334. data/lib/arel/nodes/bound_sql_literal.rb +65 -0
  335. data/lib/arel/nodes/case.rb +55 -0
  336. data/lib/arel/nodes/casted.rb +62 -0
  337. data/lib/arel/nodes/comment.rb +29 -0
  338. data/lib/arel/nodes/count.rb +12 -0
  339. data/lib/arel/nodes/cte.rb +36 -0
  340. data/lib/arel/nodes/delete_statement.rb +44 -0
  341. data/lib/arel/nodes/descending.rb +23 -0
  342. data/lib/arel/nodes/equality.rb +15 -0
  343. data/lib/arel/nodes/extract.rb +24 -0
  344. data/lib/arel/nodes/false.rb +16 -0
  345. data/lib/arel/nodes/filter.rb +10 -0
  346. data/lib/arel/nodes/fragments.rb +35 -0
  347. data/lib/arel/nodes/full_outer_join.rb +8 -0
  348. data/lib/arel/nodes/function.rb +45 -0
  349. data/lib/arel/nodes/grouping.rb +11 -0
  350. data/lib/arel/nodes/homogeneous_in.rb +68 -0
  351. data/lib/arel/nodes/in.rb +15 -0
  352. data/lib/arel/nodes/infix_operation.rb +92 -0
  353. data/lib/arel/nodes/inner_join.rb +8 -0
  354. data/lib/arel/nodes/insert_statement.rb +37 -0
  355. data/lib/arel/nodes/join_source.rb +20 -0
  356. data/lib/arel/nodes/leading_join.rb +8 -0
  357. data/lib/arel/nodes/matches.rb +18 -0
  358. data/lib/arel/nodes/named_function.rb +23 -0
  359. data/lib/arel/nodes/nary.rb +39 -0
  360. data/lib/arel/nodes/node.rb +161 -0
  361. data/lib/arel/nodes/node_expression.rb +13 -0
  362. data/lib/arel/nodes/ordering.rb +27 -0
  363. data/lib/arel/nodes/outer_join.rb +8 -0
  364. data/lib/arel/nodes/over.rb +15 -0
  365. data/lib/arel/nodes/regexp.rb +16 -0
  366. data/lib/arel/nodes/right_outer_join.rb +8 -0
  367. data/lib/arel/nodes/select_core.rb +67 -0
  368. data/lib/arel/nodes/select_statement.rb +41 -0
  369. data/lib/arel/nodes/sql_literal.rb +32 -0
  370. data/lib/arel/nodes/string_join.rb +11 -0
  371. data/lib/arel/nodes/table_alias.rb +35 -0
  372. data/lib/arel/nodes/terminal.rb +16 -0
  373. data/lib/arel/nodes/true.rb +16 -0
  374. data/lib/arel/nodes/unary.rb +44 -0
  375. data/lib/arel/nodes/unary_operation.rb +20 -0
  376. data/lib/arel/nodes/unqualified_column.rb +22 -0
  377. data/lib/arel/nodes/update_statement.rb +46 -0
  378. data/lib/arel/nodes/values_list.rb +9 -0
  379. data/lib/arel/nodes/window.rb +126 -0
  380. data/lib/arel/nodes/with.rb +11 -0
  381. data/lib/arel/nodes.rb +75 -0
  382. data/lib/arel/order_predications.rb +13 -0
  383. data/lib/arel/predications.rb +260 -0
  384. data/lib/arel/select_manager.rb +276 -0
  385. data/lib/arel/table.rb +121 -0
  386. data/lib/arel/tree_manager.rb +65 -0
  387. data/lib/arel/update_manager.rb +49 -0
  388. data/lib/arel/visitors/dot.rb +299 -0
  389. data/lib/arel/visitors/mysql.rb +111 -0
  390. data/lib/arel/visitors/postgresql.rb +99 -0
  391. data/lib/arel/visitors/sqlite.rb +38 -0
  392. data/lib/arel/visitors/to_sql.rb +1033 -0
  393. data/lib/arel/visitors/visitor.rb +45 -0
  394. data/lib/arel/visitors.rb +13 -0
  395. data/lib/arel/window_predications.rb +9 -0
  396. data/lib/arel.rb +73 -0
  397. data/lib/rails/generators/active_record/application_record/USAGE +8 -0
  398. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +26 -0
  399. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
  400. data/lib/rails/generators/active_record/migration/migration_generator.rb +76 -0
  401. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +29 -0
  402. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +48 -0
  403. data/lib/rails/generators/active_record/migration.rb +54 -0
  404. data/lib/rails/generators/active_record/model/USAGE +113 -0
  405. data/lib/rails/generators/active_record/model/model_generator.rb +94 -0
  406. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
  407. data/lib/rails/generators/active_record/model/templates/model.rb.tt +22 -0
  408. data/lib/rails/generators/active_record/model/templates/module.rb.tt +7 -0
  409. data/lib/rails/generators/active_record/multi_db/multi_db_generator.rb +16 -0
  410. data/lib/rails/generators/active_record/multi_db/templates/multi_db.rb.tt +44 -0
  411. data/lib/rails/generators/active_record.rb +19 -0
  412. metadata +505 -0
@@ -0,0 +1,614 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/deprecation"
4
+
5
+ module ActiveRecord
6
+ include ActiveSupport::Deprecation::DeprecatedConstantAccessor
7
+
8
+ # = Active Record Errors
9
+ #
10
+ # Generic Active Record exception class.
11
+ class ActiveRecordError < StandardError
12
+ end
13
+
14
+ # Raised when the single-table inheritance mechanism fails to locate the subclass
15
+ # (for example due to improper usage of column that
16
+ # {ActiveRecord::Base.inheritance_column}[rdoc-ref:ModelSchema::ClassMethods#inheritance_column]
17
+ # points to).
18
+ class SubclassNotFound < ActiveRecordError
19
+ end
20
+
21
+ # Raised when an object assigned to an association has an incorrect type.
22
+ #
23
+ # class Ticket < ActiveRecord::Base
24
+ # has_many :patches
25
+ # end
26
+ #
27
+ # class Patch < ActiveRecord::Base
28
+ # belongs_to :ticket
29
+ # end
30
+ #
31
+ # # Comments are not patches, this assignment raises AssociationTypeMismatch.
32
+ # @ticket.patches << Comment.new(content: "Please attach tests to your patch.")
33
+ class AssociationTypeMismatch < ActiveRecordError
34
+ end
35
+
36
+ # Raised when unserialized object's type mismatches one specified for serializable field.
37
+ class SerializationTypeMismatch < ActiveRecordError
38
+ end
39
+
40
+ # Raised when adapter not specified on connection (or configuration file
41
+ # +config/database.yml+ misses adapter field).
42
+ class AdapterNotSpecified < ActiveRecordError
43
+ end
44
+
45
+ # Raised when a model makes a query but it has not specified an associated table.
46
+ class TableNotSpecified < ActiveRecordError
47
+ end
48
+
49
+ # Raised when Active Record cannot find database adapter specified in
50
+ # +config/database.yml+ or programmatically.
51
+ class AdapterNotFound < ActiveRecordError
52
+ end
53
+
54
+ # Superclass for all errors raised from an Active Record adapter.
55
+ class AdapterError < ActiveRecordError
56
+ def initialize(message = nil, connection_pool: nil)
57
+ @connection_pool = connection_pool
58
+ super(message)
59
+ end
60
+
61
+ attr_reader :connection_pool
62
+ end
63
+
64
+ # Raised when connection to the database could not been established (for example when
65
+ # {ActiveRecord::Base.lease_connection=}[rdoc-ref:ConnectionHandling#lease_connection]
66
+ # is given a +nil+ object).
67
+ class ConnectionNotEstablished < AdapterError
68
+ def initialize(message = nil, connection_pool: nil)
69
+ super(message, connection_pool: connection_pool)
70
+ end
71
+
72
+ def set_pool(connection_pool)
73
+ unless @connection_pool
74
+ @connection_pool = connection_pool
75
+ end
76
+
77
+ self
78
+ end
79
+ end
80
+
81
+ # Raised when a connection could not be obtained within the connection
82
+ # acquisition timeout period: because max connections in pool
83
+ # are in use.
84
+ class ConnectionTimeoutError < ConnectionNotEstablished
85
+ end
86
+
87
+ # Raised when a database connection pool is requested but
88
+ # has not been defined.
89
+ class ConnectionNotDefined < ConnectionNotEstablished
90
+ def initialize(message = nil, connection_name: nil, role: nil, shard: nil)
91
+ super(message)
92
+ @connection_name = connection_name
93
+ @role = role
94
+ @shard = shard
95
+ end
96
+
97
+ attr_reader :connection_name, :role, :shard
98
+ end
99
+
100
+ # Raised when connection to the database could not been established because it was not
101
+ # able to connect to the host or when the authorization failed.
102
+ class DatabaseConnectionError < ConnectionNotEstablished
103
+ def initialize(message = nil)
104
+ super(message || "Database connection error")
105
+ end
106
+
107
+ class << self
108
+ def hostname_error(hostname)
109
+ DatabaseConnectionError.new(<<~MSG)
110
+ There is an issue connecting with your hostname: #{hostname}.\n
111
+ Please check your database configuration and ensure there is a valid connection to your database.
112
+ MSG
113
+ end
114
+
115
+ def username_error(username)
116
+ DatabaseConnectionError.new(<<~MSG)
117
+ There is an issue connecting to your database with your username/password, username: #{username}.\n
118
+ Please check your database configuration to ensure the username/password are valid.
119
+ MSG
120
+ end
121
+ end
122
+ end
123
+
124
+ # Raised when a pool was unable to get ahold of all its connections
125
+ # to perform a "group" action such as
126
+ # {ActiveRecord::Base.connection_pool.disconnect!}[rdoc-ref:ConnectionAdapters::ConnectionPool#disconnect!]
127
+ # or {ActiveRecord::Base.connection_handler.clear_reloadable_connections!}[rdoc-ref:ConnectionAdapters::ConnectionHandler#clear_reloadable_connections!].
128
+ class ExclusiveConnectionTimeoutError < ConnectionTimeoutError
129
+ end
130
+
131
+ # Raised when a write to the database is attempted on a read only connection.
132
+ class ReadOnlyError < ActiveRecordError
133
+ end
134
+
135
+ # Raised when Active Record cannot find a record by given id or set of ids.
136
+ class RecordNotFound < ActiveRecordError
137
+ attr_reader :model, :primary_key, :id
138
+
139
+ def initialize(message = nil, model = nil, primary_key = nil, id = nil)
140
+ @primary_key = primary_key
141
+ @model = model
142
+ @id = id
143
+
144
+ super(message)
145
+ end
146
+ end
147
+
148
+ # Raised by {ActiveRecord::Base#save!}[rdoc-ref:Persistence#save!] and
149
+ # {ActiveRecord::Base.update_attribute!}[rdoc-ref:Persistence#update_attribute!]
150
+ # methods when a record failed to validate or cannot be saved due to any of the
151
+ # <tt>before_*</tt> callbacks throwing +:abort+. See
152
+ # ActiveRecord::Callbacks for further details.
153
+ #
154
+ # class Product < ActiveRecord::Base
155
+ # before_save do
156
+ # throw :abort if price < 0
157
+ # end
158
+ # end
159
+ #
160
+ # Product.create! # => raises an ActiveRecord::RecordNotSaved
161
+ class RecordNotSaved < ActiveRecordError
162
+ attr_reader :record
163
+
164
+ def initialize(message = nil, record = nil)
165
+ @record = record
166
+ super(message)
167
+ end
168
+ end
169
+
170
+ # Raised by {ActiveRecord::Base#destroy!}[rdoc-ref:Persistence#destroy!]
171
+ # when a record cannot be destroyed due to any of the
172
+ # <tt>before_destroy</tt> callbacks throwing +:abort+. See
173
+ # ActiveRecord::Callbacks for further details.
174
+ #
175
+ # class User < ActiveRecord::Base
176
+ # before_destroy do
177
+ # throw :abort if still_active?
178
+ # end
179
+ # end
180
+ #
181
+ # User.first.destroy! # => raises an ActiveRecord::RecordNotDestroyed
182
+ class RecordNotDestroyed < ActiveRecordError
183
+ attr_reader :record
184
+
185
+ def initialize(message = nil, record = nil)
186
+ @record = record
187
+ super(message)
188
+ end
189
+ end
190
+
191
+ # Raised when Active Record finds multiple records but only expected one.
192
+ class SoleRecordExceeded < ActiveRecordError
193
+ attr_reader :record
194
+
195
+ def initialize(record = nil)
196
+ @record = record
197
+ super "Wanted only one #{record&.name || "record"}"
198
+ end
199
+ end
200
+
201
+ # Superclass for all database execution errors.
202
+ #
203
+ # Wraps the underlying database error as +cause+.
204
+ class StatementInvalid < AdapterError
205
+ def initialize(message = nil, sql: nil, binds: nil, connection_pool: nil)
206
+ super(message || $!&.message, connection_pool: connection_pool)
207
+ @sql = sql
208
+ @binds = binds
209
+ end
210
+
211
+ attr_reader :sql, :binds
212
+
213
+ def set_query(sql, binds)
214
+ unless @sql
215
+ @sql = sql
216
+ @binds = binds
217
+ end
218
+
219
+ self
220
+ end
221
+ end
222
+
223
+ # Defunct wrapper class kept for compatibility.
224
+ # StatementInvalid wraps the original exception now.
225
+ class WrappedDatabaseException < StatementInvalid
226
+ end
227
+
228
+ # Raised when a record cannot be inserted or updated because it would violate a uniqueness constraint.
229
+ class RecordNotUnique < WrappedDatabaseException
230
+ end
231
+
232
+ # Raised when a record cannot be inserted or updated because it references a non-existent record,
233
+ # or when a record cannot be deleted because a parent record references it.
234
+ class InvalidForeignKey < WrappedDatabaseException
235
+ end
236
+
237
+ # Raised when a foreign key constraint cannot be added because the column type does not match the referenced column type.
238
+ class MismatchedForeignKey < StatementInvalid
239
+ def initialize(
240
+ message: nil,
241
+ sql: nil,
242
+ binds: nil,
243
+ table: nil,
244
+ foreign_key: nil,
245
+ target_table: nil,
246
+ primary_key: nil,
247
+ primary_key_column: nil,
248
+ query_parser: nil,
249
+ connection_pool: nil
250
+ )
251
+ @original_message = message
252
+ @query_parser = query_parser
253
+
254
+ if table
255
+ type = primary_key_column.bigint? ? :bigint : primary_key_column.type
256
+ msg = <<~EOM.squish
257
+ Column `#{foreign_key}` on table `#{table}` does not match column `#{primary_key}` on `#{target_table}`,
258
+ which has type `#{primary_key_column.sql_type}`.
259
+ To resolve this issue, change the type of the `#{foreign_key}` column on `#{table}` to be :#{type}.
260
+ (For example `t.#{type} :#{foreign_key}`).
261
+ EOM
262
+ else
263
+ msg = <<~EOM.squish
264
+ There is a mismatch between the foreign key and primary key column types.
265
+ Verify that the foreign key column type and the primary key of the associated table match types.
266
+ EOM
267
+ end
268
+ if message
269
+ msg << "\nOriginal message: #{message}"
270
+ end
271
+
272
+ super(msg, sql: sql, binds: binds, connection_pool: connection_pool)
273
+ end
274
+
275
+ def set_query(sql, binds)
276
+ if @query_parser && !@sql
277
+ self.class.new(
278
+ message: @original_message,
279
+ sql: sql,
280
+ binds: binds,
281
+ connection_pool: @connection_pool,
282
+ **@query_parser.call(sql)
283
+ ).tap do |exception|
284
+ exception.set_backtrace backtrace
285
+ end
286
+ else
287
+ super
288
+ end
289
+ end
290
+ end
291
+
292
+ # Raised when a record cannot be inserted or updated because it would violate a not null constraint.
293
+ class NotNullViolation < StatementInvalid
294
+ end
295
+
296
+ # Raised when a record cannot be inserted or updated because a value too long for a column type.
297
+ class ValueTooLong < StatementInvalid
298
+ end
299
+
300
+ # Raised when values that executed are out of range.
301
+ class RangeError < StatementInvalid
302
+ end
303
+
304
+ # Raised when a statement produces an SQL warning.
305
+ class SQLWarning < AdapterError
306
+ attr_reader :code, :level
307
+ attr_accessor :sql
308
+
309
+ def initialize(message = nil, code = nil, level = nil, sql = nil, connection_pool = nil)
310
+ super(message, connection_pool: connection_pool)
311
+ @code = code
312
+ @level = level
313
+ @sql = sql
314
+ end
315
+ end
316
+
317
+ # Raised when the number of placeholders in an SQL fragment passed to
318
+ # {ActiveRecord::Base.where}[rdoc-ref:QueryMethods#where]
319
+ # does not match the number of values supplied.
320
+ #
321
+ # For example, when there are two placeholders with only one value supplied:
322
+ #
323
+ # Location.where("lat = ? AND lng = ?", 53.7362)
324
+ class PreparedStatementInvalid < ActiveRecordError
325
+ end
326
+
327
+ # Raised when a given database does not exist.
328
+ class NoDatabaseError < StatementInvalid
329
+ include ActiveSupport::ActionableError
330
+
331
+ action "Create database" do
332
+ ActiveRecord::Tasks::DatabaseTasks.create_current
333
+ end
334
+
335
+ def initialize(message = nil, connection_pool: nil)
336
+ super(message || "Database not found", connection_pool: connection_pool)
337
+ end
338
+
339
+ class << self
340
+ def db_error(db_name)
341
+ NoDatabaseError.new(<<~MSG)
342
+ We could not find your database: #{db_name}. Available database configurations can be found in config/database.yml.
343
+
344
+ To resolve this error:
345
+
346
+ - Did you not create the database, or did you delete it? To create the database, run:
347
+
348
+ bin/rails db:create
349
+
350
+ - Has the database name changed? Verify that config/database.yml contains the correct database name.
351
+ MSG
352
+ end
353
+ end
354
+ end
355
+
356
+ # Raised when creating a database if it exists.
357
+ class DatabaseAlreadyExists < StatementInvalid
358
+ end
359
+
360
+ # Raised when PostgreSQL returns 'cached plan must not change result type' and
361
+ # we cannot retry gracefully (e.g. inside a transaction)
362
+ class PreparedStatementCacheExpired < StatementInvalid
363
+ end
364
+
365
+ # Raised on attempt to save stale record. Record is stale when it's being saved in another query after
366
+ # instantiation, for example, when two users edit the same wiki page and one starts editing and saves
367
+ # the page before the other.
368
+ #
369
+ # Read more about optimistic locking in ActiveRecord::Locking module
370
+ # documentation.
371
+ class StaleObjectError < ActiveRecordError
372
+ attr_reader :record, :attempted_action
373
+
374
+ def initialize(record = nil, attempted_action = nil)
375
+ if record && attempted_action
376
+ @record = record
377
+ @attempted_action = attempted_action
378
+ super("Attempted to #{attempted_action} a stale object: #{record.class.name}.")
379
+ else
380
+ super("Stale object error.")
381
+ end
382
+ end
383
+ end
384
+
385
+ # Raised when association is being configured improperly or user tries to use
386
+ # offset and limit together with
387
+ # {ActiveRecord::Base.has_many}[rdoc-ref:Associations::ClassMethods#has_many] or
388
+ # {ActiveRecord::Base.has_and_belongs_to_many}[rdoc-ref:Associations::ClassMethods#has_and_belongs_to_many]
389
+ # associations.
390
+ class ConfigurationError < ActiveRecordError
391
+ end
392
+
393
+ # Raised on attempt to update record that is instantiated as read only.
394
+ class ReadOnlyRecord < ActiveRecordError
395
+ end
396
+
397
+ # Raised on attempt to lazily load records that are marked as strict loading.
398
+ #
399
+ # You can resolve this error by eager loading marked records before accessing
400
+ # them. The
401
+ # {Eager Loading Associations}[https://guides.rubyonrails.org/active_record_querying.html#eager-loading-associations]
402
+ # guide covers solutions, such as using
403
+ # {ActiveRecord::Base.includes}[rdoc-ref:QueryMethods#includes].
404
+ class StrictLoadingViolationError < ActiveRecordError
405
+ end
406
+
407
+ # {ActiveRecord::Base.transaction}[rdoc-ref:Transactions::ClassMethods#transaction]
408
+ # uses this exception to distinguish a deliberate rollback from other exceptional situations.
409
+ # Normally, raising an exception will cause the
410
+ # {.transaction}[rdoc-ref:Transactions::ClassMethods#transaction] method to rollback
411
+ # the database transaction *and* pass on the exception. But if you raise an
412
+ # ActiveRecord::Rollback exception, then the database transaction will be rolled back,
413
+ # without passing on the exception.
414
+ #
415
+ # For example, you could do this in your controller to rollback a transaction:
416
+ #
417
+ # class BooksController < ActionController::Base
418
+ # def create
419
+ # Book.transaction do
420
+ # book = Book.new(params[:book])
421
+ # book.save!
422
+ # if today_is_friday?
423
+ # # The system must fail on Friday so that our support department
424
+ # # won't be out of job. We silently rollback this transaction
425
+ # # without telling the user.
426
+ # raise ActiveRecord::Rollback
427
+ # end
428
+ # end
429
+ # # ActiveRecord::Rollback is the only exception that won't be passed on
430
+ # # by ActiveRecord::Base.transaction, so this line will still be reached
431
+ # # even on Friday.
432
+ # redirect_to root_url
433
+ # end
434
+ # end
435
+ class Rollback < ActiveRecordError
436
+ end
437
+
438
+ # Raised when attribute has a name reserved by Active Record (when attribute
439
+ # has name of one of Active Record instance methods).
440
+ class DangerousAttributeError < ActiveRecordError
441
+ end
442
+
443
+ # Raised when unknown attributes are supplied via mass assignment.
444
+ UnknownAttributeError = ActiveModel::UnknownAttributeError
445
+
446
+ # Raised when an error occurred while doing a mass assignment to an attribute through the
447
+ # {ActiveRecord::Base#attributes=}[rdoc-ref:AttributeAssignment#attributes=] method.
448
+ # The exception has an +attribute+ property that is the name of the offending attribute.
449
+ class AttributeAssignmentError < ActiveRecordError
450
+ attr_reader :exception, :attribute
451
+
452
+ def initialize(message = nil, exception = nil, attribute = nil)
453
+ super(message)
454
+ @exception = exception
455
+ @attribute = attribute
456
+ end
457
+ end
458
+
459
+ # Raised when there are multiple errors while doing a mass assignment through the
460
+ # {ActiveRecord::Base#attributes=}[rdoc-ref:AttributeAssignment#attributes=]
461
+ # method. The exception has an +errors+ property that contains an array of AttributeAssignmentError
462
+ # objects, each corresponding to the error while assigning to an attribute.
463
+ class MultiparameterAssignmentErrors < ActiveRecordError
464
+ attr_reader :errors
465
+
466
+ def initialize(errors = nil)
467
+ @errors = errors
468
+ end
469
+ end
470
+
471
+ # Raised when a primary key is needed, but not specified in the schema or model.
472
+ class UnknownPrimaryKey < ActiveRecordError
473
+ attr_reader :model
474
+
475
+ def initialize(model = nil, description = nil)
476
+ if model
477
+ message = "Unknown primary key for table #{model.table_name} in model #{model}."
478
+ message += "\n#{description}" if description
479
+ @model = model
480
+ super(message)
481
+ else
482
+ super("Unknown primary key.")
483
+ end
484
+ end
485
+ end
486
+
487
+ # Raised when a relation cannot be mutated because it's already loaded.
488
+ #
489
+ # class Task < ActiveRecord::Base
490
+ # end
491
+ #
492
+ # relation = Task.all
493
+ # relation.loaded? # => true
494
+ #
495
+ # # Methods which try to mutate a loaded relation fail.
496
+ # relation.where!(title: 'TODO') # => ActiveRecord::UnmodifiableRelation
497
+ # relation.limit!(5) # => ActiveRecord::UnmodifiableRelation
498
+ class UnmodifiableRelation < ActiveRecordError
499
+ end
500
+
501
+ # TransactionIsolationError will be raised under the following conditions:
502
+ #
503
+ # * The adapter does not support setting the isolation level
504
+ # * You are joining an existing open transaction
505
+ # * You are creating a nested (savepoint) transaction
506
+ #
507
+ # The mysql2, trilogy, and postgresql adapters support setting the transaction isolation level.
508
+ class TransactionIsolationError < ActiveRecordError
509
+ end
510
+
511
+ # TransactionRollbackError will be raised when a transaction is rolled
512
+ # back by the database due to a serialization failure or a deadlock.
513
+ #
514
+ # These exceptions should not be generally rescued in nested transaction
515
+ # blocks, because they have side-effects in the actual enclosing transaction
516
+ # and internal Active Record state. They can be rescued if you are above the
517
+ # root transaction block, though.
518
+ #
519
+ # In that case, beware of transactional tests, however, because they run test
520
+ # cases in their own umbrella transaction. If you absolutely need to handle
521
+ # these exceptions in tests please consider disabling transactional tests in
522
+ # the affected test class (<tt>self.use_transactional_tests = false</tt>).
523
+ #
524
+ # Due to the aforementioned side-effects, this exception should not be raised
525
+ # manually by users.
526
+ #
527
+ # See the following:
528
+ #
529
+ # * https://www.postgresql.org/docs/current/static/transaction-iso.html
530
+ # * https://dev.mysql.com/doc/mysql-errors/en/server-error-reference.html#error_er_lock_deadlock
531
+ class TransactionRollbackError < StatementInvalid
532
+ end
533
+
534
+ # AsynchronousQueryInsideTransactionError will be raised when attempting
535
+ # to perform an asynchronous query from inside a transaction
536
+ class AsynchronousQueryInsideTransactionError < ActiveRecordError
537
+ end
538
+
539
+ # SerializationFailure will be raised when a transaction is rolled
540
+ # back by the database due to a serialization failure.
541
+ #
542
+ # This is a subclass of TransactionRollbackError, please make sure to check
543
+ # its documentation to be aware of its caveats.
544
+ class SerializationFailure < TransactionRollbackError
545
+ end
546
+
547
+ # Deadlocked will be raised when a transaction is rolled
548
+ # back by the database when a deadlock is encountered.
549
+ #
550
+ # This is a subclass of TransactionRollbackError, please make sure to check
551
+ # its documentation to be aware of its caveats.
552
+ class Deadlocked < TransactionRollbackError
553
+ end
554
+
555
+ # IrreversibleOrderError is raised when a relation's order is too complex for
556
+ # +reverse_order+ to automatically reverse.
557
+ class IrreversibleOrderError < ActiveRecordError
558
+ end
559
+
560
+ # Superclass for errors that have been aborted (either by client or server).
561
+ class QueryAborted < StatementInvalid
562
+ end
563
+
564
+ # LockWaitTimeout will be raised when lock wait timeout exceeded.
565
+ class LockWaitTimeout < StatementInvalid
566
+ end
567
+
568
+ # StatementTimeout will be raised when statement timeout exceeded.
569
+ class StatementTimeout < QueryAborted
570
+ end
571
+
572
+ # QueryCanceled will be raised when canceling statement due to user request.
573
+ class QueryCanceled < QueryAborted
574
+ end
575
+
576
+ # AdapterTimeout will be raised when database clients times out while waiting from the server.
577
+ class AdapterTimeout < QueryAborted
578
+ end
579
+
580
+ # ConnectionFailed will be raised when the network connection to the
581
+ # database fails while sending a query or waiting for its result.
582
+ class ConnectionFailed < QueryAborted
583
+ end
584
+
585
+ # UnknownAttributeReference is raised when an unknown and potentially unsafe
586
+ # value is passed to a query method. For example, passing a non column name
587
+ # value to a relation's #order method might cause this exception.
588
+ #
589
+ # When working around this exception, caution should be taken to avoid SQL
590
+ # injection vulnerabilities when passing user-provided values to query
591
+ # methods. Known-safe values can be passed to query methods by wrapping them
592
+ # in Arel.sql.
593
+ #
594
+ # For example, the following code would raise this exception:
595
+ #
596
+ # Post.order("REPLACE(title, 'misc', 'zzzz') asc").pluck(:id)
597
+ #
598
+ # The desired result can be accomplished by wrapping the known-safe string
599
+ # in Arel.sql:
600
+ #
601
+ # Post.order(Arel.sql("REPLACE(title, 'misc', 'zzzz') asc")).pluck(:id)
602
+ #
603
+ # Again, such a workaround should *not* be used when passing user-provided
604
+ # values, such as request parameters or model attributes to query methods.
605
+ class UnknownAttributeReference < ActiveRecordError
606
+ end
607
+
608
+ # DatabaseVersionError will be raised when the database version is not supported, or when
609
+ # the database version cannot be determined.
610
+ class DatabaseVersionError < ActiveRecordError
611
+ end
612
+ end
613
+
614
+ require "active_record/associations/errors"
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_record/explain_registry"
4
+
5
+ module ActiveRecord
6
+ module Explain
7
+ # Executes the block with the collect flag enabled. Queries are collected
8
+ # asynchronously by the subscriber and returned.
9
+ def collecting_queries_for_explain # :nodoc:
10
+ ExplainRegistry.collect = true
11
+ yield
12
+ ExplainRegistry.queries
13
+ ensure
14
+ ExplainRegistry.reset
15
+ end
16
+
17
+ # Makes the adapter execute EXPLAIN for the tuples of queries and bindings.
18
+ # Returns a formatted string ready to be logged.
19
+ def exec_explain(queries, options = []) # :nodoc:
20
+ str = with_connection do |c|
21
+ queries.map do |sql, binds|
22
+ msg = +"#{build_explain_clause(c, options)} #{sql}"
23
+ unless binds.empty?
24
+ msg << " "
25
+ msg << binds.map { |attr| render_bind(c, attr) }.inspect
26
+ end
27
+ msg << "\n"
28
+ msg << c.explain(sql, binds, options)
29
+ end.join("\n")
30
+ end
31
+ # Overriding inspect to be more human readable, especially in the console.
32
+ def str.inspect
33
+ self
34
+ end
35
+
36
+ str
37
+ end
38
+
39
+ private
40
+ def render_bind(connection, attr)
41
+ if ActiveModel::Attribute === attr
42
+ value = if attr.type.binary? && attr.value
43
+ "<#{attr.value_for_database.to_s.bytesize} bytes of binary data>"
44
+ else
45
+ connection.type_cast(attr.value_for_database)
46
+ end
47
+ else
48
+ value = connection.type_cast(attr)
49
+ attr = nil
50
+ end
51
+
52
+ [attr&.name, value]
53
+ end
54
+
55
+ def build_explain_clause(connection, options = [])
56
+ if connection.respond_to?(:build_explain_clause, true)
57
+ connection.build_explain_clause(options)
58
+ else
59
+ "EXPLAIN for:"
60
+ end
61
+ end
62
+ end
63
+ end