activerecord 4.2.0 → 6.1.7.1

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 (374) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +1221 -796
  3. data/MIT-LICENSE +4 -2
  4. data/README.rdoc +15 -14
  5. data/examples/performance.rb +33 -32
  6. data/examples/simple.rb +5 -4
  7. data/lib/active_record/aggregations.rb +267 -249
  8. data/lib/active_record/association_relation.rb +45 -7
  9. data/lib/active_record/associations/alias_tracker.rb +40 -43
  10. data/lib/active_record/associations/association.rb +172 -67
  11. data/lib/active_record/associations/association_scope.rb +105 -129
  12. data/lib/active_record/associations/belongs_to_association.rb +85 -59
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +13 -12
  14. data/lib/active_record/associations/builder/association.rb +57 -43
  15. data/lib/active_record/associations/builder/belongs_to.rb +74 -57
  16. data/lib/active_record/associations/builder/collection_association.rb +15 -33
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +57 -70
  18. data/lib/active_record/associations/builder/has_many.rb +13 -5
  19. data/lib/active_record/associations/builder/has_one.rb +44 -6
  20. data/lib/active_record/associations/builder/singular_association.rb +16 -10
  21. data/lib/active_record/associations/collection_association.rb +168 -279
  22. data/lib/active_record/associations/collection_proxy.rb +263 -155
  23. data/lib/active_record/associations/foreign_association.rb +33 -0
  24. data/lib/active_record/associations/has_many_association.rb +57 -84
  25. data/lib/active_record/associations/has_many_through_association.rb +70 -82
  26. data/lib/active_record/associations/has_one_association.rb +74 -47
  27. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  28. data/lib/active_record/associations/join_dependency/join_association.rb +54 -73
  29. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  30. data/lib/active_record/associations/join_dependency/join_part.rb +14 -14
  31. data/lib/active_record/associations/join_dependency.rb +175 -164
  32. data/lib/active_record/associations/preloader/association.rb +107 -112
  33. data/lib/active_record/associations/preloader/through_association.rb +85 -65
  34. data/lib/active_record/associations/preloader.rb +99 -96
  35. data/lib/active_record/associations/singular_association.rb +18 -45
  36. data/lib/active_record/associations/through_association.rb +49 -24
  37. data/lib/active_record/associations.rb +1845 -1597
  38. data/lib/active_record/attribute_assignment.rb +59 -185
  39. data/lib/active_record/attribute_methods/before_type_cast.rb +20 -7
  40. data/lib/active_record/attribute_methods/dirty.rb +168 -138
  41. data/lib/active_record/attribute_methods/primary_key.rb +93 -83
  42. data/lib/active_record/attribute_methods/query.rb +8 -10
  43. data/lib/active_record/attribute_methods/read.rb +19 -79
  44. data/lib/active_record/attribute_methods/serialization.rb +49 -24
  45. data/lib/active_record/attribute_methods/time_zone_conversion.rb +59 -36
  46. data/lib/active_record/attribute_methods/write.rb +25 -56
  47. data/lib/active_record/attribute_methods.rb +153 -162
  48. data/lib/active_record/attributes.rb +234 -70
  49. data/lib/active_record/autosave_association.rb +157 -69
  50. data/lib/active_record/base.rb +49 -50
  51. data/lib/active_record/callbacks.rb +234 -79
  52. data/lib/active_record/coders/json.rb +3 -1
  53. data/lib/active_record/coders/yaml_column.rb +46 -13
  54. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +887 -317
  55. data/lib/active_record/connection_adapters/abstract/database_limits.rb +17 -41
  56. data/lib/active_record/connection_adapters/abstract/database_statements.rb +301 -113
  57. data/lib/active_record/connection_adapters/abstract/query_cache.rb +78 -24
  58. data/lib/active_record/connection_adapters/abstract/quoting.rb +187 -60
  59. data/lib/active_record/connection_adapters/abstract/savepoints.rb +9 -7
  60. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +157 -93
  61. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +485 -253
  62. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +79 -36
  63. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +909 -263
  64. data/lib/active_record/connection_adapters/abstract/transaction.rb +254 -92
  65. data/lib/active_record/connection_adapters/abstract_adapter.rb +492 -221
  66. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +580 -608
  67. data/lib/active_record/connection_adapters/column.rb +67 -40
  68. data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
  69. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +35 -0
  70. data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
  71. data/lib/active_record/connection_adapters/mysql/database_statements.rb +196 -0
  72. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +71 -0
  73. data/lib/active_record/connection_adapters/mysql/quoting.rb +96 -0
  74. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +97 -0
  75. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +103 -0
  76. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +91 -0
  77. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +271 -0
  78. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +40 -0
  79. data/lib/active_record/connection_adapters/mysql2_adapter.rb +81 -199
  80. data/lib/active_record/connection_adapters/pool_config.rb +73 -0
  81. data/lib/active_record/connection_adapters/pool_manager.rb +47 -0
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +44 -11
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +78 -161
  84. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
  85. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +49 -57
  86. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +9 -8
  87. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +5 -2
  89. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +8 -6
  90. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +13 -1
  91. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +17 -13
  92. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  93. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +6 -3
  94. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +31 -20
  95. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  98. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +44 -0
  99. data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -9
  101. data/lib/active_record/connection_adapters/postgresql/oid/{infinity.rb → oid.rb} +5 -3
  102. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +32 -11
  103. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +70 -34
  104. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
  105. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +67 -51
  106. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +18 -4
  107. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +3 -1
  108. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +3 -1
  109. data/lib/active_record/connection_adapters/postgresql/oid.rb +25 -25
  110. data/lib/active_record/connection_adapters/postgresql/quoting.rb +171 -48
  111. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +27 -14
  112. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +80 -0
  113. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +178 -108
  114. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +49 -0
  115. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +499 -293
  116. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +44 -0
  117. data/lib/active_record/connection_adapters/postgresql/utils.rb +11 -8
  118. data/lib/active_record/connection_adapters/postgresql_adapter.rb +595 -382
  119. data/lib/active_record/connection_adapters/schema_cache.rb +191 -29
  120. data/lib/active_record/connection_adapters/sql_type_metadata.rb +45 -0
  121. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +146 -0
  122. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
  123. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +102 -0
  124. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +21 -0
  125. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  126. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  127. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +170 -0
  128. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +322 -389
  129. data/lib/active_record/connection_adapters/statement_pool.rb +33 -13
  130. data/lib/active_record/connection_adapters.rb +52 -0
  131. data/lib/active_record/connection_handling.rb +314 -41
  132. data/lib/active_record/core.rb +488 -243
  133. data/lib/active_record/counter_cache.rb +71 -50
  134. data/lib/active_record/database_configurations/connection_url_resolver.rb +99 -0
  135. data/lib/active_record/database_configurations/database_config.rb +80 -0
  136. data/lib/active_record/database_configurations/hash_config.rb +96 -0
  137. data/lib/active_record/database_configurations/url_config.rb +53 -0
  138. data/lib/active_record/database_configurations.rb +273 -0
  139. data/lib/active_record/delegated_type.rb +209 -0
  140. data/lib/active_record/destroy_association_async_job.rb +36 -0
  141. data/lib/active_record/dynamic_matchers.rb +87 -106
  142. data/lib/active_record/enum.rb +212 -94
  143. data/lib/active_record/errors.rb +225 -54
  144. data/lib/active_record/explain.rb +27 -11
  145. data/lib/active_record/explain_registry.rb +4 -2
  146. data/lib/active_record/explain_subscriber.rb +11 -6
  147. data/lib/active_record/fixture_set/file.rb +33 -14
  148. data/lib/active_record/fixture_set/model_metadata.rb +32 -0
  149. data/lib/active_record/fixture_set/render_context.rb +17 -0
  150. data/lib/active_record/fixture_set/table_row.rb +152 -0
  151. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  152. data/lib/active_record/fixtures.rb +273 -496
  153. data/lib/active_record/gem_version.rb +6 -4
  154. data/lib/active_record/inheritance.rb +175 -110
  155. data/lib/active_record/insert_all.rb +212 -0
  156. data/lib/active_record/integration.rb +121 -29
  157. data/lib/active_record/internal_metadata.rb +64 -0
  158. data/lib/active_record/legacy_yaml_adapter.rb +52 -0
  159. data/lib/active_record/locale/en.yml +3 -2
  160. data/lib/active_record/locking/optimistic.rb +103 -95
  161. data/lib/active_record/locking/pessimistic.rb +22 -6
  162. data/lib/active_record/log_subscriber.rb +93 -31
  163. data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
  164. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  165. data/lib/active_record/middleware/database_selector.rb +77 -0
  166. data/lib/active_record/migration/command_recorder.rb +185 -90
  167. data/lib/active_record/migration/compatibility.rb +298 -0
  168. data/lib/active_record/migration/join_table.rb +8 -7
  169. data/lib/active_record/migration.rb +685 -309
  170. data/lib/active_record/model_schema.rb +420 -113
  171. data/lib/active_record/nested_attributes.rb +265 -216
  172. data/lib/active_record/no_touching.rb +15 -2
  173. data/lib/active_record/null_relation.rb +24 -38
  174. data/lib/active_record/persistence.rb +574 -135
  175. data/lib/active_record/query_cache.rb +29 -23
  176. data/lib/active_record/querying.rb +50 -31
  177. data/lib/active_record/railtie.rb +175 -54
  178. data/lib/active_record/railties/console_sandbox.rb +3 -3
  179. data/lib/active_record/railties/controller_runtime.rb +34 -33
  180. data/lib/active_record/railties/databases.rake +533 -216
  181. data/lib/active_record/readonly_attributes.rb +9 -4
  182. data/lib/active_record/reflection.rb +485 -310
  183. data/lib/active_record/relation/batches/batch_enumerator.rb +85 -0
  184. data/lib/active_record/relation/batches.rb +217 -59
  185. data/lib/active_record/relation/calculations.rb +326 -244
  186. data/lib/active_record/relation/delegation.rb +76 -84
  187. data/lib/active_record/relation/finder_methods.rb +318 -256
  188. data/lib/active_record/relation/from_clause.rb +30 -0
  189. data/lib/active_record/relation/merger.rb +99 -84
  190. data/lib/active_record/relation/predicate_builder/array_handler.rb +26 -25
  191. data/lib/active_record/relation/predicate_builder/association_query_value.rb +42 -0
  192. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +19 -0
  193. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +57 -0
  194. data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -0
  195. data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
  196. data/lib/active_record/relation/predicate_builder.rb +139 -96
  197. data/lib/active_record/relation/query_attribute.rb +50 -0
  198. data/lib/active_record/relation/query_methods.rb +757 -409
  199. data/lib/active_record/relation/record_fetch_warning.rb +51 -0
  200. data/lib/active_record/relation/spawn_methods.rb +23 -21
  201. data/lib/active_record/relation/where_clause.rb +239 -0
  202. data/lib/active_record/relation.rb +554 -342
  203. data/lib/active_record/result.rb +91 -47
  204. data/lib/active_record/runtime_registry.rb +6 -4
  205. data/lib/active_record/sanitization.rb +134 -122
  206. data/lib/active_record/schema.rb +21 -24
  207. data/lib/active_record/schema_dumper.rb +141 -92
  208. data/lib/active_record/schema_migration.rb +24 -26
  209. data/lib/active_record/scoping/default.rb +96 -82
  210. data/lib/active_record/scoping/named.rb +78 -36
  211. data/lib/active_record/scoping.rb +45 -27
  212. data/lib/active_record/secure_token.rb +48 -0
  213. data/lib/active_record/serialization.rb +8 -6
  214. data/lib/active_record/signed_id.rb +116 -0
  215. data/lib/active_record/statement_cache.rb +89 -36
  216. data/lib/active_record/store.rb +133 -43
  217. data/lib/active_record/suppressor.rb +61 -0
  218. data/lib/active_record/table_metadata.rb +81 -0
  219. data/lib/active_record/tasks/database_tasks.rb +366 -129
  220. data/lib/active_record/tasks/mysql_database_tasks.rb +68 -100
  221. data/lib/active_record/tasks/postgresql_database_tasks.rb +87 -39
  222. data/lib/active_record/tasks/sqlite_database_tasks.rb +44 -19
  223. data/lib/active_record/test_databases.rb +24 -0
  224. data/lib/active_record/test_fixtures.rb +291 -0
  225. data/lib/active_record/timestamp.rb +86 -43
  226. data/lib/active_record/touch_later.rb +65 -0
  227. data/lib/active_record/transactions.rb +181 -152
  228. data/lib/active_record/translation.rb +3 -1
  229. data/lib/active_record/type/adapter_specific_registry.rb +126 -0
  230. data/lib/active_record/type/date.rb +4 -41
  231. data/lib/active_record/type/date_time.rb +4 -38
  232. data/lib/active_record/type/decimal_without_scale.rb +6 -2
  233. data/lib/active_record/type/hash_lookup_type_map.rb +12 -5
  234. data/lib/active_record/type/internal/timezone.rb +17 -0
  235. data/lib/active_record/type/json.rb +30 -0
  236. data/lib/active_record/type/serialized.rb +33 -15
  237. data/lib/active_record/type/text.rb +2 -2
  238. data/lib/active_record/type/time.rb +21 -16
  239. data/lib/active_record/type/type_map.rb +16 -19
  240. data/lib/active_record/type/unsigned_integer.rb +9 -8
  241. data/lib/active_record/type.rb +84 -23
  242. data/lib/active_record/type_caster/connection.rb +33 -0
  243. data/lib/active_record/type_caster/map.rb +23 -0
  244. data/lib/active_record/type_caster.rb +9 -0
  245. data/lib/active_record/validations/absence.rb +25 -0
  246. data/lib/active_record/validations/associated.rb +12 -4
  247. data/lib/active_record/validations/length.rb +26 -0
  248. data/lib/active_record/validations/numericality.rb +35 -0
  249. data/lib/active_record/validations/presence.rb +14 -13
  250. data/lib/active_record/validations/uniqueness.rb +65 -48
  251. data/lib/active_record/validations.rb +39 -35
  252. data/lib/active_record/version.rb +3 -1
  253. data/lib/active_record.rb +44 -28
  254. data/lib/arel/alias_predication.rb +9 -0
  255. data/lib/arel/attributes/attribute.rb +41 -0
  256. data/lib/arel/collectors/bind.rb +29 -0
  257. data/lib/arel/collectors/composite.rb +39 -0
  258. data/lib/arel/collectors/plain_string.rb +20 -0
  259. data/lib/arel/collectors/sql_string.rb +27 -0
  260. data/lib/arel/collectors/substitute_binds.rb +35 -0
  261. data/lib/arel/crud.rb +42 -0
  262. data/lib/arel/delete_manager.rb +18 -0
  263. data/lib/arel/errors.rb +9 -0
  264. data/lib/arel/expressions.rb +29 -0
  265. data/lib/arel/factory_methods.rb +49 -0
  266. data/lib/arel/insert_manager.rb +49 -0
  267. data/lib/arel/math.rb +45 -0
  268. data/lib/arel/nodes/and.rb +32 -0
  269. data/lib/arel/nodes/ascending.rb +23 -0
  270. data/lib/arel/nodes/binary.rb +126 -0
  271. data/lib/arel/nodes/bind_param.rb +44 -0
  272. data/lib/arel/nodes/case.rb +55 -0
  273. data/lib/arel/nodes/casted.rb +62 -0
  274. data/lib/arel/nodes/comment.rb +29 -0
  275. data/lib/arel/nodes/count.rb +12 -0
  276. data/lib/arel/nodes/delete_statement.rb +45 -0
  277. data/lib/arel/nodes/descending.rb +23 -0
  278. data/lib/arel/nodes/equality.rb +15 -0
  279. data/lib/arel/nodes/extract.rb +24 -0
  280. data/lib/arel/nodes/false.rb +16 -0
  281. data/lib/arel/nodes/full_outer_join.rb +8 -0
  282. data/lib/arel/nodes/function.rb +44 -0
  283. data/lib/arel/nodes/grouping.rb +11 -0
  284. data/lib/arel/nodes/homogeneous_in.rb +76 -0
  285. data/lib/arel/nodes/in.rb +15 -0
  286. data/lib/arel/nodes/infix_operation.rb +92 -0
  287. data/lib/arel/nodes/inner_join.rb +8 -0
  288. data/lib/arel/nodes/insert_statement.rb +37 -0
  289. data/lib/arel/nodes/join_source.rb +20 -0
  290. data/lib/arel/nodes/matches.rb +18 -0
  291. data/lib/arel/nodes/named_function.rb +23 -0
  292. data/lib/arel/nodes/node.rb +51 -0
  293. data/lib/arel/nodes/node_expression.rb +13 -0
  294. data/lib/arel/nodes/ordering.rb +27 -0
  295. data/lib/arel/nodes/outer_join.rb +8 -0
  296. data/lib/arel/nodes/over.rb +15 -0
  297. data/lib/arel/nodes/regexp.rb +16 -0
  298. data/lib/arel/nodes/right_outer_join.rb +8 -0
  299. data/lib/arel/nodes/select_core.rb +67 -0
  300. data/lib/arel/nodes/select_statement.rb +41 -0
  301. data/lib/arel/nodes/sql_literal.rb +19 -0
  302. data/lib/arel/nodes/string_join.rb +11 -0
  303. data/lib/arel/nodes/table_alias.rb +31 -0
  304. data/lib/arel/nodes/terminal.rb +16 -0
  305. data/lib/arel/nodes/true.rb +16 -0
  306. data/lib/arel/nodes/unary.rb +44 -0
  307. data/lib/arel/nodes/unary_operation.rb +20 -0
  308. data/lib/arel/nodes/unqualified_column.rb +22 -0
  309. data/lib/arel/nodes/update_statement.rb +41 -0
  310. data/lib/arel/nodes/values_list.rb +9 -0
  311. data/lib/arel/nodes/window.rb +126 -0
  312. data/lib/arel/nodes/with.rb +11 -0
  313. data/lib/arel/nodes.rb +70 -0
  314. data/lib/arel/order_predications.rb +13 -0
  315. data/lib/arel/predications.rb +250 -0
  316. data/lib/arel/select_manager.rb +270 -0
  317. data/lib/arel/table.rb +118 -0
  318. data/lib/arel/tree_manager.rb +72 -0
  319. data/lib/arel/update_manager.rb +34 -0
  320. data/lib/arel/visitors/dot.rb +308 -0
  321. data/lib/arel/visitors/mysql.rb +93 -0
  322. data/lib/arel/visitors/postgresql.rb +120 -0
  323. data/lib/arel/visitors/sqlite.rb +38 -0
  324. data/lib/arel/visitors/to_sql.rb +899 -0
  325. data/lib/arel/visitors/visitor.rb +45 -0
  326. data/lib/arel/visitors.rb +13 -0
  327. data/lib/arel/window_predications.rb +9 -0
  328. data/lib/arel.rb +54 -0
  329. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +26 -0
  330. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
  331. data/lib/rails/generators/active_record/migration/migration_generator.rb +43 -37
  332. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +26 -0
  333. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +13 -10
  334. data/lib/rails/generators/active_record/migration.rb +35 -1
  335. data/lib/rails/generators/active_record/model/model_generator.rb +55 -22
  336. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
  337. data/lib/rails/generators/active_record/model/templates/model.rb.tt +22 -0
  338. data/lib/rails/generators/active_record.rb +7 -5
  339. metadata +175 -65
  340. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  341. data/lib/active_record/associations/preloader/collection_association.rb +0 -24
  342. data/lib/active_record/associations/preloader/has_many.rb +0 -17
  343. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  344. data/lib/active_record/associations/preloader/has_one.rb +0 -23
  345. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  346. data/lib/active_record/associations/preloader/singular_association.rb +0 -21
  347. data/lib/active_record/attribute.rb +0 -149
  348. data/lib/active_record/attribute_decorators.rb +0 -66
  349. data/lib/active_record/attribute_set/builder.rb +0 -86
  350. data/lib/active_record/attribute_set.rb +0 -77
  351. data/lib/active_record/connection_adapters/connection_specification.rb +0 -275
  352. data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -491
  353. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
  354. data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
  355. data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +0 -11
  356. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -35
  357. data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
  358. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  359. data/lib/active_record/serializers/xml_serializer.rb +0 -193
  360. data/lib/active_record/type/big_integer.rb +0 -13
  361. data/lib/active_record/type/binary.rb +0 -50
  362. data/lib/active_record/type/boolean.rb +0 -30
  363. data/lib/active_record/type/decimal.rb +0 -40
  364. data/lib/active_record/type/decorator.rb +0 -14
  365. data/lib/active_record/type/float.rb +0 -19
  366. data/lib/active_record/type/integer.rb +0 -55
  367. data/lib/active_record/type/mutable.rb +0 -16
  368. data/lib/active_record/type/numeric.rb +0 -36
  369. data/lib/active_record/type/string.rb +0 -36
  370. data/lib/active_record/type/time_value.rb +0 -38
  371. data/lib/active_record/type/value.rb +0 -101
  372. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +0 -22
  373. data/lib/rails/generators/active_record/model/templates/model.rb +0 -10
  374. /data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
@@ -1,215 +1,114 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
4
6
  module DatabaseStatements
5
7
  def explain(arel, binds = [])
6
8
  sql = "EXPLAIN #{to_sql(arel, binds)}"
7
- ExplainPrettyPrinter.new.pp(exec_query(sql, 'EXPLAIN', binds))
8
- end
9
-
10
- class ExplainPrettyPrinter # :nodoc:
11
- # Pretty prints the result of a EXPLAIN in a way that resembles the output of the
12
- # PostgreSQL shell:
13
- #
14
- # QUERY PLAN
15
- # ------------------------------------------------------------------------------
16
- # Nested Loop Left Join (cost=0.00..37.24 rows=8 width=0)
17
- # Join Filter: (posts.user_id = users.id)
18
- # -> Index Scan using users_pkey on users (cost=0.00..8.27 rows=1 width=4)
19
- # Index Cond: (id = 1)
20
- # -> Seq Scan on posts (cost=0.00..28.88 rows=8 width=4)
21
- # Filter: (posts.user_id = 1)
22
- # (6 rows)
23
- #
24
- def pp(result)
25
- header = result.columns.first
26
- lines = result.rows.map(&:first)
27
-
28
- # We add 2 because there's one char of padding at both sides, note
29
- # the extra hyphens in the example above.
30
- width = [header, *lines].map(&:length).max + 2
31
-
32
- pp = []
33
-
34
- pp << header.center(width).rstrip
35
- pp << '-' * width
36
-
37
- pp += lines.map {|line| " #{line}"}
38
-
39
- nrows = result.rows.length
40
- rows_label = nrows == 1 ? 'row' : 'rows'
41
- pp << "(#{nrows} #{rows_label})"
42
-
43
- pp.join("\n") + "\n"
44
- end
9
+ PostgreSQL::ExplainPrettyPrinter.new.pp(exec_query(sql, "EXPLAIN", binds))
45
10
  end
46
11
 
47
- def select_value(arel, name = nil, binds = [])
48
- arel, binds = binds_from_relation arel, binds
49
- sql = to_sql(arel, binds)
50
- execute_and_clear(sql, name, binds) do |result|
51
- result.getvalue(0, 0) if result.ntuples > 0 && result.nfields > 0
52
- end
53
- end
12
+ # Queries the database and returns the results in an Array-like object
13
+ def query(sql, name = nil) #:nodoc:
14
+ materialize_transactions
15
+ mark_transaction_written_if_write(sql)
54
16
 
55
- def select_values(arel, name = nil)
56
- arel, binds = binds_from_relation arel, []
57
- sql = to_sql(arel, binds)
58
- execute_and_clear(sql, name, binds) do |result|
59
- if result.nfields > 0
60
- result.column_values(0)
61
- else
62
- []
17
+ log(sql, name) do
18
+ ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
19
+ @connection.async_exec(sql).map_types!(@type_map_for_results).values
63
20
  end
64
21
  end
65
22
  end
66
23
 
67
- # Executes a SELECT query and returns an array of rows. Each row is an
68
- # array of field values.
69
- def select_rows(sql, name = nil, binds = [])
70
- execute_and_clear(sql, name, binds) do |result|
71
- result.values
72
- end
73
- end
74
-
75
- # Executes an INSERT query and returns the new record's ID
76
- def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
77
- unless pk
78
- # Extract the table from the insert sql. Yuck.
79
- table_ref = extract_table_ref_from_insert_sql(sql)
80
- pk = primary_key(table_ref) if table_ref
81
- end
82
-
83
- if pk && use_insert_returning?
84
- select_value("#{sql} RETURNING #{quote_column_name(pk)}")
85
- elsif pk
86
- super
87
- last_insert_id_value(sequence_name || default_sequence_name(table_ref, pk))
88
- else
89
- super
90
- end
91
- end
24
+ READ_QUERY = ActiveRecord::ConnectionAdapters::AbstractAdapter.build_read_query_regexp(
25
+ :close, :declare, :fetch, :move, :set, :show
26
+ ) # :nodoc:
27
+ private_constant :READ_QUERY
92
28
 
93
- def create
94
- super.insert
29
+ def write_query?(sql) # :nodoc:
30
+ !READ_QUERY.match?(sql)
31
+ rescue ArgumentError # Invalid encoding
32
+ !READ_QUERY.match?(sql.b)
95
33
  end
96
34
 
97
- # The internal PostgreSQL identifier of the money data type.
98
- MONEY_COLUMN_TYPE_OID = 790 #:nodoc:
99
- # The internal PostgreSQL identifier of the BYTEA data type.
100
- BYTEA_COLUMN_TYPE_OID = 17 #:nodoc:
101
-
102
- # create a 2D array representing the result set
103
- def result_as_array(res) #:nodoc:
104
- # check if we have any binary column and if they need escaping
105
- ftypes = Array.new(res.nfields) do |i|
106
- [i, res.ftype(i)]
107
- end
108
-
109
- rows = res.values
110
- return rows unless ftypes.any? { |_, x|
111
- x == BYTEA_COLUMN_TYPE_OID || x == MONEY_COLUMN_TYPE_OID
112
- }
113
-
114
- typehash = ftypes.group_by { |_, type| type }
115
- binaries = typehash[BYTEA_COLUMN_TYPE_OID] || []
116
- monies = typehash[MONEY_COLUMN_TYPE_OID] || []
117
-
118
- rows.each do |row|
119
- # unescape string passed BYTEA field (OID == 17)
120
- binaries.each do |index, _|
121
- row[index] = unescape_bytea(row[index])
122
- end
123
-
124
- # If this is a money type column and there are any currency symbols,
125
- # then strip them off. Indeed it would be prettier to do this in
126
- # PostgreSQLColumn.string_to_decimal but would break form input
127
- # fields that call value_before_type_cast.
128
- monies.each do |index, _|
129
- data = row[index]
130
- # Because money output is formatted according to the locale, there are two
131
- # cases to consider (note the decimal separators):
132
- # (1) $12,345,678.12
133
- # (2) $12.345.678,12
134
- case data
135
- when /^-?\D+[\d,]+\.\d{2}$/ # (1)
136
- data.gsub!(/[^-\d.]/, '')
137
- when /^-?\D+[\d.]+,\d{2}$/ # (2)
138
- data.gsub!(/[^-\d,]/, '').sub!(/,/, '.')
139
- end
140
- end
35
+ # Executes an SQL statement, returning a PG::Result object on success
36
+ # or raising a PG::Error exception otherwise.
37
+ # Note: the PG::Result object is manually memory managed; if you don't
38
+ # need it specifically, you may want consider the <tt>exec_query</tt> wrapper.
39
+ def execute(sql, name = nil)
40
+ if preventing_writes? && write_query?(sql)
41
+ raise ActiveRecord::ReadOnlyError, "Write query attempted while in readonly mode: #{sql}"
141
42
  end
142
- end
143
43
 
144
- # Queries the database and returns the results in an Array-like object
145
- def query(sql, name = nil) #:nodoc:
146
- log(sql, name) do
147
- result_as_array @connection.async_exec(sql)
148
- end
149
- end
44
+ materialize_transactions
45
+ mark_transaction_written_if_write(sql)
150
46
 
151
- # Executes an SQL statement, returning a PGresult object on success
152
- # or raising a PGError exception otherwise.
153
- def execute(sql, name = nil)
154
47
  log(sql, name) do
155
- @connection.async_exec(sql)
48
+ ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
49
+ @connection.async_exec(sql)
50
+ end
156
51
  end
157
52
  end
158
53
 
159
- def exec_query(sql, name = 'SQL', binds = [])
160
- execute_and_clear(sql, name, binds) do |result|
54
+ def exec_query(sql, name = "SQL", binds = [], prepare: false)
55
+ execute_and_clear(sql, name, binds, prepare: prepare) do |result|
161
56
  types = {}
162
57
  fields = result.fields
163
58
  fields.each_with_index do |fname, i|
164
59
  ftype = result.ftype i
165
60
  fmod = result.fmod i
166
- types[fname] = get_oid_type(ftype, fmod, fname)
61
+ case type = get_oid_type(ftype, fmod, fname)
62
+ when Type::Integer, Type::Float, OID::Decimal, Type::String, Type::DateTime, Type::Boolean
63
+ # skip if a column has already been type casted by pg decoders
64
+ else types[fname] = type
65
+ end
167
66
  end
168
- ActiveRecord::Result.new(fields, result.values, types)
67
+ build_result(columns: fields, rows: result.values, column_types: types)
169
68
  end
170
69
  end
171
70
 
172
- def exec_delete(sql, name = 'SQL', binds = [])
173
- execute_and_clear(sql, name, binds) {|result| result.cmd_tuples }
71
+ def exec_delete(sql, name = nil, binds = [])
72
+ execute_and_clear(sql, name, binds) { |result| result.cmd_tuples }
174
73
  end
175
74
  alias :exec_update :exec_delete
176
75
 
177
- def sql_for_insert(sql, pk, id_value, sequence_name, binds)
178
- unless pk
76
+ def sql_for_insert(sql, pk, binds) # :nodoc:
77
+ if pk.nil?
179
78
  # Extract the table from the insert sql. Yuck.
180
79
  table_ref = extract_table_ref_from_insert_sql(sql)
181
80
  pk = primary_key(table_ref) if table_ref
182
81
  end
183
82
 
184
- if pk && use_insert_returning?
83
+ if pk = suppress_composite_primary_key(pk)
185
84
  sql = "#{sql} RETURNING #{quote_column_name(pk)}"
186
85
  end
187
86
 
188
- [sql, binds]
87
+ super
189
88
  end
89
+ private :sql_for_insert
190
90
 
191
- def exec_insert(sql, name, binds, pk = nil, sequence_name = nil)
192
- val = exec_query(sql, name, binds)
193
- if !use_insert_returning? && pk
91
+ def exec_insert(sql, name = nil, binds = [], pk = nil, sequence_name = nil)
92
+ if use_insert_returning? || pk == false
93
+ super
94
+ else
95
+ result = exec_query(sql, name, binds)
194
96
  unless sequence_name
195
97
  table_ref = extract_table_ref_from_insert_sql(sql)
196
- sequence_name = default_sequence_name(table_ref, pk)
197
- return val unless sequence_name
98
+ if table_ref
99
+ pk = primary_key(table_ref) if pk.nil?
100
+ pk = suppress_composite_primary_key(pk)
101
+ sequence_name = default_sequence_name(table_ref, pk)
102
+ end
103
+ return result unless sequence_name
198
104
  end
199
105
  last_insert_id_result(sequence_name)
200
- else
201
- val
202
106
  end
203
107
  end
204
108
 
205
- # Executes an UPDATE query and returns the number of affected tuples.
206
- def update_sql(sql, name = nil)
207
- super.cmd_tuples
208
- end
209
-
210
109
  # Begins a transaction.
211
110
  def begin_db_transaction
212
- execute "BEGIN"
111
+ execute("BEGIN", "TRANSACTION")
213
112
  end
214
113
 
215
114
  def begin_isolated_db_transaction(isolation)
@@ -219,13 +118,31 @@ module ActiveRecord
219
118
 
220
119
  # Commits a transaction.
221
120
  def commit_db_transaction
222
- execute "COMMIT"
121
+ execute("COMMIT", "TRANSACTION")
223
122
  end
224
123
 
225
124
  # Aborts a transaction.
226
- def rollback_db_transaction
227
- execute "ROLLBACK"
125
+ def exec_rollback_db_transaction
126
+ execute("ROLLBACK", "TRANSACTION")
228
127
  end
128
+
129
+ private
130
+ def execute_batch(statements, name = nil)
131
+ execute(combine_multi_statements(statements))
132
+ end
133
+
134
+ def build_truncate_statements(table_names)
135
+ ["TRUNCATE TABLE #{table_names.map(&method(:quote_table_name)).join(", ")}"]
136
+ end
137
+
138
+ # Returns the current ID of a table's sequence.
139
+ def last_insert_id_result(sequence_name)
140
+ exec_query("SELECT currval(#{quote(sequence_name)})", "SQL")
141
+ end
142
+
143
+ def suppress_composite_primary_key(pk)
144
+ pk unless pk.is_a?(Array)
145
+ end
229
146
  end
230
147
  end
231
148
  end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module ConnectionAdapters
5
+ module PostgreSQL
6
+ class ExplainPrettyPrinter # :nodoc:
7
+ # Pretty prints the result of an EXPLAIN in a way that resembles the output of the
8
+ # PostgreSQL shell:
9
+ #
10
+ # QUERY PLAN
11
+ # ------------------------------------------------------------------------------
12
+ # Nested Loop Left Join (cost=0.00..37.24 rows=8 width=0)
13
+ # Join Filter: (posts.user_id = users.id)
14
+ # -> Index Scan using users_pkey on users (cost=0.00..8.27 rows=1 width=4)
15
+ # Index Cond: (id = 1)
16
+ # -> Seq Scan on posts (cost=0.00..28.88 rows=8 width=4)
17
+ # Filter: (posts.user_id = 1)
18
+ # (6 rows)
19
+ #
20
+ def pp(result)
21
+ header = result.columns.first
22
+ lines = result.rows.map(&:first)
23
+
24
+ # We add 2 because there's one char of padding at both sides, note
25
+ # the extra hyphens in the example above.
26
+ width = [header, *lines].map(&:length).max + 2
27
+
28
+ pp = []
29
+
30
+ pp << header.center(width).rstrip
31
+ pp << "-" * width
32
+
33
+ pp += lines.map { |line| " #{line}" }
34
+
35
+ nrows = result.rows.length
36
+ rows_label = nrows == 1 ? "row" : "rows"
37
+ pp << "(#{nrows} #{rows_label})"
38
+
39
+ pp.join("\n") + "\n"
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -1,97 +1,89 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
4
6
  module OID # :nodoc:
5
7
  class Array < Type::Value # :nodoc:
6
- include Type::Mutable
8
+ include ActiveModel::Type::Helpers::Mutable
7
9
 
8
- # Loads pg_array_parser if available. String parsing can be
9
- # performed quicker by a native extension, which will not create
10
- # a large amount of Ruby objects that will need to be garbage
11
- # collected. pg_array_parser has a C and Java extension
12
- begin
13
- require 'pg_array_parser'
14
- include PgArrayParser
15
- rescue LoadError
16
- require 'active_record/connection_adapters/postgresql/array_parser'
17
- include PostgreSQL::ArrayParser
18
- end
10
+ Data = Struct.new(:encoder, :values) # :nodoc:
19
11
 
20
12
  attr_reader :subtype, :delimiter
21
- delegate :type, to: :subtype
13
+ delegate :type, :user_input_in_time_zone, :limit, :precision, :scale, to: :subtype
22
14
 
23
- def initialize(subtype, delimiter = ',')
15
+ def initialize(subtype, delimiter = ",")
24
16
  @subtype = subtype
25
17
  @delimiter = delimiter
18
+
19
+ @pg_encoder = PG::TextEncoder::Array.new name: "#{type}[]", delimiter: delimiter
20
+ @pg_decoder = PG::TextDecoder::Array.new name: "#{type}[]", delimiter: delimiter
26
21
  end
27
22
 
28
- def type_cast_from_database(value)
29
- if value.is_a?(::String)
30
- type_cast_array(parse_pg_array(value), :type_cast_from_database)
23
+ def deserialize(value)
24
+ case value
25
+ when ::String
26
+ type_cast_array(@pg_decoder.decode(value), :deserialize)
27
+ when Data
28
+ type_cast_array(value.values, :deserialize)
31
29
  else
32
30
  super
33
31
  end
34
32
  end
35
33
 
36
- def type_cast_from_user(value)
34
+ def cast(value)
37
35
  if value.is_a?(::String)
38
- value = parse_pg_array(value)
36
+ value = begin
37
+ @pg_decoder.decode(value)
38
+ rescue TypeError
39
+ # malformed array string is treated as [], will raise in PG 2.0 gem
40
+ # this keeps a consistent implementation
41
+ []
42
+ end
39
43
  end
40
- type_cast_array(value, :type_cast_from_user)
44
+ type_cast_array(value, :cast)
41
45
  end
42
46
 
43
- def type_cast_for_database(value)
47
+ def serialize(value)
44
48
  if value.is_a?(::Array)
45
- cast_value_for_database(value)
49
+ casted_values = type_cast_array(value, :serialize)
50
+ Data.new(@pg_encoder, casted_values)
46
51
  else
47
52
  super
48
53
  end
49
54
  end
50
55
 
51
- private
56
+ def ==(other)
57
+ other.is_a?(Array) &&
58
+ subtype == other.subtype &&
59
+ delimiter == other.delimiter
60
+ end
52
61
 
53
- def type_cast_array(value, method)
54
- if value.is_a?(::Array)
55
- value.map { |item| type_cast_array(item, method) }
56
- else
57
- @subtype.public_send(method, value)
58
- end
62
+ def type_cast_for_schema(value)
63
+ return super unless value.is_a?(::Array)
64
+ "[" + value.map { |v| subtype.type_cast_for_schema(v) }.join(", ") + "]"
59
65
  end
60
66
 
61
- def cast_value_for_database(value)
62
- if value.is_a?(::Array)
63
- casted_values = value.map { |item| cast_value_for_database(item) }
64
- "{#{casted_values.join(delimiter)}}"
65
- else
66
- quote_and_escape(subtype.type_cast_for_database(value))
67
- end
67
+ def map(value, &block)
68
+ value.map(&block)
68
69
  end
69
70
 
70
- ARRAY_ESCAPE = "\\" * 2 * 2 # escape the backslash twice for PG arrays
71
+ def changed_in_place?(raw_old_value, new_value)
72
+ deserialize(raw_old_value) != new_value
73
+ end
71
74
 
72
- def quote_and_escape(value)
73
- case value
74
- when ::String
75
- if string_requires_quoting?(value)
76
- value = value.gsub(/\\/, ARRAY_ESCAPE)
77
- value.gsub!(/"/,"\\\"")
78
- %("#{value}")
75
+ def force_equality?(value)
76
+ value.is_a?(::Array)
77
+ end
78
+
79
+ private
80
+ def type_cast_array(value, method)
81
+ if value.is_a?(::Array)
82
+ value.map { |item| type_cast_array(item, method) }
79
83
  else
80
- value
84
+ @subtype.public_send(method, value)
81
85
  end
82
- when nil then "NULL"
83
- else value
84
86
  end
85
- end
86
-
87
- # See http://www.postgresql.org/docs/9.2/static/arrays.html#ARRAYS-IO
88
- # for a list of all cases in which strings will be quoted.
89
- def string_requires_quoting?(string)
90
- string.empty? ||
91
- string == "NULL" ||
92
- string =~ /[\{\}"\\\s]/ ||
93
- string.include?(delimiter)
94
- end
95
87
  end
96
88
  end
97
89
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
@@ -7,7 +9,7 @@ module ActiveRecord
7
9
  :bit
8
10
  end
9
11
 
10
- def type_cast(value)
12
+ def cast_value(value)
11
13
  if ::String === value
12
14
  case value
13
15
  when /^0x/i
@@ -16,11 +18,11 @@ module ActiveRecord
16
18
  value # Bit-string notation
17
19
  end
18
20
  else
19
- value
21
+ value.to_s
20
22
  end
21
23
  end
22
24
 
23
- def type_cast_for_database(value)
25
+ def serialize(value)
24
26
  Data.new(super) if value
25
27
  end
26
28
 
@@ -34,16 +36,15 @@ module ActiveRecord
34
36
  end
35
37
 
36
38
  def binary?
37
- /\A[01]*\Z/ === value
39
+ /\A[01]*\Z/.match?(value)
38
40
  end
39
41
 
40
42
  def hex?
41
- /\A[0-9A-F]*\Z/i === value
43
+ /\A[0-9A-F]*\Z/i.match?(value)
42
44
  end
43
45
 
44
- protected
45
-
46
- attr_reader :value
46
+ private
47
+ attr_reader :value
47
48
  end
48
49
  end
49
50
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
@@ -1,11 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
4
6
  module OID # :nodoc:
5
7
  class Bytea < Type::Binary # :nodoc:
6
- def type_cast_from_database(value)
8
+ def deserialize(value)
7
9
  return if value.nil?
8
- PGconn.unescape_bytea(super)
10
+ return value.to_s if value.is_a?(Type::Binary::Data)
11
+ PG::Connection.unescape_bytea(super)
9
12
  end
10
13
  end
11
14
  end
@@ -1,3 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "ipaddr"
4
+
1
5
  module ActiveRecord
2
6
  module ConnectionAdapters
3
7
  module PostgreSQL
@@ -8,19 +12,17 @@ module ActiveRecord
8
12
  end
9
13
 
10
14
  def type_cast_for_schema(value)
11
- subnet_mask = value.instance_variable_get(:@mask_addr)
12
-
13
15
  # If the subnet mask is equal to /32, don't output it
14
- if subnet_mask == (2**32 - 1)
16
+ if value.prefix == 32
15
17
  "\"#{value}\""
16
18
  else
17
- "\"#{value}/#{subnet_mask.to_s(2).count('1')}\""
19
+ "\"#{value}/#{value.prefix}\""
18
20
  end
19
21
  end
20
22
 
21
- def type_cast_for_database(value)
23
+ def serialize(value)
22
24
  if IPAddr === value
23
- "#{value}/#{value.instance_variable_get(:@mask_addr).to_s(2).count('1')}"
25
+ "#{value}/#{value.prefix}"
24
26
  else
25
27
  value
26
28
  end
@@ -1,9 +1,21 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
4
6
  module OID # :nodoc:
5
7
  class Date < Type::Date # :nodoc:
6
- include Infinity
8
+ def cast_value(value)
9
+ case value
10
+ when "infinity" then ::Float::INFINITY
11
+ when "-infinity" then -::Float::INFINITY
12
+ when / BC$/
13
+ value = value.sub(/^\d+/) { |year| format("%04d", -year.to_i + 1) }
14
+ super(value.delete_suffix!(" BC"))
15
+ else
16
+ super
17
+ end
18
+ end
7
19
  end
8
20
  end
9
21
  end
@@ -1,23 +1,27 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
4
6
  module OID # :nodoc:
5
7
  class DateTime < Type::DateTime # :nodoc:
6
- include Infinity
7
-
8
8
  def cast_value(value)
9
- if value.is_a?(::String)
10
- case value
11
- when 'infinity' then ::Float::INFINITY
12
- when '-infinity' then -::Float::INFINITY
13
- when / BC$/
14
- astronomical_year = format("%04d", -value[/^\d+/].to_i + 1)
15
- super(value.sub(/ BC$/, "").sub(/^\d+/, astronomical_year))
16
- else
17
- super
18
- end
9
+ case value
10
+ when "infinity" then ::Float::INFINITY
11
+ when "-infinity" then -::Float::INFINITY
12
+ when / BC$/
13
+ value = value.sub(/^\d+/) { |year| format("%04d", -year.to_i + 1) }
14
+ super(value.delete_suffix!(" BC"))
19
15
  else
20
- value
16
+ super
17
+ end
18
+ end
19
+
20
+ def type_cast_for_schema(value)
21
+ case value
22
+ when ::Float::INFINITY then "::Float::INFINITY"
23
+ when -::Float::INFINITY then "-::Float::INFINITY"
24
+ else super
21
25
  end
22
26
  end
23
27
  end