activerecord 4.2.0 → 6.1.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/CHANGELOG.md +1221 -796
- 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 +267 -249
- data/lib/active_record/association_relation.rb +45 -7
- data/lib/active_record/associations/alias_tracker.rb +40 -43
- data/lib/active_record/associations/association.rb +172 -67
- data/lib/active_record/associations/association_scope.rb +105 -129
- data/lib/active_record/associations/belongs_to_association.rb +85 -59
- 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 -33
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +57 -70
- 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 +168 -279
- data/lib/active_record/associations/collection_proxy.rb +263 -155
- data/lib/active_record/associations/foreign_association.rb +33 -0
- data/lib/active_record/associations/has_many_association.rb +57 -84
- data/lib/active_record/associations/has_many_through_association.rb +70 -82
- data/lib/active_record/associations/has_one_association.rb +74 -47
- data/lib/active_record/associations/has_one_through_association.rb +20 -11
- data/lib/active_record/associations/join_dependency/join_association.rb +54 -73
- 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 +175 -164
- data/lib/active_record/associations/preloader/association.rb +107 -112
- data/lib/active_record/associations/preloader/through_association.rb +85 -65
- data/lib/active_record/associations/preloader.rb +99 -96
- data/lib/active_record/associations/singular_association.rb +18 -45
- data/lib/active_record/associations/through_association.rb +49 -24
- data/lib/active_record/associations.rb +1845 -1597
- data/lib/active_record/attribute_assignment.rb +59 -185
- data/lib/active_record/attribute_methods/before_type_cast.rb +20 -7
- data/lib/active_record/attribute_methods/dirty.rb +168 -138
- 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 +59 -36
- data/lib/active_record/attribute_methods/write.rb +25 -56
- data/lib/active_record/attribute_methods.rb +153 -162
- data/lib/active_record/attributes.rb +234 -70
- data/lib/active_record/autosave_association.rb +157 -69
- data/lib/active_record/base.rb +49 -50
- 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 +46 -13
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +887 -317
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +17 -41
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +301 -113
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +78 -24
- data/lib/active_record/connection_adapters/abstract/quoting.rb +187 -60
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +9 -7
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +157 -93
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +485 -253
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +79 -36
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +909 -263
- data/lib/active_record/connection_adapters/abstract/transaction.rb +254 -92
- data/lib/active_record/connection_adapters/abstract_adapter.rb +492 -221
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +580 -608
- 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 +196 -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 +271 -0
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +40 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +81 -199
- 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 +78 -161
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +49 -57
- 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 +5 -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 +17 -13
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +6 -3
- 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 -1
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +67 -51
- 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 +171 -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 +499 -293
- 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 +595 -382
- data/lib/active_record/connection_adapters/schema_cache.rb +191 -29
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +45 -0
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +146 -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 -389
- 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 +488 -243
- data/lib/active_record/counter_cache.rb +71 -50
- data/lib/active_record/database_configurations/connection_url_resolver.rb +99 -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 +273 -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 +212 -94
- data/lib/active_record/errors.rb +225 -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 +11 -6
- 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 +273 -496
- 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 +64 -0
- data/lib/active_record/legacy_yaml_adapter.rb +52 -0
- data/lib/active_record/locale/en.yml +3 -2
- data/lib/active_record/locking/optimistic.rb +103 -95
- 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 +298 -0
- data/lib/active_record/migration/join_table.rb +8 -7
- data/lib/active_record/migration.rb +685 -309
- data/lib/active_record/model_schema.rb +420 -113
- data/lib/active_record/nested_attributes.rb +265 -216
- data/lib/active_record/no_touching.rb +15 -2
- data/lib/active_record/null_relation.rb +24 -38
- data/lib/active_record/persistence.rb +574 -135
- data/lib/active_record/query_cache.rb +29 -23
- data/lib/active_record/querying.rb +50 -31
- data/lib/active_record/railtie.rb +175 -54
- 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 +533 -216
- data/lib/active_record/readonly_attributes.rb +9 -4
- data/lib/active_record/reflection.rb +485 -310
- 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 +326 -244
- data/lib/active_record/relation/delegation.rb +76 -84
- data/lib/active_record/relation/finder_methods.rb +318 -256
- data/lib/active_record/relation/from_clause.rb +30 -0
- data/lib/active_record/relation/merger.rb +99 -84
- data/lib/active_record/relation/predicate_builder/array_handler.rb +26 -25
- 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 +139 -96
- data/lib/active_record/relation/query_attribute.rb +50 -0
- data/lib/active_record/relation/query_methods.rb +757 -409
- data/lib/active_record/relation/record_fetch_warning.rb +51 -0
- data/lib/active_record/relation/spawn_methods.rb +23 -21
- data/lib/active_record/relation/where_clause.rb +239 -0
- data/lib/active_record/relation.rb +554 -342
- 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 -26
- data/lib/active_record/scoping/default.rb +96 -82
- 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 +133 -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 +366 -129
- data/lib/active_record/tasks/mysql_database_tasks.rb +68 -100
- data/lib/active_record/tasks/postgresql_database_tasks.rb +87 -39
- 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 +291 -0
- data/lib/active_record/timestamp.rb +86 -43
- data/lib/active_record/touch_later.rb +65 -0
- data/lib/active_record/transactions.rb +181 -152
- 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 -41
- data/lib/active_record/type/date_time.rb +4 -38
- data/lib/active_record/type/decimal_without_scale.rb +6 -2
- data/lib/active_record/type/hash_lookup_type_map.rb +12 -5
- 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 +33 -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 +65 -48
- data/lib/active_record/validations.rb +39 -35
- data/lib/active_record/version.rb +3 -1
- data/lib/active_record.rb +44 -28
- 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 -10
- 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.rb +7 -5
- metadata +175 -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 -149
- data/lib/active_record/attribute_decorators.rb +0 -66
- data/lib/active_record/attribute_set/builder.rb +0 -86
- data/lib/active_record/attribute_set.rb +0 -77
- 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 -30
- data/lib/active_record/type/decimal.rb +0 -40
- 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 -55
- 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 -36
- data/lib/active_record/type/time_value.rb +0 -38
- data/lib/active_record/type/value.rb +0 -101
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +0 -22
- data/lib/rails/generators/active_record/model/templates/model.rb +0 -10
- /data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
@@ -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,71 +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
|
+
)
|
112
103
|
end
|
113
104
|
|
114
|
-
|
115
|
-
|
116
|
-
super(bvs.map { |bv| conn.quote(*bv.reverse) })
|
117
|
-
end
|
105
|
+
def replica?
|
106
|
+
@config[:replica] || false
|
118
107
|
end
|
119
108
|
|
120
|
-
|
121
|
-
|
122
|
-
super(bvs)
|
123
|
-
end
|
109
|
+
def use_metadata_table?
|
110
|
+
@config.fetch(:use_metadata_table, true)
|
124
111
|
end
|
125
112
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
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
|
132
128
|
end
|
133
129
|
|
134
|
-
def
|
135
|
-
|
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
|
163
|
+
end
|
164
|
+
|
165
|
+
class Version
|
166
|
+
include Comparable
|
167
|
+
|
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
|
173
|
+
end
|
174
|
+
|
175
|
+
def <=>(version_string)
|
176
|
+
@version <=> version_string.split(".").map(&:to_i)
|
177
|
+
end
|
178
|
+
|
179
|
+
def to_s
|
180
|
+
@version.join(".")
|
181
|
+
end
|
136
182
|
end
|
137
183
|
|
138
|
-
def
|
139
|
-
|
184
|
+
def valid_type?(type) # :nodoc:
|
185
|
+
!native_database_types[type].nil?
|
140
186
|
end
|
141
187
|
|
188
|
+
# this method must only be called while holding connection pool's mutex
|
142
189
|
def lease
|
143
|
-
|
144
|
-
|
145
|
-
|
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}."
|
146
197
|
end
|
198
|
+
raise ActiveRecordError, msg
|
147
199
|
end
|
200
|
+
|
201
|
+
@owner = Thread.current
|
202
|
+
end
|
203
|
+
|
204
|
+
def connection_klass # :nodoc:
|
205
|
+
@pool.connection_klass
|
206
|
+
end
|
207
|
+
|
208
|
+
def schema_cache
|
209
|
+
@pool.get_schema_cache(self)
|
148
210
|
end
|
149
211
|
|
150
212
|
def schema_cache=(cache)
|
151
213
|
cache.connection = self
|
152
|
-
@
|
214
|
+
@pool.set_schema_cache(cache)
|
153
215
|
end
|
154
216
|
|
217
|
+
# this method must only be called while holding connection pool's mutex
|
155
218
|
def expire
|
156
|
-
|
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
|
157
250
|
end
|
158
251
|
|
159
252
|
def unprepared_statement
|
160
|
-
|
253
|
+
cache = prepared_statements_disabled_cache.add?(object_id) if @prepared_statements
|
161
254
|
yield
|
162
255
|
ensure
|
163
|
-
|
256
|
+
cache&.delete(object_id)
|
164
257
|
end
|
165
258
|
|
166
259
|
# Returns the human-readable name of the adapter. Use mixed case - one
|
@@ -169,15 +262,9 @@ module ActiveRecord
|
|
169
262
|
self.class::ADAPTER_NAME
|
170
263
|
end
|
171
264
|
|
172
|
-
# Does this adapter
|
173
|
-
def
|
174
|
-
|
175
|
-
end
|
176
|
-
|
177
|
-
# Can this adapter determine the primary key for tables not attached
|
178
|
-
# to an Active Record class, such as join tables?
|
179
|
-
def supports_primary_key?
|
180
|
-
false
|
265
|
+
# Does the database for this adapter exist?
|
266
|
+
def self.database_exists?(config)
|
267
|
+
raise NotImplementedError
|
181
268
|
end
|
182
269
|
|
183
270
|
# Does this adapter support DDL rollbacks in transactions? That is, would
|
@@ -195,6 +282,11 @@ module ActiveRecord
|
|
195
282
|
false
|
196
283
|
end
|
197
284
|
|
285
|
+
# Does this adapter support application-enforced advisory locking?
|
286
|
+
def supports_advisory_locks?
|
287
|
+
false
|
288
|
+
end
|
289
|
+
|
198
290
|
# Should primary key values be selected from their corresponding
|
199
291
|
# sequence before the insert statement? If true, next_sequence_value
|
200
292
|
# is called before each insert to set the record's primary key.
|
@@ -202,6 +294,10 @@ module ActiveRecord
|
|
202
294
|
false
|
203
295
|
end
|
204
296
|
|
297
|
+
def supports_partitioned_indexes?
|
298
|
+
false
|
299
|
+
end
|
300
|
+
|
205
301
|
# Does this adapter support index sort order?
|
206
302
|
def supports_index_sort_order?
|
207
303
|
false
|
@@ -212,6 +308,11 @@ module ActiveRecord
|
|
212
308
|
false
|
213
309
|
end
|
214
310
|
|
311
|
+
# Does this adapter support expression indices?
|
312
|
+
def supports_expression_index?
|
313
|
+
false
|
314
|
+
end
|
315
|
+
|
215
316
|
# Does this adapter support explain?
|
216
317
|
def supports_explain?
|
217
318
|
false
|
@@ -238,11 +339,85 @@ module ActiveRecord
|
|
238
339
|
false
|
239
340
|
end
|
240
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
|
+
|
241
352
|
# Does this adapter support views?
|
242
353
|
def supports_views?
|
243
354
|
false
|
244
355
|
end
|
245
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
|
+
|
246
421
|
# This is meant to be implemented by the adapters that support extensions
|
247
422
|
def disable_extension(name)
|
248
423
|
end
|
@@ -251,6 +426,24 @@ module ActiveRecord
|
|
251
426
|
def enable_extension(name)
|
252
427
|
end
|
253
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
|
+
|
254
447
|
# A list of extensions, to be filled in by adapters that support them.
|
255
448
|
def extensions
|
256
449
|
[]
|
@@ -261,14 +454,6 @@ module ActiveRecord
|
|
261
454
|
{}
|
262
455
|
end
|
263
456
|
|
264
|
-
# QUOTING ==================================================
|
265
|
-
|
266
|
-
# Returns a bind substitution value given a bind +column+
|
267
|
-
# NOTE: The column param is currently being used by the sqlserver-adapter
|
268
|
-
def substitute_at(column, _unused = 0)
|
269
|
-
Arel::Nodes::BindParam.new
|
270
|
-
end
|
271
|
-
|
272
457
|
# REFERENTIAL INTEGRITY ====================================
|
273
458
|
|
274
459
|
# Override to turn off referential integrity while executing <tt>&block</tt>.
|
@@ -299,6 +484,22 @@ module ActiveRecord
|
|
299
484
|
reset_transaction
|
300
485
|
end
|
301
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
|
+
|
302
503
|
# Reset the state of this connection, directing the DBMS to clear
|
303
504
|
# transactions and other connection-related server-side state. Usually a
|
304
505
|
# database-dependent operation.
|
@@ -309,11 +510,15 @@ module ActiveRecord
|
|
309
510
|
# this should be overridden by concrete adapters
|
310
511
|
end
|
311
512
|
|
312
|
-
|
313
|
-
|
314
|
-
|
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.
|
315
520
|
def clear_cache!
|
316
|
-
|
521
|
+
@lock.synchronize { @statements.clear } if @statements
|
317
522
|
end
|
318
523
|
|
319
524
|
# Returns true if its required to reload the connection between requests for development mode.
|
@@ -322,166 +527,232 @@ module ActiveRecord
|
|
322
527
|
end
|
323
528
|
|
324
529
|
# Checks whether the connection to the database is still active (i.e. not stale).
|
325
|
-
# This is done under the hood by calling
|
530
|
+
# This is done under the hood by calling #active?. If the connection
|
326
531
|
# is no longer active, then this method will reconnect to the database.
|
327
|
-
def verify!
|
532
|
+
def verify!
|
328
533
|
reconnect! unless active?
|
329
534
|
end
|
330
535
|
|
331
536
|
# Provides access to the underlying database driver for this adapter. For
|
332
|
-
# example, this method returns a
|
333
|
-
# 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.
|
334
539
|
#
|
335
540
|
# This is useful for when you need to call a proprietary method such as
|
336
541
|
# PostgreSQL's lo_* methods.
|
337
542
|
def raw_connection
|
543
|
+
disable_lazy_transactions!
|
338
544
|
@connection
|
339
545
|
end
|
340
546
|
|
341
|
-
def
|
342
|
-
|
343
|
-
|
344
|
-
def rollback_to_savepoint(name = nil)
|
345
|
-
end
|
346
|
-
|
347
|
-
def release_savepoint(name = nil)
|
547
|
+
def default_uniqueness_comparison(attribute, value) # :nodoc:
|
548
|
+
attribute.eq(value)
|
348
549
|
end
|
349
550
|
|
350
|
-
def
|
351
|
-
|
551
|
+
def case_sensitive_comparison(attribute, value) # :nodoc:
|
552
|
+
attribute.eq(value)
|
352
553
|
end
|
353
554
|
|
354
|
-
def
|
355
|
-
|
356
|
-
value = case_sensitive_modifier(value, table_attr) unless value.nil?
|
357
|
-
table_attr.eq(value)
|
358
|
-
end
|
555
|
+
def case_insensitive_comparison(attribute, value) # :nodoc:
|
556
|
+
column = column_for_attribute(attribute)
|
359
557
|
|
360
|
-
|
361
|
-
|
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
|
362
563
|
end
|
363
564
|
|
364
|
-
def
|
365
|
-
|
565
|
+
def can_perform_case_insensitive_comparison_for?(column)
|
566
|
+
true
|
366
567
|
end
|
568
|
+
private :can_perform_case_insensitive_comparison_for?
|
367
569
|
|
368
570
|
# Check the connection back in to the connection pool
|
369
571
|
def close
|
370
572
|
pool.checkin self
|
371
573
|
end
|
372
574
|
|
373
|
-
def
|
374
|
-
|
375
|
-
initialize_type_map(mapping)
|
376
|
-
end
|
575
|
+
def default_index_type?(index) # :nodoc:
|
576
|
+
index.using.nil?
|
377
577
|
end
|
378
578
|
|
379
|
-
|
380
|
-
|
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}"
|
381
590
|
end
|
382
591
|
|
383
|
-
def
|
384
|
-
type_map.lookup(sql_type)
|
592
|
+
def get_database_version # :nodoc:
|
385
593
|
end
|
386
594
|
|
387
|
-
def
|
388
|
-
|
595
|
+
def database_version # :nodoc:
|
596
|
+
schema_cache.database_version
|
389
597
|
end
|
390
598
|
|
391
|
-
|
599
|
+
def check_version # :nodoc:
|
600
|
+
end
|
392
601
|
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
register_class_with_limit m, %r(time)i, Type::Time
|
400
|
-
register_class_with_limit m, %r(datetime)i, Type::DateTime
|
401
|
-
register_class_with_limit m, %r(float)i, Type::Float
|
402
|
-
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
|
403
608
|
|
404
|
-
m
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
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
|
410
641
|
|
411
|
-
|
412
|
-
|
413
|
-
|
642
|
+
def reload_type_map
|
643
|
+
type_map.clear
|
644
|
+
initialize_type_map
|
645
|
+
end
|
414
646
|
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
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)
|
420
651
|
end
|
421
652
|
end
|
422
|
-
end
|
423
653
|
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
def register_class_with_limit(mapping, key, klass) # :nodoc:
|
430
|
-
mapping.register_type(key) do |*args|
|
431
|
-
limit = extract_limit(args.last)
|
432
|
-
klass.new(limit: limit)
|
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
|
433
659
|
end
|
434
|
-
end
|
435
660
|
|
436
|
-
|
437
|
-
|
661
|
+
def extract_scale(sql_type)
|
662
|
+
case sql_type
|
438
663
|
when /\((\d+)\)/ then 0
|
439
664
|
when /\((\d+)(,(\d+))\)/ then $3.to_i
|
665
|
+
end
|
440
666
|
end
|
441
|
-
end
|
442
667
|
|
443
|
-
|
444
|
-
|
445
|
-
|
668
|
+
def extract_precision(sql_type)
|
669
|
+
$1.to_i if sql_type =~ /\((\d+)(,\d+)?\)/
|
670
|
+
end
|
446
671
|
|
447
|
-
|
448
|
-
|
449
|
-
|
672
|
+
def extract_limit(sql_type)
|
673
|
+
$1.to_i if sql_type =~ /\((.*)\)/
|
674
|
+
end
|
450
675
|
|
451
|
-
|
452
|
-
|
453
|
-
@logger.error message if @logger
|
454
|
-
exception = translate_exception(e, message)
|
455
|
-
exception.set_backtrace e.backtrace
|
456
|
-
exception
|
457
|
-
end
|
676
|
+
def translate_exception_class(e, sql, binds)
|
677
|
+
message = "#{e.class.name}: #{e.message}"
|
458
678
|
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
:statement_name => statement_name,
|
466
|
-
:binds => binds) { yield }
|
467
|
-
rescue => e
|
468
|
-
raise translate_exception_class(e, sql)
|
469
|
-
end
|
679
|
+
exception = translate_exception(
|
680
|
+
e, message: message, sql: sql, binds: binds
|
681
|
+
)
|
682
|
+
exception.set_backtrace e.backtrace
|
683
|
+
exception
|
684
|
+
end
|
470
685
|
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
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
|
475
702
|
|
476
|
-
|
477
|
-
|
478
|
-
|
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
|
479
712
|
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
713
|
+
def without_prepared_statement?(binds)
|
714
|
+
!prepared_statements || binds.empty?
|
715
|
+
end
|
716
|
+
|
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
|
722
|
+
|
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
|
485
756
|
end
|
486
757
|
end
|
487
758
|
end
|