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,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/per_thread_registry"
|
2
4
|
|
3
5
|
module ActiveRecord
|
4
6
|
# This is a thread locals registry for Active Record. For example:
|
@@ -12,9 +14,9 @@ module ActiveRecord
|
|
12
14
|
class RuntimeRegistry # :nodoc:
|
13
15
|
extend ActiveSupport::PerThreadRegistry
|
14
16
|
|
15
|
-
attr_accessor :
|
17
|
+
attr_accessor :sql_runtime
|
16
18
|
|
17
|
-
[:
|
19
|
+
[:sql_runtime].each do |val|
|
18
20
|
class_eval %{ def self.#{val}; instance.#{val}; end }, __FILE__, __LINE__
|
19
21
|
class_eval %{ def self.#{val}=(x); instance.#{val}=x; end }, __FILE__, __LINE__
|
20
22
|
end
|
@@ -1,17 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module Sanitization
|
3
5
|
extend ActiveSupport::Concern
|
4
6
|
|
5
7
|
module ClassMethods
|
6
|
-
# Used to sanitize objects before they're used in an SQL SELECT statement.
|
7
|
-
# Delegates to {connection.quote}[rdoc-ref:ConnectionAdapters::Quoting#quote].
|
8
|
-
def sanitize(object) # :nodoc:
|
9
|
-
connection.quote(object)
|
10
|
-
end
|
11
|
-
alias_method :quote_value, :sanitize
|
12
|
-
|
13
|
-
protected
|
14
|
-
|
15
8
|
# Accepts an array or string of SQL conditions and sanitizes
|
16
9
|
# them into a valid SQL fragment for a WHERE clause.
|
17
10
|
#
|
@@ -34,8 +27,7 @@ module ActiveRecord
|
|
34
27
|
else condition
|
35
28
|
end
|
36
29
|
end
|
37
|
-
|
38
|
-
alias_method :sanitize_conditions, :sanitize_sql
|
30
|
+
alias :sanitize_sql :sanitize_sql_for_conditions
|
39
31
|
|
40
32
|
# Accepts an array, hash, or string of SQL conditions and sanitizes
|
41
33
|
# them into a valid SQL fragment for a SET clause.
|
@@ -46,12 +38,12 @@ module ActiveRecord
|
|
46
38
|
# sanitize_sql_for_assignment(["name=:name and group_id=:group_id", name: nil, group_id: 4])
|
47
39
|
# # => "name=NULL and group_id=4"
|
48
40
|
#
|
49
|
-
# Post.
|
41
|
+
# Post.sanitize_sql_for_assignment({ name: nil, group_id: 4 })
|
50
42
|
# # => "`posts`.`name` = NULL, `posts`.`group_id` = 4"
|
51
43
|
#
|
52
44
|
# sanitize_sql_for_assignment("name=NULL and group_id='4'")
|
53
45
|
# # => "name=NULL and group_id='4'"
|
54
|
-
def sanitize_sql_for_assignment(assignments, default_table_name =
|
46
|
+
def sanitize_sql_for_assignment(assignments, default_table_name = table_name)
|
55
47
|
case assignments
|
56
48
|
when Array; sanitize_sql_array(assignments)
|
57
49
|
when Hash; sanitize_sql_hash_for_assignment(assignments, default_table_name)
|
@@ -68,47 +60,24 @@ module ActiveRecord
|
|
68
60
|
# sanitize_sql_for_order("id ASC")
|
69
61
|
# # => "id ASC"
|
70
62
|
def sanitize_sql_for_order(condition)
|
71
|
-
if condition.is_a?(Array) && condition.first.to_s.include?(
|
72
|
-
|
63
|
+
if condition.is_a?(Array) && condition.first.to_s.include?("?")
|
64
|
+
disallow_raw_sql!(
|
65
|
+
[condition.first],
|
66
|
+
permit: connection.column_name_with_order_matcher
|
67
|
+
)
|
68
|
+
|
69
|
+
# Ensure we aren't dealing with a subclass of String that might
|
70
|
+
# override methods we use (e.g. Arel::Nodes::SqlLiteral).
|
71
|
+
if condition.first.kind_of?(String) && !condition.first.instance_of?(String)
|
72
|
+
condition = [String.new(condition.first), *condition[1..-1]]
|
73
|
+
end
|
74
|
+
|
75
|
+
Arel.sql(sanitize_sql_array(condition))
|
73
76
|
else
|
74
77
|
condition
|
75
78
|
end
|
76
79
|
end
|
77
80
|
|
78
|
-
# Accepts a hash of SQL conditions and replaces those attributes
|
79
|
-
# that correspond to a {#composed_of}[rdoc-ref:Aggregations::ClassMethods#composed_of]
|
80
|
-
# relationship with their expanded aggregate attribute values.
|
81
|
-
#
|
82
|
-
# Given:
|
83
|
-
#
|
84
|
-
# class Person < ActiveRecord::Base
|
85
|
-
# composed_of :address, class_name: "Address",
|
86
|
-
# mapping: [%w(address_street street), %w(address_city city)]
|
87
|
-
# end
|
88
|
-
#
|
89
|
-
# Then:
|
90
|
-
#
|
91
|
-
# { address: Address.new("813 abc st.", "chicago") }
|
92
|
-
# # => { address_street: "813 abc st.", address_city: "chicago" }
|
93
|
-
def expand_hash_conditions_for_aggregates(attrs)
|
94
|
-
expanded_attrs = {}
|
95
|
-
attrs.each do |attr, value|
|
96
|
-
if aggregation = reflect_on_aggregation(attr.to_sym)
|
97
|
-
mapping = aggregation.mapping
|
98
|
-
mapping.each do |field_attr, aggregate_attr|
|
99
|
-
if mapping.size == 1 && !value.respond_to?(aggregate_attr)
|
100
|
-
expanded_attrs[field_attr] = value
|
101
|
-
else
|
102
|
-
expanded_attrs[field_attr] = value.send(aggregate_attr)
|
103
|
-
end
|
104
|
-
end
|
105
|
-
else
|
106
|
-
expanded_attrs[attr] = value
|
107
|
-
end
|
108
|
-
end
|
109
|
-
expanded_attrs
|
110
|
-
end
|
111
|
-
|
112
81
|
# Sanitizes a hash of attribute/value pairs into SQL conditions for a SET clause.
|
113
82
|
#
|
114
83
|
# sanitize_sql_hash_for_assignment({ status: nil, group_id: 1 }, "posts")
|
@@ -116,19 +85,10 @@ module ActiveRecord
|
|
116
85
|
def sanitize_sql_hash_for_assignment(attrs, table)
|
117
86
|
c = connection
|
118
87
|
attrs.map do |attr, value|
|
119
|
-
|
120
|
-
|
121
|
-
ActiveSupport::Deprecation.warn(<<-WARNING.squish)
|
122
|
-
Passing `ActiveRecord::Base` objects to
|
123
|
-
`sanitize_sql_hash_for_assignment` (or methods which call it,
|
124
|
-
such as `update_all`) is deprecated. Please pass the id directly,
|
125
|
-
instead.
|
126
|
-
WARNING
|
127
|
-
else
|
128
|
-
value = type_for_attribute(attr.to_s).serialize(value)
|
129
|
-
end
|
88
|
+
type = type_for_attribute(attr)
|
89
|
+
value = type.serialize(type.cast(value))
|
130
90
|
"#{c.quote_table_name_for_assignment(table, attr)} = #{c.quote(value)}"
|
131
|
-
end.join(
|
91
|
+
end.join(", ")
|
132
92
|
end
|
133
93
|
|
134
94
|
# Sanitizes a +string+ so that it is safe to use within an SQL
|
@@ -163,9 +123,9 @@ module ActiveRecord
|
|
163
123
|
# # => "name='foo''bar' and group_id='4'"
|
164
124
|
def sanitize_sql_array(ary)
|
165
125
|
statement, *values = ary
|
166
|
-
if values.first.is_a?(Hash) &&
|
126
|
+
if values.first.is_a?(Hash) && /:\w+/.match?(statement)
|
167
127
|
replace_named_bind_variables(statement, values.first)
|
168
|
-
elsif statement.include?(
|
128
|
+
elsif statement.include?("?")
|
169
129
|
replace_bind_variables(statement, values)
|
170
130
|
elsif statement.blank?
|
171
131
|
statement
|
@@ -174,57 +134,70 @@ module ActiveRecord
|
|
174
134
|
end
|
175
135
|
end
|
176
136
|
|
177
|
-
def
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
replace_bind_variable(bound.shift, c)
|
137
|
+
def disallow_raw_sql!(args, permit: connection.column_name_matcher) # :nodoc:
|
138
|
+
unexpected = nil
|
139
|
+
args.each do |arg|
|
140
|
+
next if arg.is_a?(Symbol) || Arel.arel_node?(arg) || permit.match?(arg.to_s)
|
141
|
+
(unexpected ||= []) << arg
|
183
142
|
end
|
184
|
-
end
|
185
143
|
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
144
|
+
if unexpected
|
145
|
+
raise(ActiveRecord::UnknownAttributeReference,
|
146
|
+
"Query method called with non-attribute argument(s): " +
|
147
|
+
unexpected.map(&:inspect).join(", ")
|
148
|
+
)
|
191
149
|
end
|
192
150
|
end
|
193
151
|
|
194
|
-
|
195
|
-
statement
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
raise PreparedStatementInvalid, "missing value for :#{match} in #{statement}"
|
152
|
+
private
|
153
|
+
def replace_bind_variables(statement, values)
|
154
|
+
raise_if_bind_arity_mismatch(statement, statement.count("?"), values.size)
|
155
|
+
bound = values.dup
|
156
|
+
c = connection
|
157
|
+
statement.gsub(/\?/) do
|
158
|
+
replace_bind_variable(bound.shift, c)
|
202
159
|
end
|
203
160
|
end
|
204
|
-
end
|
205
161
|
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
c.quote(nil)
|
162
|
+
def replace_bind_variable(value, c = connection)
|
163
|
+
if ActiveRecord::Relation === value
|
164
|
+
value.to_sql
|
210
165
|
else
|
211
|
-
value
|
166
|
+
quote_bound_value(value, c)
|
212
167
|
end
|
213
|
-
else
|
214
|
-
c.quote(value)
|
215
168
|
end
|
216
|
-
end
|
217
169
|
|
218
|
-
|
219
|
-
|
220
|
-
|
170
|
+
def replace_named_bind_variables(statement, bind_vars)
|
171
|
+
statement.gsub(/(:?):([a-zA-Z]\w*)/) do |match|
|
172
|
+
if $1 == ":" # skip postgresql casts
|
173
|
+
match # return the whole match
|
174
|
+
elsif bind_vars.include?(match = $2.to_sym)
|
175
|
+
replace_bind_variable(bind_vars[match])
|
176
|
+
else
|
177
|
+
raise PreparedStatementInvalid, "missing value for :#{match} in #{statement}"
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
def quote_bound_value(value, c = connection)
|
183
|
+
if value.respond_to?(:map) && !value.acts_like?(:string)
|
184
|
+
values = value.map { |v| v.respond_to?(:id_for_database) ? v.id_for_database : v }
|
185
|
+
if values.empty?
|
186
|
+
c.quote(nil)
|
187
|
+
else
|
188
|
+
values.map! { |v| c.quote(v) }.join(",")
|
189
|
+
end
|
190
|
+
else
|
191
|
+
value = value.id_for_database if value.respond_to?(:id_for_database)
|
192
|
+
c.quote(value)
|
193
|
+
end
|
221
194
|
end
|
222
|
-
end
|
223
|
-
end
|
224
195
|
|
225
|
-
|
226
|
-
|
227
|
-
|
196
|
+
def raise_if_bind_arity_mismatch(statement, expected, provided)
|
197
|
+
unless expected == provided
|
198
|
+
raise PreparedStatementInvalid, "wrong number of bind variables (#{provided} for #{expected}) in: #{statement}"
|
199
|
+
end
|
200
|
+
end
|
228
201
|
end
|
229
202
|
end
|
230
203
|
end
|
data/lib/active_record/schema.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
# = Active Record \Schema
|
3
5
|
#
|
@@ -37,10 +39,10 @@ module ActiveRecord
|
|
37
39
|
# The +info+ hash is optional, and if given is used to define metadata
|
38
40
|
# about the current schema (currently, only the schema's version):
|
39
41
|
#
|
40
|
-
# ActiveRecord::Schema.define(version:
|
42
|
+
# ActiveRecord::Schema.define(version: 2038_01_19_000001) do
|
41
43
|
# ...
|
42
44
|
# end
|
43
|
-
def self.define(info={}, &block)
|
45
|
+
def self.define(info = {}, &block)
|
44
46
|
new.define(info, &block)
|
45
47
|
end
|
46
48
|
|
@@ -48,21 +50,12 @@ module ActiveRecord
|
|
48
50
|
instance_eval(&block)
|
49
51
|
|
50
52
|
if info[:version].present?
|
51
|
-
|
52
|
-
connection.assume_migrated_upto_version(info[:version]
|
53
|
+
connection.schema_migration.create_table
|
54
|
+
connection.assume_migrated_upto_version(info[:version])
|
53
55
|
end
|
54
56
|
|
55
57
|
ActiveRecord::InternalMetadata.create_table
|
56
|
-
ActiveRecord::InternalMetadata[:environment] =
|
58
|
+
ActiveRecord::InternalMetadata[:environment] = connection.migration_context.current_environment
|
57
59
|
end
|
58
|
-
|
59
|
-
private
|
60
|
-
# Returns the migrations paths.
|
61
|
-
#
|
62
|
-
# ActiveRecord::Schema.new.migrations_paths
|
63
|
-
# # => ["db/migrate"] # Rails migration path by default.
|
64
|
-
def migrations_paths # :nodoc:
|
65
|
-
ActiveRecord::Migrator.migrations_paths
|
66
|
-
end
|
67
60
|
end
|
68
61
|
end
|
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "stringio"
|
2
4
|
|
3
5
|
module ActiveRecord
|
4
6
|
# = Active Record Schema Dumper
|
@@ -11,14 +13,25 @@ module ActiveRecord
|
|
11
13
|
##
|
12
14
|
# :singleton-method:
|
13
15
|
# A list of tables which should not be dumped to the schema.
|
14
|
-
# Acceptable values are strings as well as regexp.
|
15
|
-
#
|
16
|
-
cattr_accessor :ignore_tables
|
17
|
-
|
16
|
+
# Acceptable values are strings as well as regexp if ActiveRecord::Base.schema_format == :ruby.
|
17
|
+
# Only strings are accepted if ActiveRecord::Base.schema_format == :sql.
|
18
|
+
cattr_accessor :ignore_tables, default: []
|
19
|
+
|
20
|
+
##
|
21
|
+
# :singleton-method:
|
22
|
+
# Specify a custom regular expression matching foreign keys which name
|
23
|
+
# should not be dumped to db/schema.rb.
|
24
|
+
cattr_accessor :fk_ignore_pattern, default: /^fk_rails_[0-9a-f]{10}$/
|
25
|
+
|
26
|
+
##
|
27
|
+
# :singleton-method:
|
28
|
+
# Specify a custom regular expression matching check constraints which name
|
29
|
+
# should not be dumped to db/schema.rb.
|
30
|
+
cattr_accessor :chk_ignore_pattern, default: /^chk_rails_[0-9a-f]{10}$/
|
18
31
|
|
19
32
|
class << self
|
20
|
-
def dump(connection=ActiveRecord::Base.connection, stream=STDOUT, config = ActiveRecord::Base)
|
21
|
-
|
33
|
+
def dump(connection = ActiveRecord::Base.connection, stream = STDOUT, config = ActiveRecord::Base)
|
34
|
+
connection.create_schema_dumper(generate_options(config)).dump(stream)
|
22
35
|
stream
|
23
36
|
end
|
24
37
|
|
@@ -40,26 +53,36 @@ module ActiveRecord
|
|
40
53
|
end
|
41
54
|
|
42
55
|
private
|
56
|
+
attr_accessor :table_name
|
43
57
|
|
44
58
|
def initialize(connection, options = {})
|
45
59
|
@connection = connection
|
46
|
-
@version =
|
60
|
+
@version = connection.migration_context.current_version rescue nil
|
47
61
|
@options = options
|
48
62
|
end
|
49
63
|
|
50
|
-
|
51
|
-
|
64
|
+
# turns 20170404131909 into "2017_04_04_131909"
|
65
|
+
def formatted_version
|
66
|
+
stringified = @version.to_s
|
67
|
+
return stringified unless stringified.length == 14
|
68
|
+
stringified.insert(4, "_").insert(7, "_").insert(10, "_")
|
69
|
+
end
|
70
|
+
|
71
|
+
def define_params
|
72
|
+
@version ? "version: #{formatted_version}" : ""
|
73
|
+
end
|
52
74
|
|
75
|
+
def header(stream)
|
53
76
|
stream.puts <<HEADER
|
54
77
|
# This file is auto-generated from the current state of the database. Instead
|
55
78
|
# of editing this file, please use the migrations feature of Active Record to
|
56
79
|
# incrementally modify your database, and then regenerate this schema definition.
|
57
80
|
#
|
58
|
-
#
|
59
|
-
#
|
60
|
-
#
|
61
|
-
# from scratch.
|
62
|
-
#
|
81
|
+
# This file is the source Rails uses to define your schema when running `bin/rails
|
82
|
+
# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to
|
83
|
+
# be faster and is potentially less error prone than running all of your
|
84
|
+
# migrations from scratch. Old migrations may fail to apply correctly if those
|
85
|
+
# migrations use external dependencies or application code.
|
63
86
|
#
|
64
87
|
# It's strongly recommended that you check this file into your version control system.
|
65
88
|
|
@@ -72,20 +95,12 @@ HEADER
|
|
72
95
|
stream.puts "end"
|
73
96
|
end
|
74
97
|
|
98
|
+
# extensions are only supported by PostgreSQL
|
75
99
|
def extensions(stream)
|
76
|
-
return unless @connection.supports_extensions?
|
77
|
-
extensions = @connection.extensions
|
78
|
-
if extensions.any?
|
79
|
-
stream.puts " # These are extensions that must be enabled in order to support this database"
|
80
|
-
extensions.each do |extension|
|
81
|
-
stream.puts " enable_extension #{extension.inspect}"
|
82
|
-
end
|
83
|
-
stream.puts
|
84
|
-
end
|
85
100
|
end
|
86
101
|
|
87
102
|
def tables(stream)
|
88
|
-
sorted_tables = @connection.
|
103
|
+
sorted_tables = @connection.tables.sort
|
89
104
|
|
90
105
|
sorted_tables.each do |table_name|
|
91
106
|
table(table_name, stream) unless ignored?(table_name)
|
@@ -102,6 +117,8 @@ HEADER
|
|
102
117
|
def table(table, stream)
|
103
118
|
columns = @connection.columns(table)
|
104
119
|
begin
|
120
|
+
self.table_name = table
|
121
|
+
|
105
122
|
tbl = StringIO.new
|
106
123
|
|
107
124
|
# first dump primary key column
|
@@ -111,64 +128,44 @@ HEADER
|
|
111
128
|
|
112
129
|
case pk
|
113
130
|
when String
|
114
|
-
tbl.print ", primary_key: #{pk.inspect}" unless pk ==
|
131
|
+
tbl.print ", primary_key: #{pk.inspect}" unless pk == "id"
|
115
132
|
pkcol = columns.detect { |c| c.name == pk }
|
116
|
-
pkcolspec =
|
117
|
-
|
118
|
-
pkcolspec
|
119
|
-
|
133
|
+
pkcolspec = column_spec_for_primary_key(pkcol)
|
134
|
+
unless pkcolspec.empty?
|
135
|
+
if pkcolspec != pkcolspec.slice(:id, :default)
|
136
|
+
pkcolspec = { id: { type: pkcolspec.delete(:id), **pkcolspec }.compact }
|
120
137
|
end
|
138
|
+
tbl.print ", #{format_colspec(pkcolspec)}"
|
121
139
|
end
|
122
140
|
when Array
|
123
141
|
tbl.print ", primary_key: #{pk.inspect}"
|
124
142
|
else
|
125
143
|
tbl.print ", id: false"
|
126
144
|
end
|
127
|
-
tbl.print ", force: :cascade"
|
128
145
|
|
129
146
|
table_options = @connection.table_options(table)
|
130
147
|
if table_options.present?
|
131
148
|
tbl.print ", #{format_options(table_options)}"
|
132
149
|
end
|
133
150
|
|
134
|
-
tbl.puts " do |t|"
|
151
|
+
tbl.puts ", force: :cascade do |t|"
|
135
152
|
|
136
153
|
# then dump all non-primary key columns
|
137
|
-
|
154
|
+
columns.each do |column|
|
138
155
|
raise StandardError, "Unknown type '#{column.sql_type}' for column '#{column.name}'" unless @connection.valid_type?(column.type)
|
139
156
|
next if column.name == pk
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
lengths = keys.map { |key|
|
148
|
-
column_specs.map { |spec|
|
149
|
-
spec[key] ? spec[key].length + 2 : 0
|
150
|
-
}.max
|
151
|
-
}
|
152
|
-
|
153
|
-
# the string we're going to sprintf our values against, with standardized column widths
|
154
|
-
format_string = lengths.map{ |len| "%-#{len}s" }
|
155
|
-
|
156
|
-
# find the max length for the 'type' column, which is special
|
157
|
-
type_length = column_specs.map{ |column| column[:type].length }.max
|
158
|
-
|
159
|
-
# add column type definition to our format string
|
160
|
-
format_string.unshift " t.%-#{type_length}s "
|
161
|
-
|
162
|
-
format_string *= ''
|
163
|
-
|
164
|
-
column_specs.each do |colspec|
|
165
|
-
values = keys.zip(lengths).map{ |key, len| colspec.key?(key) ? colspec[key] + ", " : " " * len }
|
166
|
-
values.unshift colspec[:type]
|
167
|
-
tbl.print((format_string % values).gsub(/,\s*$/, ''))
|
157
|
+
type, colspec = column_spec(column)
|
158
|
+
if type.is_a?(Symbol)
|
159
|
+
tbl.print " t.#{type} #{column.name.inspect}"
|
160
|
+
else
|
161
|
+
tbl.print " t.column #{column.name.inspect}, #{type.inspect}"
|
162
|
+
end
|
163
|
+
tbl.print ", #{format_colspec(colspec)}" if colspec.present?
|
168
164
|
tbl.puts
|
169
165
|
end
|
170
166
|
|
171
167
|
indexes_in_create(table, tbl)
|
168
|
+
check_constraints_in_create(table, tbl) if @connection.supports_check_constraints?
|
172
169
|
|
173
170
|
tbl.puts " end"
|
174
171
|
tbl.puts
|
@@ -179,9 +176,9 @@ HEADER
|
|
179
176
|
stream.puts "# Could not dump table #{table.inspect} because of following #{e.class}"
|
180
177
|
stream.puts "# #{e.message}"
|
181
178
|
stream.puts
|
179
|
+
ensure
|
180
|
+
self.table_name = nil
|
182
181
|
end
|
183
|
-
|
184
|
-
stream
|
185
182
|
end
|
186
183
|
|
187
184
|
# Keep it for indexing materialized views
|
@@ -189,7 +186,7 @@ HEADER
|
|
189
186
|
if (indexes = @connection.indexes(table)).any?
|
190
187
|
add_index_statements = indexes.map do |index|
|
191
188
|
table_name = remove_prefix_and_suffix(index.table).inspect
|
192
|
-
" add_index #{([table_name]+index_parts(index)).join(', ')}"
|
189
|
+
" add_index #{([table_name] + index_parts(index)).join(', ')}"
|
193
190
|
end
|
194
191
|
|
195
192
|
stream.puts add_index_statements.sort.join("\n")
|
@@ -212,15 +209,34 @@ HEADER
|
|
212
209
|
"name: #{index.name.inspect}",
|
213
210
|
]
|
214
211
|
index_parts << "unique: true" if index.unique
|
215
|
-
index_parts << "length:
|
216
|
-
index_parts << "order:
|
212
|
+
index_parts << "length: #{format_index_parts(index.lengths)}" if index.lengths.present?
|
213
|
+
index_parts << "order: #{format_index_parts(index.orders)}" if index.orders.present?
|
214
|
+
index_parts << "opclass: #{format_index_parts(index.opclasses)}" if index.opclasses.present?
|
217
215
|
index_parts << "where: #{index.where.inspect}" if index.where
|
218
|
-
index_parts << "using: #{index.using.inspect}" if index
|
216
|
+
index_parts << "using: #{index.using.inspect}" if !@connection.default_index_type?(index)
|
219
217
|
index_parts << "type: #{index.type.inspect}" if index.type
|
220
218
|
index_parts << "comment: #{index.comment.inspect}" if index.comment
|
221
219
|
index_parts
|
222
220
|
end
|
223
221
|
|
222
|
+
def check_constraints_in_create(table, stream)
|
223
|
+
if (check_constraints = @connection.check_constraints(table)).any?
|
224
|
+
add_check_constraint_statements = check_constraints.map do |check_constraint|
|
225
|
+
parts = [
|
226
|
+
"t.check_constraint #{check_constraint.expression.inspect}"
|
227
|
+
]
|
228
|
+
|
229
|
+
if check_constraint.export_name_on_schema_dump?
|
230
|
+
parts << "name: #{check_constraint.name.inspect}"
|
231
|
+
end
|
232
|
+
|
233
|
+
" #{parts.join(', ')}"
|
234
|
+
end
|
235
|
+
|
236
|
+
stream.puts add_check_constraint_statements.sort.join("\n")
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
224
240
|
def foreign_keys(table, stream)
|
225
241
|
if (foreign_keys = @connection.foreign_keys(table)).any?
|
226
242
|
add_foreign_key_statements = foreign_keys.map do |foreign_key|
|
@@ -237,7 +253,7 @@ HEADER
|
|
237
253
|
parts << "primary_key: #{foreign_key.primary_key.inspect}"
|
238
254
|
end
|
239
255
|
|
240
|
-
if foreign_key.
|
256
|
+
if foreign_key.export_name_on_schema_dump?
|
241
257
|
parts << "name: #{foreign_key.name.inspect}"
|
242
258
|
end
|
243
259
|
|
@@ -251,12 +267,28 @@ HEADER
|
|
251
267
|
end
|
252
268
|
end
|
253
269
|
|
270
|
+
def format_colspec(colspec)
|
271
|
+
colspec.map do |key, value|
|
272
|
+
"#{key}: #{ value.is_a?(Hash) ? "{ #{format_colspec(value)} }" : value }"
|
273
|
+
end.join(", ")
|
274
|
+
end
|
275
|
+
|
254
276
|
def format_options(options)
|
255
277
|
options.map { |key, value| "#{key}: #{value.inspect}" }.join(", ")
|
256
278
|
end
|
257
279
|
|
280
|
+
def format_index_parts(options)
|
281
|
+
if options.is_a?(Hash)
|
282
|
+
"{ #{format_options(options)} }"
|
283
|
+
else
|
284
|
+
options.inspect
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
258
288
|
def remove_prefix_and_suffix(table)
|
259
|
-
|
289
|
+
prefix = Regexp.escape(@options[:table_name_prefix].to_s)
|
290
|
+
suffix = Regexp.escape(@options[:table_name_suffix].to_s)
|
291
|
+
table.sub(/\A#{prefix}(.+)#{suffix}\z/, "\\1")
|
260
292
|
end
|
261
293
|
|
262
294
|
def ignored?(table_name)
|