activerecord 6.0.1

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

Potentially problematic release.


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

Files changed (340) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +1086 -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 +49 -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 +340 -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 +262 -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 +512 -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 +1175 -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 +516 -0
  59. data/lib/active_record/connection_adapters/abstract/query_cache.rb +155 -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 +772 -0
  68. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +830 -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 +202 -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 +184 -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 +953 -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 +120 -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 +561 -0
  127. data/lib/active_record/connection_adapters/statement_pool.rb +61 -0
  128. data/lib/active_record/connection_handling.rb +274 -0
  129. data/lib/active_record/core.rb +603 -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 +88 -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 +545 -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 +860 -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 +561 -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 +1371 -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 +58 -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 +418 -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,561 @@
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_common_table_expressions?
148
+ database_version >= "3.8.3"
149
+ end
150
+
151
+ def supports_insert_on_conflict?
152
+ database_version >= "3.24.0"
153
+ end
154
+ alias supports_insert_on_duplicate_skip? supports_insert_on_conflict?
155
+ alias supports_insert_on_duplicate_update? supports_insert_on_conflict?
156
+ alias supports_insert_conflict_target? supports_insert_on_conflict?
157
+
158
+ def active?
159
+ !@connection.closed?
160
+ end
161
+
162
+ def reconnect!
163
+ super
164
+ connect if @connection.closed?
165
+ end
166
+
167
+ # Disconnects from the database if already connected. Otherwise, this
168
+ # method does nothing.
169
+ def disconnect!
170
+ super
171
+ @connection.close rescue nil
172
+ end
173
+
174
+ def supports_index_sort_order?
175
+ true
176
+ end
177
+
178
+ # Returns 62. SQLite supports index names up to 64
179
+ # characters. The rest is used by Rails internally to perform
180
+ # temporary rename operations
181
+ def allowed_index_name_length
182
+ index_name_length - 2
183
+ end
184
+
185
+ def native_database_types #:nodoc:
186
+ NATIVE_DATABASE_TYPES
187
+ end
188
+
189
+ # Returns the current database encoding format as a string, eg: 'UTF-8'
190
+ def encoding
191
+ @connection.encoding.to_s
192
+ end
193
+
194
+ def supports_explain?
195
+ true
196
+ end
197
+
198
+ def supports_lazy_transactions?
199
+ true
200
+ end
201
+
202
+ # REFERENTIAL INTEGRITY ====================================
203
+
204
+ def disable_referential_integrity # :nodoc:
205
+ old_foreign_keys = query_value("PRAGMA foreign_keys")
206
+ old_defer_foreign_keys = query_value("PRAGMA defer_foreign_keys")
207
+
208
+ begin
209
+ execute("PRAGMA defer_foreign_keys = ON")
210
+ execute("PRAGMA foreign_keys = OFF")
211
+ yield
212
+ ensure
213
+ execute("PRAGMA defer_foreign_keys = #{old_defer_foreign_keys}")
214
+ execute("PRAGMA foreign_keys = #{old_foreign_keys}")
215
+ end
216
+ end
217
+
218
+ #--
219
+ # DATABASE STATEMENTS ======================================
220
+ #++
221
+ def explain(arel, binds = [])
222
+ sql = "EXPLAIN QUERY PLAN #{to_sql(arel, binds)}"
223
+ SQLite3::ExplainPrettyPrinter.new.pp(exec_query(sql, "EXPLAIN", []))
224
+ end
225
+
226
+ # SCHEMA STATEMENTS ========================================
227
+
228
+ def primary_keys(table_name) # :nodoc:
229
+ pks = table_structure(table_name).select { |f| f["pk"] > 0 }
230
+ pks.sort_by { |f| f["pk"] }.map { |f| f["name"] }
231
+ end
232
+
233
+ def remove_index(table_name, options = {}) #:nodoc:
234
+ index_name = index_name_for_remove(table_name, options)
235
+ exec_query "DROP INDEX #{quote_column_name(index_name)}"
236
+ end
237
+
238
+ # Renames a table.
239
+ #
240
+ # Example:
241
+ # rename_table('octopuses', 'octopi')
242
+ def rename_table(table_name, new_name)
243
+ exec_query "ALTER TABLE #{quote_table_name(table_name)} RENAME TO #{quote_table_name(new_name)}"
244
+ rename_table_indexes(table_name, new_name)
245
+ end
246
+
247
+ def add_column(table_name, column_name, type, options = {}) #:nodoc:
248
+ if invalid_alter_table_type?(type, options)
249
+ alter_table(table_name) do |definition|
250
+ definition.column(column_name, type, options)
251
+ end
252
+ else
253
+ super
254
+ end
255
+ end
256
+
257
+ def remove_column(table_name, column_name, type = nil, options = {}) #:nodoc:
258
+ alter_table(table_name) do |definition|
259
+ definition.remove_column column_name
260
+ definition.foreign_keys.delete_if do |_, fk_options|
261
+ fk_options[:column] == column_name.to_s
262
+ end
263
+ end
264
+ end
265
+
266
+ def change_column_default(table_name, column_name, default_or_changes) #:nodoc:
267
+ default = extract_new_default_value(default_or_changes)
268
+
269
+ alter_table(table_name) do |definition|
270
+ definition[column_name].default = default
271
+ end
272
+ end
273
+
274
+ def change_column_null(table_name, column_name, null, default = nil) #:nodoc:
275
+ unless null || default.nil?
276
+ exec_query("UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote(default)} WHERE #{quote_column_name(column_name)} IS NULL")
277
+ end
278
+ alter_table(table_name) do |definition|
279
+ definition[column_name].null = null
280
+ end
281
+ end
282
+
283
+ def change_column(table_name, column_name, type, options = {}) #:nodoc:
284
+ alter_table(table_name) do |definition|
285
+ definition[column_name].instance_eval do
286
+ self.type = type
287
+ self.limit = options[:limit] if options.include?(:limit)
288
+ self.default = options[:default] if options.include?(:default)
289
+ self.null = options[:null] if options.include?(:null)
290
+ self.precision = options[:precision] if options.include?(:precision)
291
+ self.scale = options[:scale] if options.include?(:scale)
292
+ self.collation = options[:collation] if options.include?(:collation)
293
+ end
294
+ end
295
+ end
296
+
297
+ def rename_column(table_name, column_name, new_column_name) #:nodoc:
298
+ column = column_for(table_name, column_name)
299
+ alter_table(table_name, rename: { column.name => new_column_name.to_s })
300
+ rename_column_indexes(table_name, column.name, new_column_name)
301
+ end
302
+
303
+ def add_reference(table_name, ref_name, **options) # :nodoc:
304
+ super(table_name, ref_name, type: :integer, **options)
305
+ end
306
+ alias :add_belongs_to :add_reference
307
+
308
+ def foreign_keys(table_name)
309
+ fk_info = exec_query("PRAGMA foreign_key_list(#{quote(table_name)})", "SCHEMA")
310
+ fk_info.map do |row|
311
+ options = {
312
+ column: row["from"],
313
+ primary_key: row["to"],
314
+ on_delete: extract_foreign_key_action(row["on_delete"]),
315
+ on_update: extract_foreign_key_action(row["on_update"])
316
+ }
317
+ ForeignKeyDefinition.new(table_name, row["table"], options)
318
+ end
319
+ end
320
+
321
+ def build_insert_sql(insert) # :nodoc:
322
+ sql = +"INSERT #{insert.into} #{insert.values_list}"
323
+
324
+ if insert.skip_duplicates?
325
+ sql << " ON CONFLICT #{insert.conflict_target} DO NOTHING"
326
+ elsif insert.update_duplicates?
327
+ sql << " ON CONFLICT #{insert.conflict_target} DO UPDATE SET "
328
+ sql << insert.updatable_columns.map { |column| "#{column}=excluded.#{column}" }.join(",")
329
+ end
330
+
331
+ sql
332
+ end
333
+
334
+ def get_database_version # :nodoc:
335
+ SQLite3Adapter::Version.new(query_value("SELECT sqlite_version(*)"))
336
+ end
337
+
338
+ def check_version # :nodoc:
339
+ if database_version < "3.8.0"
340
+ raise "Your version of SQLite (#{database_version}) is too old. Active Record supports SQLite >= 3.8."
341
+ end
342
+ end
343
+
344
+ private
345
+ # See https://www.sqlite.org/limits.html,
346
+ # the default value is 999 when not configured.
347
+ def bind_params_length
348
+ 999
349
+ end
350
+
351
+ def initialize_type_map(m = type_map)
352
+ super
353
+ register_class_with_limit m, %r(int)i, SQLite3Integer
354
+ end
355
+
356
+ def table_structure(table_name)
357
+ structure = exec_query("PRAGMA table_info(#{quote_table_name(table_name)})", "SCHEMA")
358
+ raise(ActiveRecord::StatementInvalid, "Could not find table '#{table_name}'") if structure.empty?
359
+ table_structure_with_collation(table_name, structure)
360
+ end
361
+ alias column_definitions table_structure
362
+
363
+ # See: https://www.sqlite.org/lang_altertable.html
364
+ # SQLite has an additional restriction on the ALTER TABLE statement
365
+ def invalid_alter_table_type?(type, options)
366
+ type.to_sym == :primary_key || options[:primary_key]
367
+ end
368
+
369
+ def alter_table(table_name, foreign_keys = foreign_keys(table_name), **options)
370
+ altered_table_name = "a#{table_name}"
371
+
372
+ caller = lambda do |definition|
373
+ rename = options[:rename] || {}
374
+ foreign_keys.each do |fk|
375
+ if column = rename[fk.options[:column]]
376
+ fk.options[:column] = column
377
+ end
378
+ to_table = strip_table_name_prefix_and_suffix(fk.to_table)
379
+ definition.foreign_key(to_table, fk.options)
380
+ end
381
+
382
+ yield definition if block_given?
383
+ end
384
+
385
+ transaction do
386
+ disable_referential_integrity do
387
+ move_table(table_name, altered_table_name, options.merge(temporary: true))
388
+ move_table(altered_table_name, table_name, &caller)
389
+ end
390
+ end
391
+ end
392
+
393
+ def move_table(from, to, options = {}, &block)
394
+ copy_table(from, to, options, &block)
395
+ drop_table(from)
396
+ end
397
+
398
+ def copy_table(from, to, options = {})
399
+ from_primary_key = primary_key(from)
400
+ options[:id] = false
401
+ create_table(to, options) do |definition|
402
+ @definition = definition
403
+ if from_primary_key.is_a?(Array)
404
+ @definition.primary_keys from_primary_key
405
+ end
406
+ columns(from).each do |column|
407
+ column_name = options[:rename] ?
408
+ (options[:rename][column.name] ||
409
+ options[:rename][column.name.to_sym] ||
410
+ column.name) : column.name
411
+
412
+ @definition.column(column_name, column.type,
413
+ limit: column.limit, default: column.default,
414
+ precision: column.precision, scale: column.scale,
415
+ null: column.null, collation: column.collation,
416
+ primary_key: column_name == from_primary_key
417
+ )
418
+ end
419
+
420
+ yield @definition if block_given?
421
+ end
422
+ copy_table_indexes(from, to, options[:rename] || {})
423
+ copy_table_contents(from, to,
424
+ @definition.columns.map(&:name),
425
+ options[:rename] || {})
426
+ end
427
+
428
+ def copy_table_indexes(from, to, rename = {})
429
+ indexes(from).each do |index|
430
+ name = index.name
431
+ if to == "a#{from}"
432
+ name = "t#{name}"
433
+ elsif from == "a#{to}"
434
+ name = name[1..-1]
435
+ end
436
+
437
+ columns = index.columns
438
+ if columns.is_a?(Array)
439
+ to_column_names = columns(to).map(&:name)
440
+ columns = columns.map { |c| rename[c] || c }.select do |column|
441
+ to_column_names.include?(column)
442
+ end
443
+ end
444
+
445
+ unless columns.empty?
446
+ # index name can't be the same
447
+ opts = { name: name.gsub(/(^|_)(#{from})_/, "\\1#{to}_"), internal: true }
448
+ opts[:unique] = true if index.unique
449
+ opts[:where] = index.where if index.where
450
+ add_index(to, columns, opts)
451
+ end
452
+ end
453
+ end
454
+
455
+ def copy_table_contents(from, to, columns, rename = {})
456
+ column_mappings = Hash[columns.map { |name| [name, name] }]
457
+ rename.each { |a| column_mappings[a.last] = a.first }
458
+ from_columns = columns(from).collect(&:name)
459
+ columns = columns.find_all { |col| from_columns.include?(column_mappings[col]) }
460
+ from_columns_to_copy = columns.map { |col| column_mappings[col] }
461
+ quoted_columns = columns.map { |col| quote_column_name(col) } * ","
462
+ quoted_from_columns = from_columns_to_copy.map { |col| quote_column_name(col) } * ","
463
+
464
+ exec_query("INSERT INTO #{quote_table_name(to)} (#{quoted_columns})
465
+ SELECT #{quoted_from_columns} FROM #{quote_table_name(from)}")
466
+ end
467
+
468
+ def translate_exception(exception, message:, sql:, binds:)
469
+ case exception.message
470
+ # SQLite 3.8.2 returns a newly formatted error message:
471
+ # UNIQUE constraint failed: *table_name*.*column_name*
472
+ # Older versions of SQLite return:
473
+ # column *column_name* is not unique
474
+ when /column(s)? .* (is|are) not unique/, /UNIQUE constraint failed: .*/
475
+ RecordNotUnique.new(message, sql: sql, binds: binds)
476
+ when /.* may not be NULL/, /NOT NULL constraint failed: .*/
477
+ NotNullViolation.new(message, sql: sql, binds: binds)
478
+ when /FOREIGN KEY constraint failed/i
479
+ InvalidForeignKey.new(message, sql: sql, binds: binds)
480
+ else
481
+ super
482
+ end
483
+ end
484
+
485
+ COLLATE_REGEX = /.*\"(\w+)\".*collate\s+\"(\w+)\".*/i.freeze
486
+
487
+ def table_structure_with_collation(table_name, basic_structure)
488
+ collation_hash = {}
489
+ sql = <<~SQL
490
+ SELECT sql FROM
491
+ (SELECT * FROM sqlite_master UNION ALL
492
+ SELECT * FROM sqlite_temp_master)
493
+ WHERE type = 'table' AND name = #{quote(table_name)}
494
+ SQL
495
+
496
+ # Result will have following sample string
497
+ # CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
498
+ # "password_digest" varchar COLLATE "NOCASE");
499
+ result = exec_query(sql, "SCHEMA").first
500
+
501
+ if result
502
+ # Splitting with left parentheses and discarding the first part will return all
503
+ # columns separated with comma(,).
504
+ columns_string = result["sql"].split("(", 2).last
505
+
506
+ columns_string.split(",").each do |column_string|
507
+ # This regex will match the column name and collation type and will save
508
+ # the value in $1 and $2 respectively.
509
+ collation_hash[$1] = $2 if COLLATE_REGEX =~ column_string
510
+ end
511
+
512
+ basic_structure.map! do |column|
513
+ column_name = column["name"]
514
+
515
+ if collation_hash.has_key? column_name
516
+ column["collation"] = collation_hash[column_name]
517
+ end
518
+
519
+ column
520
+ end
521
+ else
522
+ basic_structure.to_a
523
+ end
524
+ end
525
+
526
+ def arel_visitor
527
+ Arel::Visitors::SQLite.new(self)
528
+ end
529
+
530
+ def build_statement_pool
531
+ StatementPool.new(self.class.type_cast_config_to_integer(@config[:statement_limit]))
532
+ end
533
+
534
+ def connect
535
+ @connection = ::SQLite3::Database.new(
536
+ @config[:database].to_s,
537
+ @config.merge(results_as_hash: true)
538
+ )
539
+ configure_connection
540
+ end
541
+
542
+ def configure_connection
543
+ @connection.busy_timeout(self.class.type_cast_config_to_integer(@config[:timeout])) if @config[:timeout]
544
+
545
+ execute("PRAGMA foreign_keys = ON", "SCHEMA")
546
+ end
547
+
548
+ class SQLite3Integer < Type::Integer # :nodoc:
549
+ private
550
+ def _limit
551
+ # INTEGER storage class can be stored 8 bytes value.
552
+ # See https://www.sqlite.org/datatype3.html#storage_classes_and_datatypes
553
+ limit || 8
554
+ end
555
+ end
556
+
557
+ ActiveRecord::Type.register(:integer, SQLite3Integer, adapter: :sqlite3)
558
+ end
559
+ ActiveSupport.run_load_hooks(:active_record_sqlite3adapter, SQLite3Adapter)
560
+ end
561
+ end