activerecord 5.0.7.2 → 6.1.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 +4 -4
- data/CHANGELOG.md +829 -2015
- data/MIT-LICENSE +3 -1
- data/README.rdoc +11 -9
- data/examples/performance.rb +31 -29
- data/examples/simple.rb +5 -3
- data/lib/active_record.rb +37 -29
- data/lib/active_record/aggregations.rb +249 -247
- data/lib/active_record/association_relation.rb +30 -18
- data/lib/active_record/associations.rb +1714 -1596
- data/lib/active_record/associations/alias_tracker.rb +36 -42
- data/lib/active_record/associations/association.rb +143 -68
- data/lib/active_record/associations/association_scope.rb +98 -94
- data/lib/active_record/associations/belongs_to_association.rb +76 -46
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +13 -12
- data/lib/active_record/associations/builder/association.rb +27 -28
- data/lib/active_record/associations/builder/belongs_to.rb +52 -60
- data/lib/active_record/associations/builder/collection_association.rb +12 -22
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +40 -62
- data/lib/active_record/associations/builder/has_many.rb +10 -2
- data/lib/active_record/associations/builder/has_one.rb +35 -2
- data/lib/active_record/associations/builder/singular_association.rb +5 -1
- data/lib/active_record/associations/collection_association.rb +104 -259
- data/lib/active_record/associations/collection_proxy.rb +169 -125
- data/lib/active_record/associations/foreign_association.rb +22 -0
- data/lib/active_record/associations/has_many_association.rb +46 -31
- data/lib/active_record/associations/has_many_through_association.rb +66 -46
- data/lib/active_record/associations/has_one_association.rb +71 -52
- data/lib/active_record/associations/has_one_through_association.rb +20 -11
- data/lib/active_record/associations/join_dependency.rb +169 -180
- data/lib/active_record/associations/join_dependency/join_association.rb +53 -79
- 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/preloader.rb +97 -104
- data/lib/active_record/associations/preloader/association.rb +109 -97
- data/lib/active_record/associations/preloader/through_association.rb +77 -76
- data/lib/active_record/associations/singular_association.rb +12 -45
- data/lib/active_record/associations/through_association.rb +27 -15
- data/lib/active_record/attribute_assignment.rb +55 -60
- data/lib/active_record/attribute_methods.rb +111 -141
- data/lib/active_record/attribute_methods/before_type_cast.rb +17 -9
- data/lib/active_record/attribute_methods/dirty.rb +172 -112
- data/lib/active_record/attribute_methods/primary_key.rb +88 -91
- data/lib/active_record/attribute_methods/query.rb +6 -8
- data/lib/active_record/attribute_methods/read.rb +18 -50
- data/lib/active_record/attribute_methods/serialization.rb +38 -10
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +38 -66
- data/lib/active_record/attribute_methods/write.rb +25 -32
- data/lib/active_record/attributes.rb +69 -31
- data/lib/active_record/autosave_association.rb +102 -66
- data/lib/active_record/base.rb +16 -25
- data/lib/active_record/callbacks.rb +202 -43
- data/lib/active_record/coders/json.rb +2 -0
- data/lib/active_record/coders/yaml_column.rb +11 -12
- data/lib/active_record/connection_adapters.rb +50 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +661 -375
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +14 -38
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +269 -105
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +54 -35
- data/lib/active_record/connection_adapters/abstract/quoting.rb +137 -93
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +5 -3
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +155 -113
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +328 -162
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +68 -80
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +591 -259
- data/lib/active_record/connection_adapters/abstract/transaction.rb +229 -91
- data/lib/active_record/connection_adapters/abstract_adapter.rb +392 -244
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +457 -582
- data/lib/active_record/connection_adapters/column.rb +55 -13
- data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
- data/lib/active_record/connection_adapters/legacy_pool_manager.rb +31 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +8 -31
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +135 -49
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +24 -23
- data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -20
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +79 -49
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +66 -56
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +70 -36
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +268 -0
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +20 -12
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +74 -37
- data/lib/active_record/connection_adapters/pool_config.rb +63 -0
- data/lib/active_record/connection_adapters/pool_manager.rb +43 -0
- data/lib/active_record/connection_adapters/postgresql/column.rb +39 -28
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +70 -101
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +5 -3
- data/lib/active_record/connection_adapters/postgresql/oid.rb +26 -21
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +22 -11
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +6 -5
- data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +6 -6
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +14 -4
- 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 +19 -18
- 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 -5
- data/lib/active_record/connection_adapters/postgresql/oid/{json.rb → oid.rb} +6 -1
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +30 -9
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +52 -30
- 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 +58 -54
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +18 -4
- data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +98 -38
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +21 -27
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +80 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +147 -105
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +34 -32
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +426 -324
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +32 -23
- data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -6
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +418 -293
- data/lib/active_record/connection_adapters/schema_cache.rb +135 -18
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +22 -7
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +144 -0
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +3 -1
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +72 -18
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -6
- 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 +282 -290
- data/lib/active_record/connection_adapters/statement_pool.rb +9 -8
- data/lib/active_record/connection_handling.rb +287 -45
- data/lib/active_record/core.rb +385 -181
- data/lib/active_record/counter_cache.rb +60 -28
- data/lib/active_record/database_configurations.rb +272 -0
- 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/delegated_type.rb +209 -0
- data/lib/active_record/destroy_association_async_job.rb +36 -0
- data/lib/active_record/dynamic_matchers.rb +87 -87
- data/lib/active_record/enum.rb +122 -47
- data/lib/active_record/errors.rb +153 -22
- data/lib/active_record/explain.rb +13 -8
- data/lib/active_record/explain_registry.rb +3 -1
- data/lib/active_record/explain_subscriber.rb +9 -4
- data/lib/active_record/fixture_set/file.rb +20 -22
- 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 +246 -507
- data/lib/active_record/gem_version.rb +6 -4
- data/lib/active_record/inheritance.rb +168 -95
- data/lib/active_record/insert_all.rb +208 -0
- data/lib/active_record/integration.rb +114 -25
- data/lib/active_record/internal_metadata.rb +30 -24
- data/lib/active_record/legacy_yaml_adapter.rb +11 -5
- data/lib/active_record/locking/optimistic.rb +81 -85
- data/lib/active_record/locking/pessimistic.rb +22 -6
- data/lib/active_record/log_subscriber.rb +68 -31
- data/lib/active_record/middleware/database_selector.rb +77 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
- data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
- data/lib/active_record/migration.rb +439 -342
- data/lib/active_record/migration/command_recorder.rb +152 -98
- data/lib/active_record/migration/compatibility.rb +229 -60
- data/lib/active_record/migration/join_table.rb +8 -7
- data/lib/active_record/model_schema.rb +230 -122
- data/lib/active_record/nested_attributes.rb +213 -203
- data/lib/active_record/no_touching.rb +11 -2
- data/lib/active_record/null_relation.rb +12 -34
- data/lib/active_record/persistence.rb +471 -97
- data/lib/active_record/query_cache.rb +23 -12
- data/lib/active_record/querying.rb +43 -25
- data/lib/active_record/railtie.rb +155 -43
- data/lib/active_record/railties/console_sandbox.rb +2 -0
- data/lib/active_record/railties/controller_runtime.rb +34 -33
- data/lib/active_record/railties/databases.rake +507 -195
- data/lib/active_record/readonly_attributes.rb +9 -4
- data/lib/active_record/reflection.rb +245 -269
- data/lib/active_record/relation.rb +475 -324
- data/lib/active_record/relation/batches.rb +125 -72
- data/lib/active_record/relation/batches/batch_enumerator.rb +28 -10
- data/lib/active_record/relation/calculations.rb +267 -171
- data/lib/active_record/relation/delegation.rb +73 -69
- data/lib/active_record/relation/finder_methods.rb +238 -248
- data/lib/active_record/relation/from_clause.rb +7 -9
- data/lib/active_record/relation/merger.rb +95 -77
- data/lib/active_record/relation/predicate_builder.rb +109 -110
- data/lib/active_record/relation/predicate_builder/array_handler.rb +22 -17
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +42 -0
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +6 -4
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +55 -0
- data/lib/active_record/relation/predicate_builder/range_handler.rb +7 -18
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
- data/lib/active_record/relation/query_attribute.rb +33 -2
- data/lib/active_record/relation/query_methods.rb +654 -374
- data/lib/active_record/relation/record_fetch_warning.rb +8 -6
- data/lib/active_record/relation/spawn_methods.rb +15 -14
- data/lib/active_record/relation/where_clause.rb +171 -109
- data/lib/active_record/result.rb +88 -51
- data/lib/active_record/runtime_registry.rb +5 -3
- data/lib/active_record/sanitization.rb +73 -100
- data/lib/active_record/schema.rb +7 -14
- data/lib/active_record/schema_dumper.rb +101 -69
- data/lib/active_record/schema_migration.rb +16 -12
- data/lib/active_record/scoping.rb +20 -20
- data/lib/active_record/scoping/default.rb +92 -95
- data/lib/active_record/scoping/named.rb +39 -30
- data/lib/active_record/secure_token.rb +19 -9
- data/lib/active_record/serialization.rb +7 -3
- data/lib/active_record/signed_id.rb +116 -0
- data/lib/active_record/statement_cache.rb +80 -29
- data/lib/active_record/store.rb +122 -42
- data/lib/active_record/suppressor.rb +6 -3
- data/lib/active_record/table_metadata.rb +51 -39
- data/lib/active_record/tasks/database_tasks.rb +332 -115
- data/lib/active_record/tasks/mysql_database_tasks.rb +66 -104
- data/lib/active_record/tasks/postgresql_database_tasks.rb +84 -56
- data/lib/active_record/tasks/sqlite_database_tasks.rb +40 -19
- data/lib/active_record/test_databases.rb +24 -0
- data/lib/active_record/test_fixtures.rb +246 -0
- data/lib/active_record/timestamp.rb +70 -38
- data/lib/active_record/touch_later.rb +26 -24
- data/lib/active_record/transactions.rb +121 -184
- data/lib/active_record/translation.rb +3 -1
- data/lib/active_record/type.rb +29 -17
- data/lib/active_record/type/adapter_specific_registry.rb +44 -48
- data/lib/active_record/type/date.rb +2 -0
- data/lib/active_record/type/date_time.rb +2 -0
- data/lib/active_record/type/decimal_without_scale.rb +15 -0
- data/lib/active_record/type/hash_lookup_type_map.rb +5 -4
- data/lib/active_record/type/internal/timezone.rb +2 -0
- data/lib/active_record/type/json.rb +30 -0
- data/lib/active_record/type/serialized.rb +20 -9
- data/lib/active_record/type/text.rb +11 -0
- data/lib/active_record/type/time.rb +12 -1
- data/lib/active_record/type/type_map.rb +14 -17
- data/lib/active_record/type/unsigned_integer.rb +16 -0
- data/lib/active_record/type_caster.rb +4 -2
- data/lib/active_record/type_caster/connection.rb +17 -13
- data/lib/active_record/type_caster/map.rb +10 -6
- data/lib/active_record/validations.rb +8 -5
- data/lib/active_record/validations/absence.rb +2 -0
- data/lib/active_record/validations/associated.rb +4 -3
- data/lib/active_record/validations/length.rb +2 -0
- data/lib/active_record/validations/numericality.rb +35 -0
- data/lib/active_record/validations/presence.rb +4 -2
- data/lib/active_record/validations/uniqueness.rb +52 -45
- data/lib/active_record/version.rb +3 -1
- data/lib/arel.rb +54 -0
- 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.rb +70 -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 +72 -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/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.rb +13 -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/window_predications.rb +9 -0
- data/lib/rails/generators/active_record.rb +7 -5
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +26 -0
- data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
- data/lib/rails/generators/active_record/migration.rb +22 -3
- data/lib/rails/generators/active_record/migration/migration_generator.rb +38 -35
- data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +3 -1
- data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +7 -5
- data/lib/rails/generators/active_record/model/model_generator.rb +41 -25
- 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 → model.rb.tt} +10 -1
- data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
- metadata +141 -57
- data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
- data/lib/active_record/associations/preloader/collection_association.rb +0 -17
- 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 -15
- data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
- data/lib/active_record/associations/preloader/singular_association.rb +0 -20
- data/lib/active_record/attribute.rb +0 -213
- data/lib/active_record/attribute/user_provided_default.rb +0 -28
- data/lib/active_record/attribute_decorators.rb +0 -67
- data/lib/active_record/attribute_mutation_tracker.rb +0 -70
- data/lib/active_record/attribute_set.rb +0 -110
- data/lib/active_record/attribute_set/builder.rb +0 -132
- data/lib/active_record/collection_cache_key.rb +0 -50
- data/lib/active_record/connection_adapters/connection_specification.rb +0 -263
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -22
- data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +0 -50
- data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
- data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
- data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -17
- data/lib/active_record/relation/predicate_builder/class_handler.rb +0 -27
- data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -57
- data/lib/active_record/relation/where_clause_factory.rb +0 -38
- data/lib/active_record/type/internal/abstract_json.rb +0 -33
@@ -1,20 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module ConnectionAdapters # :nodoc:
|
3
5
|
module DatabaseLimits
|
4
|
-
|
5
|
-
# Returns the maximum length of a table alias.
|
6
|
-
def table_alias_length
|
7
|
-
255
|
8
|
-
end
|
9
|
-
|
10
|
-
# Returns the maximum length of a column name.
|
11
|
-
def column_name_length
|
6
|
+
def max_identifier_length # :nodoc:
|
12
7
|
64
|
13
8
|
end
|
14
9
|
|
15
|
-
# Returns the maximum length of a table
|
16
|
-
def
|
17
|
-
|
10
|
+
# Returns the maximum length of a table alias.
|
11
|
+
def table_alias_length
|
12
|
+
max_identifier_length
|
18
13
|
end
|
19
14
|
|
20
15
|
# Returns the maximum allowed length for an index name. This
|
@@ -25,43 +20,24 @@ module ActiveRecord
|
|
25
20
|
def allowed_index_name_length
|
26
21
|
index_name_length
|
27
22
|
end
|
23
|
+
deprecate :allowed_index_name_length
|
28
24
|
|
29
25
|
# Returns the maximum length of an index name.
|
30
26
|
def index_name_length
|
31
|
-
|
32
|
-
end
|
33
|
-
|
34
|
-
# Returns the maximum number of columns per table.
|
35
|
-
def columns_per_table
|
36
|
-
1024
|
37
|
-
end
|
38
|
-
|
39
|
-
# Returns the maximum number of indexes per table.
|
40
|
-
def indexes_per_table
|
41
|
-
16
|
42
|
-
end
|
43
|
-
|
44
|
-
# Returns the maximum number of columns in a multicolumn index.
|
45
|
-
def columns_per_multicolumn_index
|
46
|
-
16
|
27
|
+
max_identifier_length
|
47
28
|
end
|
48
29
|
|
49
30
|
# Returns the maximum number of elements in an IN (x,y,z) clause.
|
50
|
-
# nil means no limit.
|
31
|
+
# +nil+ means no limit.
|
51
32
|
def in_clause_length
|
52
33
|
nil
|
53
34
|
end
|
35
|
+
deprecate :in_clause_length
|
54
36
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
# Returns maximum number of joins in a single query.
|
61
|
-
def joins_per_query
|
62
|
-
256
|
63
|
-
end
|
64
|
-
|
37
|
+
private
|
38
|
+
def bind_params_length
|
39
|
+
65535
|
40
|
+
end
|
65
41
|
end
|
66
42
|
end
|
67
43
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module ConnectionAdapters # :nodoc:
|
3
5
|
module DatabaseStatements
|
@@ -7,39 +9,67 @@ module ActiveRecord
|
|
7
9
|
end
|
8
10
|
|
9
11
|
# Converts an arel AST to SQL
|
10
|
-
def to_sql(
|
11
|
-
|
12
|
-
|
13
|
-
|
12
|
+
def to_sql(arel_or_sql_string, binds = [])
|
13
|
+
sql, _ = to_sql_and_binds(arel_or_sql_string, binds)
|
14
|
+
sql
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_sql_and_binds(arel_or_sql_string, binds = [], preparable = nil) # :nodoc:
|
18
|
+
if arel_or_sql_string.respond_to?(:ast)
|
19
|
+
unless binds.empty?
|
20
|
+
raise "Passing bind parameters with an arel AST is forbidden. " \
|
21
|
+
"The values must be stored on the AST directly"
|
22
|
+
end
|
23
|
+
|
24
|
+
collector = collector()
|
25
|
+
|
26
|
+
if prepared_statements
|
27
|
+
collector.preparable = true
|
28
|
+
sql, binds = visitor.compile(arel_or_sql_string.ast, collector)
|
29
|
+
|
30
|
+
if binds.length > bind_params_length
|
31
|
+
unprepared_statement do
|
32
|
+
return to_sql_and_binds(arel_or_sql_string)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
preparable = collector.preparable
|
36
|
+
else
|
37
|
+
sql = visitor.compile(arel_or_sql_string.ast, collector)
|
38
|
+
end
|
39
|
+
[sql.freeze, binds, preparable]
|
14
40
|
else
|
15
|
-
|
41
|
+
arel_or_sql_string = arel_or_sql_string.dup.freeze unless arel_or_sql_string.frozen?
|
42
|
+
[arel_or_sql_string, binds, preparable]
|
16
43
|
end
|
17
44
|
end
|
45
|
+
private :to_sql_and_binds
|
18
46
|
|
19
47
|
# This is used in the StatementCache object. It returns an object that
|
20
48
|
# can be used to query the database repeatedly.
|
21
|
-
def cacheable_query(arel) # :nodoc:
|
49
|
+
def cacheable_query(klass, arel) # :nodoc:
|
22
50
|
if prepared_statements
|
23
|
-
|
51
|
+
sql, binds = visitor.compile(arel.ast, collector)
|
52
|
+
query = klass.query(sql)
|
24
53
|
else
|
25
|
-
|
54
|
+
collector = klass.partial_query_collector
|
55
|
+
parts, binds = visitor.compile(arel.ast, collector)
|
56
|
+
query = klass.partial_query(parts)
|
26
57
|
end
|
58
|
+
[query, binds]
|
27
59
|
end
|
28
60
|
|
29
61
|
# Returns an ActiveRecord::Result instance.
|
30
62
|
def select_all(arel, name = nil, binds = [], preparable: nil)
|
31
|
-
arel
|
32
|
-
sql =
|
33
|
-
|
34
|
-
preparable = false
|
35
|
-
else
|
36
|
-
preparable = visitor.preparable
|
37
|
-
end
|
63
|
+
arel = arel_from_relation(arel)
|
64
|
+
sql, binds, preparable = to_sql_and_binds(arel, binds, preparable)
|
65
|
+
|
38
66
|
if prepared_statements && preparable
|
39
67
|
select_prepared(sql, name, binds)
|
40
68
|
else
|
41
69
|
select(sql, name, binds)
|
42
70
|
end
|
71
|
+
rescue ::RangeError
|
72
|
+
ActiveRecord::Result.new([], [])
|
43
73
|
end
|
44
74
|
|
45
75
|
# Returns a record hash with the column names as keys and column values
|
@@ -50,23 +80,36 @@ module ActiveRecord
|
|
50
80
|
|
51
81
|
# Returns a single value from a record
|
52
82
|
def select_value(arel, name = nil, binds = [])
|
53
|
-
arel,
|
54
|
-
if result = select_rows(to_sql(arel, binds), name, binds).first
|
55
|
-
result.first
|
56
|
-
end
|
83
|
+
single_value_from_rows(select_rows(arel, name, binds))
|
57
84
|
end
|
58
85
|
|
59
86
|
# Returns an array of the values of the first column in a select:
|
60
87
|
# select_values("SELECT id FROM companies LIMIT 3") => [1,2,3]
|
61
88
|
def select_values(arel, name = nil, binds = [])
|
62
|
-
arel,
|
63
|
-
select_rows(to_sql(arel, binds), name, binds).map(&:first)
|
89
|
+
select_rows(arel, name, binds).map(&:first)
|
64
90
|
end
|
65
91
|
|
66
92
|
# Returns an array of arrays containing the field values.
|
67
93
|
# Order is the same as that returned by +columns+.
|
68
|
-
def select_rows(
|
69
|
-
|
94
|
+
def select_rows(arel, name = nil, binds = [])
|
95
|
+
select_all(arel, name, binds).rows
|
96
|
+
end
|
97
|
+
|
98
|
+
def query_value(sql, name = nil) # :nodoc:
|
99
|
+
single_value_from_rows(query(sql, name))
|
100
|
+
end
|
101
|
+
|
102
|
+
def query_values(sql, name = nil) # :nodoc:
|
103
|
+
query(sql, name).map(&:first)
|
104
|
+
end
|
105
|
+
|
106
|
+
def query(sql, name = nil) # :nodoc:
|
107
|
+
exec_query(sql, name).rows
|
108
|
+
end
|
109
|
+
|
110
|
+
# Determines whether the SQL statement is a write query.
|
111
|
+
def write_query?(sql)
|
112
|
+
raise NotImplementedError
|
70
113
|
end
|
71
114
|
|
72
115
|
# Executes the SQL statement in the context of this connection and returns
|
@@ -81,71 +124,83 @@ module ActiveRecord
|
|
81
124
|
# Executes +sql+ statement in the context of this connection using
|
82
125
|
# +binds+ as the bind substitutes. +name+ is logged along with
|
83
126
|
# the executed +sql+ statement.
|
84
|
-
def exec_query(sql, name =
|
127
|
+
def exec_query(sql, name = "SQL", binds = [], prepare: false)
|
85
128
|
raise NotImplementedError
|
86
129
|
end
|
87
130
|
|
88
131
|
# Executes insert +sql+ statement in the context of this connection using
|
89
132
|
# +binds+ as the bind substitutes. +name+ is logged along with
|
90
133
|
# the executed +sql+ statement.
|
91
|
-
def exec_insert(sql, name, binds, pk = nil, sequence_name = nil)
|
134
|
+
def exec_insert(sql, name = nil, binds = [], pk = nil, sequence_name = nil)
|
135
|
+
sql, binds = sql_for_insert(sql, pk, binds)
|
92
136
|
exec_query(sql, name, binds)
|
93
137
|
end
|
94
138
|
|
95
139
|
# Executes delete +sql+ statement in the context of this connection using
|
96
140
|
# +binds+ as the bind substitutes. +name+ is logged along with
|
97
141
|
# the executed +sql+ statement.
|
98
|
-
def exec_delete(sql, name, binds)
|
142
|
+
def exec_delete(sql, name = nil, binds = [])
|
99
143
|
exec_query(sql, name, binds)
|
100
144
|
end
|
101
145
|
|
102
|
-
# Executes the truncate statement.
|
103
|
-
def truncate(table_name, name = nil)
|
104
|
-
raise NotImplementedError
|
105
|
-
end
|
106
|
-
|
107
146
|
# Executes update +sql+ statement in the context of this connection using
|
108
147
|
# +binds+ as the bind substitutes. +name+ is logged along with
|
109
148
|
# the executed +sql+ statement.
|
110
|
-
def exec_update(sql, name, binds)
|
149
|
+
def exec_update(sql, name = nil, binds = [])
|
111
150
|
exec_query(sql, name, binds)
|
112
151
|
end
|
113
152
|
|
153
|
+
def exec_insert_all(sql, name) # :nodoc:
|
154
|
+
exec_query(sql, name)
|
155
|
+
end
|
156
|
+
|
157
|
+
def explain(arel, binds = []) # :nodoc:
|
158
|
+
raise NotImplementedError
|
159
|
+
end
|
160
|
+
|
114
161
|
# Executes an INSERT query and returns the new record's ID
|
115
162
|
#
|
116
|
-
# +id_value+ will be returned unless the value is nil
|
163
|
+
# +id_value+ will be returned unless the value is +nil+, in
|
117
164
|
# which case the database will attempt to calculate the last inserted
|
118
165
|
# id and return that value.
|
119
166
|
#
|
120
167
|
# If the next id was calculated in advance (as in Oracle), it should be
|
121
168
|
# passed in as +id_value+.
|
122
169
|
def insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [])
|
123
|
-
sql, binds
|
170
|
+
sql, binds = to_sql_and_binds(arel, binds)
|
124
171
|
value = exec_insert(sql, name, binds, pk, sequence_name)
|
125
172
|
id_value || last_inserted_id(value)
|
126
173
|
end
|
127
174
|
alias create insert
|
128
|
-
alias insert_sql insert
|
129
|
-
deprecate insert_sql: :insert
|
130
175
|
|
131
176
|
# Executes the update statement and returns the number of rows affected.
|
132
177
|
def update(arel, name = nil, binds = [])
|
133
|
-
|
178
|
+
sql, binds = to_sql_and_binds(arel, binds)
|
179
|
+
exec_update(sql, name, binds)
|
134
180
|
end
|
135
|
-
alias update_sql update
|
136
|
-
deprecate update_sql: :update
|
137
181
|
|
138
182
|
# Executes the delete statement and returns the number of rows affected.
|
139
183
|
def delete(arel, name = nil, binds = [])
|
140
|
-
|
184
|
+
sql, binds = to_sql_and_binds(arel, binds)
|
185
|
+
exec_delete(sql, name, binds)
|
186
|
+
end
|
187
|
+
|
188
|
+
# Executes the truncate statement.
|
189
|
+
def truncate(table_name, name = nil)
|
190
|
+
execute(build_truncate_statement(table_name), name)
|
141
191
|
end
|
142
|
-
alias delete_sql delete
|
143
|
-
deprecate delete_sql: :delete
|
144
192
|
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
193
|
+
def truncate_tables(*table_names) # :nodoc:
|
194
|
+
table_names -= [schema_migration.table_name, InternalMetadata.table_name]
|
195
|
+
|
196
|
+
return if table_names.empty?
|
197
|
+
|
198
|
+
with_multi_statements do
|
199
|
+
disable_referential_integrity do
|
200
|
+
statements = build_truncate_statements(table_names)
|
201
|
+
execute_batch(statements, "Truncate Tables")
|
202
|
+
end
|
203
|
+
end
|
149
204
|
end
|
150
205
|
|
151
206
|
# Runs the given block in a database transaction, and returns the result
|
@@ -153,15 +208,30 @@ module ActiveRecord
|
|
153
208
|
#
|
154
209
|
# == Nested transactions support
|
155
210
|
#
|
211
|
+
# #transaction calls can be nested. By default, this makes all database
|
212
|
+
# statements in the nested transaction block become part of the parent
|
213
|
+
# transaction. For example, the following behavior may be surprising:
|
214
|
+
#
|
215
|
+
# ActiveRecord::Base.transaction do
|
216
|
+
# Post.create(title: 'first')
|
217
|
+
# ActiveRecord::Base.transaction do
|
218
|
+
# Post.create(title: 'second')
|
219
|
+
# raise ActiveRecord::Rollback
|
220
|
+
# end
|
221
|
+
# end
|
222
|
+
#
|
223
|
+
# This creates both "first" and "second" posts. Reason is the
|
224
|
+
# ActiveRecord::Rollback exception in the nested block does not issue a
|
225
|
+
# ROLLBACK. Since these exceptions are captured in transaction blocks,
|
226
|
+
# the parent block does not see it and the real transaction is committed.
|
227
|
+
#
|
156
228
|
# Most databases don't support true nested transactions. At the time of
|
157
229
|
# writing, the only database that supports true nested transactions that
|
158
230
|
# we're aware of, is MS-SQL.
|
159
231
|
#
|
160
232
|
# In order to get around this problem, #transaction will emulate the effect
|
161
233
|
# of nested transactions, by using savepoints:
|
162
|
-
#
|
163
|
-
# Savepoints are supported by MySQL and PostgreSQL. SQLite3 version >= '3.6.8'
|
164
|
-
# supports savepoints.
|
234
|
+
# https://dev.mysql.com/doc/refman/en/savepoint.html.
|
165
235
|
#
|
166
236
|
# It is safe to call this method if a database transaction is already open,
|
167
237
|
# i.e. if #transaction is called within another #transaction block. In case
|
@@ -173,6 +243,24 @@ module ActiveRecord
|
|
173
243
|
# - However, if +:requires_new+ is set, the block will be wrapped in a
|
174
244
|
# database savepoint acting as a sub-transaction.
|
175
245
|
#
|
246
|
+
# In order to get a ROLLBACK for the nested transaction you may ask for a
|
247
|
+
# real sub-transaction by passing <tt>requires_new: true</tt>.
|
248
|
+
# If anything goes wrong, the database rolls back to the beginning of
|
249
|
+
# the sub-transaction without rolling back the parent transaction.
|
250
|
+
# If we add it to the previous example:
|
251
|
+
#
|
252
|
+
# ActiveRecord::Base.transaction do
|
253
|
+
# Post.create(title: 'first')
|
254
|
+
# ActiveRecord::Base.transaction(requires_new: true) do
|
255
|
+
# Post.create(title: 'second')
|
256
|
+
# raise ActiveRecord::Rollback
|
257
|
+
# end
|
258
|
+
# end
|
259
|
+
#
|
260
|
+
# only post with title "first" is created.
|
261
|
+
#
|
262
|
+
# See ActiveRecord::Transactions to learn more.
|
263
|
+
#
|
176
264
|
# === Caveats
|
177
265
|
#
|
178
266
|
# MySQL doesn't support DDL transactions. If you perform a DDL operation,
|
@@ -211,8 +299,8 @@ module ActiveRecord
|
|
211
299
|
# You should consult the documentation for your database to understand the
|
212
300
|
# semantics of these different levels:
|
213
301
|
#
|
214
|
-
# *
|
215
|
-
# * https://dev.mysql.com/doc/refman/
|
302
|
+
# * https://www.postgresql.org/docs/current/static/transaction-iso.html
|
303
|
+
# * https://dev.mysql.com/doc/refman/en/set-transaction.html
|
216
304
|
#
|
217
305
|
# An ActiveRecord::TransactionIsolationError will be raised if:
|
218
306
|
#
|
@@ -237,7 +325,16 @@ module ActiveRecord
|
|
237
325
|
|
238
326
|
attr_reader :transaction_manager #:nodoc:
|
239
327
|
|
240
|
-
delegate :within_new_transaction, :open_transactions, :current_transaction, :begin_transaction,
|
328
|
+
delegate :within_new_transaction, :open_transactions, :current_transaction, :begin_transaction,
|
329
|
+
:commit_transaction, :rollback_transaction, :materialize_transactions,
|
330
|
+
:disable_lazy_transactions!, :enable_lazy_transactions!, to: :transaction_manager
|
331
|
+
|
332
|
+
def mark_transaction_written_if_write(sql) # :nodoc:
|
333
|
+
transaction = current_transaction
|
334
|
+
if transaction.open?
|
335
|
+
transaction.written ||= write_query?(sql)
|
336
|
+
end
|
337
|
+
end
|
241
338
|
|
242
339
|
def transaction_open?
|
243
340
|
current_transaction.open?
|
@@ -249,12 +346,8 @@ module ActiveRecord
|
|
249
346
|
|
250
347
|
# Register a record with the current transaction so that its after_commit and after_rollback callbacks
|
251
348
|
# can be called.
|
252
|
-
def add_transaction_record(record)
|
253
|
-
current_transaction.add_record(record)
|
254
|
-
end
|
255
|
-
|
256
|
-
def transaction_state
|
257
|
-
current_transaction.state
|
349
|
+
def add_transaction_record(record, ensure_finalize = true)
|
350
|
+
current_transaction.add_record(record, ensure_finalize)
|
258
351
|
end
|
259
352
|
|
260
353
|
# Begins the transaction (and turns off auto-committing).
|
@@ -301,71 +394,137 @@ module ActiveRecord
|
|
301
394
|
end
|
302
395
|
|
303
396
|
# Inserts the given fixture into the table. Overridden in adapters that require
|
304
|
-
# something beyond a simple insert (
|
397
|
+
# something beyond a simple insert (e.g. Oracle).
|
398
|
+
# Most of adapters should implement `insert_fixtures_set` that leverages bulk SQL insert.
|
399
|
+
# We keep this method to provide fallback
|
400
|
+
# for databases like sqlite that do not support bulk inserts.
|
305
401
|
def insert_fixture(fixture, table_name)
|
306
|
-
fixture
|
402
|
+
execute(build_fixture_sql(Array.wrap(fixture), table_name), "Fixture Insert")
|
403
|
+
end
|
307
404
|
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
value_list = prepare_binds_for_database(binds).map do |value|
|
319
|
-
begin
|
320
|
-
quote(value)
|
321
|
-
rescue TypeError
|
322
|
-
quote(YAML.dump(value))
|
405
|
+
def insert_fixtures_set(fixture_set, tables_to_delete = [])
|
406
|
+
fixture_inserts = build_fixture_statements(fixture_set)
|
407
|
+
table_deletes = tables_to_delete.map { |table| "DELETE FROM #{quote_table_name(table)}" }
|
408
|
+
statements = table_deletes + fixture_inserts
|
409
|
+
|
410
|
+
with_multi_statements do
|
411
|
+
disable_referential_integrity do
|
412
|
+
transaction(requires_new: true) do
|
413
|
+
execute_batch(statements, "Fixtures Load")
|
414
|
+
end
|
323
415
|
end
|
324
416
|
end
|
325
|
-
|
326
|
-
execute "INSERT INTO #{quote_table_name(table_name)} (#{key_list.join(', ')}) VALUES (#{value_list.join(', ')})", 'Fixture Insert'
|
327
417
|
end
|
328
418
|
|
329
|
-
def empty_insert_statement_value
|
419
|
+
def empty_insert_statement_value(primary_key = nil)
|
330
420
|
"DEFAULT VALUES"
|
331
421
|
end
|
332
422
|
|
333
423
|
# Sanitizes the given LIMIT parameter in order to prevent SQL injection.
|
334
424
|
#
|
335
425
|
# The +limit+ may be anything that can evaluate to a string via #to_s. It
|
336
|
-
# should look like an integer, or
|
337
|
-
# an Arel SQL literal.
|
426
|
+
# should look like an integer, or an Arel SQL literal.
|
338
427
|
#
|
339
428
|
# Returns Integer and Arel::Nodes::SqlLiteral limits as is.
|
340
|
-
# Returns the sanitized limit parameter, either as an integer, or as a
|
341
|
-
# string which contains a comma-delimited list of integers.
|
342
429
|
def sanitize_limit(limit)
|
343
430
|
if limit.is_a?(Integer) || limit.is_a?(Arel::Nodes::SqlLiteral)
|
344
431
|
limit
|
345
|
-
elsif limit.to_s.include?(',')
|
346
|
-
Arel.sql limit.to_s.split(',').map{ |i| Integer(i) }.join(',')
|
347
432
|
else
|
348
433
|
Integer(limit)
|
349
434
|
end
|
350
435
|
end
|
351
436
|
|
352
|
-
#
|
353
|
-
#
|
354
|
-
#
|
355
|
-
def
|
356
|
-
|
357
|
-
|
358
|
-
|
437
|
+
# Fixture value is quoted by Arel, however scalar values
|
438
|
+
# are not quotable. In this case we want to convert
|
439
|
+
# the column value to YAML.
|
440
|
+
def with_yaml_fallback(value) # :nodoc:
|
441
|
+
if value.is_a?(Hash) || value.is_a?(Array)
|
442
|
+
YAML.dump(value)
|
443
|
+
else
|
444
|
+
value
|
445
|
+
end
|
359
446
|
end
|
360
|
-
alias join_to_delete join_to_update
|
361
447
|
|
362
|
-
|
448
|
+
private
|
449
|
+
def execute_batch(statements, name = nil)
|
450
|
+
statements.each do |statement|
|
451
|
+
execute(statement, name)
|
452
|
+
end
|
453
|
+
end
|
454
|
+
|
455
|
+
DEFAULT_INSERT_VALUE = Arel.sql("DEFAULT").freeze
|
456
|
+
private_constant :DEFAULT_INSERT_VALUE
|
363
457
|
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
458
|
+
def default_insert_value(column)
|
459
|
+
DEFAULT_INSERT_VALUE
|
460
|
+
end
|
461
|
+
|
462
|
+
def build_fixture_sql(fixtures, table_name)
|
463
|
+
columns = schema_cache.columns_hash(table_name)
|
464
|
+
|
465
|
+
values_list = fixtures.map do |fixture|
|
466
|
+
fixture = fixture.stringify_keys
|
467
|
+
|
468
|
+
unknown_columns = fixture.keys - columns.keys
|
469
|
+
if unknown_columns.any?
|
470
|
+
raise Fixture::FixtureError, %(table "#{table_name}" has no columns named #{unknown_columns.map(&:inspect).join(', ')}.)
|
471
|
+
end
|
472
|
+
|
473
|
+
columns.map do |name, column|
|
474
|
+
if fixture.key?(name)
|
475
|
+
type = lookup_cast_type_from_column(column)
|
476
|
+
with_yaml_fallback(type.serialize(fixture[name]))
|
477
|
+
else
|
478
|
+
default_insert_value(column)
|
479
|
+
end
|
480
|
+
end
|
481
|
+
end
|
482
|
+
|
483
|
+
table = Arel::Table.new(table_name)
|
484
|
+
manager = Arel::InsertManager.new
|
485
|
+
manager.into(table)
|
486
|
+
|
487
|
+
if values_list.size == 1
|
488
|
+
values = values_list.shift
|
489
|
+
new_values = []
|
490
|
+
columns.each_key.with_index { |column, i|
|
491
|
+
unless values[i].equal?(DEFAULT_INSERT_VALUE)
|
492
|
+
new_values << values[i]
|
493
|
+
manager.columns << table[column]
|
494
|
+
end
|
495
|
+
}
|
496
|
+
values_list << new_values
|
497
|
+
else
|
498
|
+
columns.each_key { |column| manager.columns << table[column] }
|
499
|
+
end
|
500
|
+
|
501
|
+
manager.values = manager.create_values_list(values_list)
|
502
|
+
visitor.compile(manager.ast)
|
503
|
+
end
|
504
|
+
|
505
|
+
def build_fixture_statements(fixture_set)
|
506
|
+
fixture_set.map do |table_name, fixtures|
|
507
|
+
next if fixtures.empty?
|
508
|
+
build_fixture_sql(fixtures, table_name)
|
509
|
+
end.compact
|
510
|
+
end
|
511
|
+
|
512
|
+
def build_truncate_statement(table_name)
|
513
|
+
"TRUNCATE TABLE #{quote_table_name(table_name)}"
|
514
|
+
end
|
515
|
+
|
516
|
+
def build_truncate_statements(table_names)
|
517
|
+
table_names.map do |table_name|
|
518
|
+
build_truncate_statement(table_name)
|
519
|
+
end
|
520
|
+
end
|
521
|
+
|
522
|
+
def with_multi_statements
|
523
|
+
yield
|
524
|
+
end
|
525
|
+
|
526
|
+
def combine_multi_statements(total_sql)
|
527
|
+
total_sql.join(";\n")
|
369
528
|
end
|
370
529
|
|
371
530
|
# Returns an ActiveRecord::Result instance.
|
@@ -377,20 +536,25 @@ module ActiveRecord
|
|
377
536
|
exec_query(sql, name, binds, prepare: true)
|
378
537
|
end
|
379
538
|
|
380
|
-
def sql_for_insert(sql, pk,
|
381
|
-
[sql, binds
|
539
|
+
def sql_for_insert(sql, pk, binds)
|
540
|
+
[sql, binds]
|
382
541
|
end
|
383
542
|
|
384
543
|
def last_inserted_id(result)
|
385
|
-
|
544
|
+
single_value_from_rows(result.rows)
|
545
|
+
end
|
546
|
+
|
547
|
+
def single_value_from_rows(rows)
|
548
|
+
row = rows.first
|
386
549
|
row && row.first
|
387
550
|
end
|
388
551
|
|
389
|
-
def
|
390
|
-
if relation.is_a?(Relation)
|
391
|
-
relation
|
552
|
+
def arel_from_relation(relation)
|
553
|
+
if relation.is_a?(Relation)
|
554
|
+
relation.arel
|
555
|
+
else
|
556
|
+
relation
|
392
557
|
end
|
393
|
-
[relation, binds]
|
394
558
|
end
|
395
559
|
end
|
396
560
|
end
|