activerecord 6.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activerecord might be problematic. Click here for more details.

Files changed (340) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +1013 -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.rb +195 -0
  8. data/lib/active_record/aggregations.rb +285 -0
  9. data/lib/active_record/association_relation.rb +40 -0
  10. data/lib/active_record/associations.rb +1865 -0
  11. data/lib/active_record/associations/alias_tracker.rb +81 -0
  12. data/lib/active_record/associations/association.rb +332 -0
  13. data/lib/active_record/associations/association_scope.rb +166 -0
  14. data/lib/active_record/associations/belongs_to_association.rb +124 -0
  15. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +36 -0
  16. data/lib/active_record/associations/builder/association.rb +136 -0
  17. data/lib/active_record/associations/builder/belongs_to.rb +130 -0
  18. data/lib/active_record/associations/builder/collection_association.rb +72 -0
  19. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +114 -0
  20. data/lib/active_record/associations/builder/has_many.rb +19 -0
  21. data/lib/active_record/associations/builder/has_one.rb +64 -0
  22. data/lib/active_record/associations/builder/singular_association.rb +44 -0
  23. data/lib/active_record/associations/collection_association.rb +498 -0
  24. data/lib/active_record/associations/collection_proxy.rb +1128 -0
  25. data/lib/active_record/associations/foreign_association.rb +20 -0
  26. data/lib/active_record/associations/has_many_association.rb +136 -0
  27. data/lib/active_record/associations/has_many_through_association.rb +220 -0
  28. data/lib/active_record/associations/has_one_association.rb +118 -0
  29. data/lib/active_record/associations/has_one_through_association.rb +45 -0
  30. data/lib/active_record/associations/join_dependency.rb +258 -0
  31. data/lib/active_record/associations/join_dependency/join_association.rb +80 -0
  32. data/lib/active_record/associations/join_dependency/join_base.rb +23 -0
  33. data/lib/active_record/associations/join_dependency/join_part.rb +71 -0
  34. data/lib/active_record/associations/preloader.rb +201 -0
  35. data/lib/active_record/associations/preloader/association.rb +133 -0
  36. data/lib/active_record/associations/preloader/through_association.rb +116 -0
  37. data/lib/active_record/associations/singular_association.rb +59 -0
  38. data/lib/active_record/associations/through_association.rb +121 -0
  39. data/lib/active_record/attribute_assignment.rb +85 -0
  40. data/lib/active_record/attribute_decorators.rb +90 -0
  41. data/lib/active_record/attribute_methods.rb +420 -0
  42. data/lib/active_record/attribute_methods/before_type_cast.rb +81 -0
  43. data/lib/active_record/attribute_methods/dirty.rb +221 -0
  44. data/lib/active_record/attribute_methods/primary_key.rb +136 -0
  45. data/lib/active_record/attribute_methods/query.rb +41 -0
  46. data/lib/active_record/attribute_methods/read.rb +47 -0
  47. data/lib/active_record/attribute_methods/serialization.rb +90 -0
  48. data/lib/active_record/attribute_methods/time_zone_conversion.rb +91 -0
  49. data/lib/active_record/attribute_methods/write.rb +61 -0
  50. data/lib/active_record/attributes.rb +279 -0
  51. data/lib/active_record/autosave_association.rb +508 -0
  52. data/lib/active_record/base.rb +328 -0
  53. data/lib/active_record/callbacks.rb +339 -0
  54. data/lib/active_record/coders/json.rb +15 -0
  55. data/lib/active_record/coders/yaml_column.rb +50 -0
  56. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +1165 -0
  57. data/lib/active_record/connection_adapters/abstract/database_limits.rb +85 -0
  58. data/lib/active_record/connection_adapters/abstract/database_statements.rb +512 -0
  59. data/lib/active_record/connection_adapters/abstract/query_cache.rb +154 -0
  60. data/lib/active_record/connection_adapters/abstract/quoting.rb +251 -0
  61. data/lib/active_record/connection_adapters/abstract/savepoints.rb +23 -0
  62. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +153 -0
  63. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +713 -0
  64. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +93 -0
  65. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +1475 -0
  66. data/lib/active_record/connection_adapters/abstract/transaction.rb +323 -0
  67. data/lib/active_record/connection_adapters/abstract_adapter.rb +761 -0
  68. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +821 -0
  69. data/lib/active_record/connection_adapters/column.rb +95 -0
  70. data/lib/active_record/connection_adapters/connection_specification.rb +297 -0
  71. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +29 -0
  72. data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
  73. data/lib/active_record/connection_adapters/mysql/database_statements.rb +200 -0
  74. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +72 -0
  75. data/lib/active_record/connection_adapters/mysql/quoting.rb +81 -0
  76. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +72 -0
  77. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +95 -0
  78. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +88 -0
  79. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +264 -0
  80. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +31 -0
  81. data/lib/active_record/connection_adapters/mysql2_adapter.rb +146 -0
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +30 -0
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +182 -0
  84. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
  85. data/lib/active_record/connection_adapters/postgresql/oid.rb +34 -0
  86. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +92 -0
  87. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +53 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +15 -0
  89. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +17 -0
  90. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +50 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
  92. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +23 -0
  93. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +15 -0
  94. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +21 -0
  95. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +71 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +15 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +15 -0
  98. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +45 -0
  99. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +41 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +15 -0
  101. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +65 -0
  102. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +97 -0
  103. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +18 -0
  104. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +113 -0
  105. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +26 -0
  106. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +28 -0
  107. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +30 -0
  108. data/lib/active_record/connection_adapters/postgresql/quoting.rb +205 -0
  109. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +43 -0
  110. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
  111. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +222 -0
  112. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +50 -0
  113. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +776 -0
  114. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +36 -0
  115. data/lib/active_record/connection_adapters/postgresql/utils.rb +81 -0
  116. data/lib/active_record/connection_adapters/postgresql_adapter.rb +949 -0
  117. data/lib/active_record/connection_adapters/schema_cache.rb +141 -0
  118. data/lib/active_record/connection_adapters/sql_type_metadata.rb +37 -0
  119. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +118 -0
  120. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
  121. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +103 -0
  122. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +17 -0
  123. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  124. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  125. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +137 -0
  126. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +557 -0
  127. data/lib/active_record/connection_adapters/statement_pool.rb +61 -0
  128. data/lib/active_record/connection_handling.rb +267 -0
  129. data/lib/active_record/core.rb +599 -0
  130. data/lib/active_record/counter_cache.rb +193 -0
  131. data/lib/active_record/database_configurations.rb +233 -0
  132. data/lib/active_record/database_configurations/database_config.rb +37 -0
  133. data/lib/active_record/database_configurations/hash_config.rb +50 -0
  134. data/lib/active_record/database_configurations/url_config.rb +79 -0
  135. data/lib/active_record/define_callbacks.rb +22 -0
  136. data/lib/active_record/dynamic_matchers.rb +122 -0
  137. data/lib/active_record/enum.rb +274 -0
  138. data/lib/active_record/errors.rb +388 -0
  139. data/lib/active_record/explain.rb +50 -0
  140. data/lib/active_record/explain_registry.rb +32 -0
  141. data/lib/active_record/explain_subscriber.rb +34 -0
  142. data/lib/active_record/fixture_set/file.rb +82 -0
  143. data/lib/active_record/fixture_set/model_metadata.rb +33 -0
  144. data/lib/active_record/fixture_set/render_context.rb +17 -0
  145. data/lib/active_record/fixture_set/table_row.rb +153 -0
  146. data/lib/active_record/fixture_set/table_rows.rb +47 -0
  147. data/lib/active_record/fixtures.rb +738 -0
  148. data/lib/active_record/gem_version.rb +17 -0
  149. data/lib/active_record/inheritance.rb +293 -0
  150. data/lib/active_record/insert_all.rb +179 -0
  151. data/lib/active_record/integration.rb +207 -0
  152. data/lib/active_record/internal_metadata.rb +53 -0
  153. data/lib/active_record/legacy_yaml_adapter.rb +48 -0
  154. data/lib/active_record/locale/en.yml +48 -0
  155. data/lib/active_record/locking/optimistic.rb +197 -0
  156. data/lib/active_record/locking/pessimistic.rb +89 -0
  157. data/lib/active_record/log_subscriber.rb +118 -0
  158. data/lib/active_record/middleware/database_selector.rb +75 -0
  159. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  160. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  161. data/lib/active_record/migration.rb +1397 -0
  162. data/lib/active_record/migration/command_recorder.rb +284 -0
  163. data/lib/active_record/migration/compatibility.rb +244 -0
  164. data/lib/active_record/migration/join_table.rb +17 -0
  165. data/lib/active_record/model_schema.rb +542 -0
  166. data/lib/active_record/nested_attributes.rb +600 -0
  167. data/lib/active_record/no_touching.rb +65 -0
  168. data/lib/active_record/null_relation.rb +68 -0
  169. data/lib/active_record/persistence.rb +967 -0
  170. data/lib/active_record/query_cache.rb +52 -0
  171. data/lib/active_record/querying.rb +82 -0
  172. data/lib/active_record/railtie.rb +263 -0
  173. data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
  174. data/lib/active_record/railties/console_sandbox.rb +7 -0
  175. data/lib/active_record/railties/controller_runtime.rb +51 -0
  176. data/lib/active_record/railties/databases.rake +527 -0
  177. data/lib/active_record/readonly_attributes.rb +24 -0
  178. data/lib/active_record/reflection.rb +1042 -0
  179. data/lib/active_record/relation.rb +859 -0
  180. data/lib/active_record/relation/batches.rb +290 -0
  181. data/lib/active_record/relation/batches/batch_enumerator.rb +69 -0
  182. data/lib/active_record/relation/calculations.rb +424 -0
  183. data/lib/active_record/relation/delegation.rb +130 -0
  184. data/lib/active_record/relation/finder_methods.rb +552 -0
  185. data/lib/active_record/relation/from_clause.rb +26 -0
  186. data/lib/active_record/relation/merger.rb +184 -0
  187. data/lib/active_record/relation/predicate_builder.rb +150 -0
  188. data/lib/active_record/relation/predicate_builder/array_handler.rb +49 -0
  189. data/lib/active_record/relation/predicate_builder/association_query_value.rb +43 -0
  190. data/lib/active_record/relation/predicate_builder/base_handler.rb +18 -0
  191. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +19 -0
  192. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +53 -0
  193. data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -0
  194. data/lib/active_record/relation/predicate_builder/relation_handler.rb +19 -0
  195. data/lib/active_record/relation/query_attribute.rb +50 -0
  196. data/lib/active_record/relation/query_methods.rb +1359 -0
  197. data/lib/active_record/relation/record_fetch_warning.rb +51 -0
  198. data/lib/active_record/relation/spawn_methods.rb +77 -0
  199. data/lib/active_record/relation/where_clause.rb +190 -0
  200. data/lib/active_record/relation/where_clause_factory.rb +33 -0
  201. data/lib/active_record/result.rb +168 -0
  202. data/lib/active_record/runtime_registry.rb +24 -0
  203. data/lib/active_record/sanitization.rb +214 -0
  204. data/lib/active_record/schema.rb +61 -0
  205. data/lib/active_record/schema_dumper.rb +270 -0
  206. data/lib/active_record/schema_migration.rb +60 -0
  207. data/lib/active_record/scoping.rb +106 -0
  208. data/lib/active_record/scoping/default.rb +151 -0
  209. data/lib/active_record/scoping/named.rb +217 -0
  210. data/lib/active_record/secure_token.rb +40 -0
  211. data/lib/active_record/serialization.rb +22 -0
  212. data/lib/active_record/statement_cache.rb +148 -0
  213. data/lib/active_record/store.rb +290 -0
  214. data/lib/active_record/suppressor.rb +61 -0
  215. data/lib/active_record/table_metadata.rb +75 -0
  216. data/lib/active_record/tasks/database_tasks.rb +506 -0
  217. data/lib/active_record/tasks/mysql_database_tasks.rb +115 -0
  218. data/lib/active_record/tasks/postgresql_database_tasks.rb +141 -0
  219. data/lib/active_record/tasks/sqlite_database_tasks.rb +77 -0
  220. data/lib/active_record/test_databases.rb +23 -0
  221. data/lib/active_record/test_fixtures.rb +224 -0
  222. data/lib/active_record/timestamp.rb +167 -0
  223. data/lib/active_record/touch_later.rb +66 -0
  224. data/lib/active_record/transactions.rb +493 -0
  225. data/lib/active_record/translation.rb +24 -0
  226. data/lib/active_record/type.rb +78 -0
  227. data/lib/active_record/type/adapter_specific_registry.rb +129 -0
  228. data/lib/active_record/type/date.rb +9 -0
  229. data/lib/active_record/type/date_time.rb +9 -0
  230. data/lib/active_record/type/decimal_without_scale.rb +15 -0
  231. data/lib/active_record/type/hash_lookup_type_map.rb +25 -0
  232. data/lib/active_record/type/internal/timezone.rb +17 -0
  233. data/lib/active_record/type/json.rb +30 -0
  234. data/lib/active_record/type/serialized.rb +71 -0
  235. data/lib/active_record/type/text.rb +11 -0
  236. data/lib/active_record/type/time.rb +21 -0
  237. data/lib/active_record/type/type_map.rb +62 -0
  238. data/lib/active_record/type/unsigned_integer.rb +17 -0
  239. data/lib/active_record/type_caster.rb +9 -0
  240. data/lib/active_record/type_caster/connection.rb +34 -0
  241. data/lib/active_record/type_caster/map.rb +20 -0
  242. data/lib/active_record/validations.rb +94 -0
  243. data/lib/active_record/validations/absence.rb +25 -0
  244. data/lib/active_record/validations/associated.rb +60 -0
  245. data/lib/active_record/validations/length.rb +26 -0
  246. data/lib/active_record/validations/presence.rb +68 -0
  247. data/lib/active_record/validations/uniqueness.rb +226 -0
  248. data/lib/active_record/version.rb +10 -0
  249. data/lib/arel.rb +51 -0
  250. data/lib/arel/alias_predication.rb +9 -0
  251. data/lib/arel/attributes.rb +22 -0
  252. data/lib/arel/attributes/attribute.rb +37 -0
  253. data/lib/arel/collectors/bind.rb +24 -0
  254. data/lib/arel/collectors/composite.rb +31 -0
  255. data/lib/arel/collectors/plain_string.rb +20 -0
  256. data/lib/arel/collectors/sql_string.rb +20 -0
  257. data/lib/arel/collectors/substitute_binds.rb +28 -0
  258. data/lib/arel/crud.rb +42 -0
  259. data/lib/arel/delete_manager.rb +18 -0
  260. data/lib/arel/errors.rb +9 -0
  261. data/lib/arel/expressions.rb +29 -0
  262. data/lib/arel/factory_methods.rb +49 -0
  263. data/lib/arel/insert_manager.rb +49 -0
  264. data/lib/arel/math.rb +45 -0
  265. data/lib/arel/nodes.rb +68 -0
  266. data/lib/arel/nodes/and.rb +32 -0
  267. data/lib/arel/nodes/ascending.rb +23 -0
  268. data/lib/arel/nodes/binary.rb +52 -0
  269. data/lib/arel/nodes/bind_param.rb +36 -0
  270. data/lib/arel/nodes/case.rb +55 -0
  271. data/lib/arel/nodes/casted.rb +50 -0
  272. data/lib/arel/nodes/comment.rb +29 -0
  273. data/lib/arel/nodes/count.rb +12 -0
  274. data/lib/arel/nodes/delete_statement.rb +45 -0
  275. data/lib/arel/nodes/descending.rb +23 -0
  276. data/lib/arel/nodes/equality.rb +18 -0
  277. data/lib/arel/nodes/extract.rb +24 -0
  278. data/lib/arel/nodes/false.rb +16 -0
  279. data/lib/arel/nodes/full_outer_join.rb +8 -0
  280. data/lib/arel/nodes/function.rb +44 -0
  281. data/lib/arel/nodes/grouping.rb +8 -0
  282. data/lib/arel/nodes/in.rb +8 -0
  283. data/lib/arel/nodes/infix_operation.rb +80 -0
  284. data/lib/arel/nodes/inner_join.rb +8 -0
  285. data/lib/arel/nodes/insert_statement.rb +37 -0
  286. data/lib/arel/nodes/join_source.rb +20 -0
  287. data/lib/arel/nodes/matches.rb +18 -0
  288. data/lib/arel/nodes/named_function.rb +23 -0
  289. data/lib/arel/nodes/node.rb +50 -0
  290. data/lib/arel/nodes/node_expression.rb +13 -0
  291. data/lib/arel/nodes/outer_join.rb +8 -0
  292. data/lib/arel/nodes/over.rb +15 -0
  293. data/lib/arel/nodes/regexp.rb +16 -0
  294. data/lib/arel/nodes/right_outer_join.rb +8 -0
  295. data/lib/arel/nodes/select_core.rb +67 -0
  296. data/lib/arel/nodes/select_statement.rb +41 -0
  297. data/lib/arel/nodes/sql_literal.rb +16 -0
  298. data/lib/arel/nodes/string_join.rb +11 -0
  299. data/lib/arel/nodes/table_alias.rb +27 -0
  300. data/lib/arel/nodes/terminal.rb +16 -0
  301. data/lib/arel/nodes/true.rb +16 -0
  302. data/lib/arel/nodes/unary.rb +45 -0
  303. data/lib/arel/nodes/unary_operation.rb +20 -0
  304. data/lib/arel/nodes/unqualified_column.rb +22 -0
  305. data/lib/arel/nodes/update_statement.rb +41 -0
  306. data/lib/arel/nodes/values_list.rb +9 -0
  307. data/lib/arel/nodes/window.rb +126 -0
  308. data/lib/arel/nodes/with.rb +11 -0
  309. data/lib/arel/order_predications.rb +13 -0
  310. data/lib/arel/predications.rb +257 -0
  311. data/lib/arel/select_manager.rb +271 -0
  312. data/lib/arel/table.rb +110 -0
  313. data/lib/arel/tree_manager.rb +72 -0
  314. data/lib/arel/update_manager.rb +34 -0
  315. data/lib/arel/visitors.rb +20 -0
  316. data/lib/arel/visitors/depth_first.rb +204 -0
  317. data/lib/arel/visitors/dot.rb +297 -0
  318. data/lib/arel/visitors/ibm_db.rb +34 -0
  319. data/lib/arel/visitors/informix.rb +62 -0
  320. data/lib/arel/visitors/mssql.rb +157 -0
  321. data/lib/arel/visitors/mysql.rb +83 -0
  322. data/lib/arel/visitors/oracle.rb +159 -0
  323. data/lib/arel/visitors/oracle12.rb +66 -0
  324. data/lib/arel/visitors/postgresql.rb +110 -0
  325. data/lib/arel/visitors/sqlite.rb +39 -0
  326. data/lib/arel/visitors/to_sql.rb +889 -0
  327. data/lib/arel/visitors/visitor.rb +46 -0
  328. data/lib/arel/visitors/where_sql.rb +23 -0
  329. data/lib/arel/window_predications.rb +9 -0
  330. data/lib/rails/generators/active_record.rb +19 -0
  331. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
  332. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
  333. data/lib/rails/generators/active_record/migration.rb +48 -0
  334. data/lib/rails/generators/active_record/migration/migration_generator.rb +75 -0
  335. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +24 -0
  336. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +48 -0
  337. data/lib/rails/generators/active_record/model/model_generator.rb +49 -0
  338. data/lib/rails/generators/active_record/model/templates/model.rb.tt +22 -0
  339. data/lib/rails/generators/active_record/model/templates/module.rb.tt +7 -0
  340. metadata +415 -0
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module ConnectionAdapters
5
+ module SQLite3
6
+ class SchemaDumper < ConnectionAdapters::SchemaDumper # :nodoc:
7
+ private
8
+ def default_primary_key?(column)
9
+ schema_type(column) == :integer
10
+ end
11
+
12
+ def explicit_primary_key_default?(column)
13
+ column.bigint?
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,137 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module ConnectionAdapters
5
+ module SQLite3
6
+ module SchemaStatements # :nodoc:
7
+ # Returns an array of indexes for the given table.
8
+ def indexes(table_name)
9
+ exec_query("PRAGMA index_list(#{quote_table_name(table_name)})", "SCHEMA").map do |row|
10
+ # Indexes SQLite creates implicitly for internal use start with "sqlite_".
11
+ # See https://www.sqlite.org/fileformat2.html#intschema
12
+ next if row["name"].starts_with?("sqlite_")
13
+
14
+ index_sql = query_value(<<~SQL, "SCHEMA")
15
+ SELECT sql
16
+ FROM sqlite_master
17
+ WHERE name = #{quote(row['name'])} AND type = 'index'
18
+ UNION ALL
19
+ SELECT sql
20
+ FROM sqlite_temp_master
21
+ WHERE name = #{quote(row['name'])} AND type = 'index'
22
+ SQL
23
+
24
+ /\bON\b\s*"?(\w+?)"?\s*\((?<expressions>.+?)\)(?:\s*WHERE\b\s*(?<where>.+))?\z/i =~ index_sql
25
+
26
+ columns = exec_query("PRAGMA index_info(#{quote(row['name'])})", "SCHEMA").map do |col|
27
+ col["name"]
28
+ end
29
+
30
+ orders = {}
31
+
32
+ if columns.any?(&:nil?) # index created with an expression
33
+ columns = expressions
34
+ else
35
+ # Add info on sort order for columns (only desc order is explicitly specified,
36
+ # asc is the default)
37
+ if index_sql # index_sql can be null in case of primary key indexes
38
+ index_sql.scan(/"(\w+)" DESC/).flatten.each { |order_column|
39
+ orders[order_column] = :desc
40
+ }
41
+ end
42
+ end
43
+
44
+ IndexDefinition.new(
45
+ table_name,
46
+ row["name"],
47
+ row["unique"] != 0,
48
+ columns,
49
+ where: where,
50
+ orders: orders
51
+ )
52
+ end.compact
53
+ end
54
+
55
+ def add_foreign_key(from_table, to_table, **options)
56
+ alter_table(from_table) do |definition|
57
+ to_table = strip_table_name_prefix_and_suffix(to_table)
58
+ definition.foreign_key(to_table, options)
59
+ end
60
+ end
61
+
62
+ def remove_foreign_key(from_table, to_table = nil, **options)
63
+ to_table ||= options[:to_table]
64
+ options = options.except(:name, :to_table)
65
+ foreign_keys = foreign_keys(from_table)
66
+
67
+ fkey = foreign_keys.detect do |fk|
68
+ table = to_table || begin
69
+ table = options[:column].to_s.delete_suffix("_id")
70
+ Base.pluralize_table_names ? table.pluralize : table
71
+ end
72
+ table = strip_table_name_prefix_and_suffix(table)
73
+ fk_to_table = strip_table_name_prefix_and_suffix(fk.to_table)
74
+ fk_to_table == table && options.all? { |k, v| fk.options[k].to_s == v.to_s }
75
+ end || raise(ArgumentError, "Table '#{from_table}' has no foreign key for #{to_table || options}")
76
+
77
+ foreign_keys.delete(fkey)
78
+ alter_table(from_table, foreign_keys)
79
+ end
80
+
81
+ def create_schema_dumper(options)
82
+ SQLite3::SchemaDumper.create(self, options)
83
+ end
84
+
85
+ private
86
+ def schema_creation
87
+ SQLite3::SchemaCreation.new(self)
88
+ end
89
+
90
+ def create_table_definition(*args)
91
+ SQLite3::TableDefinition.new(self, *args)
92
+ end
93
+
94
+ def new_column_from_field(table_name, field)
95
+ default = \
96
+ case field["dflt_value"]
97
+ when /^null$/i
98
+ nil
99
+ when /^'(.*)'$/m
100
+ $1.gsub("''", "'")
101
+ when /^"(.*)"$/m
102
+ $1.gsub('""', '"')
103
+ else
104
+ field["dflt_value"]
105
+ end
106
+
107
+ type_metadata = fetch_type_metadata(field["type"])
108
+ Column.new(field["name"], default, type_metadata, field["notnull"].to_i == 0, collation: field["collation"])
109
+ end
110
+
111
+ def data_source_sql(name = nil, type: nil)
112
+ scope = quoted_scope(name, type: type)
113
+ scope[:type] ||= "'table','view'"
114
+
115
+ sql = +"SELECT name FROM sqlite_master WHERE name <> 'sqlite_sequence'"
116
+ sql << " AND name = #{scope[:name]}" if scope[:name]
117
+ sql << " AND type IN (#{scope[:type]})"
118
+ sql
119
+ end
120
+
121
+ def quoted_scope(name = nil, type: nil)
122
+ type = \
123
+ case type
124
+ when "BASE TABLE"
125
+ "'table'"
126
+ when "VIEW"
127
+ "'view'"
128
+ end
129
+ scope = {}
130
+ scope[:name] = quote(name) if name
131
+ scope[:type] = type if type
132
+ scope
133
+ end
134
+ end
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,557 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_record/connection_adapters/abstract_adapter"
4
+ require "active_record/connection_adapters/statement_pool"
5
+ require "active_record/connection_adapters/sqlite3/explain_pretty_printer"
6
+ require "active_record/connection_adapters/sqlite3/quoting"
7
+ require "active_record/connection_adapters/sqlite3/database_statements"
8
+ require "active_record/connection_adapters/sqlite3/schema_creation"
9
+ require "active_record/connection_adapters/sqlite3/schema_definitions"
10
+ require "active_record/connection_adapters/sqlite3/schema_dumper"
11
+ require "active_record/connection_adapters/sqlite3/schema_statements"
12
+
13
+ gem "sqlite3", "~> 1.4"
14
+ require "sqlite3"
15
+
16
+ module ActiveRecord
17
+ module ConnectionHandling # :nodoc:
18
+ def sqlite3_connection(config)
19
+ config = config.symbolize_keys
20
+
21
+ # Require database.
22
+ unless config[:database]
23
+ raise ArgumentError, "No database file specified. Missing argument: database"
24
+ end
25
+
26
+ # Allow database path relative to Rails.root, but only if the database
27
+ # path is not the special path that tells sqlite to build a database only
28
+ # in memory.
29
+ if ":memory:" != config[:database]
30
+ config[:database] = File.expand_path(config[:database], Rails.root) if defined?(Rails.root)
31
+ dirname = File.dirname(config[:database])
32
+ Dir.mkdir(dirname) unless File.directory?(dirname)
33
+ end
34
+
35
+ db = SQLite3::Database.new(
36
+ config[:database].to_s,
37
+ config.merge(results_as_hash: true)
38
+ )
39
+
40
+ ConnectionAdapters::SQLite3Adapter.new(db, logger, nil, config)
41
+ rescue Errno::ENOENT => error
42
+ if error.message.include?("No such file or directory")
43
+ raise ActiveRecord::NoDatabaseError
44
+ else
45
+ raise
46
+ end
47
+ end
48
+ end
49
+
50
+ module ConnectionAdapters #:nodoc:
51
+ # The SQLite3 adapter works SQLite 3.6.16 or newer
52
+ # with the sqlite3-ruby drivers (available as gem from https://rubygems.org/gems/sqlite3).
53
+ #
54
+ # Options:
55
+ #
56
+ # * <tt>:database</tt> - Path to the database file.
57
+ class SQLite3Adapter < AbstractAdapter
58
+ ADAPTER_NAME = "SQLite"
59
+
60
+ include SQLite3::Quoting
61
+ include SQLite3::SchemaStatements
62
+ include SQLite3::DatabaseStatements
63
+
64
+ NATIVE_DATABASE_TYPES = {
65
+ primary_key: "integer PRIMARY KEY AUTOINCREMENT NOT NULL",
66
+ string: { name: "varchar" },
67
+ text: { name: "text" },
68
+ integer: { name: "integer" },
69
+ float: { name: "float" },
70
+ decimal: { name: "decimal" },
71
+ datetime: { name: "datetime" },
72
+ time: { name: "time" },
73
+ date: { name: "date" },
74
+ binary: { name: "blob" },
75
+ boolean: { name: "boolean" },
76
+ json: { name: "json" },
77
+ }
78
+
79
+ def self.represent_boolean_as_integer=(value) # :nodoc:
80
+ if value == false
81
+ raise "`.represent_boolean_as_integer=` is now always true, so make sure your application can work with it and remove this settings."
82
+ end
83
+
84
+ ActiveSupport::Deprecation.warn(
85
+ "`.represent_boolean_as_integer=` is now always true, so setting this is deprecated and will be removed in Rails 6.1."
86
+ )
87
+ end
88
+
89
+ class StatementPool < ConnectionAdapters::StatementPool # :nodoc:
90
+ private
91
+ def dealloc(stmt)
92
+ stmt.close unless stmt.closed?
93
+ end
94
+ end
95
+
96
+ def initialize(connection, logger, connection_options, config)
97
+ super(connection, logger, config)
98
+ configure_connection
99
+ end
100
+
101
+ def self.database_exists?(config)
102
+ config = config.symbolize_keys
103
+ if config[:database] == ":memory:"
104
+ return true
105
+ else
106
+ database_file = defined?(Rails.root) ? File.expand_path(config[:database], Rails.root) : config[:database]
107
+ File.exist?(database_file)
108
+ end
109
+ end
110
+
111
+ def supports_ddl_transactions?
112
+ true
113
+ end
114
+
115
+ def supports_savepoints?
116
+ true
117
+ end
118
+
119
+ def supports_partial_index?
120
+ true
121
+ end
122
+
123
+ def supports_expression_index?
124
+ database_version >= "3.9.0"
125
+ end
126
+
127
+ def requires_reloading?
128
+ true
129
+ end
130
+
131
+ def supports_foreign_keys?
132
+ true
133
+ end
134
+
135
+ def supports_views?
136
+ true
137
+ end
138
+
139
+ def supports_datetime_with_precision?
140
+ true
141
+ end
142
+
143
+ def supports_json?
144
+ true
145
+ end
146
+
147
+ def supports_insert_on_conflict?
148
+ database_version >= "3.24.0"
149
+ end
150
+ alias supports_insert_on_duplicate_skip? supports_insert_on_conflict?
151
+ alias supports_insert_on_duplicate_update? supports_insert_on_conflict?
152
+ alias supports_insert_conflict_target? supports_insert_on_conflict?
153
+
154
+ def active?
155
+ !@connection.closed?
156
+ end
157
+
158
+ def reconnect!
159
+ super
160
+ connect if @connection.closed?
161
+ end
162
+
163
+ # Disconnects from the database if already connected. Otherwise, this
164
+ # method does nothing.
165
+ def disconnect!
166
+ super
167
+ @connection.close rescue nil
168
+ end
169
+
170
+ def supports_index_sort_order?
171
+ true
172
+ end
173
+
174
+ # Returns 62. SQLite supports index names up to 64
175
+ # characters. The rest is used by Rails internally to perform
176
+ # temporary rename operations
177
+ def allowed_index_name_length
178
+ index_name_length - 2
179
+ end
180
+
181
+ def native_database_types #:nodoc:
182
+ NATIVE_DATABASE_TYPES
183
+ end
184
+
185
+ # Returns the current database encoding format as a string, eg: 'UTF-8'
186
+ def encoding
187
+ @connection.encoding.to_s
188
+ end
189
+
190
+ def supports_explain?
191
+ true
192
+ end
193
+
194
+ def supports_lazy_transactions?
195
+ true
196
+ end
197
+
198
+ # REFERENTIAL INTEGRITY ====================================
199
+
200
+ def disable_referential_integrity # :nodoc:
201
+ old_foreign_keys = query_value("PRAGMA foreign_keys")
202
+ old_defer_foreign_keys = query_value("PRAGMA defer_foreign_keys")
203
+
204
+ begin
205
+ execute("PRAGMA defer_foreign_keys = ON")
206
+ execute("PRAGMA foreign_keys = OFF")
207
+ yield
208
+ ensure
209
+ execute("PRAGMA defer_foreign_keys = #{old_defer_foreign_keys}")
210
+ execute("PRAGMA foreign_keys = #{old_foreign_keys}")
211
+ end
212
+ end
213
+
214
+ #--
215
+ # DATABASE STATEMENTS ======================================
216
+ #++
217
+ def explain(arel, binds = [])
218
+ sql = "EXPLAIN QUERY PLAN #{to_sql(arel, binds)}"
219
+ SQLite3::ExplainPrettyPrinter.new.pp(exec_query(sql, "EXPLAIN", []))
220
+ end
221
+
222
+ # SCHEMA STATEMENTS ========================================
223
+
224
+ def primary_keys(table_name) # :nodoc:
225
+ pks = table_structure(table_name).select { |f| f["pk"] > 0 }
226
+ pks.sort_by { |f| f["pk"] }.map { |f| f["name"] }
227
+ end
228
+
229
+ def remove_index(table_name, options = {}) #:nodoc:
230
+ index_name = index_name_for_remove(table_name, options)
231
+ exec_query "DROP INDEX #{quote_column_name(index_name)}"
232
+ end
233
+
234
+ # Renames a table.
235
+ #
236
+ # Example:
237
+ # rename_table('octopuses', 'octopi')
238
+ def rename_table(table_name, new_name)
239
+ exec_query "ALTER TABLE #{quote_table_name(table_name)} RENAME TO #{quote_table_name(new_name)}"
240
+ rename_table_indexes(table_name, new_name)
241
+ end
242
+
243
+ def add_column(table_name, column_name, type, options = {}) #:nodoc:
244
+ if invalid_alter_table_type?(type, options)
245
+ alter_table(table_name) do |definition|
246
+ definition.column(column_name, type, options)
247
+ end
248
+ else
249
+ super
250
+ end
251
+ end
252
+
253
+ def remove_column(table_name, column_name, type = nil, options = {}) #:nodoc:
254
+ alter_table(table_name) do |definition|
255
+ definition.remove_column column_name
256
+ definition.foreign_keys.delete_if do |_, fk_options|
257
+ fk_options[:column] == column_name.to_s
258
+ end
259
+ end
260
+ end
261
+
262
+ def change_column_default(table_name, column_name, default_or_changes) #:nodoc:
263
+ default = extract_new_default_value(default_or_changes)
264
+
265
+ alter_table(table_name) do |definition|
266
+ definition[column_name].default = default
267
+ end
268
+ end
269
+
270
+ def change_column_null(table_name, column_name, null, default = nil) #:nodoc:
271
+ unless null || default.nil?
272
+ exec_query("UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote(default)} WHERE #{quote_column_name(column_name)} IS NULL")
273
+ end
274
+ alter_table(table_name) do |definition|
275
+ definition[column_name].null = null
276
+ end
277
+ end
278
+
279
+ def change_column(table_name, column_name, type, options = {}) #:nodoc:
280
+ alter_table(table_name) do |definition|
281
+ definition[column_name].instance_eval do
282
+ self.type = type
283
+ self.limit = options[:limit] if options.include?(:limit)
284
+ self.default = options[:default] if options.include?(:default)
285
+ self.null = options[:null] if options.include?(:null)
286
+ self.precision = options[:precision] if options.include?(:precision)
287
+ self.scale = options[:scale] if options.include?(:scale)
288
+ self.collation = options[:collation] if options.include?(:collation)
289
+ end
290
+ end
291
+ end
292
+
293
+ def rename_column(table_name, column_name, new_column_name) #:nodoc:
294
+ column = column_for(table_name, column_name)
295
+ alter_table(table_name, rename: { column.name => new_column_name.to_s })
296
+ rename_column_indexes(table_name, column.name, new_column_name)
297
+ end
298
+
299
+ def add_reference(table_name, ref_name, **options) # :nodoc:
300
+ super(table_name, ref_name, type: :integer, **options)
301
+ end
302
+ alias :add_belongs_to :add_reference
303
+
304
+ def foreign_keys(table_name)
305
+ fk_info = exec_query("PRAGMA foreign_key_list(#{quote(table_name)})", "SCHEMA")
306
+ fk_info.map do |row|
307
+ options = {
308
+ column: row["from"],
309
+ primary_key: row["to"],
310
+ on_delete: extract_foreign_key_action(row["on_delete"]),
311
+ on_update: extract_foreign_key_action(row["on_update"])
312
+ }
313
+ ForeignKeyDefinition.new(table_name, row["table"], options)
314
+ end
315
+ end
316
+
317
+ def build_insert_sql(insert) # :nodoc:
318
+ sql = +"INSERT #{insert.into} #{insert.values_list}"
319
+
320
+ if insert.skip_duplicates?
321
+ sql << " ON CONFLICT #{insert.conflict_target} DO NOTHING"
322
+ elsif insert.update_duplicates?
323
+ sql << " ON CONFLICT #{insert.conflict_target} DO UPDATE SET "
324
+ sql << insert.updatable_columns.map { |column| "#{column}=excluded.#{column}" }.join(",")
325
+ end
326
+
327
+ sql
328
+ end
329
+
330
+ def get_database_version # :nodoc:
331
+ SQLite3Adapter::Version.new(query_value("SELECT sqlite_version(*)"))
332
+ end
333
+
334
+ def check_version # :nodoc:
335
+ if database_version < "3.8.0"
336
+ raise "Your version of SQLite (#{database_version}) is too old. Active Record supports SQLite >= 3.8."
337
+ end
338
+ end
339
+
340
+ private
341
+ # See https://www.sqlite.org/limits.html,
342
+ # the default value is 999 when not configured.
343
+ def bind_params_length
344
+ 999
345
+ end
346
+
347
+ def initialize_type_map(m = type_map)
348
+ super
349
+ register_class_with_limit m, %r(int)i, SQLite3Integer
350
+ end
351
+
352
+ def table_structure(table_name)
353
+ structure = exec_query("PRAGMA table_info(#{quote_table_name(table_name)})", "SCHEMA")
354
+ raise(ActiveRecord::StatementInvalid, "Could not find table '#{table_name}'") if structure.empty?
355
+ table_structure_with_collation(table_name, structure)
356
+ end
357
+ alias column_definitions table_structure
358
+
359
+ # See: https://www.sqlite.org/lang_altertable.html
360
+ # SQLite has an additional restriction on the ALTER TABLE statement
361
+ def invalid_alter_table_type?(type, options)
362
+ type.to_sym == :primary_key || options[:primary_key]
363
+ end
364
+
365
+ def alter_table(table_name, foreign_keys = foreign_keys(table_name), **options)
366
+ altered_table_name = "a#{table_name}"
367
+
368
+ caller = lambda do |definition|
369
+ rename = options[:rename] || {}
370
+ foreign_keys.each do |fk|
371
+ if column = rename[fk.options[:column]]
372
+ fk.options[:column] = column
373
+ end
374
+ to_table = strip_table_name_prefix_and_suffix(fk.to_table)
375
+ definition.foreign_key(to_table, fk.options)
376
+ end
377
+
378
+ yield definition if block_given?
379
+ end
380
+
381
+ transaction do
382
+ disable_referential_integrity do
383
+ move_table(table_name, altered_table_name, options.merge(temporary: true))
384
+ move_table(altered_table_name, table_name, &caller)
385
+ end
386
+ end
387
+ end
388
+
389
+ def move_table(from, to, options = {}, &block)
390
+ copy_table(from, to, options, &block)
391
+ drop_table(from)
392
+ end
393
+
394
+ def copy_table(from, to, options = {})
395
+ from_primary_key = primary_key(from)
396
+ options[:id] = false
397
+ create_table(to, options) do |definition|
398
+ @definition = definition
399
+ if from_primary_key.is_a?(Array)
400
+ @definition.primary_keys from_primary_key
401
+ end
402
+ columns(from).each do |column|
403
+ column_name = options[:rename] ?
404
+ (options[:rename][column.name] ||
405
+ options[:rename][column.name.to_sym] ||
406
+ column.name) : column.name
407
+
408
+ @definition.column(column_name, column.type,
409
+ limit: column.limit, default: column.default,
410
+ precision: column.precision, scale: column.scale,
411
+ null: column.null, collation: column.collation,
412
+ primary_key: column_name == from_primary_key
413
+ )
414
+ end
415
+
416
+ yield @definition if block_given?
417
+ end
418
+ copy_table_indexes(from, to, options[:rename] || {})
419
+ copy_table_contents(from, to,
420
+ @definition.columns.map(&:name),
421
+ options[:rename] || {})
422
+ end
423
+
424
+ def copy_table_indexes(from, to, rename = {})
425
+ indexes(from).each do |index|
426
+ name = index.name
427
+ if to == "a#{from}"
428
+ name = "t#{name}"
429
+ elsif from == "a#{to}"
430
+ name = name[1..-1]
431
+ end
432
+
433
+ columns = index.columns
434
+ if columns.is_a?(Array)
435
+ to_column_names = columns(to).map(&:name)
436
+ columns = columns.map { |c| rename[c] || c }.select do |column|
437
+ to_column_names.include?(column)
438
+ end
439
+ end
440
+
441
+ unless columns.empty?
442
+ # index name can't be the same
443
+ opts = { name: name.gsub(/(^|_)(#{from})_/, "\\1#{to}_"), internal: true }
444
+ opts[:unique] = true if index.unique
445
+ opts[:where] = index.where if index.where
446
+ add_index(to, columns, opts)
447
+ end
448
+ end
449
+ end
450
+
451
+ def copy_table_contents(from, to, columns, rename = {})
452
+ column_mappings = Hash[columns.map { |name| [name, name] }]
453
+ rename.each { |a| column_mappings[a.last] = a.first }
454
+ from_columns = columns(from).collect(&:name)
455
+ columns = columns.find_all { |col| from_columns.include?(column_mappings[col]) }
456
+ from_columns_to_copy = columns.map { |col| column_mappings[col] }
457
+ quoted_columns = columns.map { |col| quote_column_name(col) } * ","
458
+ quoted_from_columns = from_columns_to_copy.map { |col| quote_column_name(col) } * ","
459
+
460
+ exec_query("INSERT INTO #{quote_table_name(to)} (#{quoted_columns})
461
+ SELECT #{quoted_from_columns} FROM #{quote_table_name(from)}")
462
+ end
463
+
464
+ def translate_exception(exception, message:, sql:, binds:)
465
+ case exception.message
466
+ # SQLite 3.8.2 returns a newly formatted error message:
467
+ # UNIQUE constraint failed: *table_name*.*column_name*
468
+ # Older versions of SQLite return:
469
+ # column *column_name* is not unique
470
+ when /column(s)? .* (is|are) not unique/, /UNIQUE constraint failed: .*/
471
+ RecordNotUnique.new(message, sql: sql, binds: binds)
472
+ when /.* may not be NULL/, /NOT NULL constraint failed: .*/
473
+ NotNullViolation.new(message, sql: sql, binds: binds)
474
+ when /FOREIGN KEY constraint failed/i
475
+ InvalidForeignKey.new(message, sql: sql, binds: binds)
476
+ else
477
+ super
478
+ end
479
+ end
480
+
481
+ COLLATE_REGEX = /.*\"(\w+)\".*collate\s+\"(\w+)\".*/i.freeze
482
+
483
+ def table_structure_with_collation(table_name, basic_structure)
484
+ collation_hash = {}
485
+ sql = <<~SQL
486
+ SELECT sql FROM
487
+ (SELECT * FROM sqlite_master UNION ALL
488
+ SELECT * FROM sqlite_temp_master)
489
+ WHERE type = 'table' AND name = #{quote(table_name)}
490
+ SQL
491
+
492
+ # Result will have following sample string
493
+ # CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
494
+ # "password_digest" varchar COLLATE "NOCASE");
495
+ result = exec_query(sql, "SCHEMA").first
496
+
497
+ if result
498
+ # Splitting with left parentheses and discarding the first part will return all
499
+ # columns separated with comma(,).
500
+ columns_string = result["sql"].split("(", 2).last
501
+
502
+ columns_string.split(",").each do |column_string|
503
+ # This regex will match the column name and collation type and will save
504
+ # the value in $1 and $2 respectively.
505
+ collation_hash[$1] = $2 if COLLATE_REGEX =~ column_string
506
+ end
507
+
508
+ basic_structure.map! do |column|
509
+ column_name = column["name"]
510
+
511
+ if collation_hash.has_key? column_name
512
+ column["collation"] = collation_hash[column_name]
513
+ end
514
+
515
+ column
516
+ end
517
+ else
518
+ basic_structure.to_a
519
+ end
520
+ end
521
+
522
+ def arel_visitor
523
+ Arel::Visitors::SQLite.new(self)
524
+ end
525
+
526
+ def build_statement_pool
527
+ StatementPool.new(self.class.type_cast_config_to_integer(@config[:statement_limit]))
528
+ end
529
+
530
+ def connect
531
+ @connection = ::SQLite3::Database.new(
532
+ @config[:database].to_s,
533
+ @config.merge(results_as_hash: true)
534
+ )
535
+ configure_connection
536
+ end
537
+
538
+ def configure_connection
539
+ @connection.busy_timeout(self.class.type_cast_config_to_integer(@config[:timeout])) if @config[:timeout]
540
+
541
+ execute("PRAGMA foreign_keys = ON", "SCHEMA")
542
+ end
543
+
544
+ class SQLite3Integer < Type::Integer # :nodoc:
545
+ private
546
+ def _limit
547
+ # INTEGER storage class can be stored 8 bytes value.
548
+ # See https://www.sqlite.org/datatype3.html#storage_classes_and_datatypes
549
+ limit || 8
550
+ end
551
+ end
552
+
553
+ ActiveRecord::Type.register(:integer, SQLite3Integer, adapter: :sqlite3)
554
+ end
555
+ ActiveSupport.run_load_hooks(:active_record_sqlite3adapter, SQLite3Adapter)
556
+ end
557
+ end