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,87 +1,53 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "set"
|
4
|
+
require "active_record/connection_adapters/sql_type_metadata"
|
5
|
+
require "active_record/connection_adapters/abstract/schema_dumper"
|
6
|
+
require "active_record/connection_adapters/abstract/schema_creation"
|
7
|
+
require "active_support/concurrency/load_interlock_aware_monitor"
|
8
|
+
require "arel/collectors/bind"
|
9
|
+
require "arel/collectors/composite"
|
10
|
+
require "arel/collectors/sql_string"
|
11
|
+
require "arel/collectors/substitute_binds"
|
12
12
|
|
13
13
|
module ActiveRecord
|
14
14
|
module ConnectionAdapters # :nodoc:
|
15
|
-
extend ActiveSupport::Autoload
|
16
|
-
|
17
|
-
autoload :Column
|
18
|
-
autoload :ConnectionSpecification
|
19
|
-
|
20
|
-
autoload_at 'active_record/connection_adapters/abstract/schema_definitions' do
|
21
|
-
autoload :IndexDefinition
|
22
|
-
autoload :ColumnDefinition
|
23
|
-
autoload :ChangeColumnDefinition
|
24
|
-
autoload :TableDefinition
|
25
|
-
autoload :Table
|
26
|
-
autoload :AlterTable
|
27
|
-
autoload :TimestampDefaultDeprecation
|
28
|
-
end
|
29
|
-
|
30
|
-
autoload_at 'active_record/connection_adapters/abstract/connection_pool' do
|
31
|
-
autoload :ConnectionHandler
|
32
|
-
autoload :ConnectionManagement
|
33
|
-
end
|
34
|
-
|
35
|
-
autoload_under 'abstract' do
|
36
|
-
autoload :SchemaStatements
|
37
|
-
autoload :DatabaseStatements
|
38
|
-
autoload :DatabaseLimits
|
39
|
-
autoload :Quoting
|
40
|
-
autoload :ConnectionPool
|
41
|
-
autoload :QueryCache
|
42
|
-
autoload :Savepoints
|
43
|
-
end
|
44
|
-
|
45
|
-
autoload_at 'active_record/connection_adapters/abstract/transaction' do
|
46
|
-
autoload :TransactionManager
|
47
|
-
autoload :NullTransaction
|
48
|
-
autoload :RealTransaction
|
49
|
-
autoload :SavepointTransaction
|
50
|
-
autoload :TransactionState
|
51
|
-
end
|
52
|
-
|
53
15
|
# Active Record supports multiple database systems. AbstractAdapter and
|
54
16
|
# related classes form the abstraction layer which makes this possible.
|
55
17
|
# An AbstractAdapter represents a connection to a database, and provides an
|
56
18
|
# abstract interface for database-specific functionality such as establishing
|
57
|
-
# a connection, escaping values, building the right SQL fragments for
|
58
|
-
# and
|
19
|
+
# a connection, escaping values, building the right SQL fragments for +:offset+
|
20
|
+
# and +:limit+ options, etc.
|
59
21
|
#
|
60
22
|
# All the concrete database adapters follow the interface laid down in this class.
|
61
|
-
# ActiveRecord::Base.connection returns an AbstractAdapter object, which
|
23
|
+
# {ActiveRecord::Base.connection}[rdoc-ref:ConnectionHandling#connection] returns an AbstractAdapter object, which
|
62
24
|
# you can use.
|
63
25
|
#
|
64
26
|
# Most of the methods in the adapter are useful during migrations. Most
|
65
|
-
# notably, the instance methods provided by
|
27
|
+
# notably, the instance methods provided by SchemaStatements are very useful.
|
66
28
|
class AbstractAdapter
|
67
|
-
ADAPTER_NAME =
|
29
|
+
ADAPTER_NAME = "Abstract"
|
30
|
+
include ActiveSupport::Callbacks
|
31
|
+
define_callbacks :checkout, :checkin
|
32
|
+
|
68
33
|
include Quoting, DatabaseStatements, SchemaStatements
|
69
34
|
include DatabaseLimits
|
70
35
|
include QueryCache
|
71
|
-
include
|
72
|
-
include MonitorMixin
|
73
|
-
include ColumnDumper
|
36
|
+
include Savepoints
|
74
37
|
|
75
38
|
SIMPLE_INT = /\A\d+\z/
|
39
|
+
COMMENT_REGEX = %r{(?:\-\-.*\n)*|/\*(?:[^\*]|\*[^/])*\*/}m
|
76
40
|
|
77
|
-
|
78
|
-
|
79
|
-
attr_accessor :visitor, :pool
|
80
|
-
attr_reader :schema_cache, :owner, :logger
|
41
|
+
attr_accessor :pool
|
42
|
+
attr_reader :visitor, :owner, :logger, :lock
|
81
43
|
alias :in_use? :owner
|
82
44
|
|
45
|
+
set_callback :checkin, :after, :enable_lazy_transactions!
|
46
|
+
|
83
47
|
def self.type_cast_config_to_integer(config)
|
84
|
-
if config
|
48
|
+
if config.is_a?(Integer)
|
49
|
+
config
|
50
|
+
elsif SIMPLE_INT.match?(config)
|
85
51
|
config.to_i
|
86
52
|
else
|
87
53
|
config
|
@@ -96,83 +62,198 @@ module ActiveRecord
|
|
96
62
|
end
|
97
63
|
end
|
98
64
|
|
99
|
-
|
65
|
+
DEFAULT_READ_QUERY = [:begin, :commit, :explain, :release, :rollback, :savepoint, :select, :with] # :nodoc:
|
66
|
+
private_constant :DEFAULT_READ_QUERY
|
67
|
+
|
68
|
+
def self.build_read_query_regexp(*parts) # :nodoc:
|
69
|
+
parts += DEFAULT_READ_QUERY
|
70
|
+
parts = parts.map { |part| /#{part}/i }
|
71
|
+
/\A(?:[\(\s]|#{COMMENT_REGEX})*#{Regexp.union(*parts)}/
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.quoted_column_names # :nodoc:
|
75
|
+
@quoted_column_names ||= {}
|
76
|
+
end
|
100
77
|
|
101
|
-
def
|
78
|
+
def self.quoted_table_names # :nodoc:
|
79
|
+
@quoted_table_names ||= {}
|
80
|
+
end
|
81
|
+
|
82
|
+
def initialize(connection, logger = nil, config = {}) # :nodoc:
|
102
83
|
super()
|
103
84
|
|
104
85
|
@connection = connection
|
105
86
|
@owner = nil
|
106
87
|
@instrumenter = ActiveSupport::Notifications.instrumenter
|
107
88
|
@logger = logger
|
108
|
-
@
|
109
|
-
@
|
110
|
-
@
|
111
|
-
@
|
89
|
+
@config = config
|
90
|
+
@pool = ActiveRecord::ConnectionAdapters::NullPool.new
|
91
|
+
@idle_since = Concurrent.monotonic_time
|
92
|
+
@visitor = arel_visitor
|
93
|
+
@statements = build_statement_pool
|
94
|
+
@lock = ActiveSupport::Concurrency::LoadInterlockAwareMonitor.new
|
95
|
+
|
96
|
+
@prepared_statements = self.class.type_cast_config_to_boolean(
|
97
|
+
config.fetch(:prepared_statements, true)
|
98
|
+
)
|
99
|
+
|
100
|
+
@advisory_locks_enabled = self.class.type_cast_config_to_boolean(
|
101
|
+
config.fetch(:advisory_locks, true)
|
102
|
+
)
|
103
|
+
end
|
104
|
+
|
105
|
+
def replica?
|
106
|
+
@config[:replica] || false
|
107
|
+
end
|
108
|
+
|
109
|
+
def use_metadata_table?
|
110
|
+
@config.fetch(:use_metadata_table, true)
|
111
|
+
end
|
112
|
+
|
113
|
+
# Determines whether writes are currently being prevented.
|
114
|
+
#
|
115
|
+
# Returns true if the connection is a replica.
|
116
|
+
#
|
117
|
+
# If the application is using legacy handling, returns
|
118
|
+
# true if +connection_handler.prevent_writes+ is set.
|
119
|
+
#
|
120
|
+
# If the application is using the new connection handling
|
121
|
+
# will return true based on +current_preventing_writes+.
|
122
|
+
def preventing_writes?
|
123
|
+
return true if replica?
|
124
|
+
return ActiveRecord::Base.connection_handler.prevent_writes if ActiveRecord::Base.legacy_connection_handling
|
125
|
+
return false if connection_klass.nil?
|
126
|
+
|
127
|
+
connection_klass.current_preventing_writes
|
128
|
+
end
|
129
|
+
|
130
|
+
def migrations_paths # :nodoc:
|
131
|
+
@config[:migrations_paths] || Migrator.migrations_paths
|
132
|
+
end
|
133
|
+
|
134
|
+
def migration_context # :nodoc:
|
135
|
+
MigrationContext.new(migrations_paths, schema_migration)
|
136
|
+
end
|
137
|
+
|
138
|
+
def schema_migration # :nodoc:
|
139
|
+
@schema_migration ||= begin
|
140
|
+
conn = self
|
141
|
+
spec_name = conn.pool.pool_config.connection_specification_name
|
142
|
+
|
143
|
+
return ActiveRecord::SchemaMigration if spec_name == "ActiveRecord::Base"
|
144
|
+
|
145
|
+
schema_migration_name = "#{spec_name}::SchemaMigration"
|
146
|
+
|
147
|
+
Class.new(ActiveRecord::SchemaMigration) do
|
148
|
+
define_singleton_method(:name) { schema_migration_name }
|
149
|
+
define_singleton_method(:to_s) { schema_migration_name }
|
150
|
+
|
151
|
+
self.connection_specification_name = spec_name
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def prepared_statements?
|
157
|
+
@prepared_statements && !prepared_statements_disabled_cache.include?(object_id)
|
158
|
+
end
|
159
|
+
alias :prepared_statements :prepared_statements?
|
160
|
+
|
161
|
+
def prepared_statements_disabled_cache # :nodoc:
|
162
|
+
Thread.current[:ar_prepared_statements_disabled_cache] ||= Set.new
|
112
163
|
end
|
113
164
|
|
114
165
|
class Version
|
115
166
|
include Comparable
|
116
167
|
|
117
|
-
|
118
|
-
|
168
|
+
attr_reader :full_version_string
|
169
|
+
|
170
|
+
def initialize(version_string, full_version_string = nil)
|
171
|
+
@version = version_string.split(".").map(&:to_i)
|
172
|
+
@full_version_string = full_version_string
|
119
173
|
end
|
120
174
|
|
121
175
|
def <=>(version_string)
|
122
|
-
@version <=> version_string.split(
|
176
|
+
@version <=> version_string.split(".").map(&:to_i)
|
123
177
|
end
|
124
|
-
end
|
125
178
|
|
126
|
-
|
127
|
-
|
128
|
-
super(bvs.map { |bv| conn.quote(*bv.reverse) })
|
179
|
+
def to_s
|
180
|
+
@version.join(".")
|
129
181
|
end
|
130
182
|
end
|
131
183
|
|
132
|
-
|
133
|
-
|
134
|
-
super(bvs)
|
135
|
-
end
|
184
|
+
def valid_type?(type) # :nodoc:
|
185
|
+
!native_database_types[type].nil?
|
136
186
|
end
|
137
187
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
188
|
+
# this method must only be called while holding connection pool's mutex
|
189
|
+
def lease
|
190
|
+
if in_use?
|
191
|
+
msg = +"Cannot lease connection, "
|
192
|
+
if @owner == Thread.current
|
193
|
+
msg << "it is already leased by the current thread."
|
194
|
+
else
|
195
|
+
msg << "it is already in use by a different thread: #{@owner}. " \
|
196
|
+
"Current thread: #{Thread.current}."
|
197
|
+
end
|
198
|
+
raise ActiveRecordError, msg
|
143
199
|
end
|
144
|
-
end
|
145
200
|
|
146
|
-
|
147
|
-
true
|
201
|
+
@owner = Thread.current
|
148
202
|
end
|
149
203
|
|
150
|
-
def
|
151
|
-
|
204
|
+
def connection_klass # :nodoc:
|
205
|
+
@pool.connection_klass
|
152
206
|
end
|
153
207
|
|
154
|
-
def
|
155
|
-
|
156
|
-
unless in_use?
|
157
|
-
@owner = Thread.current
|
158
|
-
end
|
159
|
-
end
|
208
|
+
def schema_cache
|
209
|
+
@pool.get_schema_cache(self)
|
160
210
|
end
|
161
211
|
|
162
212
|
def schema_cache=(cache)
|
163
213
|
cache.connection = self
|
164
|
-
@
|
214
|
+
@pool.set_schema_cache(cache)
|
165
215
|
end
|
166
216
|
|
217
|
+
# this method must only be called while holding connection pool's mutex
|
167
218
|
def expire
|
168
|
-
|
219
|
+
if in_use?
|
220
|
+
if @owner != Thread.current
|
221
|
+
raise ActiveRecordError, "Cannot expire connection, " \
|
222
|
+
"it is owned by a different thread: #{@owner}. " \
|
223
|
+
"Current thread: #{Thread.current}."
|
224
|
+
end
|
225
|
+
|
226
|
+
@idle_since = Concurrent.monotonic_time
|
227
|
+
@owner = nil
|
228
|
+
else
|
229
|
+
raise ActiveRecordError, "Cannot expire connection, it is not currently leased."
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
# this method must only be called while holding connection pool's mutex (and a desire for segfaults)
|
234
|
+
def steal! # :nodoc:
|
235
|
+
if in_use?
|
236
|
+
if @owner != Thread.current
|
237
|
+
pool.send :remove_connection_from_thread_cache, self, @owner
|
238
|
+
|
239
|
+
@owner = Thread.current
|
240
|
+
end
|
241
|
+
else
|
242
|
+
raise ActiveRecordError, "Cannot steal connection, it is not currently leased."
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
# Seconds since this connection was returned to the pool
|
247
|
+
def seconds_idle # :nodoc:
|
248
|
+
return 0 if in_use?
|
249
|
+
Concurrent.monotonic_time - @idle_since
|
169
250
|
end
|
170
251
|
|
171
252
|
def unprepared_statement
|
172
|
-
|
253
|
+
cache = prepared_statements_disabled_cache.add?(object_id) if @prepared_statements
|
173
254
|
yield
|
174
255
|
ensure
|
175
|
-
|
256
|
+
cache&.delete(object_id)
|
176
257
|
end
|
177
258
|
|
178
259
|
# Returns the human-readable name of the adapter. Use mixed case - one
|
@@ -181,15 +262,9 @@ module ActiveRecord
|
|
181
262
|
self.class::ADAPTER_NAME
|
182
263
|
end
|
183
264
|
|
184
|
-
# Does this adapter
|
185
|
-
def
|
186
|
-
|
187
|
-
end
|
188
|
-
|
189
|
-
# Can this adapter determine the primary key for tables not attached
|
190
|
-
# to an Active Record class, such as join tables?
|
191
|
-
def supports_primary_key?
|
192
|
-
false
|
265
|
+
# Does the database for this adapter exist?
|
266
|
+
def self.database_exists?(config)
|
267
|
+
raise NotImplementedError
|
193
268
|
end
|
194
269
|
|
195
270
|
# Does this adapter support DDL rollbacks in transactions? That is, would
|
@@ -207,6 +282,11 @@ module ActiveRecord
|
|
207
282
|
false
|
208
283
|
end
|
209
284
|
|
285
|
+
# Does this adapter support application-enforced advisory locking?
|
286
|
+
def supports_advisory_locks?
|
287
|
+
false
|
288
|
+
end
|
289
|
+
|
210
290
|
# Should primary key values be selected from their corresponding
|
211
291
|
# sequence before the insert statement? If true, next_sequence_value
|
212
292
|
# is called before each insert to set the record's primary key.
|
@@ -214,6 +294,10 @@ module ActiveRecord
|
|
214
294
|
false
|
215
295
|
end
|
216
296
|
|
297
|
+
def supports_partitioned_indexes?
|
298
|
+
false
|
299
|
+
end
|
300
|
+
|
217
301
|
# Does this adapter support index sort order?
|
218
302
|
def supports_index_sort_order?
|
219
303
|
false
|
@@ -224,6 +308,11 @@ module ActiveRecord
|
|
224
308
|
false
|
225
309
|
end
|
226
310
|
|
311
|
+
# Does this adapter support expression indices?
|
312
|
+
def supports_expression_index?
|
313
|
+
false
|
314
|
+
end
|
315
|
+
|
227
316
|
# Does this adapter support explain?
|
228
317
|
def supports_explain?
|
229
318
|
false
|
@@ -250,11 +339,85 @@ module ActiveRecord
|
|
250
339
|
false
|
251
340
|
end
|
252
341
|
|
342
|
+
# Does this adapter support creating invalid constraints?
|
343
|
+
def supports_validate_constraints?
|
344
|
+
false
|
345
|
+
end
|
346
|
+
|
347
|
+
# Does this adapter support creating check constraints?
|
348
|
+
def supports_check_constraints?
|
349
|
+
false
|
350
|
+
end
|
351
|
+
|
253
352
|
# Does this adapter support views?
|
254
353
|
def supports_views?
|
255
354
|
false
|
256
355
|
end
|
257
356
|
|
357
|
+
# Does this adapter support materialized views?
|
358
|
+
def supports_materialized_views?
|
359
|
+
false
|
360
|
+
end
|
361
|
+
|
362
|
+
# Does this adapter support datetime with precision?
|
363
|
+
def supports_datetime_with_precision?
|
364
|
+
false
|
365
|
+
end
|
366
|
+
|
367
|
+
# Does this adapter support json data type?
|
368
|
+
def supports_json?
|
369
|
+
false
|
370
|
+
end
|
371
|
+
|
372
|
+
# Does this adapter support metadata comments on database objects (tables, columns, indexes)?
|
373
|
+
def supports_comments?
|
374
|
+
false
|
375
|
+
end
|
376
|
+
|
377
|
+
# Can comments for tables, columns, and indexes be specified in create/alter table statements?
|
378
|
+
def supports_comments_in_create?
|
379
|
+
false
|
380
|
+
end
|
381
|
+
|
382
|
+
# Does this adapter support virtual columns?
|
383
|
+
def supports_virtual_columns?
|
384
|
+
false
|
385
|
+
end
|
386
|
+
|
387
|
+
# Does this adapter support foreign/external tables?
|
388
|
+
def supports_foreign_tables?
|
389
|
+
false
|
390
|
+
end
|
391
|
+
|
392
|
+
# Does this adapter support optimizer hints?
|
393
|
+
def supports_optimizer_hints?
|
394
|
+
false
|
395
|
+
end
|
396
|
+
|
397
|
+
def supports_common_table_expressions?
|
398
|
+
false
|
399
|
+
end
|
400
|
+
|
401
|
+
def supports_lazy_transactions?
|
402
|
+
false
|
403
|
+
end
|
404
|
+
|
405
|
+
def supports_insert_returning?
|
406
|
+
false
|
407
|
+
end
|
408
|
+
|
409
|
+
def supports_insert_on_duplicate_skip?
|
410
|
+
false
|
411
|
+
end
|
412
|
+
|
413
|
+
def supports_insert_on_duplicate_update?
|
414
|
+
false
|
415
|
+
end
|
416
|
+
|
417
|
+
def supports_insert_conflict_target?
|
418
|
+
false
|
419
|
+
end
|
420
|
+
|
258
421
|
# This is meant to be implemented by the adapters that support extensions
|
259
422
|
def disable_extension(name)
|
260
423
|
end
|
@@ -263,6 +426,24 @@ module ActiveRecord
|
|
263
426
|
def enable_extension(name)
|
264
427
|
end
|
265
428
|
|
429
|
+
def advisory_locks_enabled? # :nodoc:
|
430
|
+
supports_advisory_locks? && @advisory_locks_enabled
|
431
|
+
end
|
432
|
+
|
433
|
+
# This is meant to be implemented by the adapters that support advisory
|
434
|
+
# locks
|
435
|
+
#
|
436
|
+
# Return true if we got the lock, otherwise false
|
437
|
+
def get_advisory_lock(lock_id) # :nodoc:
|
438
|
+
end
|
439
|
+
|
440
|
+
# This is meant to be implemented by the adapters that support advisory
|
441
|
+
# locks.
|
442
|
+
#
|
443
|
+
# Return true if we released the lock, otherwise false
|
444
|
+
def release_advisory_lock(lock_id) # :nodoc:
|
445
|
+
end
|
446
|
+
|
266
447
|
# A list of extensions, to be filled in by adapters that support them.
|
267
448
|
def extensions
|
268
449
|
[]
|
@@ -273,14 +454,6 @@ module ActiveRecord
|
|
273
454
|
{}
|
274
455
|
end
|
275
456
|
|
276
|
-
# QUOTING ==================================================
|
277
|
-
|
278
|
-
# Returns a bind substitution value given a bind +column+
|
279
|
-
# NOTE: The column param is currently being used by the sqlserver-adapter
|
280
|
-
def substitute_at(column, _unused = 0)
|
281
|
-
Arel::Nodes::BindParam.new
|
282
|
-
end
|
283
|
-
|
284
457
|
# REFERENTIAL INTEGRITY ====================================
|
285
458
|
|
286
459
|
# Override to turn off referential integrity while executing <tt>&block</tt>.
|
@@ -311,6 +484,22 @@ module ActiveRecord
|
|
311
484
|
reset_transaction
|
312
485
|
end
|
313
486
|
|
487
|
+
# Immediately forget this connection ever existed. Unlike disconnect!,
|
488
|
+
# this will not communicate with the server.
|
489
|
+
#
|
490
|
+
# After calling this method, the behavior of all other methods becomes
|
491
|
+
# undefined. This is called internally just before a forked process gets
|
492
|
+
# rid of a connection that belonged to its parent.
|
493
|
+
def discard!
|
494
|
+
# This should be overridden by concrete adapters.
|
495
|
+
#
|
496
|
+
# Prevent @connection's finalizer from touching the socket, or
|
497
|
+
# otherwise communicating with its server, when it is collected.
|
498
|
+
if schema_cache.connection == self
|
499
|
+
schema_cache.connection = nil
|
500
|
+
end
|
501
|
+
end
|
502
|
+
|
314
503
|
# Reset the state of this connection, directing the DBMS to clear
|
315
504
|
# transactions and other connection-related server-side state. Usually a
|
316
505
|
# database-dependent operation.
|
@@ -321,11 +510,15 @@ module ActiveRecord
|
|
321
510
|
# this should be overridden by concrete adapters
|
322
511
|
end
|
323
512
|
|
324
|
-
|
325
|
-
|
326
|
-
|
513
|
+
# Removes the connection from the pool and disconnect it.
|
514
|
+
def throw_away!
|
515
|
+
pool.remove self
|
516
|
+
disconnect!
|
517
|
+
end
|
518
|
+
|
519
|
+
# Clear any caching the database adapter may be doing.
|
327
520
|
def clear_cache!
|
328
|
-
|
521
|
+
@lock.synchronize { @statements.clear } if @statements
|
329
522
|
end
|
330
523
|
|
331
524
|
# Returns true if its required to reload the connection between requests for development mode.
|
@@ -334,172 +527,232 @@ module ActiveRecord
|
|
334
527
|
end
|
335
528
|
|
336
529
|
# Checks whether the connection to the database is still active (i.e. not stale).
|
337
|
-
# This is done under the hood by calling
|
530
|
+
# This is done under the hood by calling #active?. If the connection
|
338
531
|
# is no longer active, then this method will reconnect to the database.
|
339
|
-
def verify!
|
532
|
+
def verify!
|
340
533
|
reconnect! unless active?
|
341
534
|
end
|
342
535
|
|
343
536
|
# Provides access to the underlying database driver for this adapter. For
|
344
|
-
# example, this method returns a
|
345
|
-
# and a
|
537
|
+
# example, this method returns a Mysql2::Client object in case of Mysql2Adapter,
|
538
|
+
# and a PG::Connection object in case of PostgreSQLAdapter.
|
346
539
|
#
|
347
540
|
# This is useful for when you need to call a proprietary method such as
|
348
541
|
# PostgreSQL's lo_* methods.
|
349
542
|
def raw_connection
|
543
|
+
disable_lazy_transactions!
|
350
544
|
@connection
|
351
545
|
end
|
352
546
|
|
353
|
-
def
|
547
|
+
def default_uniqueness_comparison(attribute, value) # :nodoc:
|
548
|
+
attribute.eq(value)
|
354
549
|
end
|
355
550
|
|
356
|
-
def
|
551
|
+
def case_sensitive_comparison(attribute, value) # :nodoc:
|
552
|
+
attribute.eq(value)
|
357
553
|
end
|
358
554
|
|
359
|
-
def
|
360
|
-
|
361
|
-
end
|
362
|
-
|
363
|
-
def case_sensitive_comparison(table, attribute, column, value)
|
364
|
-
table_attr = table[attribute]
|
365
|
-
value = case_sensitive_modifier(value, table_attr) unless value.nil?
|
366
|
-
table_attr.eq(value)
|
367
|
-
end
|
555
|
+
def case_insensitive_comparison(attribute, value) # :nodoc:
|
556
|
+
column = column_for_attribute(attribute)
|
368
557
|
|
369
|
-
|
370
|
-
|
558
|
+
if can_perform_case_insensitive_comparison_for?(column)
|
559
|
+
attribute.lower.eq(attribute.relation.lower(value))
|
560
|
+
else
|
561
|
+
attribute.eq(value)
|
562
|
+
end
|
371
563
|
end
|
372
564
|
|
373
|
-
def
|
374
|
-
|
565
|
+
def can_perform_case_insensitive_comparison_for?(column)
|
566
|
+
true
|
375
567
|
end
|
568
|
+
private :can_perform_case_insensitive_comparison_for?
|
376
569
|
|
377
570
|
# Check the connection back in to the connection pool
|
378
571
|
def close
|
379
572
|
pool.checkin self
|
380
573
|
end
|
381
574
|
|
382
|
-
def
|
383
|
-
|
384
|
-
initialize_type_map(mapping)
|
385
|
-
end
|
575
|
+
def default_index_type?(index) # :nodoc:
|
576
|
+
index.using.nil?
|
386
577
|
end
|
387
578
|
|
388
|
-
|
389
|
-
|
579
|
+
# Called by ActiveRecord::InsertAll,
|
580
|
+
# Passed an instance of ActiveRecord::InsertAll::Builder,
|
581
|
+
# This method implements standard bulk inserts for all databases, but
|
582
|
+
# should be overridden by adapters to implement common features with
|
583
|
+
# non-standard syntax like handling duplicates or returning values.
|
584
|
+
def build_insert_sql(insert) # :nodoc:
|
585
|
+
if insert.skip_duplicates? || insert.update_duplicates?
|
586
|
+
raise NotImplementedError, "#{self.class} should define `build_insert_sql` to implement adapter-specific logic for handling duplicates during INSERT"
|
587
|
+
end
|
588
|
+
|
589
|
+
"INSERT #{insert.into} #{insert.values_list}"
|
390
590
|
end
|
391
591
|
|
392
|
-
def
|
393
|
-
type_map.lookup(sql_type)
|
592
|
+
def get_database_version # :nodoc:
|
394
593
|
end
|
395
594
|
|
396
|
-
def
|
397
|
-
|
595
|
+
def database_version # :nodoc:
|
596
|
+
schema_cache.database_version
|
398
597
|
end
|
399
598
|
|
400
|
-
|
599
|
+
def check_version # :nodoc:
|
600
|
+
end
|
401
601
|
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
register_class_with_limit m, %r(time)i, Type::Time
|
409
|
-
register_class_with_limit m, %r(datetime)i, Type::DateTime
|
410
|
-
register_class_with_limit m, %r(float)i, Type::Float
|
411
|
-
register_class_with_limit m, %r(int)i, Type::Integer
|
602
|
+
private
|
603
|
+
def type_map
|
604
|
+
@type_map ||= Type::TypeMap.new.tap do |mapping|
|
605
|
+
initialize_type_map(mapping)
|
606
|
+
end
|
607
|
+
end
|
412
608
|
|
413
|
-
m
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
609
|
+
def initialize_type_map(m = type_map)
|
610
|
+
register_class_with_limit m, %r(boolean)i, Type::Boolean
|
611
|
+
register_class_with_limit m, %r(char)i, Type::String
|
612
|
+
register_class_with_limit m, %r(binary)i, Type::Binary
|
613
|
+
register_class_with_limit m, %r(text)i, Type::Text
|
614
|
+
register_class_with_precision m, %r(date)i, Type::Date
|
615
|
+
register_class_with_precision m, %r(time)i, Type::Time
|
616
|
+
register_class_with_precision m, %r(datetime)i, Type::DateTime
|
617
|
+
register_class_with_limit m, %r(float)i, Type::Float
|
618
|
+
register_class_with_limit m, %r(int)i, Type::Integer
|
619
|
+
|
620
|
+
m.alias_type %r(blob)i, "binary"
|
621
|
+
m.alias_type %r(clob)i, "text"
|
622
|
+
m.alias_type %r(timestamp)i, "datetime"
|
623
|
+
m.alias_type %r(numeric)i, "decimal"
|
624
|
+
m.alias_type %r(number)i, "decimal"
|
625
|
+
m.alias_type %r(double)i, "float"
|
626
|
+
|
627
|
+
m.register_type %r(^json)i, Type::Json.new
|
628
|
+
|
629
|
+
m.register_type(%r(decimal)i) do |sql_type|
|
630
|
+
scale = extract_scale(sql_type)
|
631
|
+
precision = extract_precision(sql_type)
|
632
|
+
|
633
|
+
if scale == 0
|
634
|
+
# FIXME: Remove this class as well
|
635
|
+
Type::DecimalWithoutScale.new(precision: precision)
|
636
|
+
else
|
637
|
+
Type::Decimal.new(precision: precision, scale: scale)
|
638
|
+
end
|
639
|
+
end
|
640
|
+
end
|
419
641
|
|
420
|
-
|
421
|
-
|
422
|
-
|
642
|
+
def reload_type_map
|
643
|
+
type_map.clear
|
644
|
+
initialize_type_map
|
645
|
+
end
|
423
646
|
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
Type::Decimal.new(precision: precision, scale: scale)
|
647
|
+
def register_class_with_limit(mapping, key, klass)
|
648
|
+
mapping.register_type(key) do |*args|
|
649
|
+
limit = extract_limit(args.last)
|
650
|
+
klass.new(limit: limit)
|
429
651
|
end
|
430
652
|
end
|
431
|
-
end
|
432
|
-
|
433
|
-
def reload_type_map # :nodoc:
|
434
|
-
type_map.clear
|
435
|
-
initialize_type_map(type_map)
|
436
|
-
end
|
437
653
|
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
654
|
+
def register_class_with_precision(mapping, key, klass)
|
655
|
+
mapping.register_type(key) do |*args|
|
656
|
+
precision = extract_precision(args.last)
|
657
|
+
klass.new(precision: precision)
|
658
|
+
end
|
442
659
|
end
|
443
|
-
end
|
444
660
|
|
445
|
-
|
446
|
-
|
661
|
+
def extract_scale(sql_type)
|
662
|
+
case sql_type
|
447
663
|
when /\((\d+)\)/ then 0
|
448
664
|
when /\((\d+)(,(\d+))\)/ then $3.to_i
|
665
|
+
end
|
449
666
|
end
|
450
|
-
end
|
451
667
|
|
452
|
-
|
453
|
-
|
454
|
-
|
668
|
+
def extract_precision(sql_type)
|
669
|
+
$1.to_i if sql_type =~ /\((\d+)(,\d+)?\)/
|
670
|
+
end
|
455
671
|
|
456
|
-
|
457
|
-
|
458
|
-
when /^bigint/i
|
459
|
-
8
|
460
|
-
when /\((.*)\)/
|
461
|
-
$1.to_i
|
672
|
+
def extract_limit(sql_type)
|
673
|
+
$1.to_i if sql_type =~ /\((.*)\)/
|
462
674
|
end
|
463
|
-
end
|
464
675
|
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
676
|
+
def translate_exception_class(e, sql, binds)
|
677
|
+
message = "#{e.class.name}: #{e.message}"
|
678
|
+
|
679
|
+
exception = translate_exception(
|
680
|
+
e, message: message, sql: sql, binds: binds
|
681
|
+
)
|
682
|
+
exception.set_backtrace e.backtrace
|
683
|
+
exception
|
470
684
|
end
|
471
685
|
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
686
|
+
def log(sql, name = "SQL", binds = [], type_casted_binds = [], statement_name = nil) # :doc:
|
687
|
+
@instrumenter.instrument(
|
688
|
+
"sql.active_record",
|
689
|
+
sql: sql,
|
690
|
+
name: name,
|
691
|
+
binds: binds,
|
692
|
+
type_casted_binds: type_casted_binds,
|
693
|
+
statement_name: statement_name,
|
694
|
+
connection: self) do
|
695
|
+
@lock.synchronize do
|
696
|
+
yield
|
697
|
+
end
|
698
|
+
rescue => e
|
699
|
+
raise translate_exception_class(e, sql, binds)
|
700
|
+
end
|
701
|
+
end
|
476
702
|
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
raise translate_exception_class(e, sql)
|
487
|
-
end
|
703
|
+
def translate_exception(exception, message:, sql:, binds:)
|
704
|
+
# override in derived class
|
705
|
+
case exception
|
706
|
+
when RuntimeError
|
707
|
+
exception
|
708
|
+
else
|
709
|
+
ActiveRecord::StatementInvalid.new(message, sql: sql, binds: binds)
|
710
|
+
end
|
711
|
+
end
|
488
712
|
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
end
|
713
|
+
def without_prepared_statement?(binds)
|
714
|
+
!prepared_statements || binds.empty?
|
715
|
+
end
|
493
716
|
|
494
|
-
|
495
|
-
|
496
|
-
|
717
|
+
def column_for(table_name, column_name)
|
718
|
+
column_name = column_name.to_s
|
719
|
+
columns(table_name).detect { |c| c.name == column_name } ||
|
720
|
+
raise(ActiveRecordError, "No such column: #{table_name}.#{column_name}")
|
721
|
+
end
|
497
722
|
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
723
|
+
def column_for_attribute(attribute)
|
724
|
+
table_name = attribute.relation.name
|
725
|
+
schema_cache.columns_hash(table_name)[attribute.name.to_s]
|
726
|
+
end
|
727
|
+
|
728
|
+
def collector
|
729
|
+
if prepared_statements
|
730
|
+
Arel::Collectors::Composite.new(
|
731
|
+
Arel::Collectors::SQLString.new,
|
732
|
+
Arel::Collectors::Bind.new,
|
733
|
+
)
|
734
|
+
else
|
735
|
+
Arel::Collectors::SubstituteBinds.new(
|
736
|
+
self,
|
737
|
+
Arel::Collectors::SQLString.new,
|
738
|
+
)
|
739
|
+
end
|
740
|
+
end
|
741
|
+
|
742
|
+
def arel_visitor
|
743
|
+
Arel::Visitors::ToSql.new(self)
|
744
|
+
end
|
745
|
+
|
746
|
+
def build_statement_pool
|
747
|
+
end
|
748
|
+
|
749
|
+
# Builds the result object.
|
750
|
+
#
|
751
|
+
# This is an internal hook to make possible connection adapters to build
|
752
|
+
# custom result objects with connection-specific data.
|
753
|
+
def build_result(columns:, rows:, column_types: {})
|
754
|
+
ActiveRecord::Result.new(columns, rows, column_types)
|
755
|
+
end
|
503
756
|
end
|
504
757
|
end
|
505
758
|
end
|