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,145 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module ConnectionAdapters
5
+ module SQLite3
6
+ module DatabaseStatements
7
+ READ_QUERY = ActiveRecord::ConnectionAdapters::AbstractAdapter.build_read_query_regexp(
8
+ :pragma
9
+ ) # :nodoc:
10
+ private_constant :READ_QUERY
11
+
12
+ def write_query?(sql) # :nodoc:
13
+ !READ_QUERY.match?(sql)
14
+ rescue ArgumentError # Invalid encoding
15
+ !READ_QUERY.match?(sql.b)
16
+ end
17
+
18
+ def explain(arel, binds = [], _options = [])
19
+ sql = "EXPLAIN QUERY PLAN " + to_sql(arel, binds)
20
+ result = internal_exec_query(sql, "EXPLAIN", [])
21
+ SQLite3::ExplainPrettyPrinter.new.pp(result)
22
+ end
23
+
24
+ def begin_deferred_transaction(isolation = nil) # :nodoc:
25
+ internal_begin_transaction(:deferred, isolation)
26
+ end
27
+
28
+ def begin_isolated_db_transaction(isolation) # :nodoc:
29
+ internal_begin_transaction(:deferred, isolation)
30
+ end
31
+
32
+ def begin_db_transaction # :nodoc:
33
+ internal_begin_transaction(:immediate, nil)
34
+ end
35
+
36
+ def commit_db_transaction # :nodoc:
37
+ internal_execute("COMMIT TRANSACTION", "TRANSACTION", allow_retry: true, materialize_transactions: false)
38
+ end
39
+
40
+ def exec_rollback_db_transaction # :nodoc:
41
+ internal_execute("ROLLBACK TRANSACTION", "TRANSACTION", allow_retry: true, materialize_transactions: false)
42
+ end
43
+
44
+ # https://stackoverflow.com/questions/17574784
45
+ # https://www.sqlite.org/lang_datefunc.html
46
+ HIGH_PRECISION_CURRENT_TIMESTAMP = Arel.sql("STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')", retryable: true).freeze # :nodoc:
47
+ private_constant :HIGH_PRECISION_CURRENT_TIMESTAMP
48
+
49
+ def high_precision_current_timestamp
50
+ HIGH_PRECISION_CURRENT_TIMESTAMP
51
+ end
52
+
53
+ def execute(...) # :nodoc:
54
+ # SQLite3Adapter was refactored to use ActiveRecord::Result internally
55
+ # but for backward compatibility we have to keep returning arrays of hashes here
56
+ super&.to_a
57
+ end
58
+
59
+ def reset_isolation_level # :nodoc:
60
+ internal_execute("PRAGMA read_uncommitted=#{@previous_read_uncommitted}", "TRANSACTION", allow_retry: true, materialize_transactions: false)
61
+ @previous_read_uncommitted = nil
62
+ end
63
+
64
+ private
65
+ def internal_begin_transaction(mode, isolation)
66
+ if isolation
67
+ raise TransactionIsolationError, "SQLite3 only supports the `read_uncommitted` transaction isolation level" if isolation != :read_uncommitted
68
+ raise StandardError, "You need to enable the shared-cache mode in SQLite mode before attempting to change the transaction isolation level" unless shared_cache?
69
+ end
70
+
71
+ internal_execute("BEGIN #{mode} TRANSACTION", allow_retry: true, materialize_transactions: false)
72
+ if isolation
73
+ @previous_read_uncommitted = query_value("PRAGMA read_uncommitted")
74
+ internal_execute("PRAGMA read_uncommitted=ON", "TRANSACTION", allow_retry: true, materialize_transactions: false)
75
+ end
76
+ end
77
+
78
+ def perform_query(raw_connection, sql, binds, type_casted_binds, prepare:, notification_payload:, batch: false)
79
+ if batch
80
+ raw_connection.execute_batch2(sql)
81
+ elsif prepare
82
+ stmt = @statements[sql] ||= raw_connection.prepare(sql)
83
+ stmt.reset!
84
+ stmt.bind_params(type_casted_binds)
85
+
86
+ result = if stmt.column_count.zero? # No return
87
+ stmt.step
88
+ ActiveRecord::Result.empty
89
+ else
90
+ ActiveRecord::Result.new(stmt.columns, stmt.to_a)
91
+ end
92
+ else
93
+ # Don't cache statements if they are not prepared.
94
+ stmt = raw_connection.prepare(sql)
95
+ begin
96
+ unless binds.nil? || binds.empty?
97
+ stmt.bind_params(type_casted_binds)
98
+ end
99
+ result = if stmt.column_count.zero? # No return
100
+ stmt.step
101
+ ActiveRecord::Result.empty
102
+ else
103
+ ActiveRecord::Result.new(stmt.columns, stmt.to_a)
104
+ end
105
+ ensure
106
+ stmt.close
107
+ end
108
+ end
109
+ @last_affected_rows = raw_connection.changes
110
+ verified!
111
+
112
+ notification_payload[:row_count] = result&.length || 0
113
+ result
114
+ end
115
+
116
+ def cast_result(result)
117
+ # Given that SQLite3 doesn't really a Result type, raw_execute already return an ActiveRecord::Result
118
+ # and we have nothing to cast here.
119
+ result
120
+ end
121
+
122
+ def affected_rows(result)
123
+ @last_affected_rows
124
+ end
125
+
126
+ def execute_batch(statements, name = nil, **kwargs)
127
+ sql = combine_multi_statements(statements)
128
+ raw_execute(sql, name, batch: true, **kwargs)
129
+ end
130
+
131
+ def build_truncate_statement(table_name)
132
+ "DELETE FROM #{quote_table_name(table_name)}"
133
+ end
134
+
135
+ def returning_column_values(result)
136
+ result.rows.first
137
+ end
138
+
139
+ def default_insert_value(column)
140
+ column.default
141
+ end
142
+ end
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module ConnectionAdapters
5
+ module SQLite3
6
+ class ExplainPrettyPrinter # :nodoc:
7
+ # Pretty prints the result of an EXPLAIN QUERY PLAN in a way that resembles
8
+ # the output of the SQLite shell:
9
+ #
10
+ # 0|0|0|SEARCH TABLE users USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)
11
+ # 0|1|1|SCAN TABLE posts (~100000 rows)
12
+ #
13
+ def pp(result)
14
+ result.rows.map do |row|
15
+ row.join("|")
16
+ end.join("\n") + "\n"
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,116 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module ConnectionAdapters
5
+ module SQLite3
6
+ module Quoting # :nodoc:
7
+ extend ActiveSupport::Concern
8
+
9
+ QUOTED_COLUMN_NAMES = Concurrent::Map.new # :nodoc:
10
+ QUOTED_TABLE_NAMES = Concurrent::Map.new # :nodoc:
11
+
12
+ module ClassMethods # :nodoc:
13
+ def column_name_matcher
14
+ /
15
+ \A
16
+ (
17
+ (?:
18
+ # "table_name"."column_name" | function(one or no argument)
19
+ ((?:\w+\.|"\w+"\.)?(?:\w+|"\w+") | \w+\((?:|\g<2>)\))
20
+ )
21
+ (?:(?:\s+AS)?\s+(?:\w+|"\w+"))?
22
+ )
23
+ (?:\s*,\s*\g<1>)*
24
+ \z
25
+ /ix
26
+ end
27
+
28
+ def column_name_with_order_matcher
29
+ /
30
+ \A
31
+ (
32
+ (?:
33
+ # "table_name"."column_name" | function(one or no argument)
34
+ ((?:\w+\.|"\w+"\.)?(?:\w+|"\w+") | \w+\((?:|\g<2>)\))
35
+ )
36
+ (?:\s+COLLATE\s+(?:\w+|"\w+"))?
37
+ (?:\s+ASC|\s+DESC)?
38
+ )
39
+ (?:\s*,\s*\g<1>)*
40
+ \z
41
+ /ix
42
+ end
43
+
44
+ def quote_column_name(name)
45
+ QUOTED_COLUMN_NAMES[name] ||= %Q("#{name.to_s.gsub('"', '""')}").freeze
46
+ end
47
+
48
+ def quote_table_name(name)
49
+ QUOTED_TABLE_NAMES[name] ||= %Q("#{name.to_s.gsub('"', '""').gsub(".", "\".\"")}").freeze
50
+ end
51
+ end
52
+
53
+ def quote_string(s)
54
+ ::SQLite3::Database.quote(s)
55
+ end
56
+
57
+ def quote_table_name_for_assignment(table, attr)
58
+ quote_column_name(attr)
59
+ end
60
+
61
+ def quoted_time(value)
62
+ value = value.change(year: 2000, month: 1, day: 1)
63
+ quoted_date(value).sub(/\A\d\d\d\d-\d\d-\d\d /, "2000-01-01 ")
64
+ end
65
+
66
+ def quoted_binary(value)
67
+ "x'#{value.hex}'"
68
+ end
69
+
70
+ def quoted_true
71
+ "1"
72
+ end
73
+
74
+ def unquoted_true
75
+ 1
76
+ end
77
+
78
+ def quoted_false
79
+ "0"
80
+ end
81
+
82
+ def unquoted_false
83
+ 0
84
+ end
85
+
86
+ def quote_default_expression(value, column) # :nodoc:
87
+ if value.is_a?(Proc)
88
+ value = value.call
89
+ if value.match?(/\A\w+\(.*\)\z/)
90
+ "(#{value})"
91
+ else
92
+ value
93
+ end
94
+ else
95
+ super
96
+ end
97
+ end
98
+
99
+ def type_cast(value) # :nodoc:
100
+ case value
101
+ when BigDecimal, Rational
102
+ value.to_f
103
+ when String
104
+ if value.encoding == Encoding::ASCII_8BIT
105
+ super(value.encode(Encoding::UTF_8))
106
+ else
107
+ super
108
+ end
109
+ else
110
+ super
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module ConnectionAdapters
5
+ module SQLite3
6
+ class SchemaCreation < SchemaCreation # :nodoc:
7
+ private
8
+ def visit_ForeignKeyDefinition(o)
9
+ super.dup.tap do |sql|
10
+ sql << " DEFERRABLE INITIALLY #{o.deferrable.to_s.upcase}" if o.deferrable
11
+ end
12
+ end
13
+
14
+ def supports_index_using?
15
+ false
16
+ end
17
+
18
+ def add_column_options!(sql, options)
19
+ if options[:collation]
20
+ sql << " COLLATE \"#{options[:collation]}\""
21
+ end
22
+
23
+ if as = options[:as]
24
+ sql << " GENERATED ALWAYS AS (#{as})"
25
+
26
+ if options[:stored]
27
+ sql << " STORED"
28
+ else
29
+ sql << " VIRTUAL"
30
+ end
31
+ end
32
+ super
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module ConnectionAdapters
5
+ module SQLite3
6
+ # = Active Record SQLite3 Adapter \Table Definition
7
+ class TableDefinition < ActiveRecord::ConnectionAdapters::TableDefinition
8
+ def change_column(column_name, type, **options)
9
+ name = column_name.to_s
10
+ @columns_hash[name] = nil
11
+ column(name, type, **options)
12
+ end
13
+
14
+ def references(*args, **options)
15
+ super(*args, type: :integer, **options)
16
+ end
17
+ alias :belongs_to :references
18
+
19
+ def new_column_definition(name, type, **options) # :nodoc:
20
+ case type
21
+ when :virtual
22
+ type = options[:type]
23
+ end
24
+
25
+ super
26
+ end
27
+
28
+ private
29
+ def integer_like_primary_key_type(type, options)
30
+ :primary_key
31
+ end
32
+
33
+ def valid_column_definition_options
34
+ super + [:as, :type, :stored]
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module ConnectionAdapters
5
+ module SQLite3
6
+ class SchemaDumper < ConnectionAdapters::SchemaDumper # :nodoc:
7
+ private
8
+ def virtual_tables(stream)
9
+ virtual_tables = @connection.virtual_tables
10
+ if virtual_tables.any?
11
+ stream.puts
12
+ stream.puts " # Virtual tables defined in this database."
13
+ stream.puts " # Note that virtual tables may not work with other database engines. Be careful if changing database."
14
+ virtual_tables.sort.each do |table_name, options|
15
+ module_name, arguments = options
16
+ stream.puts " create_virtual_table #{table_name.inspect}, #{module_name.inspect}, #{arguments.split(", ").inspect}"
17
+ end
18
+ end
19
+ end
20
+
21
+ def default_primary_key?(column)
22
+ schema_type(column) == :integer
23
+ end
24
+
25
+ def explicit_primary_key_default?(column)
26
+ column.bigint?
27
+ end
28
+
29
+ def prepare_column_options(column)
30
+ spec = super
31
+
32
+ if @connection.supports_virtual_columns? && column.virtual?
33
+ spec[:as] = extract_expression_for_virtual_column(column)
34
+ spec[:stored] = column.virtual_stored?
35
+ spec = { type: schema_type(column).inspect }.merge!(spec)
36
+ end
37
+
38
+ spec
39
+ end
40
+
41
+ def extract_expression_for_virtual_column(column)
42
+ column.default_function.inspect
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,221 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module ConnectionAdapters
5
+ module SQLite3
6
+ module SchemaStatements # :nodoc:
7
+ # Returns an array of indexes for the given table.
8
+ def indexes(table_name)
9
+ internal_exec_query("PRAGMA index_list(#{quote_table_name(table_name)})", "SCHEMA").filter_map do |row|
10
+ # Indexes SQLite creates implicitly for internal use start with "sqlite_".
11
+ # See https://www.sqlite.org/fileformat2.html#intschema
12
+ next if row["name"].start_with?("sqlite_")
13
+
14
+ index_sql = query_value(<<~SQL, "SCHEMA")
15
+ SELECT sql
16
+ FROM sqlite_master
17
+ WHERE name = #{quote(row['name'])} AND type = 'index'
18
+ UNION ALL
19
+ SELECT sql
20
+ FROM sqlite_temp_master
21
+ WHERE name = #{quote(row['name'])} AND type = 'index'
22
+ SQL
23
+
24
+ /\bON\b\s*"?(\w+?)"?\s*\((?<expressions>.+?)\)(?:\s*WHERE\b\s*(?<where>.+))?(?:\s*\/\*.*\*\/)?\z/i =~ index_sql
25
+
26
+ columns = internal_exec_query("PRAGMA index_info(#{quote(row['name'])})", "SCHEMA").map do |col|
27
+ col["name"]
28
+ end
29
+
30
+ orders = {}
31
+
32
+ if columns.any?(&:nil?) # index created with an expression
33
+ columns = expressions
34
+ else
35
+ # Add info on sort order for columns (only desc order is explicitly specified,
36
+ # asc is the default)
37
+ if index_sql # index_sql can be null in case of primary key indexes
38
+ index_sql.scan(/"(\w+)" DESC/).flatten.each { |order_column|
39
+ orders[order_column] = :desc
40
+ }
41
+ end
42
+ end
43
+
44
+ IndexDefinition.new(
45
+ table_name,
46
+ row["name"],
47
+ row["unique"] != 0,
48
+ columns,
49
+ where: where,
50
+ orders: orders
51
+ )
52
+ end
53
+ end
54
+
55
+ def add_foreign_key(from_table, to_table, **options)
56
+ assert_valid_deferrable(options[:deferrable])
57
+
58
+ alter_table(from_table) do |definition|
59
+ to_table = strip_table_name_prefix_and_suffix(to_table)
60
+ definition.foreign_key(to_table, **options)
61
+ end
62
+ end
63
+
64
+ def remove_foreign_key(from_table, to_table = nil, **options)
65
+ return if options.delete(:if_exists) == true && !foreign_key_exists?(from_table, to_table)
66
+
67
+ to_table ||= options[:to_table]
68
+ options = options.except(:name, :to_table, :validate)
69
+ foreign_keys = foreign_keys(from_table)
70
+
71
+ fkey = foreign_keys.detect do |fk|
72
+ table = to_table || begin
73
+ table = options[:column].to_s.delete_suffix("_id")
74
+ Base.pluralize_table_names ? table.pluralize : table
75
+ end
76
+ table = strip_table_name_prefix_and_suffix(table)
77
+ fk_to_table = strip_table_name_prefix_and_suffix(fk.to_table)
78
+ fk_to_table == table && options.all? { |k, v| fk.options[k].to_s == v.to_s }
79
+ end || raise(ArgumentError, "Table '#{from_table}' has no foreign key for #{to_table || options}")
80
+
81
+ foreign_keys.delete(fkey)
82
+ alter_table(from_table, foreign_keys)
83
+ end
84
+
85
+ def virtual_table_exists?(table_name)
86
+ query_values(data_source_sql(table_name, type: "VIRTUAL TABLE"), "SCHEMA").any?
87
+ end
88
+
89
+ def check_constraints(table_name)
90
+ table_sql = query_value(<<-SQL, "SCHEMA")
91
+ SELECT sql
92
+ FROM sqlite_master
93
+ WHERE name = #{quote(table_name)} AND type = 'table'
94
+ UNION ALL
95
+ SELECT sql
96
+ FROM sqlite_temp_master
97
+ WHERE name = #{quote(table_name)} AND type = 'table'
98
+ SQL
99
+
100
+ table_sql.to_s.scan(/CONSTRAINT\s+(?<name>\w+)\s+CHECK\s+\((?<expression>(:?[^()]|\(\g<expression>\))+)\)/i).map do |name, expression|
101
+ CheckConstraintDefinition.new(table_name, expression, name: name)
102
+ end
103
+ end
104
+
105
+ def add_check_constraint(table_name, expression, **options)
106
+ alter_table(table_name) do |definition|
107
+ definition.check_constraint(expression, **options)
108
+ end
109
+ end
110
+
111
+ def remove_check_constraint(table_name, expression = nil, if_exists: false, **options)
112
+ return if if_exists && !check_constraint_exists?(table_name, **options)
113
+
114
+ check_constraints = check_constraints(table_name)
115
+ chk_name_to_delete = check_constraint_for!(table_name, expression: expression, **options).name
116
+ check_constraints.delete_if { |chk| chk.name == chk_name_to_delete }
117
+ alter_table(table_name, foreign_keys(table_name), check_constraints)
118
+ end
119
+
120
+ def create_schema_dumper(options)
121
+ SQLite3::SchemaDumper.create(self, options)
122
+ end
123
+
124
+ def schema_creation # :nodoc
125
+ SQLite3::SchemaCreation.new(self)
126
+ end
127
+
128
+ private
129
+ def valid_table_definition_options
130
+ super + [:rename]
131
+ end
132
+
133
+ def create_table_definition(name, **options)
134
+ SQLite3::TableDefinition.new(self, name, **options)
135
+ end
136
+
137
+ def validate_index_length!(table_name, new_name, internal = false)
138
+ super unless internal
139
+ end
140
+
141
+ def new_column_from_field(table_name, field, definitions)
142
+ default = field["dflt_value"]
143
+
144
+ type_metadata = fetch_type_metadata(field["type"])
145
+ default_value = extract_value_from_default(default)
146
+ generated_type = extract_generated_type(field)
147
+
148
+ if generated_type.present?
149
+ default_function = default
150
+ else
151
+ default_function = extract_default_function(default_value, default)
152
+ end
153
+
154
+ rowid = is_column_the_rowid?(field, definitions)
155
+
156
+ Column.new(
157
+ field["name"],
158
+ default_value,
159
+ type_metadata,
160
+ field["notnull"].to_i == 0,
161
+ default_function,
162
+ collation: field["collation"],
163
+ auto_increment: field["auto_increment"],
164
+ rowid: rowid,
165
+ generated_type: generated_type
166
+ )
167
+ end
168
+
169
+ INTEGER_REGEX = /integer/i
170
+ # if a rowid table has a primary key that consists of a single column
171
+ # and the declared type of that column is "INTEGER" in any mixture of upper and lower case,
172
+ # then the column becomes an alias for the rowid.
173
+ def is_column_the_rowid?(field, column_definitions)
174
+ return false unless INTEGER_REGEX.match?(field["type"]) && field["pk"] == 1
175
+ # is the primary key a single column?
176
+ column_definitions.one? { |c| c["pk"] > 0 }
177
+ end
178
+
179
+ def data_source_sql(name = nil, type: nil)
180
+ scope = quoted_scope(name, type: type)
181
+ scope[:type] ||= "'table','view'"
182
+
183
+ sql = +"SELECT name FROM pragma_table_list WHERE schema <> 'temp'"
184
+ sql << " AND name NOT IN ('sqlite_sequence', 'sqlite_schema')"
185
+ sql << " AND name = #{scope[:name]}" if scope[:name]
186
+ sql << " AND type IN (#{scope[:type]})"
187
+ sql
188
+ end
189
+
190
+ def quoted_scope(name = nil, type: nil)
191
+ type = \
192
+ case type
193
+ when "BASE TABLE"
194
+ "'table'"
195
+ when "VIEW"
196
+ "'view'"
197
+ when "VIRTUAL TABLE"
198
+ "'virtual'"
199
+ end
200
+ scope = {}
201
+ scope[:name] = quote(name) if name
202
+ scope[:type] = type if type
203
+ scope
204
+ end
205
+
206
+ def assert_valid_deferrable(deferrable)
207
+ return if !deferrable || %i(immediate deferred).include?(deferrable)
208
+
209
+ raise ArgumentError, "deferrable must be `:immediate` or `:deferred`, got: `#{deferrable.inspect}`"
210
+ end
211
+
212
+ def extract_generated_type(field)
213
+ case field["hidden"]
214
+ when 2 then :virtual
215
+ when 3 then :stored
216
+ end
217
+ end
218
+ end
219
+ end
220
+ end
221
+ end