activerecord 4.2.9 → 6.1.4.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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +964 -1382
- data/MIT-LICENSE +4 -2
- data/README.rdoc +15 -14
- data/examples/performance.rb +33 -32
- data/examples/simple.rb +5 -4
- data/lib/active_record/aggregations.rb +266 -251
- data/lib/active_record/association_relation.rb +40 -15
- data/lib/active_record/associations/alias_tracker.rb +40 -43
- data/lib/active_record/associations/association.rb +162 -69
- data/lib/active_record/associations/association_scope.rb +105 -130
- data/lib/active_record/associations/belongs_to_association.rb +83 -65
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +13 -12
- data/lib/active_record/associations/builder/association.rb +57 -43
- data/lib/active_record/associations/builder/belongs_to.rb +74 -57
- data/lib/active_record/associations/builder/collection_association.rb +15 -37
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +49 -66
- data/lib/active_record/associations/builder/has_many.rb +13 -5
- data/lib/active_record/associations/builder/has_one.rb +44 -6
- data/lib/active_record/associations/builder/singular_association.rb +16 -10
- data/lib/active_record/associations/collection_association.rb +148 -287
- data/lib/active_record/associations/collection_proxy.rb +252 -150
- data/lib/active_record/associations/foreign_association.rb +23 -1
- data/lib/active_record/associations/has_many_association.rb +56 -98
- data/lib/active_record/associations/has_many_through_association.rb +68 -89
- data/lib/active_record/associations/has_one_association.rb +73 -47
- data/lib/active_record/associations/has_one_through_association.rb +20 -11
- data/lib/active_record/associations/join_dependency/join_association.rb +54 -81
- data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
- data/lib/active_record/associations/join_dependency/join_part.rb +14 -14
- data/lib/active_record/associations/join_dependency.rb +174 -169
- data/lib/active_record/associations/preloader/association.rb +108 -115
- data/lib/active_record/associations/preloader/through_association.rb +85 -65
- data/lib/active_record/associations/preloader.rb +97 -94
- data/lib/active_record/associations/singular_association.rb +18 -39
- data/lib/active_record/associations/through_association.rb +39 -19
- data/lib/active_record/associations.rb +1845 -1598
- data/lib/active_record/attribute_assignment.rb +59 -185
- data/lib/active_record/attribute_methods/before_type_cast.rb +18 -10
- data/lib/active_record/attribute_methods/dirty.rb +168 -148
- data/lib/active_record/attribute_methods/primary_key.rb +93 -83
- data/lib/active_record/attribute_methods/query.rb +8 -10
- data/lib/active_record/attribute_methods/read.rb +19 -79
- data/lib/active_record/attribute_methods/serialization.rb +49 -24
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +55 -36
- data/lib/active_record/attribute_methods/write.rb +24 -55
- data/lib/active_record/attribute_methods.rb +149 -154
- data/lib/active_record/attributes.rb +234 -78
- data/lib/active_record/autosave_association.rb +133 -60
- data/lib/active_record/base.rb +46 -46
- data/lib/active_record/callbacks.rb +234 -79
- data/lib/active_record/coders/json.rb +3 -1
- data/lib/active_record/coders/yaml_column.rb +34 -13
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +887 -323
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +17 -41
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +292 -124
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +78 -24
- data/lib/active_record/connection_adapters/abstract/quoting.rb +177 -60
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +8 -6
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +157 -93
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +473 -255
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +79 -36
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +869 -286
- data/lib/active_record/connection_adapters/abstract/transaction.rb +257 -91
- data/lib/active_record/connection_adapters/abstract_adapter.rb +483 -230
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +557 -640
- data/lib/active_record/connection_adapters/column.rb +67 -40
- data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
- data/lib/active_record/connection_adapters/legacy_pool_manager.rb +35 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +194 -0
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +71 -0
- data/lib/active_record/connection_adapters/mysql/quoting.rb +96 -0
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +97 -0
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +103 -0
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +91 -0
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +268 -0
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +40 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +80 -192
- data/lib/active_record/connection_adapters/pool_config.rb +73 -0
- data/lib/active_record/connection_adapters/pool_manager.rb +47 -0
- data/lib/active_record/connection_adapters/postgresql/column.rb +44 -11
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +75 -160
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +49 -58
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +9 -8
- data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +4 -2
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +8 -6
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +13 -1
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +14 -19
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -4
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +31 -20
- data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
- data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +44 -0
- data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -9
- data/lib/active_record/connection_adapters/postgresql/oid/{infinity.rb → oid.rb} +5 -3
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +32 -11
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +70 -34
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -5
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +18 -4
- data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid.rb +25 -25
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +145 -48
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +27 -14
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +80 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +178 -108
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +49 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +496 -298
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +44 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +11 -8
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +588 -375
- data/lib/active_record/connection_adapters/schema_cache.rb +167 -29
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +45 -0
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +144 -0
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +102 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +21 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +170 -0
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +322 -373
- data/lib/active_record/connection_adapters/statement_pool.rb +33 -13
- data/lib/active_record/connection_adapters.rb +52 -0
- data/lib/active_record/connection_handling.rb +314 -41
- data/lib/active_record/core.rb +458 -241
- data/lib/active_record/counter_cache.rb +70 -49
- data/lib/active_record/database_configurations/connection_url_resolver.rb +98 -0
- data/lib/active_record/database_configurations/database_config.rb +80 -0
- data/lib/active_record/database_configurations/hash_config.rb +96 -0
- data/lib/active_record/database_configurations/url_config.rb +53 -0
- data/lib/active_record/database_configurations.rb +272 -0
- data/lib/active_record/delegated_type.rb +209 -0
- data/lib/active_record/destroy_association_async_job.rb +36 -0
- data/lib/active_record/dynamic_matchers.rb +87 -106
- data/lib/active_record/enum.rb +211 -92
- data/lib/active_record/errors.rb +224 -54
- data/lib/active_record/explain.rb +27 -11
- data/lib/active_record/explain_registry.rb +4 -2
- data/lib/active_record/explain_subscriber.rb +10 -5
- data/lib/active_record/fixture_set/file.rb +33 -14
- data/lib/active_record/fixture_set/model_metadata.rb +32 -0
- data/lib/active_record/fixture_set/render_context.rb +17 -0
- data/lib/active_record/fixture_set/table_row.rb +152 -0
- data/lib/active_record/fixture_set/table_rows.rb +46 -0
- data/lib/active_record/fixtures.rb +275 -500
- data/lib/active_record/gem_version.rb +6 -4
- data/lib/active_record/inheritance.rb +175 -110
- data/lib/active_record/insert_all.rb +212 -0
- data/lib/active_record/integration.rb +121 -29
- data/lib/active_record/internal_metadata.rb +62 -0
- data/lib/active_record/legacy_yaml_adapter.rb +27 -5
- data/lib/active_record/locale/en.yml +3 -2
- data/lib/active_record/locking/optimistic.rb +98 -92
- data/lib/active_record/locking/pessimistic.rb +22 -6
- data/lib/active_record/log_subscriber.rb +93 -31
- data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
- data/lib/active_record/middleware/database_selector.rb +77 -0
- data/lib/active_record/migration/command_recorder.rb +185 -90
- data/lib/active_record/migration/compatibility.rb +295 -0
- data/lib/active_record/migration/join_table.rb +8 -7
- data/lib/active_record/migration.rb +673 -325
- data/lib/active_record/model_schema.rb +418 -113
- data/lib/active_record/nested_attributes.rb +263 -224
- data/lib/active_record/no_touching.rb +15 -2
- data/lib/active_record/null_relation.rb +24 -38
- data/lib/active_record/persistence.rb +572 -136
- data/lib/active_record/query_cache.rb +29 -23
- data/lib/active_record/querying.rb +50 -31
- data/lib/active_record/railtie.rb +170 -51
- data/lib/active_record/railties/console_sandbox.rb +3 -3
- data/lib/active_record/railties/controller_runtime.rb +34 -33
- data/lib/active_record/railties/databases.rake +523 -199
- data/lib/active_record/readonly_attributes.rb +9 -4
- data/lib/active_record/reflection.rb +454 -291
- data/lib/active_record/relation/batches/batch_enumerator.rb +85 -0
- data/lib/active_record/relation/batches.rb +217 -59
- data/lib/active_record/relation/calculations.rb +324 -249
- data/lib/active_record/relation/delegation.rb +76 -84
- data/lib/active_record/relation/finder_methods.rb +316 -242
- data/lib/active_record/relation/from_clause.rb +30 -0
- data/lib/active_record/relation/merger.rb +95 -103
- data/lib/active_record/relation/predicate_builder/array_handler.rb +26 -26
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +42 -0
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +19 -0
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +57 -0
- data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -0
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
- data/lib/active_record/relation/predicate_builder.rb +136 -122
- data/lib/active_record/relation/query_attribute.rb +50 -0
- data/lib/active_record/relation/query_methods.rb +757 -413
- data/lib/active_record/relation/record_fetch_warning.rb +51 -0
- data/lib/active_record/relation/spawn_methods.rb +18 -20
- data/lib/active_record/relation/where_clause.rb +239 -0
- data/lib/active_record/relation.rb +554 -343
- data/lib/active_record/result.rb +91 -47
- data/lib/active_record/runtime_registry.rb +6 -4
- data/lib/active_record/sanitization.rb +134 -122
- data/lib/active_record/schema.rb +21 -24
- data/lib/active_record/schema_dumper.rb +141 -92
- data/lib/active_record/schema_migration.rb +24 -23
- data/lib/active_record/scoping/default.rb +96 -83
- data/lib/active_record/scoping/named.rb +78 -36
- data/lib/active_record/scoping.rb +45 -27
- data/lib/active_record/secure_token.rb +48 -0
- data/lib/active_record/serialization.rb +8 -6
- data/lib/active_record/signed_id.rb +116 -0
- data/lib/active_record/statement_cache.rb +89 -36
- data/lib/active_record/store.rb +128 -43
- data/lib/active_record/suppressor.rb +61 -0
- data/lib/active_record/table_metadata.rb +81 -0
- data/lib/active_record/tasks/database_tasks.rb +364 -130
- data/lib/active_record/tasks/mysql_database_tasks.rb +67 -113
- data/lib/active_record/tasks/postgresql_database_tasks.rb +86 -49
- data/lib/active_record/tasks/sqlite_database_tasks.rb +44 -19
- data/lib/active_record/test_databases.rb +24 -0
- data/lib/active_record/test_fixtures.rb +287 -0
- data/lib/active_record/timestamp.rb +86 -43
- data/lib/active_record/touch_later.rb +65 -0
- data/lib/active_record/transactions.rb +182 -163
- data/lib/active_record/translation.rb +3 -1
- data/lib/active_record/type/adapter_specific_registry.rb +126 -0
- data/lib/active_record/type/date.rb +4 -45
- data/lib/active_record/type/date_time.rb +4 -49
- data/lib/active_record/type/decimal_without_scale.rb +6 -2
- data/lib/active_record/type/hash_lookup_type_map.rb +5 -4
- data/lib/active_record/type/internal/timezone.rb +17 -0
- data/lib/active_record/type/json.rb +30 -0
- data/lib/active_record/type/serialized.rb +27 -15
- data/lib/active_record/type/text.rb +2 -2
- data/lib/active_record/type/time.rb +21 -16
- data/lib/active_record/type/type_map.rb +16 -19
- data/lib/active_record/type/unsigned_integer.rb +9 -8
- data/lib/active_record/type.rb +84 -23
- data/lib/active_record/type_caster/connection.rb +33 -0
- data/lib/active_record/type_caster/map.rb +23 -0
- data/lib/active_record/type_caster.rb +9 -0
- data/lib/active_record/validations/absence.rb +25 -0
- data/lib/active_record/validations/associated.rb +12 -4
- data/lib/active_record/validations/length.rb +26 -0
- data/lib/active_record/validations/numericality.rb +35 -0
- data/lib/active_record/validations/presence.rb +14 -13
- data/lib/active_record/validations/uniqueness.rb +63 -56
- data/lib/active_record/validations.rb +39 -35
- data/lib/active_record/version.rb +3 -1
- data/lib/active_record.rb +42 -29
- data/lib/arel/alias_predication.rb +9 -0
- data/lib/arel/attributes/attribute.rb +41 -0
- data/lib/arel/collectors/bind.rb +29 -0
- data/lib/arel/collectors/composite.rb +39 -0
- data/lib/arel/collectors/plain_string.rb +20 -0
- data/lib/arel/collectors/sql_string.rb +27 -0
- data/lib/arel/collectors/substitute_binds.rb +35 -0
- data/lib/arel/crud.rb +42 -0
- data/lib/arel/delete_manager.rb +18 -0
- data/lib/arel/errors.rb +9 -0
- data/lib/arel/expressions.rb +29 -0
- data/lib/arel/factory_methods.rb +49 -0
- data/lib/arel/insert_manager.rb +49 -0
- data/lib/arel/math.rb +45 -0
- data/lib/arel/nodes/and.rb +32 -0
- data/lib/arel/nodes/ascending.rb +23 -0
- data/lib/arel/nodes/binary.rb +126 -0
- data/lib/arel/nodes/bind_param.rb +44 -0
- data/lib/arel/nodes/case.rb +55 -0
- data/lib/arel/nodes/casted.rb +62 -0
- data/lib/arel/nodes/comment.rb +29 -0
- data/lib/arel/nodes/count.rb +12 -0
- data/lib/arel/nodes/delete_statement.rb +45 -0
- data/lib/arel/nodes/descending.rb +23 -0
- data/lib/arel/nodes/equality.rb +15 -0
- data/lib/arel/nodes/extract.rb +24 -0
- data/lib/arel/nodes/false.rb +16 -0
- data/lib/arel/nodes/full_outer_join.rb +8 -0
- data/lib/arel/nodes/function.rb +44 -0
- data/lib/arel/nodes/grouping.rb +11 -0
- data/lib/arel/nodes/homogeneous_in.rb +76 -0
- data/lib/arel/nodes/in.rb +15 -0
- data/lib/arel/nodes/infix_operation.rb +92 -0
- data/lib/arel/nodes/inner_join.rb +8 -0
- data/lib/arel/nodes/insert_statement.rb +37 -0
- data/lib/arel/nodes/join_source.rb +20 -0
- data/lib/arel/nodes/matches.rb +18 -0
- data/lib/arel/nodes/named_function.rb +23 -0
- data/lib/arel/nodes/node.rb +51 -0
- data/lib/arel/nodes/node_expression.rb +13 -0
- data/lib/arel/nodes/ordering.rb +27 -0
- data/lib/arel/nodes/outer_join.rb +8 -0
- data/lib/arel/nodes/over.rb +15 -0
- data/lib/arel/nodes/regexp.rb +16 -0
- data/lib/arel/nodes/right_outer_join.rb +8 -0
- data/lib/arel/nodes/select_core.rb +67 -0
- data/lib/arel/nodes/select_statement.rb +41 -0
- data/lib/arel/nodes/sql_literal.rb +19 -0
- data/lib/arel/nodes/string_join.rb +11 -0
- data/lib/arel/nodes/table_alias.rb +31 -0
- data/lib/arel/nodes/terminal.rb +16 -0
- data/lib/arel/nodes/true.rb +16 -0
- data/lib/arel/nodes/unary.rb +44 -0
- data/lib/arel/nodes/unary_operation.rb +20 -0
- data/lib/arel/nodes/unqualified_column.rb +22 -0
- data/lib/arel/nodes/update_statement.rb +41 -0
- data/lib/arel/nodes/values_list.rb +9 -0
- data/lib/arel/nodes/window.rb +126 -0
- data/lib/arel/nodes/with.rb +11 -0
- data/lib/arel/nodes.rb +70 -0
- data/lib/arel/order_predications.rb +13 -0
- data/lib/arel/predications.rb +250 -0
- data/lib/arel/select_manager.rb +270 -0
- data/lib/arel/table.rb +118 -0
- data/lib/arel/tree_manager.rb +72 -0
- data/lib/arel/update_manager.rb +34 -0
- data/lib/arel/visitors/dot.rb +308 -0
- data/lib/arel/visitors/mysql.rb +93 -0
- data/lib/arel/visitors/postgresql.rb +120 -0
- data/lib/arel/visitors/sqlite.rb +38 -0
- data/lib/arel/visitors/to_sql.rb +899 -0
- data/lib/arel/visitors/visitor.rb +45 -0
- data/lib/arel/visitors.rb +13 -0
- data/lib/arel/window_predications.rb +9 -0
- data/lib/arel.rb +54 -0
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +26 -0
- data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
- data/lib/rails/generators/active_record/migration/migration_generator.rb +43 -37
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +26 -0
- data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +13 -4
- data/lib/rails/generators/active_record/migration.rb +35 -1
- data/lib/rails/generators/active_record/model/model_generator.rb +55 -22
- data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +22 -0
- data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
- data/lib/rails/generators/active_record.rb +7 -5
- metadata +172 -65
- data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
- data/lib/active_record/associations/preloader/collection_association.rb +0 -24
- data/lib/active_record/associations/preloader/has_many.rb +0 -17
- data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
- data/lib/active_record/associations/preloader/has_one.rb +0 -23
- data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
- data/lib/active_record/associations/preloader/singular_association.rb +0 -21
- data/lib/active_record/attribute.rb +0 -163
- data/lib/active_record/attribute_decorators.rb +0 -66
- data/lib/active_record/attribute_set/builder.rb +0 -106
- data/lib/active_record/attribute_set.rb +0 -81
- data/lib/active_record/connection_adapters/connection_specification.rb +0 -275
- data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -491
- data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
- data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
- data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +0 -11
- data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -35
- data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
- data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
- data/lib/active_record/serializers/xml_serializer.rb +0 -193
- data/lib/active_record/type/big_integer.rb +0 -13
- data/lib/active_record/type/binary.rb +0 -50
- data/lib/active_record/type/boolean.rb +0 -31
- data/lib/active_record/type/decimal.rb +0 -64
- data/lib/active_record/type/decorator.rb +0 -14
- data/lib/active_record/type/float.rb +0 -19
- data/lib/active_record/type/integer.rb +0 -59
- data/lib/active_record/type/mutable.rb +0 -16
- data/lib/active_record/type/numeric.rb +0 -36
- data/lib/active_record/type/string.rb +0 -40
- data/lib/active_record/type/time_value.rb +0 -38
- data/lib/active_record/type/value.rb +0 -110
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +0 -19
- data/lib/rails/generators/active_record/model/templates/model.rb +0 -10
@@ -1,215 +1,112 @@
|
|
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,
|
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
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
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
|
-
|
56
|
-
|
57
|
-
|
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
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
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
|
94
|
-
|
29
|
+
def write_query?(sql) # :nodoc:
|
30
|
+
!READ_QUERY.match?(sql)
|
95
31
|
end
|
96
32
|
|
97
|
-
#
|
98
|
-
|
99
|
-
#
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
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
|
33
|
+
# Executes an SQL statement, returning a PG::Result object on success
|
34
|
+
# or raising a PG::Error exception otherwise.
|
35
|
+
# Note: the PG::Result object is manually memory managed; if you don't
|
36
|
+
# need it specifically, you may want consider the <tt>exec_query</tt> wrapper.
|
37
|
+
def execute(sql, name = nil)
|
38
|
+
if preventing_writes? && write_query?(sql)
|
39
|
+
raise ActiveRecord::ReadOnlyError, "Write query attempted while in readonly mode: #{sql}"
|
141
40
|
end
|
142
|
-
end
|
143
41
|
|
144
|
-
|
145
|
-
|
146
|
-
log(sql, name) do
|
147
|
-
result_as_array @connection.async_exec(sql)
|
148
|
-
end
|
149
|
-
end
|
42
|
+
materialize_transactions
|
43
|
+
mark_transaction_written_if_write(sql)
|
150
44
|
|
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
45
|
log(sql, name) do
|
155
|
-
|
46
|
+
ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
|
47
|
+
@connection.async_exec(sql)
|
48
|
+
end
|
156
49
|
end
|
157
50
|
end
|
158
51
|
|
159
|
-
def exec_query(sql, name =
|
160
|
-
execute_and_clear(sql, name, binds) do |result|
|
52
|
+
def exec_query(sql, name = "SQL", binds = [], prepare: false)
|
53
|
+
execute_and_clear(sql, name, binds, prepare: prepare) do |result|
|
161
54
|
types = {}
|
162
55
|
fields = result.fields
|
163
56
|
fields.each_with_index do |fname, i|
|
164
57
|
ftype = result.ftype i
|
165
58
|
fmod = result.fmod i
|
166
|
-
|
59
|
+
case type = get_oid_type(ftype, fmod, fname)
|
60
|
+
when Type::Integer, Type::Float, OID::Decimal, Type::String, Type::DateTime, Type::Boolean
|
61
|
+
# skip if a column has already been type casted by pg decoders
|
62
|
+
else types[fname] = type
|
63
|
+
end
|
167
64
|
end
|
168
|
-
|
65
|
+
build_result(columns: fields, rows: result.values, column_types: types)
|
169
66
|
end
|
170
67
|
end
|
171
68
|
|
172
|
-
def exec_delete(sql, name =
|
173
|
-
execute_and_clear(sql, name, binds) {|result| result.cmd_tuples }
|
69
|
+
def exec_delete(sql, name = nil, binds = [])
|
70
|
+
execute_and_clear(sql, name, binds) { |result| result.cmd_tuples }
|
174
71
|
end
|
175
72
|
alias :exec_update :exec_delete
|
176
73
|
|
177
|
-
def sql_for_insert(sql, pk,
|
178
|
-
|
74
|
+
def sql_for_insert(sql, pk, binds) # :nodoc:
|
75
|
+
if pk.nil?
|
179
76
|
# Extract the table from the insert sql. Yuck.
|
180
77
|
table_ref = extract_table_ref_from_insert_sql(sql)
|
181
78
|
pk = primary_key(table_ref) if table_ref
|
182
79
|
end
|
183
80
|
|
184
|
-
if pk
|
81
|
+
if pk = suppress_composite_primary_key(pk)
|
185
82
|
sql = "#{sql} RETURNING #{quote_column_name(pk)}"
|
186
83
|
end
|
187
84
|
|
188
|
-
|
85
|
+
super
|
189
86
|
end
|
87
|
+
private :sql_for_insert
|
190
88
|
|
191
|
-
def exec_insert(sql, name, binds, pk = nil, sequence_name = nil)
|
192
|
-
|
193
|
-
|
89
|
+
def exec_insert(sql, name = nil, binds = [], pk = nil, sequence_name = nil)
|
90
|
+
if use_insert_returning? || pk == false
|
91
|
+
super
|
92
|
+
else
|
93
|
+
result = exec_query(sql, name, binds)
|
194
94
|
unless sequence_name
|
195
95
|
table_ref = extract_table_ref_from_insert_sql(sql)
|
196
|
-
|
197
|
-
|
96
|
+
if table_ref
|
97
|
+
pk = primary_key(table_ref) if pk.nil?
|
98
|
+
pk = suppress_composite_primary_key(pk)
|
99
|
+
sequence_name = default_sequence_name(table_ref, pk)
|
100
|
+
end
|
101
|
+
return result unless sequence_name
|
198
102
|
end
|
199
103
|
last_insert_id_result(sequence_name)
|
200
|
-
else
|
201
|
-
val
|
202
104
|
end
|
203
105
|
end
|
204
106
|
|
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
107
|
# Begins a transaction.
|
211
108
|
def begin_db_transaction
|
212
|
-
execute
|
109
|
+
execute("BEGIN", "TRANSACTION")
|
213
110
|
end
|
214
111
|
|
215
112
|
def begin_isolated_db_transaction(isolation)
|
@@ -219,13 +116,31 @@ module ActiveRecord
|
|
219
116
|
|
220
117
|
# Commits a transaction.
|
221
118
|
def commit_db_transaction
|
222
|
-
execute
|
119
|
+
execute("COMMIT", "TRANSACTION")
|
223
120
|
end
|
224
121
|
|
225
122
|
# Aborts a transaction.
|
226
123
|
def exec_rollback_db_transaction
|
227
|
-
execute
|
124
|
+
execute("ROLLBACK", "TRANSACTION")
|
228
125
|
end
|
126
|
+
|
127
|
+
private
|
128
|
+
def execute_batch(statements, name = nil)
|
129
|
+
execute(combine_multi_statements(statements))
|
130
|
+
end
|
131
|
+
|
132
|
+
def build_truncate_statements(table_names)
|
133
|
+
["TRUNCATE TABLE #{table_names.map(&method(:quote_table_name)).join(", ")}"]
|
134
|
+
end
|
135
|
+
|
136
|
+
# Returns the current ID of a table's sequence.
|
137
|
+
def last_insert_id_result(sequence_name)
|
138
|
+
exec_query("SELECT currval(#{quote(sequence_name)})", "SQL")
|
139
|
+
end
|
140
|
+
|
141
|
+
def suppress_composite_primary_key(pk)
|
142
|
+
pk unless pk.is_a?(Array)
|
143
|
+
end
|
229
144
|
end
|
230
145
|
end
|
231
146
|
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,98 +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
|
-
|
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, :limit, 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
|
29
|
-
|
30
|
-
|
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
|
34
|
+
def cast(value)
|
37
35
|
if value.is_a?(::String)
|
38
|
-
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, :
|
44
|
+
type_cast_array(value, :cast)
|
41
45
|
end
|
42
46
|
|
43
|
-
def
|
47
|
+
def serialize(value)
|
44
48
|
if value.is_a?(::Array)
|
45
|
-
|
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
|
-
|
56
|
+
def ==(other)
|
57
|
+
other.is_a?(Array) &&
|
58
|
+
subtype == other.subtype &&
|
59
|
+
delimiter == other.delimiter
|
60
|
+
end
|
52
61
|
|
53
|
-
def
|
54
|
-
|
55
|
-
|
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
|
62
|
-
|
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
|
-
|
71
|
+
def changed_in_place?(raw_old_value, new_value)
|
72
|
+
deserialize(raw_old_value) != new_value
|
73
|
+
end
|
71
74
|
|
72
|
-
def
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
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
|
-
when ::Date, ::DateTime, ::Time then subtype.type_cast_for_schema(value)
|
84
|
-
else value
|
85
86
|
end
|
86
|
-
end
|
87
|
-
|
88
|
-
# See http://www.postgresql.org/docs/9.2/static/arrays.html#ARRAYS-IO
|
89
|
-
# for a list of all cases in which strings will be quoted.
|
90
|
-
def string_requires_quoting?(string)
|
91
|
-
string.empty? ||
|
92
|
-
string == "NULL" ||
|
93
|
-
string =~ /[\{\}"\\\s]/ ||
|
94
|
-
string.include?(delimiter)
|
95
|
-
end
|
96
87
|
end
|
97
88
|
end
|
98
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
|
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
|
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
|
39
|
+
/\A[01]*\Z/.match?(value)
|
38
40
|
end
|
39
41
|
|
40
42
|
def hex?
|
41
|
-
/\A[0-9A-F]*\Z/i
|
43
|
+
/\A[0-9A-F]*\Z/i.match?(value)
|
42
44
|
end
|
43
45
|
|
44
|
-
|
45
|
-
|
46
|
-
attr_reader :value
|
46
|
+
private
|
47
|
+
attr_reader :value
|
47
48
|
end
|
48
49
|
end
|
49
50
|
end
|
@@ -1,12 +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
|
8
|
+
def deserialize(value)
|
7
9
|
return if value.nil?
|
8
10
|
return value.to_s if value.is_a?(Type::Binary::Data)
|
9
|
-
|
11
|
+
PG::Connection.unescape_bytea(super)
|
10
12
|
end
|
11
13
|
end
|
12
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
|
16
|
+
if value.prefix == 32
|
15
17
|
"\"#{value}\""
|
16
18
|
else
|
17
|
-
"\"#{value}/#{
|
19
|
+
"\"#{value}/#{value.prefix}\""
|
18
20
|
end
|
19
21
|
end
|
20
22
|
|
21
|
-
def
|
23
|
+
def serialize(value)
|
22
24
|
if IPAddr === value
|
23
|
-
"#{value}/#{value.
|
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
|
-
|
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,32 +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
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
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"))
|
12
15
|
else
|
13
16
|
super
|
14
17
|
end
|
15
18
|
end
|
16
19
|
|
17
|
-
def
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
when / BC$/
|
23
|
-
astronomical_year = format("%04d", -value[/^\d+/].to_i + 1)
|
24
|
-
super(value.sub(/ BC$/, "").sub(/^\d+/, astronomical_year))
|
25
|
-
else
|
26
|
-
super
|
27
|
-
end
|
28
|
-
else
|
29
|
-
value
|
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
|
30
25
|
end
|
31
26
|
end
|
32
27
|
end
|