activerecord 6.0.3 → 6.1.3
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 +968 -682
- data/MIT-LICENSE +1 -1
- data/README.rdoc +3 -3
- data/lib/active_record.rb +7 -14
- data/lib/active_record/aggregations.rb +5 -5
- data/lib/active_record/association_relation.rb +30 -12
- data/lib/active_record/associations.rb +118 -11
- data/lib/active_record/associations/alias_tracker.rb +19 -15
- data/lib/active_record/associations/association.rb +44 -28
- data/lib/active_record/associations/association_scope.rb +19 -15
- data/lib/active_record/associations/belongs_to_association.rb +22 -8
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -3
- data/lib/active_record/associations/builder/association.rb +32 -5
- data/lib/active_record/associations/builder/belongs_to.rb +10 -7
- data/lib/active_record/associations/builder/collection_association.rb +5 -4
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +0 -1
- data/lib/active_record/associations/builder/has_many.rb +6 -2
- data/lib/active_record/associations/builder/has_one.rb +11 -14
- data/lib/active_record/associations/builder/singular_association.rb +1 -1
- data/lib/active_record/associations/collection_association.rb +19 -6
- data/lib/active_record/associations/collection_proxy.rb +13 -5
- data/lib/active_record/associations/foreign_association.rb +13 -0
- data/lib/active_record/associations/has_many_association.rb +24 -2
- data/lib/active_record/associations/has_many_through_association.rb +10 -4
- data/lib/active_record/associations/has_one_association.rb +15 -1
- data/lib/active_record/associations/join_dependency.rb +72 -50
- data/lib/active_record/associations/join_dependency/join_association.rb +39 -16
- data/lib/active_record/associations/join_dependency/join_part.rb +3 -3
- data/lib/active_record/associations/preloader.rb +11 -5
- data/lib/active_record/associations/preloader/association.rb +51 -25
- data/lib/active_record/associations/preloader/through_association.rb +2 -2
- data/lib/active_record/associations/singular_association.rb +1 -1
- data/lib/active_record/associations/through_association.rb +1 -1
- data/lib/active_record/attribute_assignment.rb +10 -8
- data/lib/active_record/attribute_methods.rb +64 -54
- data/lib/active_record/attribute_methods/before_type_cast.rb +13 -9
- data/lib/active_record/attribute_methods/dirty.rb +1 -11
- data/lib/active_record/attribute_methods/primary_key.rb +6 -2
- data/lib/active_record/attribute_methods/query.rb +3 -6
- data/lib/active_record/attribute_methods/read.rb +8 -11
- data/lib/active_record/attribute_methods/serialization.rb +11 -5
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +12 -13
- data/lib/active_record/attribute_methods/write.rb +12 -20
- data/lib/active_record/attributes.rb +33 -8
- data/lib/active_record/autosave_association.rb +57 -40
- data/lib/active_record/base.rb +2 -14
- data/lib/active_record/callbacks.rb +152 -22
- data/lib/active_record/coders/yaml_column.rb +1 -1
- data/lib/active_record/connection_adapters.rb +50 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +191 -134
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +2 -44
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +66 -23
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +3 -8
- data/lib/active_record/connection_adapters/abstract/quoting.rb +34 -34
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +153 -116
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +116 -27
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +3 -3
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +228 -83
- data/lib/active_record/connection_adapters/abstract/transaction.rb +80 -32
- data/lib/active_record/connection_adapters/abstract_adapter.rb +54 -72
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +129 -88
- data/lib/active_record/connection_adapters/column.rb +15 -1
- 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/database_statements.rb +23 -25
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/quoting.rb +18 -3
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +32 -6
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +8 -0
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +5 -2
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +11 -7
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +10 -1
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +31 -12
- data/lib/active_record/connection_adapters/pool_config.rb +73 -0
- data/lib/active_record/connection_adapters/pool_manager.rb +43 -0
- data/lib/active_record/connection_adapters/postgresql/column.rb +24 -1
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +13 -54
- data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -5
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +10 -2
- data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +24 -5
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +11 -1
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +4 -4
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +5 -1
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +61 -29
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +8 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +74 -63
- data/lib/active_record/connection_adapters/schema_cache.rb +98 -15
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +10 -0
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +31 -6
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +1 -1
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -1
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +37 -4
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +49 -50
- data/lib/active_record/connection_handling.rb +218 -71
- data/lib/active_record/core.rb +245 -61
- data/lib/active_record/database_configurations.rb +124 -85
- data/lib/active_record/database_configurations/connection_url_resolver.rb +98 -0
- data/lib/active_record/database_configurations/database_config.rb +52 -9
- data/lib/active_record/database_configurations/hash_config.rb +54 -8
- data/lib/active_record/database_configurations/url_config.rb +15 -40
- data/lib/active_record/delegated_type.rb +209 -0
- data/lib/active_record/destroy_association_async_job.rb +36 -0
- data/lib/active_record/enum.rb +82 -38
- data/lib/active_record/errors.rb +47 -12
- data/lib/active_record/explain.rb +9 -4
- data/lib/active_record/explain_subscriber.rb +1 -1
- data/lib/active_record/fixture_set/file.rb +10 -17
- data/lib/active_record/fixture_set/model_metadata.rb +1 -2
- data/lib/active_record/fixture_set/render_context.rb +1 -1
- data/lib/active_record/fixture_set/table_row.rb +2 -2
- data/lib/active_record/fixtures.rb +58 -9
- data/lib/active_record/gem_version.rb +1 -1
- data/lib/active_record/inheritance.rb +40 -18
- data/lib/active_record/insert_all.rb +35 -6
- data/lib/active_record/integration.rb +3 -5
- data/lib/active_record/internal_metadata.rb +16 -7
- data/lib/active_record/legacy_yaml_adapter.rb +7 -3
- data/lib/active_record/locking/optimistic.rb +33 -17
- data/lib/active_record/locking/pessimistic.rb +6 -2
- data/lib/active_record/log_subscriber.rb +27 -8
- data/lib/active_record/middleware/database_selector.rb +4 -1
- data/lib/active_record/middleware/database_selector/resolver.rb +5 -0
- data/lib/active_record/middleware/database_selector/resolver/session.rb +3 -0
- data/lib/active_record/migration.rb +114 -84
- data/lib/active_record/migration/command_recorder.rb +47 -27
- data/lib/active_record/migration/compatibility.rb +68 -17
- data/lib/active_record/model_schema.rb +117 -13
- data/lib/active_record/nested_attributes.rb +2 -3
- data/lib/active_record/no_touching.rb +1 -1
- data/lib/active_record/persistence.rb +50 -45
- data/lib/active_record/query_cache.rb +15 -5
- data/lib/active_record/querying.rb +11 -6
- data/lib/active_record/railtie.rb +64 -44
- data/lib/active_record/railties/console_sandbox.rb +2 -4
- data/lib/active_record/railties/databases.rake +276 -99
- data/lib/active_record/readonly_attributes.rb +4 -0
- data/lib/active_record/reflection.rb +71 -57
- data/lib/active_record/relation.rb +95 -67
- data/lib/active_record/relation/batches.rb +38 -31
- data/lib/active_record/relation/batches/batch_enumerator.rb +25 -9
- data/lib/active_record/relation/calculations.rb +101 -44
- data/lib/active_record/relation/delegation.rb +2 -1
- data/lib/active_record/relation/finder_methods.rb +45 -15
- data/lib/active_record/relation/from_clause.rb +1 -1
- data/lib/active_record/relation/merger.rb +27 -25
- data/lib/active_record/relation/predicate_builder.rb +61 -38
- data/lib/active_record/relation/predicate_builder/array_handler.rb +8 -9
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +4 -5
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +10 -6
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
- data/lib/active_record/relation/query_methods.rb +333 -195
- data/lib/active_record/relation/record_fetch_warning.rb +3 -3
- data/lib/active_record/relation/spawn_methods.rb +8 -7
- data/lib/active_record/relation/where_clause.rb +107 -60
- data/lib/active_record/result.rb +41 -33
- data/lib/active_record/runtime_registry.rb +2 -2
- data/lib/active_record/sanitization.rb +6 -17
- data/lib/active_record/schema_dumper.rb +34 -4
- data/lib/active_record/schema_migration.rb +2 -8
- data/lib/active_record/scoping/named.rb +6 -17
- data/lib/active_record/secure_token.rb +16 -8
- data/lib/active_record/serialization.rb +5 -3
- data/lib/active_record/signed_id.rb +116 -0
- data/lib/active_record/statement_cache.rb +20 -4
- data/lib/active_record/store.rb +2 -2
- data/lib/active_record/suppressor.rb +2 -2
- data/lib/active_record/table_metadata.rb +42 -51
- data/lib/active_record/tasks/database_tasks.rb +140 -113
- data/lib/active_record/tasks/mysql_database_tasks.rb +34 -35
- data/lib/active_record/tasks/postgresql_database_tasks.rb +24 -26
- data/lib/active_record/tasks/sqlite_database_tasks.rb +13 -9
- data/lib/active_record/test_databases.rb +5 -4
- data/lib/active_record/test_fixtures.rb +37 -16
- data/lib/active_record/timestamp.rb +4 -6
- data/lib/active_record/touch_later.rb +21 -21
- data/lib/active_record/transactions.rb +19 -66
- data/lib/active_record/type.rb +8 -1
- data/lib/active_record/type/serialized.rb +6 -2
- data/lib/active_record/type/time.rb +10 -0
- data/lib/active_record/type_caster/connection.rb +0 -1
- data/lib/active_record/type_caster/map.rb +8 -5
- data/lib/active_record/validations.rb +1 -0
- data/lib/active_record/validations/numericality.rb +35 -0
- data/lib/active_record/validations/uniqueness.rb +24 -4
- data/lib/arel.rb +5 -13
- data/lib/arel/attributes/attribute.rb +4 -0
- data/lib/arel/collectors/bind.rb +5 -0
- data/lib/arel/collectors/composite.rb +8 -0
- data/lib/arel/collectors/sql_string.rb +7 -0
- data/lib/arel/collectors/substitute_binds.rb +7 -0
- data/lib/arel/nodes.rb +3 -1
- data/lib/arel/nodes/binary.rb +82 -8
- data/lib/arel/nodes/bind_param.rb +8 -0
- data/lib/arel/nodes/casted.rb +21 -9
- data/lib/arel/nodes/equality.rb +6 -9
- data/lib/arel/nodes/grouping.rb +3 -0
- data/lib/arel/nodes/homogeneous_in.rb +72 -0
- data/lib/arel/nodes/in.rb +8 -1
- data/lib/arel/nodes/infix_operation.rb +13 -1
- data/lib/arel/nodes/join_source.rb +1 -1
- data/lib/arel/nodes/node.rb +7 -6
- data/lib/arel/nodes/ordering.rb +27 -0
- data/lib/arel/nodes/sql_literal.rb +3 -0
- data/lib/arel/nodes/table_alias.rb +7 -3
- data/lib/arel/nodes/unary.rb +0 -1
- data/lib/arel/predications.rb +12 -18
- data/lib/arel/select_manager.rb +1 -2
- data/lib/arel/table.rb +13 -5
- data/lib/arel/visitors.rb +0 -7
- data/lib/arel/visitors/dot.rb +14 -2
- data/lib/arel/visitors/mysql.rb +11 -1
- data/lib/arel/visitors/postgresql.rb +15 -4
- data/lib/arel/visitors/to_sql.rb +89 -78
- data/lib/rails/generators/active_record/migration.rb +6 -1
- data/lib/rails/generators/active_record/migration/migration_generator.rb +1 -0
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +2 -0
- data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +3 -3
- data/lib/rails/generators/active_record/model/model_generator.rb +39 -2
- data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
- metadata +28 -29
- data/lib/active_record/advisory_lock_base.rb +0 -18
- data/lib/active_record/attribute_decorators.rb +0 -88
- data/lib/active_record/connection_adapters/connection_specification.rb +0 -296
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -29
- data/lib/active_record/define_callbacks.rb +0 -22
- data/lib/active_record/railties/collection_cache_association_loading.rb +0 -34
- data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -18
- data/lib/active_record/relation/where_clause_factory.rb +0 -33
- data/lib/arel/attributes.rb +0 -22
- data/lib/arel/visitors/depth_first.rb +0 -203
- data/lib/arel/visitors/ibm_db.rb +0 -34
- data/lib/arel/visitors/informix.rb +0 -62
- data/lib/arel/visitors/mssql.rb +0 -156
- data/lib/arel/visitors/oracle.rb +0 -158
- data/lib/arel/visitors/oracle12.rb +0 -65
- data/lib/arel/visitors/where_sql.rb +0 -22
@@ -2,151 +2,188 @@
|
|
2
2
|
|
3
3
|
module ActiveRecord
|
4
4
|
module ConnectionAdapters
|
5
|
-
class
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
5
|
+
class SchemaCreation # :nodoc:
|
6
|
+
def initialize(conn)
|
7
|
+
@conn = conn
|
8
|
+
@cache = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def accept(o)
|
12
|
+
m = @cache[o.class] ||= "visit_#{o.class.name.split('::').last}"
|
13
|
+
send m, o
|
14
|
+
end
|
15
|
+
|
16
|
+
delegate :quote_column_name, :quote_table_name, :quote_default_expression, :type_to_sql,
|
17
|
+
:options_include_default?, :supports_indexes_in_create?, :supports_foreign_keys?, :foreign_key_options,
|
18
|
+
:quoted_columns_for_index, :supports_partial_index?, :supports_check_constraints?, :check_constraint_options,
|
19
|
+
to: :@conn, private: true
|
20
|
+
|
21
|
+
private
|
22
|
+
def visit_AlterTable(o)
|
23
|
+
sql = +"ALTER TABLE #{quote_table_name(o.name)} "
|
24
|
+
sql << o.adds.map { |col| accept col }.join(" ")
|
25
|
+
sql << o.foreign_key_adds.map { |fk| visit_AddForeignKey fk }.join(" ")
|
26
|
+
sql << o.foreign_key_drops.map { |fk| visit_DropForeignKey fk }.join(" ")
|
27
|
+
sql << o.check_constraint_adds.map { |con| visit_AddCheckConstraint con }.join(" ")
|
28
|
+
sql << o.check_constraint_drops.map { |con| visit_DropCheckConstraint con }.join(" ")
|
29
|
+
end
|
30
|
+
|
31
|
+
def visit_ColumnDefinition(o)
|
32
|
+
o.sql_type = type_to_sql(o.type, **o.options)
|
33
|
+
column_sql = +"#{quote_column_name(o.name)} #{o.sql_type}"
|
34
|
+
add_column_options!(column_sql, column_options(o)) unless o.type == :primary_key
|
35
|
+
column_sql
|
10
36
|
end
|
11
37
|
|
12
|
-
def
|
13
|
-
|
14
|
-
send m, o
|
38
|
+
def visit_AddColumnDefinition(o)
|
39
|
+
+"ADD #{accept(o.column)}"
|
15
40
|
end
|
16
41
|
|
17
|
-
|
18
|
-
|
19
|
-
|
42
|
+
def visit_TableDefinition(o)
|
43
|
+
create_sql = +"CREATE#{table_modifier_in_create(o)} TABLE "
|
44
|
+
create_sql << "IF NOT EXISTS " if o.if_not_exists
|
45
|
+
create_sql << "#{quote_table_name(o.name)} "
|
20
46
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
sql << o.foreign_key_drops.map { |fk| visit_DropForeignKey fk }.join(" ")
|
47
|
+
statements = o.columns.map { |c| accept c }
|
48
|
+
statements << accept(o.primary_keys) if o.primary_keys
|
49
|
+
|
50
|
+
if supports_indexes_in_create?
|
51
|
+
statements.concat(o.indexes.map { |column_name, options| index_in_create(o.name, column_name, options) })
|
27
52
|
end
|
28
53
|
|
29
|
-
|
30
|
-
o.
|
31
|
-
column_sql = +"#{quote_column_name(o.name)} #{o.sql_type}"
|
32
|
-
add_column_options!(column_sql, column_options(o)) unless o.type == :primary_key
|
33
|
-
column_sql
|
54
|
+
if supports_foreign_keys?
|
55
|
+
statements.concat(o.foreign_keys.map { |to_table, options| foreign_key_in_create(o.name, to_table, options) })
|
34
56
|
end
|
35
57
|
|
36
|
-
|
37
|
-
|
58
|
+
if supports_check_constraints?
|
59
|
+
statements.concat(o.check_constraints.map { |expression, options| check_constraint_in_create(o.name, expression, options) })
|
38
60
|
end
|
39
61
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
62
|
+
create_sql << "(#{statements.join(', ')})" if statements.present?
|
63
|
+
add_table_options!(create_sql, o)
|
64
|
+
create_sql << " AS #{to_sql(o.as)}" if o.as
|
65
|
+
create_sql
|
66
|
+
end
|
44
67
|
|
45
|
-
|
46
|
-
|
68
|
+
def visit_PrimaryKeyDefinition(o)
|
69
|
+
"PRIMARY KEY (#{o.name.map { |name| quote_column_name(name) }.join(', ')})"
|
70
|
+
end
|
47
71
|
|
48
|
-
|
49
|
-
|
50
|
-
|
72
|
+
def visit_ForeignKeyDefinition(o)
|
73
|
+
sql = +<<~SQL
|
74
|
+
CONSTRAINT #{quote_column_name(o.name)}
|
75
|
+
FOREIGN KEY (#{quote_column_name(o.column)})
|
76
|
+
REFERENCES #{quote_table_name(o.to_table)} (#{quote_column_name(o.primary_key)})
|
77
|
+
SQL
|
78
|
+
sql << " #{action_sql('DELETE', o.on_delete)}" if o.on_delete
|
79
|
+
sql << " #{action_sql('UPDATE', o.on_update)}" if o.on_update
|
80
|
+
sql
|
81
|
+
end
|
51
82
|
|
52
|
-
|
53
|
-
|
54
|
-
|
83
|
+
def visit_AddForeignKey(o)
|
84
|
+
"ADD #{accept(o)}"
|
85
|
+
end
|
55
86
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
create_sql
|
60
|
-
end
|
87
|
+
def visit_DropForeignKey(name)
|
88
|
+
"DROP CONSTRAINT #{quote_column_name(name)}"
|
89
|
+
end
|
61
90
|
|
62
|
-
|
63
|
-
|
64
|
-
|
91
|
+
def visit_CreateIndexDefinition(o)
|
92
|
+
index = o.index
|
93
|
+
|
94
|
+
sql = ["CREATE"]
|
95
|
+
sql << "UNIQUE" if index.unique
|
96
|
+
sql << "INDEX"
|
97
|
+
sql << "IF NOT EXISTS" if o.if_not_exists
|
98
|
+
sql << o.algorithm if o.algorithm
|
99
|
+
sql << index.type if index.type
|
100
|
+
sql << "#{quote_column_name(index.name)} ON #{quote_table_name(index.table)}"
|
101
|
+
sql << "USING #{index.using}" if supports_index_using? && index.using
|
102
|
+
sql << "(#{quoted_columns(index)})"
|
103
|
+
sql << "WHERE #{index.where}" if supports_partial_index? && index.where
|
104
|
+
|
105
|
+
sql.join(" ")
|
106
|
+
end
|
65
107
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
FOREIGN KEY (#{quote_column_name(o.column)})
|
70
|
-
REFERENCES #{quote_table_name(o.to_table)} (#{quote_column_name(o.primary_key)})
|
71
|
-
SQL
|
72
|
-
sql << " #{action_sql('DELETE', o.on_delete)}" if o.on_delete
|
73
|
-
sql << " #{action_sql('UPDATE', o.on_update)}" if o.on_update
|
74
|
-
sql
|
75
|
-
end
|
108
|
+
def visit_CheckConstraintDefinition(o)
|
109
|
+
"CONSTRAINT #{o.name} CHECK (#{o.expression})"
|
110
|
+
end
|
76
111
|
|
77
|
-
|
78
|
-
|
79
|
-
|
112
|
+
def visit_AddCheckConstraint(o)
|
113
|
+
"ADD #{accept(o)}"
|
114
|
+
end
|
80
115
|
|
81
|
-
|
82
|
-
|
83
|
-
|
116
|
+
def visit_DropCheckConstraint(name)
|
117
|
+
"DROP CONSTRAINT #{quote_column_name(name)}"
|
118
|
+
end
|
84
119
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
table_options[:options] = o.options
|
89
|
-
table_options
|
90
|
-
end
|
120
|
+
def quoted_columns(o)
|
121
|
+
String === o.columns ? o.columns : quoted_columns_for_index(o.columns, o.column_options)
|
122
|
+
end
|
91
123
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
end
|
96
|
-
create_sql
|
97
|
-
end
|
124
|
+
def supports_index_using?
|
125
|
+
true
|
126
|
+
end
|
98
127
|
|
99
|
-
|
100
|
-
|
101
|
-
|
128
|
+
def add_table_options!(create_sql, o)
|
129
|
+
create_sql << " #{o.options}" if o.options
|
130
|
+
create_sql
|
131
|
+
end
|
102
132
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
if options[:null] == false
|
107
|
-
sql << " NOT NULL"
|
108
|
-
end
|
109
|
-
if options[:auto_increment] == true
|
110
|
-
sql << " AUTO_INCREMENT"
|
111
|
-
end
|
112
|
-
if options[:primary_key] == true
|
113
|
-
sql << " PRIMARY KEY"
|
114
|
-
end
|
115
|
-
sql
|
116
|
-
end
|
133
|
+
def column_options(o)
|
134
|
+
o.options.merge(column: o)
|
135
|
+
end
|
117
136
|
|
118
|
-
|
119
|
-
|
120
|
-
|
137
|
+
def add_column_options!(sql, options)
|
138
|
+
sql << " DEFAULT #{quote_default_expression(options[:default], options[:column])}" if options_include_default?(options)
|
139
|
+
# must explicitly check for :null to allow change_column to work on migrations
|
140
|
+
if options[:null] == false
|
141
|
+
sql << " NOT NULL"
|
121
142
|
end
|
122
|
-
|
123
|
-
|
124
|
-
def table_modifier_in_create(o)
|
125
|
-
" TEMPORARY" if o.temporary
|
143
|
+
if options[:auto_increment] == true
|
144
|
+
sql << " AUTO_INCREMENT"
|
126
145
|
end
|
127
|
-
|
128
|
-
|
129
|
-
prefix = ActiveRecord::Base.table_name_prefix
|
130
|
-
suffix = ActiveRecord::Base.table_name_suffix
|
131
|
-
to_table = "#{prefix}#{to_table}#{suffix}"
|
132
|
-
options = foreign_key_options(from_table, to_table, options)
|
133
|
-
accept ForeignKeyDefinition.new(from_table, to_table, options)
|
146
|
+
if options[:primary_key] == true
|
147
|
+
sql << " PRIMARY KEY"
|
134
148
|
end
|
149
|
+
sql
|
150
|
+
end
|
135
151
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
152
|
+
def to_sql(sql)
|
153
|
+
sql = sql.to_sql if sql.respond_to?(:to_sql)
|
154
|
+
sql
|
155
|
+
end
|
156
|
+
|
157
|
+
# Returns any SQL string to go between CREATE and TABLE. May be nil.
|
158
|
+
def table_modifier_in_create(o)
|
159
|
+
" TEMPORARY" if o.temporary
|
160
|
+
end
|
161
|
+
|
162
|
+
def foreign_key_in_create(from_table, to_table, options)
|
163
|
+
prefix = ActiveRecord::Base.table_name_prefix
|
164
|
+
suffix = ActiveRecord::Base.table_name_suffix
|
165
|
+
to_table = "#{prefix}#{to_table}#{suffix}"
|
166
|
+
options = foreign_key_options(from_table, to_table, options)
|
167
|
+
accept ForeignKeyDefinition.new(from_table, to_table, options)
|
168
|
+
end
|
169
|
+
|
170
|
+
def check_constraint_in_create(table_name, expression, options)
|
171
|
+
options = check_constraint_options(table_name, expression, options)
|
172
|
+
accept CheckConstraintDefinition.new(table_name, expression, options)
|
173
|
+
end
|
174
|
+
|
175
|
+
def action_sql(action, dependency)
|
176
|
+
case dependency
|
177
|
+
when :nullify then "ON #{action} SET NULL"
|
178
|
+
when :cascade then "ON #{action} CASCADE"
|
179
|
+
when :restrict then "ON #{action} RESTRICT"
|
180
|
+
else
|
181
|
+
raise ArgumentError, <<~MSG
|
182
|
+
'#{dependency}' is not supported for :on_update or :on_delete.
|
183
|
+
Supported values are: :nullify, :cascade, :restrict
|
184
|
+
MSG
|
147
185
|
end
|
148
|
-
|
186
|
+
end
|
149
187
|
end
|
150
|
-
SchemaCreation = AbstractAdapter::SchemaCreation # :nodoc:
|
151
188
|
end
|
152
189
|
end
|
@@ -33,6 +33,14 @@ module ActiveRecord
|
|
33
33
|
@comment = comment
|
34
34
|
end
|
35
35
|
|
36
|
+
def column_options
|
37
|
+
{
|
38
|
+
length: lengths,
|
39
|
+
order: orders,
|
40
|
+
opclass: opclasses,
|
41
|
+
}
|
42
|
+
end
|
43
|
+
|
36
44
|
private
|
37
45
|
def concise_options(options)
|
38
46
|
if columns.size == options.size && options.values.uniq.size == 1
|
@@ -63,12 +71,18 @@ module ActiveRecord
|
|
63
71
|
end
|
64
72
|
CODE
|
65
73
|
end
|
74
|
+
|
75
|
+
def aliased_types(name, fallback)
|
76
|
+
"timestamp" == name ? :datetime : fallback
|
77
|
+
end
|
66
78
|
end
|
67
79
|
|
68
80
|
AddColumnDefinition = Struct.new(:column) # :nodoc:
|
69
81
|
|
70
82
|
ChangeColumnDefinition = Struct.new(:column, :name) #:nodoc:
|
71
83
|
|
84
|
+
CreateIndexDefinition = Struct.new(:index, :algorithm, :if_not_exists) # :nodoc:
|
85
|
+
|
72
86
|
PrimaryKeyDefinition = Struct.new(:name) # :nodoc:
|
73
87
|
|
74
88
|
ForeignKeyDefinition = Struct.new(:from_table, :to_table, :options) do #:nodoc:
|
@@ -105,8 +119,9 @@ module ActiveRecord
|
|
105
119
|
!ActiveRecord::SchemaDumper.fk_ignore_pattern.match?(name) if name
|
106
120
|
end
|
107
121
|
|
108
|
-
def defined_for?(to_table: nil, **options)
|
122
|
+
def defined_for?(to_table: nil, validate: nil, **options)
|
109
123
|
(to_table.nil? || to_table.to_s == self.to_table) &&
|
124
|
+
(validate.nil? || validate == options.fetch(:validate, validate)) &&
|
110
125
|
options.all? { |k, v| self.options[k].to_s == v.to_s }
|
111
126
|
end
|
112
127
|
|
@@ -116,6 +131,21 @@ module ActiveRecord
|
|
116
131
|
end
|
117
132
|
end
|
118
133
|
|
134
|
+
CheckConstraintDefinition = Struct.new(:table_name, :expression, :options) do
|
135
|
+
def name
|
136
|
+
options[:name]
|
137
|
+
end
|
138
|
+
|
139
|
+
def validate?
|
140
|
+
options.fetch(:validate, true)
|
141
|
+
end
|
142
|
+
alias validated? validate?
|
143
|
+
|
144
|
+
def export_name_on_schema_dump?
|
145
|
+
!ActiveRecord::SchemaDumper.chk_ignore_pattern.match?(name) if name
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
119
149
|
class ReferenceDefinition # :nodoc:
|
120
150
|
def initialize(
|
121
151
|
name,
|
@@ -138,13 +168,12 @@ module ActiveRecord
|
|
138
168
|
end
|
139
169
|
|
140
170
|
def add_to(table)
|
141
|
-
columns.each do |
|
142
|
-
|
143
|
-
table.column(*column_options, **kwargs)
|
171
|
+
columns.each do |name, type, options|
|
172
|
+
table.column(name, type, **options)
|
144
173
|
end
|
145
174
|
|
146
175
|
if index
|
147
|
-
table.index(column_names, index_options)
|
176
|
+
table.index(column_names, **index_options(table.name))
|
148
177
|
end
|
149
178
|
|
150
179
|
if foreign_key
|
@@ -163,8 +192,14 @@ module ActiveRecord
|
|
163
192
|
as_options(polymorphic).merge(options.slice(:null, :first, :after))
|
164
193
|
end
|
165
194
|
|
166
|
-
def
|
167
|
-
|
195
|
+
def polymorphic_index_name(table_name)
|
196
|
+
"index_#{table_name}_on_#{name}"
|
197
|
+
end
|
198
|
+
|
199
|
+
def index_options(table_name)
|
200
|
+
index_options = as_options(index)
|
201
|
+
index_options[:name] ||= polymorphic_index_name(table_name) if polymorphic
|
202
|
+
index_options
|
168
203
|
end
|
169
204
|
|
170
205
|
def foreign_key_options
|
@@ -222,7 +257,7 @@ module ActiveRecord
|
|
222
257
|
end
|
223
258
|
|
224
259
|
class_methods do
|
225
|
-
|
260
|
+
def define_column_methods(*column_types) # :nodoc:
|
226
261
|
column_types.each do |column_type|
|
227
262
|
module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
228
263
|
def #{column_type}(*names, **options)
|
@@ -232,6 +267,7 @@ module ActiveRecord
|
|
232
267
|
RUBY
|
233
268
|
end
|
234
269
|
end
|
270
|
+
private :define_column_methods
|
235
271
|
end
|
236
272
|
end
|
237
273
|
|
@@ -241,7 +277,7 @@ module ActiveRecord
|
|
241
277
|
# Inside migration files, the +t+ object in {create_table}[rdoc-ref:SchemaStatements#create_table]
|
242
278
|
# is actually of this type:
|
243
279
|
#
|
244
|
-
# class SomeMigration < ActiveRecord::Migration[
|
280
|
+
# class SomeMigration < ActiveRecord::Migration[6.0]
|
245
281
|
# def up
|
246
282
|
# create_table :foo do |t|
|
247
283
|
# puts t.class # => "ActiveRecord::ConnectionAdapters::TableDefinition"
|
@@ -256,7 +292,7 @@ module ActiveRecord
|
|
256
292
|
class TableDefinition
|
257
293
|
include ColumnMethods
|
258
294
|
|
259
|
-
attr_reader :name, :temporary, :if_not_exists, :options, :as, :comment, :indexes, :foreign_keys
|
295
|
+
attr_reader :name, :temporary, :if_not_exists, :options, :as, :comment, :indexes, :foreign_keys, :check_constraints
|
260
296
|
|
261
297
|
def initialize(
|
262
298
|
conn,
|
@@ -273,6 +309,7 @@ module ActiveRecord
|
|
273
309
|
@indexes = []
|
274
310
|
@foreign_keys = []
|
275
311
|
@primary_keys = nil
|
312
|
+
@check_constraints = []
|
276
313
|
@temporary = temporary
|
277
314
|
@if_not_exists = if_not_exists
|
278
315
|
@options = options
|
@@ -361,7 +398,7 @@ module ActiveRecord
|
|
361
398
|
# t.references :tagger, polymorphic: true
|
362
399
|
# t.references :taggable, polymorphic: { default: 'Photo' }, index: false
|
363
400
|
# end
|
364
|
-
def column(name, type, **options)
|
401
|
+
def column(name, type, index: nil, **options)
|
365
402
|
name = name.to_s
|
366
403
|
type = type.to_sym if type
|
367
404
|
|
@@ -373,9 +410,13 @@ module ActiveRecord
|
|
373
410
|
end
|
374
411
|
end
|
375
412
|
|
376
|
-
index_options = options.delete(:index)
|
377
|
-
index(name, index_options.is_a?(Hash) ? index_options : {}) if index_options
|
378
413
|
@columns_hash[name] = new_column_definition(name, type, **options)
|
414
|
+
|
415
|
+
if index
|
416
|
+
index_options = index.is_a?(Hash) ? index : {}
|
417
|
+
index(name, **index_options)
|
418
|
+
end
|
419
|
+
|
379
420
|
self
|
380
421
|
end
|
381
422
|
|
@@ -389,7 +430,7 @@ module ActiveRecord
|
|
389
430
|
# This is primarily used to track indexes that need to be created after the table
|
390
431
|
#
|
391
432
|
# index(:account_id, name: 'index_projects_on_account_id')
|
392
|
-
def index(column_name, options
|
433
|
+
def index(column_name, **options)
|
393
434
|
indexes << [column_name, options]
|
394
435
|
end
|
395
436
|
|
@@ -397,6 +438,10 @@ module ActiveRecord
|
|
397
438
|
foreign_keys << [table_name, options]
|
398
439
|
end
|
399
440
|
|
441
|
+
def check_constraint(expression, **options)
|
442
|
+
check_constraints << [expression, options]
|
443
|
+
end
|
444
|
+
|
400
445
|
# Appends <tt>:datetime</tt> columns <tt>:created_at</tt> and
|
401
446
|
# <tt>:updated_at</tt> to the table. See {connection.add_timestamps}[rdoc-ref:SchemaStatements#add_timestamps]
|
402
447
|
#
|
@@ -456,14 +501,16 @@ module ActiveRecord
|
|
456
501
|
|
457
502
|
class AlterTable # :nodoc:
|
458
503
|
attr_reader :adds
|
459
|
-
attr_reader :foreign_key_adds
|
460
|
-
attr_reader :
|
504
|
+
attr_reader :foreign_key_adds, :foreign_key_drops
|
505
|
+
attr_reader :check_constraint_adds, :check_constraint_drops
|
461
506
|
|
462
507
|
def initialize(td)
|
463
508
|
@td = td
|
464
509
|
@adds = []
|
465
510
|
@foreign_key_adds = []
|
466
511
|
@foreign_key_drops = []
|
512
|
+
@check_constraint_adds = []
|
513
|
+
@check_constraint_drops = []
|
467
514
|
end
|
468
515
|
|
469
516
|
def name; @td.name; end
|
@@ -476,6 +523,14 @@ module ActiveRecord
|
|
476
523
|
@foreign_key_drops << name
|
477
524
|
end
|
478
525
|
|
526
|
+
def add_check_constraint(expression, options)
|
527
|
+
@check_constraint_adds << CheckConstraintDefinition.new(name, expression, options)
|
528
|
+
end
|
529
|
+
|
530
|
+
def drop_check_constraint(constraint_name)
|
531
|
+
@check_constraint_drops << constraint_name
|
532
|
+
end
|
533
|
+
|
479
534
|
def add_column(name, type, **options)
|
480
535
|
name = name.to_s
|
481
536
|
type = type.to_sym
|
@@ -496,9 +551,11 @@ module ActiveRecord
|
|
496
551
|
# t.timestamps
|
497
552
|
# t.change
|
498
553
|
# t.change_default
|
554
|
+
# t.change_null
|
499
555
|
# t.rename
|
500
556
|
# t.references
|
501
557
|
# t.belongs_to
|
558
|
+
# t.check_constraint
|
502
559
|
# t.string
|
503
560
|
# t.text
|
504
561
|
# t.integer
|
@@ -520,6 +577,7 @@ module ActiveRecord
|
|
520
577
|
# t.remove_references
|
521
578
|
# t.remove_belongs_to
|
522
579
|
# t.remove_index
|
580
|
+
# t.remove_check_constraint
|
523
581
|
# t.remove_timestamps
|
524
582
|
# end
|
525
583
|
#
|
@@ -538,10 +596,12 @@ module ActiveRecord
|
|
538
596
|
# t.column(:name, :string)
|
539
597
|
#
|
540
598
|
# See TableDefinition#column for details of the options you can use.
|
541
|
-
def column(column_name, type, **options)
|
542
|
-
index_options = options.delete(:index)
|
599
|
+
def column(column_name, type, index: nil, **options)
|
543
600
|
@base.add_column(name, column_name, type, **options)
|
544
|
-
|
601
|
+
if index
|
602
|
+
index_options = index.is_a?(Hash) ? index : {}
|
603
|
+
index(column_name, **index_options)
|
604
|
+
end
|
545
605
|
end
|
546
606
|
|
547
607
|
# Checks to see if a column exists.
|
@@ -561,8 +621,8 @@ module ActiveRecord
|
|
561
621
|
# t.index([:branch_id, :party_id], unique: true, name: 'by_branch_party')
|
562
622
|
#
|
563
623
|
# See {connection.add_index}[rdoc-ref:SchemaStatements#add_index] for details of the options you can use.
|
564
|
-
def index(column_name, options
|
565
|
-
@base.add_index(name, column_name, options)
|
624
|
+
def index(column_name, **options)
|
625
|
+
@base.add_index(name, column_name, **options)
|
566
626
|
end
|
567
627
|
|
568
628
|
# Checks to see if an index exists.
|
@@ -600,8 +660,8 @@ module ActiveRecord
|
|
600
660
|
# t.change(:description, :text)
|
601
661
|
#
|
602
662
|
# See TableDefinition#column for details of the options you can use.
|
603
|
-
def change(column_name, type, options
|
604
|
-
@base.change_column(name, column_name, type, options)
|
663
|
+
def change(column_name, type, **options)
|
664
|
+
@base.change_column(name, column_name, type, **options)
|
605
665
|
end
|
606
666
|
|
607
667
|
# Sets a new default value for a column.
|
@@ -615,14 +675,24 @@ module ActiveRecord
|
|
615
675
|
@base.change_column_default(name, column_name, default_or_changes)
|
616
676
|
end
|
617
677
|
|
678
|
+
# Sets or removes a NOT NULL constraint on a column.
|
679
|
+
#
|
680
|
+
# t.change_null(:qualification, true)
|
681
|
+
# t.change_null(:qualification, false, 0)
|
682
|
+
#
|
683
|
+
# See {connection.change_column_null}[rdoc-ref:SchemaStatements#change_column_null]
|
684
|
+
def change_null(column_name, null, default = nil)
|
685
|
+
@base.change_column_null(name, column_name, null, default)
|
686
|
+
end
|
687
|
+
|
618
688
|
# Removes the column(s) from the table definition.
|
619
689
|
#
|
620
690
|
# t.remove(:qualification)
|
621
691
|
# t.remove(:qualification, :experience)
|
622
692
|
#
|
623
693
|
# See {connection.remove_columns}[rdoc-ref:SchemaStatements#remove_columns]
|
624
|
-
def remove(*column_names)
|
625
|
-
@base.remove_columns(name, *column_names)
|
694
|
+
def remove(*column_names, **options)
|
695
|
+
@base.remove_columns(name, *column_names, **options)
|
626
696
|
end
|
627
697
|
|
628
698
|
# Removes the given index from the table.
|
@@ -630,10 +700,11 @@ module ActiveRecord
|
|
630
700
|
# t.remove_index(:branch_id)
|
631
701
|
# t.remove_index(column: [:branch_id, :party_id])
|
632
702
|
# t.remove_index(name: :by_branch_party)
|
703
|
+
# t.remove_index(:branch_id, name: :by_branch_party)
|
633
704
|
#
|
634
705
|
# See {connection.remove_index}[rdoc-ref:SchemaStatements#remove_index]
|
635
|
-
def remove_index(
|
636
|
-
@base.remove_index(name, options)
|
706
|
+
def remove_index(column_name = nil, **options)
|
707
|
+
@base.remove_index(name, column_name, **options)
|
637
708
|
end
|
638
709
|
|
639
710
|
# Removes the timestamp columns (+created_at+ and +updated_at+) from the table.
|
@@ -708,6 +779,24 @@ module ActiveRecord
|
|
708
779
|
def foreign_key_exists?(*args, **options)
|
709
780
|
@base.foreign_key_exists?(name, *args, **options)
|
710
781
|
end
|
782
|
+
|
783
|
+
# Adds a check constraint.
|
784
|
+
#
|
785
|
+
# t.check_constraint("price > 0", name: "price_check")
|
786
|
+
#
|
787
|
+
# See {connection.add_check_constraint}[rdoc-ref:SchemaStatements#add_check_constraint]
|
788
|
+
def check_constraint(*args)
|
789
|
+
@base.add_check_constraint(name, *args)
|
790
|
+
end
|
791
|
+
|
792
|
+
# Removes the given check constraint from the table.
|
793
|
+
#
|
794
|
+
# t.remove_check_constraint(name: "price_check")
|
795
|
+
#
|
796
|
+
# See {connection.remove_check_constraint}[rdoc-ref:SchemaStatements#remove_check_constraint]
|
797
|
+
def remove_check_constraint(*args)
|
798
|
+
@base.remove_check_constraint(name, *args)
|
799
|
+
end
|
711
800
|
end
|
712
801
|
end
|
713
802
|
end
|