activerecord 6.0.6.1 → 6.1.0.rc1
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 +764 -942
- data/MIT-LICENSE +1 -1
- data/README.rdoc +3 -3
- data/lib/active_record/aggregations.rb +1 -1
- data/lib/active_record/association_relation.rb +22 -14
- data/lib/active_record/associations/alias_tracker.rb +19 -15
- data/lib/active_record/associations/association.rb +39 -27
- data/lib/active_record/associations/association_scope.rb +11 -15
- data/lib/active_record/associations/belongs_to_association.rb +15 -5
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +1 -1
- data/lib/active_record/associations/builder/association.rb +9 -3
- 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 -13
- data/lib/active_record/associations/collection_proxy.rb +12 -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/join_association.rb +29 -14
- data/lib/active_record/associations/join_dependency/join_part.rb +1 -1
- data/lib/active_record/associations/join_dependency.rb +63 -49
- data/lib/active_record/associations/preloader/association.rb +13 -5
- data/lib/active_record/associations/preloader/through_association.rb +1 -1
- data/lib/active_record/associations/preloader.rb +5 -3
- data/lib/active_record/associations/singular_association.rb +1 -1
- data/lib/active_record/associations.rb +114 -11
- data/lib/active_record/attribute_assignment.rb +10 -8
- 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 +4 -4
- 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/attribute_methods.rb +52 -48
- data/lib/active_record/attributes.rb +27 -7
- data/lib/active_record/autosave_association.rb +47 -30
- data/lib/active_record/base.rb +2 -14
- data/lib/active_record/callbacks.rb +32 -22
- data/lib/active_record/coders/yaml_column.rb +2 -24
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +180 -134
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +2 -44
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +65 -22
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +2 -7
- data/lib/active_record/connection_adapters/abstract/quoting.rb +35 -44
- 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 +110 -30
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +3 -3
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +224 -85
- data/lib/active_record/connection_adapters/abstract/transaction.rb +66 -24
- data/lib/active_record/connection_adapters/abstract_adapter.rb +31 -70
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +123 -87
- 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 +22 -24
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/quoting.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +33 -6
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +8 -0
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +3 -3
- 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 +63 -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 +12 -53
- 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 +2 -10
- 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/uuid.rb +11 -1
- data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
- 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 +72 -55
- 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 +30 -5
- 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 +36 -3
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +48 -50
- data/lib/active_record/connection_adapters.rb +50 -0
- data/lib/active_record/connection_handling.rb +210 -71
- data/lib/active_record/core.rb +214 -58
- 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/database_configurations.rb +124 -85
- 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 +33 -23
- 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 +54 -8
- data/lib/active_record/gem_version.rb +3 -3
- data/lib/active_record/inheritance.rb +40 -18
- data/lib/active_record/insert_all.rb +32 -5
- data/lib/active_record/integration.rb +3 -5
- data/lib/active_record/internal_metadata.rb +15 -4
- data/lib/active_record/legacy_yaml_adapter.rb +7 -3
- data/lib/active_record/locking/optimistic.rb +13 -16
- data/lib/active_record/locking/pessimistic.rb +6 -2
- data/lib/active_record/log_subscriber.rb +26 -8
- data/lib/active_record/middleware/database_selector/resolver/session.rb +3 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +5 -0
- data/lib/active_record/middleware/database_selector.rb +4 -1
- data/lib/active_record/migration/command_recorder.rb +47 -27
- data/lib/active_record/migration/compatibility.rb +67 -17
- data/lib/active_record/migration.rb +113 -83
- data/lib/active_record/model_schema.rb +88 -42
- 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/databases.rake +253 -98
- data/lib/active_record/readonly_attributes.rb +4 -0
- data/lib/active_record/reflection.rb +59 -44
- data/lib/active_record/relation/batches/batch_enumerator.rb +25 -9
- data/lib/active_record/relation/batches.rb +38 -31
- data/lib/active_record/relation/calculations.rb +100 -43
- data/lib/active_record/relation/finder_methods.rb +44 -14
- data/lib/active_record/relation/from_clause.rb +1 -1
- data/lib/active_record/relation/merger.rb +20 -23
- data/lib/active_record/relation/predicate_builder/array_handler.rb +8 -9
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +2 -2
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +3 -3
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
- data/lib/active_record/relation/predicate_builder.rb +57 -33
- data/lib/active_record/relation/query_methods.rb +319 -198
- data/lib/active_record/relation/record_fetch_warning.rb +3 -3
- data/lib/active_record/relation/spawn_methods.rb +6 -5
- data/lib/active_record/relation/where_clause.rb +104 -57
- data/lib/active_record/relation.rb +90 -64
- 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 +0 -4
- data/lib/active_record/scoping/named.rb +1 -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 +36 -52
- data/lib/active_record/tasks/database_tasks.rb +139 -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 +36 -33
- data/lib/active_record/timestamp.rb +4 -6
- data/lib/active_record/touch_later.rb +21 -21
- data/lib/active_record/transactions.rb +15 -64
- data/lib/active_record/type/serialized.rb +6 -2
- data/lib/active_record/type.rb +8 -1
- 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/associated.rb +1 -1
- data/lib/active_record/validations/numericality.rb +35 -0
- data/lib/active_record/validations/uniqueness.rb +24 -4
- data/lib/active_record/validations.rb +1 -0
- data/lib/active_record.rb +7 -14
- 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/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/nodes.rb +3 -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/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/arel/visitors.rb +0 -7
- data/lib/arel.rb +5 -13
- 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/migration.rb +6 -1
- 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 +30 -32
- 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,16 +71,14 @@ module ActiveRecord
|
|
63
71
|
end
|
64
72
|
CODE
|
65
73
|
end
|
66
|
-
|
67
|
-
def aliased_types(name, fallback)
|
68
|
-
"timestamp" == name ? :datetime : fallback
|
69
|
-
end
|
70
74
|
end
|
71
75
|
|
72
76
|
AddColumnDefinition = Struct.new(:column) # :nodoc:
|
73
77
|
|
74
78
|
ChangeColumnDefinition = Struct.new(:column, :name) #:nodoc:
|
75
79
|
|
80
|
+
CreateIndexDefinition = Struct.new(:index, :algorithm, :if_not_exists) # :nodoc:
|
81
|
+
|
76
82
|
PrimaryKeyDefinition = Struct.new(:name) # :nodoc:
|
77
83
|
|
78
84
|
ForeignKeyDefinition = Struct.new(:from_table, :to_table, :options) do #:nodoc:
|
@@ -121,6 +127,21 @@ module ActiveRecord
|
|
121
127
|
end
|
122
128
|
end
|
123
129
|
|
130
|
+
CheckConstraintDefinition = Struct.new(:table_name, :expression, :options) do
|
131
|
+
def name
|
132
|
+
options[:name]
|
133
|
+
end
|
134
|
+
|
135
|
+
def validate?
|
136
|
+
options.fetch(:validate, true)
|
137
|
+
end
|
138
|
+
alias validated? validate?
|
139
|
+
|
140
|
+
def export_name_on_schema_dump?
|
141
|
+
!ActiveRecord::SchemaDumper.chk_ignore_pattern.match?(name) if name
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
124
145
|
class ReferenceDefinition # :nodoc:
|
125
146
|
def initialize(
|
126
147
|
name,
|
@@ -143,13 +164,12 @@ module ActiveRecord
|
|
143
164
|
end
|
144
165
|
|
145
166
|
def add_to(table)
|
146
|
-
columns.each do |
|
147
|
-
|
148
|
-
table.column(*column_options, **kwargs)
|
167
|
+
columns.each do |name, type, options|
|
168
|
+
table.column(name, type, **options)
|
149
169
|
end
|
150
170
|
|
151
171
|
if index
|
152
|
-
table.index(column_names, index_options)
|
172
|
+
table.index(column_names, **index_options(table.name))
|
153
173
|
end
|
154
174
|
|
155
175
|
if foreign_key
|
@@ -168,8 +188,14 @@ module ActiveRecord
|
|
168
188
|
as_options(polymorphic).merge(options.slice(:null, :first, :after))
|
169
189
|
end
|
170
190
|
|
171
|
-
def
|
172
|
-
|
191
|
+
def polymorphic_index_name(table_name)
|
192
|
+
"index_#{table_name}_on_#{name}"
|
193
|
+
end
|
194
|
+
|
195
|
+
def index_options(table_name)
|
196
|
+
index_options = as_options(index)
|
197
|
+
index_options[:name] ||= polymorphic_index_name(table_name) if polymorphic
|
198
|
+
index_options
|
173
199
|
end
|
174
200
|
|
175
201
|
def foreign_key_options
|
@@ -227,7 +253,7 @@ module ActiveRecord
|
|
227
253
|
end
|
228
254
|
|
229
255
|
class_methods do
|
230
|
-
|
256
|
+
def define_column_methods(*column_types) # :nodoc:
|
231
257
|
column_types.each do |column_type|
|
232
258
|
module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
233
259
|
def #{column_type}(*names, **options)
|
@@ -237,6 +263,7 @@ module ActiveRecord
|
|
237
263
|
RUBY
|
238
264
|
end
|
239
265
|
end
|
266
|
+
private :define_column_methods
|
240
267
|
end
|
241
268
|
end
|
242
269
|
|
@@ -246,7 +273,7 @@ module ActiveRecord
|
|
246
273
|
# Inside migration files, the +t+ object in {create_table}[rdoc-ref:SchemaStatements#create_table]
|
247
274
|
# is actually of this type:
|
248
275
|
#
|
249
|
-
# class SomeMigration < ActiveRecord::Migration[
|
276
|
+
# class SomeMigration < ActiveRecord::Migration[6.0]
|
250
277
|
# def up
|
251
278
|
# create_table :foo do |t|
|
252
279
|
# puts t.class # => "ActiveRecord::ConnectionAdapters::TableDefinition"
|
@@ -261,7 +288,7 @@ module ActiveRecord
|
|
261
288
|
class TableDefinition
|
262
289
|
include ColumnMethods
|
263
290
|
|
264
|
-
attr_reader :name, :temporary, :if_not_exists, :options, :as, :comment, :indexes, :foreign_keys
|
291
|
+
attr_reader :name, :temporary, :if_not_exists, :options, :as, :comment, :indexes, :foreign_keys, :check_constraints
|
265
292
|
|
266
293
|
def initialize(
|
267
294
|
conn,
|
@@ -278,6 +305,7 @@ module ActiveRecord
|
|
278
305
|
@indexes = []
|
279
306
|
@foreign_keys = []
|
280
307
|
@primary_keys = nil
|
308
|
+
@check_constraints = []
|
281
309
|
@temporary = temporary
|
282
310
|
@if_not_exists = if_not_exists
|
283
311
|
@options = options
|
@@ -366,7 +394,7 @@ module ActiveRecord
|
|
366
394
|
# t.references :tagger, polymorphic: true
|
367
395
|
# t.references :taggable, polymorphic: { default: 'Photo' }, index: false
|
368
396
|
# end
|
369
|
-
def column(name, type, **options)
|
397
|
+
def column(name, type, index: nil, **options)
|
370
398
|
name = name.to_s
|
371
399
|
type = type.to_sym if type
|
372
400
|
|
@@ -378,9 +406,13 @@ module ActiveRecord
|
|
378
406
|
end
|
379
407
|
end
|
380
408
|
|
381
|
-
index_options = options.delete(:index)
|
382
|
-
index(name, index_options.is_a?(Hash) ? index_options : {}) if index_options
|
383
409
|
@columns_hash[name] = new_column_definition(name, type, **options)
|
410
|
+
|
411
|
+
if index
|
412
|
+
index_options = index.is_a?(Hash) ? index : {}
|
413
|
+
index(name, **index_options)
|
414
|
+
end
|
415
|
+
|
384
416
|
self
|
385
417
|
end
|
386
418
|
|
@@ -394,7 +426,7 @@ module ActiveRecord
|
|
394
426
|
# This is primarily used to track indexes that need to be created after the table
|
395
427
|
#
|
396
428
|
# index(:account_id, name: 'index_projects_on_account_id')
|
397
|
-
def index(column_name, options
|
429
|
+
def index(column_name, **options)
|
398
430
|
indexes << [column_name, options]
|
399
431
|
end
|
400
432
|
|
@@ -402,6 +434,10 @@ module ActiveRecord
|
|
402
434
|
foreign_keys << [table_name, options]
|
403
435
|
end
|
404
436
|
|
437
|
+
def check_constraint(expression, **options)
|
438
|
+
check_constraints << [expression, options]
|
439
|
+
end
|
440
|
+
|
405
441
|
# Appends <tt>:datetime</tt> columns <tt>:created_at</tt> and
|
406
442
|
# <tt>:updated_at</tt> to the table. See {connection.add_timestamps}[rdoc-ref:SchemaStatements#add_timestamps]
|
407
443
|
#
|
@@ -461,14 +497,16 @@ module ActiveRecord
|
|
461
497
|
|
462
498
|
class AlterTable # :nodoc:
|
463
499
|
attr_reader :adds
|
464
|
-
attr_reader :foreign_key_adds
|
465
|
-
attr_reader :
|
500
|
+
attr_reader :foreign_key_adds, :foreign_key_drops
|
501
|
+
attr_reader :check_constraint_adds, :check_constraint_drops
|
466
502
|
|
467
503
|
def initialize(td)
|
468
504
|
@td = td
|
469
505
|
@adds = []
|
470
506
|
@foreign_key_adds = []
|
471
507
|
@foreign_key_drops = []
|
508
|
+
@check_constraint_adds = []
|
509
|
+
@check_constraint_drops = []
|
472
510
|
end
|
473
511
|
|
474
512
|
def name; @td.name; end
|
@@ -481,6 +519,14 @@ module ActiveRecord
|
|
481
519
|
@foreign_key_drops << name
|
482
520
|
end
|
483
521
|
|
522
|
+
def add_check_constraint(expression, options)
|
523
|
+
@check_constraint_adds << CheckConstraintDefinition.new(name, expression, options)
|
524
|
+
end
|
525
|
+
|
526
|
+
def drop_check_constraint(constraint_name)
|
527
|
+
@check_constraint_drops << constraint_name
|
528
|
+
end
|
529
|
+
|
484
530
|
def add_column(name, type, **options)
|
485
531
|
name = name.to_s
|
486
532
|
type = type.to_sym
|
@@ -501,9 +547,11 @@ module ActiveRecord
|
|
501
547
|
# t.timestamps
|
502
548
|
# t.change
|
503
549
|
# t.change_default
|
550
|
+
# t.change_null
|
504
551
|
# t.rename
|
505
552
|
# t.references
|
506
553
|
# t.belongs_to
|
554
|
+
# t.check_constraint
|
507
555
|
# t.string
|
508
556
|
# t.text
|
509
557
|
# t.integer
|
@@ -525,6 +573,7 @@ module ActiveRecord
|
|
525
573
|
# t.remove_references
|
526
574
|
# t.remove_belongs_to
|
527
575
|
# t.remove_index
|
576
|
+
# t.remove_check_constraint
|
528
577
|
# t.remove_timestamps
|
529
578
|
# end
|
530
579
|
#
|
@@ -543,10 +592,12 @@ module ActiveRecord
|
|
543
592
|
# t.column(:name, :string)
|
544
593
|
#
|
545
594
|
# See TableDefinition#column for details of the options you can use.
|
546
|
-
def column(column_name, type, **options)
|
547
|
-
index_options = options.delete(:index)
|
595
|
+
def column(column_name, type, index: nil, **options)
|
548
596
|
@base.add_column(name, column_name, type, **options)
|
549
|
-
|
597
|
+
if index
|
598
|
+
index_options = index.is_a?(Hash) ? index : {}
|
599
|
+
index(column_name, **index_options)
|
600
|
+
end
|
550
601
|
end
|
551
602
|
|
552
603
|
# Checks to see if a column exists.
|
@@ -566,8 +617,8 @@ module ActiveRecord
|
|
566
617
|
# t.index([:branch_id, :party_id], unique: true, name: 'by_branch_party')
|
567
618
|
#
|
568
619
|
# See {connection.add_index}[rdoc-ref:SchemaStatements#add_index] for details of the options you can use.
|
569
|
-
def index(column_name, options
|
570
|
-
@base.add_index(name, column_name, options)
|
620
|
+
def index(column_name, **options)
|
621
|
+
@base.add_index(name, column_name, **options)
|
571
622
|
end
|
572
623
|
|
573
624
|
# Checks to see if an index exists.
|
@@ -605,8 +656,8 @@ module ActiveRecord
|
|
605
656
|
# t.change(:description, :text)
|
606
657
|
#
|
607
658
|
# See TableDefinition#column for details of the options you can use.
|
608
|
-
def change(column_name, type, options
|
609
|
-
@base.change_column(name, column_name, type, options)
|
659
|
+
def change(column_name, type, **options)
|
660
|
+
@base.change_column(name, column_name, type, **options)
|
610
661
|
end
|
611
662
|
|
612
663
|
# Sets a new default value for a column.
|
@@ -620,14 +671,24 @@ module ActiveRecord
|
|
620
671
|
@base.change_column_default(name, column_name, default_or_changes)
|
621
672
|
end
|
622
673
|
|
674
|
+
# Sets or removes a NOT NULL constraint on a column.
|
675
|
+
#
|
676
|
+
# t.change_null(:qualification, true)
|
677
|
+
# t.change_null(:qualification, false, 0)
|
678
|
+
#
|
679
|
+
# See {connection.change_column_null}[rdoc-ref:SchemaStatements#change_column_null]
|
680
|
+
def change_null(column_name, null, default = nil)
|
681
|
+
@base.change_column_null(name, column_name, null, default)
|
682
|
+
end
|
683
|
+
|
623
684
|
# Removes the column(s) from the table definition.
|
624
685
|
#
|
625
686
|
# t.remove(:qualification)
|
626
687
|
# t.remove(:qualification, :experience)
|
627
688
|
#
|
628
689
|
# See {connection.remove_columns}[rdoc-ref:SchemaStatements#remove_columns]
|
629
|
-
def remove(*column_names)
|
630
|
-
@base.remove_columns(name, *column_names)
|
690
|
+
def remove(*column_names, **options)
|
691
|
+
@base.remove_columns(name, *column_names, **options)
|
631
692
|
end
|
632
693
|
|
633
694
|
# Removes the given index from the table.
|
@@ -635,10 +696,11 @@ module ActiveRecord
|
|
635
696
|
# t.remove_index(:branch_id)
|
636
697
|
# t.remove_index(column: [:branch_id, :party_id])
|
637
698
|
# t.remove_index(name: :by_branch_party)
|
699
|
+
# t.remove_index(:branch_id, name: :by_branch_party)
|
638
700
|
#
|
639
701
|
# See {connection.remove_index}[rdoc-ref:SchemaStatements#remove_index]
|
640
|
-
def remove_index(
|
641
|
-
@base.remove_index(name, options)
|
702
|
+
def remove_index(column_name = nil, **options)
|
703
|
+
@base.remove_index(name, column_name, **options)
|
642
704
|
end
|
643
705
|
|
644
706
|
# Removes the timestamp columns (+created_at+ and +updated_at+) from the table.
|
@@ -713,6 +775,24 @@ module ActiveRecord
|
|
713
775
|
def foreign_key_exists?(*args, **options)
|
714
776
|
@base.foreign_key_exists?(name, *args, **options)
|
715
777
|
end
|
778
|
+
|
779
|
+
# Adds a check constraint.
|
780
|
+
#
|
781
|
+
# t.check_constraint("price > 0", name: "price_check")
|
782
|
+
#
|
783
|
+
# See {connection.add_check_constraint}[rdoc-ref:SchemaStatements#add_check_constraint]
|
784
|
+
def check_constraint(*args)
|
785
|
+
@base.add_check_constraint(name, *args)
|
786
|
+
end
|
787
|
+
|
788
|
+
# Removes the given check constraint from the table.
|
789
|
+
#
|
790
|
+
# t.remove_check_constraint(name: "price_check")
|
791
|
+
#
|
792
|
+
# See {connection.remove_check_constraint}[rdoc-ref:SchemaStatements#remove_check_constraint]
|
793
|
+
def remove_check_constraint(*args)
|
794
|
+
@base.remove_check_constraint(name, *args)
|
795
|
+
end
|
716
796
|
end
|
717
797
|
end
|
718
798
|
end
|
@@ -13,9 +13,9 @@ module ActiveRecord
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def column_spec_for_primary_key(column)
|
16
|
-
|
17
|
-
spec =
|
18
|
-
spec.merge!(prepare_column_options(column).except!(:null
|
16
|
+
spec = {}
|
17
|
+
spec[:id] = schema_type(column).inspect unless default_primary_key?(column)
|
18
|
+
spec.merge!(prepare_column_options(column).except!(:null))
|
19
19
|
spec[:default] ||= "nil" if explicit_primary_key_default?(column)
|
20
20
|
spec
|
21
21
|
end
|