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,635 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "monitor"
4
+
5
+ module ActiveRecord
6
+ module ModelSchema
7
+ extend ActiveSupport::Concern
8
+
9
+ ##
10
+ # :method: id_value
11
+ # :call-seq: id_value
12
+ #
13
+ # Returns the underlying column value for a column named "id". Useful when defining
14
+ # a composite primary key including an "id" column so that the value is readable.
15
+
16
+ ##
17
+ # :singleton-method: primary_key_prefix_type
18
+ # :call-seq: primary_key_prefix_type
19
+ #
20
+ # The prefix type that will be prepended to every primary key column name.
21
+ # The options are +:table_name+ and +:table_name_with_underscore+. If the first is specified,
22
+ # the Product class will look for "productid" instead of "id" as the primary column. If the
23
+ # latter is specified, the Product class will look for "product_id" instead of "id". Remember
24
+ # that this is a global setting for all Active Records.
25
+
26
+ ##
27
+ # :singleton-method: primary_key_prefix_type=
28
+ # :call-seq: primary_key_prefix_type=(prefix_type)
29
+ #
30
+ # Sets the prefix type that will be prepended to every primary key column name.
31
+ # The options are +:table_name+ and +:table_name_with_underscore+. If the first is specified,
32
+ # the Product class will look for "productid" instead of "id" as the primary column. If the
33
+ # latter is specified, the Product class will look for "product_id" instead of "id". Remember
34
+ # that this is a global setting for all Active Records.
35
+
36
+ ##
37
+ # :singleton-method: table_name_prefix
38
+ # :call-seq: table_name_prefix
39
+ #
40
+ # The prefix string to prepend to every table name.
41
+
42
+ ##
43
+ # :singleton-method: table_name_prefix=
44
+ # :call-seq: table_name_prefix=(prefix)
45
+ #
46
+ # Sets the prefix string to prepend to every table name. So if set to "basecamp_", all table
47
+ # names will be named like "basecamp_projects", "basecamp_people", etc. This is a convenient
48
+ # way of creating a namespace for tables in a shared database. By default, the prefix is the
49
+ # empty string.
50
+ #
51
+ # If you are organising your models within modules you can add a prefix to the models within
52
+ # a namespace by defining a singleton method in the parent module called table_name_prefix which
53
+ # returns your chosen prefix.
54
+
55
+ ##
56
+ # :singleton-method: table_name_suffix
57
+ # :call-seq: table_name_suffix
58
+ #
59
+ # The suffix string to append to every table name.
60
+
61
+ ##
62
+ # :singleton-method: table_name_suffix=
63
+ # :call-seq: table_name_suffix=(suffix)
64
+ #
65
+ # Works like +table_name_prefix=+, but appends instead of prepends (set to "_basecamp" gives "projects_basecamp",
66
+ # "people_basecamp"). By default, the suffix is the empty string.
67
+ #
68
+ # If you are organising your models within modules, you can add a suffix to the models within
69
+ # a namespace by defining a singleton method in the parent module called table_name_suffix which
70
+ # returns your chosen suffix.
71
+
72
+ ##
73
+ # :singleton-method: schema_migrations_table_name
74
+ # :call-seq: schema_migrations_table_name
75
+ #
76
+ # The name of the schema migrations table. By default, the value is <tt>"schema_migrations"</tt>.
77
+
78
+ ##
79
+ # :singleton-method: schema_migrations_table_name=
80
+ # :call-seq: schema_migrations_table_name=(table_name)
81
+ #
82
+ # Sets the name of the schema migrations table.
83
+
84
+ ##
85
+ # :singleton-method: internal_metadata_table_name
86
+ # :call-seq: internal_metadata_table_name
87
+ #
88
+ # The name of the internal metadata table. By default, the value is <tt>"ar_internal_metadata"</tt>.
89
+
90
+ ##
91
+ # :singleton-method: internal_metadata_table_name=
92
+ # :call-seq: internal_metadata_table_name=(table_name)
93
+ #
94
+ # Sets the name of the internal metadata table.
95
+
96
+ ##
97
+ # :singleton-method: pluralize_table_names
98
+ # :call-seq: pluralize_table_names
99
+ #
100
+ # Indicates whether table names should be the pluralized versions of the corresponding class names.
101
+ # If true, the default table name for a Product class will be "products". If false, it would just be "product".
102
+ # See table_name for the full rules on table/class naming. This is true, by default.
103
+
104
+ ##
105
+ # :singleton-method: pluralize_table_names=
106
+ # :call-seq: pluralize_table_names=(value)
107
+ #
108
+ # Set whether table names should be the pluralized versions of the corresponding class names.
109
+ # If true, the default table name for a Product class will be "products". If false, it would just be "product".
110
+ # See table_name for the full rules on table/class naming. This is true, by default.
111
+
112
+ ##
113
+ # :singleton-method: implicit_order_column
114
+ # :call-seq: implicit_order_column
115
+ #
116
+ # The name of the column records are ordered by if no explicit order clause
117
+ # is used during an ordered finder call. If not set the primary key is used.
118
+
119
+ ##
120
+ # :singleton-method: implicit_order_column=
121
+ # :call-seq: implicit_order_column=(column_name)
122
+ #
123
+ # Sets the column to sort records by when no explicit order clause is used
124
+ # during an ordered finder call. Useful when the primary key is not an
125
+ # auto-incrementing integer, for example when it's a UUID. Records are subsorted
126
+ # by the primary key if it exists to ensure deterministic results.
127
+
128
+ ##
129
+ # :singleton-method: immutable_strings_by_default=
130
+ # :call-seq: immutable_strings_by_default=(bool)
131
+ #
132
+ # Determines whether columns should infer their type as +:string+ or
133
+ # +:immutable_string+. This setting does not affect the behavior of
134
+ # <tt>attribute :foo, :string</tt>. Defaults to false.
135
+
136
+ ##
137
+ # :singleton-method: inheritance_column
138
+ # :call-seq: inheritance_column
139
+ #
140
+ # The name of the table column which stores the class name on single-table
141
+ # inheritance situations.
142
+ #
143
+ # The default inheritance column name is +type+, which means it's a
144
+ # reserved word inside Active Record. To be able to use single-table
145
+ # inheritance with another column name, or to use the column +type+ in
146
+ # your own model for something else, you can set +inheritance_column+:
147
+ #
148
+ # self.inheritance_column = 'zoink'
149
+ #
150
+ # If you wish to disable single-table inheritance altogether you can set
151
+ # +inheritance_column+ to +nil+
152
+ #
153
+ # self.inheritance_column = nil
154
+
155
+ ##
156
+ # :singleton-method: inheritance_column=
157
+ # :call-seq: inheritance_column=(column)
158
+ #
159
+ # Defines the name of the table column which will store the class name on single-table
160
+ # inheritance situations.
161
+
162
+ included do
163
+ class_attribute :primary_key_prefix_type, instance_writer: false
164
+ class_attribute :table_name_prefix, instance_writer: false, default: ""
165
+ class_attribute :table_name_suffix, instance_writer: false, default: ""
166
+ class_attribute :schema_migrations_table_name, instance_accessor: false, default: "schema_migrations"
167
+ class_attribute :internal_metadata_table_name, instance_accessor: false, default: "ar_internal_metadata"
168
+ class_attribute :pluralize_table_names, instance_writer: false, default: true
169
+ class_attribute :implicit_order_column, instance_accessor: false
170
+ class_attribute :immutable_strings_by_default, instance_accessor: false
171
+
172
+ class_attribute :inheritance_column, instance_accessor: false, default: "type"
173
+ singleton_class.class_eval do
174
+ alias_method :_inheritance_column=, :inheritance_column=
175
+ private :_inheritance_column=
176
+ alias_method :inheritance_column=, :real_inheritance_column=
177
+ end
178
+
179
+ self.protected_environments = ["production"]
180
+
181
+ self.ignored_columns = [].freeze
182
+
183
+ delegate :type_for_attribute, :column_for_attribute, to: :class
184
+
185
+ initialize_load_schema_monitor
186
+ end
187
+
188
+ # Derives the join table name for +first_table+ and +second_table+. The
189
+ # table names appear in alphabetical order. A common prefix is removed
190
+ # (useful for namespaced models like Music::Artist and Music::Record):
191
+ #
192
+ # artists, records => artists_records
193
+ # records, artists => artists_records
194
+ # music_artists, music_records => music_artists_records
195
+ # music.artists, music.records => music.artists_records
196
+ def self.derive_join_table_name(first_table, second_table) # :nodoc:
197
+ [first_table.to_s, second_table.to_s].sort.join("\0").gsub(/^(.*[_.])(.+)\0\1(.+)/, '\1\2_\3').tr("\0", "_")
198
+ end
199
+
200
+ module ClassMethods
201
+ # Guesses the table name (in forced lower-case) based on the name of the class in the
202
+ # inheritance hierarchy descending directly from ActiveRecord::Base. So if the hierarchy
203
+ # looks like: Reply < Message < ActiveRecord::Base, then Message is used
204
+ # to guess the table name even when called on Reply. The rules used to do the guess
205
+ # are handled by the Inflector class in Active Support, which knows almost all common
206
+ # English inflections. You can add new inflections in config/initializers/inflections.rb.
207
+ #
208
+ # Nested classes are given table names prefixed by the singular form of
209
+ # the parent's table name. Enclosing modules are not considered.
210
+ #
211
+ # ==== Examples
212
+ #
213
+ # class Invoice < ActiveRecord::Base
214
+ # end
215
+ #
216
+ # file class table_name
217
+ # invoice.rb Invoice invoices
218
+ #
219
+ # class Invoice < ActiveRecord::Base
220
+ # class Lineitem < ActiveRecord::Base
221
+ # end
222
+ # end
223
+ #
224
+ # file class table_name
225
+ # invoice.rb Invoice::Lineitem invoice_lineitems
226
+ #
227
+ # module Invoice
228
+ # class Lineitem < ActiveRecord::Base
229
+ # end
230
+ # end
231
+ #
232
+ # file class table_name
233
+ # invoice/lineitem.rb Invoice::Lineitem lineitems
234
+ #
235
+ # Additionally, the class-level +table_name_prefix+ is prepended and the
236
+ # +table_name_suffix+ is appended. So if you have "myapp_" as a prefix,
237
+ # the table name guess for an Invoice class becomes "myapp_invoices".
238
+ # Invoice::Lineitem becomes "myapp_invoice_lineitems".
239
+ #
240
+ # Active Model Naming's +model_name+ is the base name used to guess the
241
+ # table name. In case a custom Active Model Name is defined, it will be
242
+ # used for the table name as well:
243
+ #
244
+ # class PostRecord < ActiveRecord::Base
245
+ # class << self
246
+ # def model_name
247
+ # ActiveModel::Name.new(self, nil, "Post")
248
+ # end
249
+ # end
250
+ # end
251
+ #
252
+ # PostRecord.table_name
253
+ # # => "posts"
254
+ #
255
+ # You can also set your own table name explicitly:
256
+ #
257
+ # class Mouse < ActiveRecord::Base
258
+ # self.table_name = "mice"
259
+ # end
260
+ def table_name
261
+ reset_table_name unless defined?(@table_name)
262
+ @table_name
263
+ end
264
+
265
+ # Sets the table name explicitly. Example:
266
+ #
267
+ # class Project < ActiveRecord::Base
268
+ # self.table_name = "project"
269
+ # end
270
+ def table_name=(value)
271
+ value = value && value.to_s
272
+
273
+ if defined?(@table_name)
274
+ return if value == @table_name
275
+ reset_column_information if connected?
276
+ end
277
+
278
+ @table_name = value
279
+ @quoted_table_name = nil
280
+ @arel_table = nil
281
+ @sequence_name = nil unless @explicit_sequence_name
282
+ @predicate_builder = nil
283
+ end
284
+
285
+ # Returns a quoted version of the table name, used to construct SQL statements.
286
+ def quoted_table_name
287
+ @quoted_table_name ||= adapter_class.quote_table_name(table_name)
288
+ end
289
+
290
+ # Computes the table name, (re)sets it internally, and returns it.
291
+ def reset_table_name # :nodoc:
292
+ self.table_name = if self == Base
293
+ nil
294
+ elsif abstract_class?
295
+ superclass.table_name
296
+ elsif superclass.abstract_class?
297
+ superclass.table_name || compute_table_name
298
+ else
299
+ compute_table_name
300
+ end
301
+ end
302
+
303
+ def full_table_name_prefix # :nodoc:
304
+ (module_parents.detect { |p| p.respond_to?(:table_name_prefix) } || self).table_name_prefix
305
+ end
306
+
307
+ def full_table_name_suffix # :nodoc:
308
+ (module_parents.detect { |p| p.respond_to?(:table_name_suffix) } || self).table_name_suffix
309
+ end
310
+
311
+ # The array of names of environments where destructive actions should be prohibited. By default,
312
+ # the value is <tt>["production"]</tt>.
313
+ def protected_environments
314
+ if defined?(@protected_environments)
315
+ @protected_environments
316
+ else
317
+ superclass.protected_environments
318
+ end
319
+ end
320
+
321
+ # Sets an array of names of environments where destructive actions should be prohibited.
322
+ def protected_environments=(environments)
323
+ @protected_environments = environments.map(&:to_s)
324
+ end
325
+
326
+ def real_inheritance_column=(value) # :nodoc:
327
+ self._inheritance_column = value.to_s
328
+ end
329
+
330
+ # The list of columns names the model should ignore. Ignored columns won't have attribute
331
+ # accessors defined, and won't be referenced in SQL queries.
332
+ def ignored_columns
333
+ @ignored_columns || superclass.ignored_columns
334
+ end
335
+
336
+ # Sets the columns names the model should ignore. Ignored columns won't have attribute
337
+ # accessors defined, and won't be referenced in SQL queries.
338
+ #
339
+ # A common usage pattern for this method is to ensure all references to an attribute
340
+ # have been removed and deployed, before a migration to drop the column from the database
341
+ # has been deployed and run. Using this two step approach to dropping columns ensures there
342
+ # is no code that raises errors due to having a cached schema in memory at the time the
343
+ # schema migration is run.
344
+ #
345
+ # For example, given a model where you want to drop the "category" attribute, first mark it
346
+ # as ignored:
347
+ #
348
+ # class Project < ActiveRecord::Base
349
+ # # schema:
350
+ # # id :bigint
351
+ # # name :string, limit: 255
352
+ # # category :string, limit: 255
353
+ #
354
+ # self.ignored_columns += [:category]
355
+ # end
356
+ #
357
+ # The schema still contains "category", but now the model omits it, so any meta-driven code or
358
+ # schema caching will not attempt to use the column:
359
+ #
360
+ # Project.columns_hash["category"] => nil
361
+ #
362
+ # You will get an error if accessing that attribute directly, so ensure all usages of the
363
+ # column are removed (automated tests can help you find any usages).
364
+ #
365
+ # user = Project.create!(name: "First Project")
366
+ # user.category # => raises NoMethodError
367
+ def ignored_columns=(columns)
368
+ reload_schema_from_cache
369
+ @ignored_columns = columns.map(&:to_s).freeze
370
+ end
371
+
372
+ def sequence_name
373
+ if base_class?
374
+ @sequence_name ||= reset_sequence_name
375
+ else
376
+ (@sequence_name ||= nil) || base_class.sequence_name
377
+ end
378
+ end
379
+
380
+ def reset_sequence_name # :nodoc:
381
+ @explicit_sequence_name = false
382
+ @sequence_name = with_connection { |c| c.default_sequence_name(table_name, primary_key) }
383
+ end
384
+
385
+ # Sets the name of the sequence to use when generating ids to the given
386
+ # value, or (if the value is +nil+ or +false+) to the value returned by the
387
+ # given block. This is required for Oracle and is useful for any
388
+ # database which relies on sequences for primary key generation.
389
+ #
390
+ # If a sequence name is not explicitly set when using Oracle,
391
+ # it will default to the commonly used pattern of: #{table_name}_seq
392
+ #
393
+ # If a sequence name is not explicitly set when using PostgreSQL, it
394
+ # will discover the sequence corresponding to your primary key for you.
395
+ #
396
+ # class Project < ActiveRecord::Base
397
+ # self.sequence_name = "projectseq" # default would have been "project_seq"
398
+ # end
399
+ def sequence_name=(value)
400
+ @sequence_name = value.to_s
401
+ @explicit_sequence_name = true
402
+ end
403
+
404
+ # Determines if the primary key values should be selected from their
405
+ # corresponding sequence before the insert statement.
406
+ def prefetch_primary_key?
407
+ with_connection { |c| c.prefetch_primary_key?(table_name) }
408
+ end
409
+
410
+ # Returns the next value that will be used as the primary key on
411
+ # an insert statement.
412
+ def next_sequence_value
413
+ with_connection { |c| c.next_sequence_value(sequence_name) }
414
+ end
415
+
416
+ # Indicates whether the table associated with this class exists
417
+ def table_exists?
418
+ schema_cache.data_source_exists?(table_name)
419
+ end
420
+
421
+ def attributes_builder # :nodoc:
422
+ @attributes_builder ||= begin
423
+ defaults = _default_attributes.except(*(column_names - [primary_key]))
424
+ ActiveModel::AttributeSet::Builder.new(attribute_types, defaults)
425
+ end
426
+ end
427
+
428
+ def columns_hash # :nodoc:
429
+ load_schema unless @columns_hash
430
+ @columns_hash
431
+ end
432
+
433
+ def columns
434
+ load_schema unless @columns
435
+ @columns ||= columns_hash.values.freeze
436
+ end
437
+
438
+ def _returning_columns_for_insert(connection) # :nodoc:
439
+ @_returning_columns_for_insert ||= begin
440
+ auto_populated_columns = columns.filter_map do |c|
441
+ c.name if connection.return_value_after_insert?(c)
442
+ end
443
+
444
+ auto_populated_columns.empty? ? Array(primary_key) : auto_populated_columns
445
+ end
446
+ end
447
+
448
+ def yaml_encoder # :nodoc:
449
+ @yaml_encoder ||= ActiveModel::AttributeSet::YAMLEncoder.new(attribute_types)
450
+ end
451
+
452
+ # Returns the column object for the named attribute.
453
+ # Returns an ActiveRecord::ConnectionAdapters::NullColumn if the
454
+ # named attribute does not exist.
455
+ #
456
+ # class Person < ActiveRecord::Base
457
+ # end
458
+ #
459
+ # person = Person.new
460
+ # person.column_for_attribute(:name) # the result depends on the ConnectionAdapter
461
+ # # => #<ActiveRecord::ConnectionAdapters::Column:0x007ff4ab083980 @name="name", @sql_type="varchar(255)", @null=true, ...>
462
+ #
463
+ # person.column_for_attribute(:nothing)
464
+ # # => #<ActiveRecord::ConnectionAdapters::NullColumn:0xXXX @name=nil, @sql_type=nil, @cast_type=#<Type::Value>, ...>
465
+ def column_for_attribute(name)
466
+ name = name.to_s
467
+ columns_hash.fetch(name) do
468
+ ConnectionAdapters::NullColumn.new(name)
469
+ end
470
+ end
471
+
472
+ # Returns a hash where the keys are column names and the values are
473
+ # default values when instantiating the Active Record object for this table.
474
+ def column_defaults
475
+ load_schema
476
+ @column_defaults ||= _default_attributes.deep_dup.to_hash.freeze
477
+ end
478
+
479
+ # Returns an array of column names as strings.
480
+ def column_names
481
+ @column_names ||= columns.map(&:name).freeze
482
+ end
483
+
484
+ def symbol_column_to_string(name_symbol) # :nodoc:
485
+ @symbol_column_to_string_name_hash ||= column_names.index_by(&:to_sym)
486
+ @symbol_column_to_string_name_hash[name_symbol]
487
+ end
488
+
489
+ # Returns an array of column objects where the primary id, all columns ending in "_id" or "_count",
490
+ # and columns used for single table inheritance have been removed.
491
+ def content_columns
492
+ @content_columns ||= columns.reject do |c|
493
+ c.name == primary_key ||
494
+ c.name == inheritance_column ||
495
+ c.name.end_with?("_id", "_count")
496
+ end.freeze
497
+ end
498
+
499
+ # Resets all the cached information about columns, which will cause them
500
+ # to be reloaded on the next request.
501
+ #
502
+ # The most common usage pattern for this method is probably in a migration,
503
+ # when just after creating a table you want to populate it with some default
504
+ # values, e.g.:
505
+ #
506
+ # class CreateJobLevels < ActiveRecord::Migration[8.0]
507
+ # def up
508
+ # create_table :job_levels do |t|
509
+ # t.integer :id
510
+ # t.string :name
511
+ #
512
+ # t.timestamps
513
+ # end
514
+ #
515
+ # JobLevel.reset_column_information
516
+ # %w{assistant executive manager director}.each do |type|
517
+ # JobLevel.create(name: type)
518
+ # end
519
+ # end
520
+ #
521
+ # def down
522
+ # drop_table :job_levels
523
+ # end
524
+ # end
525
+ def reset_column_information
526
+ connection_pool.active_connection&.clear_cache!
527
+ ([self] + descendants).each(&:undefine_attribute_methods)
528
+ schema_cache.clear_data_source_cache!(table_name)
529
+
530
+ reload_schema_from_cache
531
+ initialize_find_by_cache
532
+ end
533
+
534
+ # Load the model's schema information either from the schema cache
535
+ # or directly from the database.
536
+ def load_schema
537
+ return if schema_loaded?
538
+ @load_schema_monitor.synchronize do
539
+ return if schema_loaded?
540
+
541
+ load_schema!
542
+
543
+ @schema_loaded = true
544
+ rescue
545
+ reload_schema_from_cache # If the schema loading failed half way through, we must reset the state.
546
+ raise
547
+ end
548
+ end
549
+
550
+ protected
551
+ def initialize_load_schema_monitor
552
+ @load_schema_monitor = Monitor.new
553
+ end
554
+
555
+ def reload_schema_from_cache(recursive = true)
556
+ @_returning_columns_for_insert = nil
557
+ @arel_table = nil
558
+ @column_names = nil
559
+ @symbol_column_to_string_name_hash = nil
560
+ @content_columns = nil
561
+ @column_defaults = nil
562
+ @attributes_builder = nil
563
+ @columns = nil
564
+ @columns_hash = nil
565
+ @schema_loaded = false
566
+ @attribute_names = nil
567
+ @yaml_encoder = nil
568
+ if recursive
569
+ subclasses.each do |descendant|
570
+ descendant.send(:reload_schema_from_cache)
571
+ end
572
+ end
573
+ end
574
+
575
+ private
576
+ def inherited(child_class)
577
+ super
578
+ child_class.initialize_load_schema_monitor
579
+ child_class.reload_schema_from_cache(false)
580
+ child_class.class_eval do
581
+ @ignored_columns = nil
582
+ end
583
+ end
584
+
585
+ def schema_loaded?
586
+ @schema_loaded
587
+ end
588
+
589
+ def load_schema!
590
+ unless table_name
591
+ raise ActiveRecord::TableNotSpecified, "#{self} has no table configured. Set one with #{self}.table_name="
592
+ end
593
+
594
+ columns_hash = schema_cache.columns_hash(table_name)
595
+ columns_hash = columns_hash.except(*ignored_columns) unless ignored_columns.empty?
596
+ @columns_hash = columns_hash.freeze
597
+
598
+ _default_attributes # Precompute to cache DB-dependent attribute types
599
+ end
600
+
601
+ # Guesses the table name, but does not decorate it with prefix and suffix information.
602
+ def undecorated_table_name(model_name)
603
+ table_name = model_name.to_s.demodulize.underscore
604
+ pluralize_table_names ? table_name.pluralize : table_name
605
+ end
606
+
607
+ # Computes and returns a table name according to default conventions.
608
+ def compute_table_name
609
+ if base_class?
610
+ # Nested classes are prefixed with singular parent table name.
611
+ if module_parent < Base && !module_parent.abstract_class?
612
+ contained = module_parent.table_name
613
+ contained = contained.singularize if module_parent.pluralize_table_names
614
+ contained += "_"
615
+ end
616
+
617
+ "#{full_table_name_prefix}#{contained}#{undecorated_table_name(model_name)}#{full_table_name_suffix}"
618
+ else
619
+ # STI subclasses always use their superclass's table.
620
+ base_class.table_name
621
+ end
622
+ end
623
+
624
+ def type_for_column(connection, column)
625
+ type = connection.lookup_cast_type_from_column(column)
626
+
627
+ if immutable_strings_by_default && type.respond_to?(:to_immutable_string)
628
+ type = type.to_immutable_string
629
+ end
630
+
631
+ type
632
+ end
633
+ end
634
+ end
635
+ end