activerecord 6.0.6.1 → 6.1.7.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1152 -779
- data/MIT-LICENSE +1 -1
- data/README.rdoc +2 -2
- data/lib/active_record/aggregations.rb +5 -5
- data/lib/active_record/association_relation.rb +30 -12
- data/lib/active_record/associations/alias_tracker.rb +19 -15
- data/lib/active_record/associations/association.rb +49 -26
- data/lib/active_record/associations/association_scope.rb +18 -20
- data/lib/active_record/associations/belongs_to_association.rb +23 -10
- 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 +32 -18
- 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 +37 -21
- 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 +14 -8
- 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 +118 -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 +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/attribute_methods.rb +64 -54
- data/lib/active_record/attributes.rb +33 -8
- data/lib/active_record/autosave_association.rb +47 -30
- 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/abstract/connection_pool.rb +185 -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 +114 -26
- 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 +92 -33
- data/lib/active_record/connection_adapters/abstract_adapter.rb +52 -76
- 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 +35 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +24 -24
- 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 +7 -4
- 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 +47 -0
- data/lib/active_record/connection_adapters/postgresql/column.rb +24 -1
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +14 -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 -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/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 +30 -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 +75 -64
- data/lib/active_record/connection_adapters/schema_cache.rb +130 -15
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +8 -0
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +32 -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 +52 -0
- data/lib/active_record/connection_handling.rb +218 -71
- data/lib/active_record/core.rb +264 -63
- data/lib/active_record/database_configurations/connection_url_resolver.rb +99 -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 +125 -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 +69 -34
- 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 +3 -3
- data/lib/active_record/inheritance.rb +40 -18
- data/lib/active_record/insert_all.rb +38 -5
- data/lib/active_record/integration.rb +3 -5
- data/lib/active_record/internal_metadata.rb +18 -7
- data/lib/active_record/legacy_yaml_adapter.rb +7 -3
- data/lib/active_record/locking/optimistic.rb +24 -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/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 +72 -18
- data/lib/active_record/migration.rb +114 -84
- data/lib/active_record/model_schema.rb +89 -14
- 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 +279 -101
- data/lib/active_record/readonly_attributes.rb +4 -0
- data/lib/active_record/reflection.rb +60 -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 +104 -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 +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/predicate_builder.rb +61 -38
- data/lib/active_record/relation/query_methods.rb +322 -196
- 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 +111 -61
- data/lib/active_record/relation.rb +100 -81
- 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/default.rb +1 -3
- 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 +8 -3
- 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 +79 -31
- 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/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 +76 -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 +25 -26
- 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 << o.algorithm if o.algorithm
|
98
|
+
sql << "IF NOT EXISTS" if o.if_not_exists
|
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
|
@@ -73,6 +81,8 @@ module ActiveRecord
|
|
73
81
|
|
74
82
|
ChangeColumnDefinition = Struct.new(:column, :name) #:nodoc:
|
75
83
|
|
84
|
+
CreateIndexDefinition = Struct.new(:index, :algorithm, :if_not_exists) # :nodoc:
|
85
|
+
|
76
86
|
PrimaryKeyDefinition = Struct.new(:name) # :nodoc:
|
77
87
|
|
78
88
|
ForeignKeyDefinition = Struct.new(:from_table, :to_table, :options) do #:nodoc:
|
@@ -121,6 +131,21 @@ module ActiveRecord
|
|
121
131
|
end
|
122
132
|
end
|
123
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
|
+
|
124
149
|
class ReferenceDefinition # :nodoc:
|
125
150
|
def initialize(
|
126
151
|
name,
|
@@ -143,13 +168,12 @@ module ActiveRecord
|
|
143
168
|
end
|
144
169
|
|
145
170
|
def add_to(table)
|
146
|
-
columns.each do |
|
147
|
-
|
148
|
-
table.column(*column_options, **kwargs)
|
171
|
+
columns.each do |name, type, options|
|
172
|
+
table.column(name, type, **options)
|
149
173
|
end
|
150
174
|
|
151
175
|
if index
|
152
|
-
table.index(column_names, index_options)
|
176
|
+
table.index(column_names, **index_options(table.name))
|
153
177
|
end
|
154
178
|
|
155
179
|
if foreign_key
|
@@ -168,8 +192,18 @@ module ActiveRecord
|
|
168
192
|
as_options(polymorphic).merge(options.slice(:null, :first, :after))
|
169
193
|
end
|
170
194
|
|
171
|
-
def
|
172
|
-
|
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
|
+
|
202
|
+
# legacy reference index names are used on versions 6.0 and earlier
|
203
|
+
return index_options if options[:_uses_legacy_reference_index_name]
|
204
|
+
|
205
|
+
index_options[:name] ||= polymorphic_index_name(table_name) if polymorphic
|
206
|
+
index_options
|
173
207
|
end
|
174
208
|
|
175
209
|
def foreign_key_options
|
@@ -227,7 +261,7 @@ module ActiveRecord
|
|
227
261
|
end
|
228
262
|
|
229
263
|
class_methods do
|
230
|
-
|
264
|
+
def define_column_methods(*column_types) # :nodoc:
|
231
265
|
column_types.each do |column_type|
|
232
266
|
module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
233
267
|
def #{column_type}(*names, **options)
|
@@ -237,6 +271,7 @@ module ActiveRecord
|
|
237
271
|
RUBY
|
238
272
|
end
|
239
273
|
end
|
274
|
+
private :define_column_methods
|
240
275
|
end
|
241
276
|
end
|
242
277
|
|
@@ -246,7 +281,7 @@ module ActiveRecord
|
|
246
281
|
# Inside migration files, the +t+ object in {create_table}[rdoc-ref:SchemaStatements#create_table]
|
247
282
|
# is actually of this type:
|
248
283
|
#
|
249
|
-
# class SomeMigration < ActiveRecord::Migration[
|
284
|
+
# class SomeMigration < ActiveRecord::Migration[6.0]
|
250
285
|
# def up
|
251
286
|
# create_table :foo do |t|
|
252
287
|
# puts t.class # => "ActiveRecord::ConnectionAdapters::TableDefinition"
|
@@ -261,7 +296,7 @@ module ActiveRecord
|
|
261
296
|
class TableDefinition
|
262
297
|
include ColumnMethods
|
263
298
|
|
264
|
-
attr_reader :name, :temporary, :if_not_exists, :options, :as, :comment, :indexes, :foreign_keys
|
299
|
+
attr_reader :name, :temporary, :if_not_exists, :options, :as, :comment, :indexes, :foreign_keys, :check_constraints
|
265
300
|
|
266
301
|
def initialize(
|
267
302
|
conn,
|
@@ -278,6 +313,7 @@ module ActiveRecord
|
|
278
313
|
@indexes = []
|
279
314
|
@foreign_keys = []
|
280
315
|
@primary_keys = nil
|
316
|
+
@check_constraints = []
|
281
317
|
@temporary = temporary
|
282
318
|
@if_not_exists = if_not_exists
|
283
319
|
@options = options
|
@@ -366,7 +402,7 @@ module ActiveRecord
|
|
366
402
|
# t.references :tagger, polymorphic: true
|
367
403
|
# t.references :taggable, polymorphic: { default: 'Photo' }, index: false
|
368
404
|
# end
|
369
|
-
def column(name, type, **options)
|
405
|
+
def column(name, type, index: nil, **options)
|
370
406
|
name = name.to_s
|
371
407
|
type = type.to_sym if type
|
372
408
|
|
@@ -378,9 +414,13 @@ module ActiveRecord
|
|
378
414
|
end
|
379
415
|
end
|
380
416
|
|
381
|
-
index_options = options.delete(:index)
|
382
|
-
index(name, index_options.is_a?(Hash) ? index_options : {}) if index_options
|
383
417
|
@columns_hash[name] = new_column_definition(name, type, **options)
|
418
|
+
|
419
|
+
if index
|
420
|
+
index_options = index.is_a?(Hash) ? index : {}
|
421
|
+
index(name, **index_options)
|
422
|
+
end
|
423
|
+
|
384
424
|
self
|
385
425
|
end
|
386
426
|
|
@@ -394,7 +434,7 @@ module ActiveRecord
|
|
394
434
|
# This is primarily used to track indexes that need to be created after the table
|
395
435
|
#
|
396
436
|
# index(:account_id, name: 'index_projects_on_account_id')
|
397
|
-
def index(column_name, options
|
437
|
+
def index(column_name, **options)
|
398
438
|
indexes << [column_name, options]
|
399
439
|
end
|
400
440
|
|
@@ -402,6 +442,10 @@ module ActiveRecord
|
|
402
442
|
foreign_keys << [table_name, options]
|
403
443
|
end
|
404
444
|
|
445
|
+
def check_constraint(expression, **options)
|
446
|
+
check_constraints << [expression, options]
|
447
|
+
end
|
448
|
+
|
405
449
|
# Appends <tt>:datetime</tt> columns <tt>:created_at</tt> and
|
406
450
|
# <tt>:updated_at</tt> to the table. See {connection.add_timestamps}[rdoc-ref:SchemaStatements#add_timestamps]
|
407
451
|
#
|
@@ -461,14 +505,16 @@ module ActiveRecord
|
|
461
505
|
|
462
506
|
class AlterTable # :nodoc:
|
463
507
|
attr_reader :adds
|
464
|
-
attr_reader :foreign_key_adds
|
465
|
-
attr_reader :
|
508
|
+
attr_reader :foreign_key_adds, :foreign_key_drops
|
509
|
+
attr_reader :check_constraint_adds, :check_constraint_drops
|
466
510
|
|
467
511
|
def initialize(td)
|
468
512
|
@td = td
|
469
513
|
@adds = []
|
470
514
|
@foreign_key_adds = []
|
471
515
|
@foreign_key_drops = []
|
516
|
+
@check_constraint_adds = []
|
517
|
+
@check_constraint_drops = []
|
472
518
|
end
|
473
519
|
|
474
520
|
def name; @td.name; end
|
@@ -481,6 +527,14 @@ module ActiveRecord
|
|
481
527
|
@foreign_key_drops << name
|
482
528
|
end
|
483
529
|
|
530
|
+
def add_check_constraint(expression, options)
|
531
|
+
@check_constraint_adds << CheckConstraintDefinition.new(name, expression, options)
|
532
|
+
end
|
533
|
+
|
534
|
+
def drop_check_constraint(constraint_name)
|
535
|
+
@check_constraint_drops << constraint_name
|
536
|
+
end
|
537
|
+
|
484
538
|
def add_column(name, type, **options)
|
485
539
|
name = name.to_s
|
486
540
|
type = type.to_sym
|
@@ -501,9 +555,11 @@ module ActiveRecord
|
|
501
555
|
# t.timestamps
|
502
556
|
# t.change
|
503
557
|
# t.change_default
|
558
|
+
# t.change_null
|
504
559
|
# t.rename
|
505
560
|
# t.references
|
506
561
|
# t.belongs_to
|
562
|
+
# t.check_constraint
|
507
563
|
# t.string
|
508
564
|
# t.text
|
509
565
|
# t.integer
|
@@ -525,6 +581,7 @@ module ActiveRecord
|
|
525
581
|
# t.remove_references
|
526
582
|
# t.remove_belongs_to
|
527
583
|
# t.remove_index
|
584
|
+
# t.remove_check_constraint
|
528
585
|
# t.remove_timestamps
|
529
586
|
# end
|
530
587
|
#
|
@@ -543,10 +600,12 @@ module ActiveRecord
|
|
543
600
|
# t.column(:name, :string)
|
544
601
|
#
|
545
602
|
# See TableDefinition#column for details of the options you can use.
|
546
|
-
def column(column_name, type, **options)
|
547
|
-
index_options = options.delete(:index)
|
603
|
+
def column(column_name, type, index: nil, **options)
|
548
604
|
@base.add_column(name, column_name, type, **options)
|
549
|
-
|
605
|
+
if index
|
606
|
+
index_options = index.is_a?(Hash) ? index : {}
|
607
|
+
index(column_name, **index_options)
|
608
|
+
end
|
550
609
|
end
|
551
610
|
|
552
611
|
# Checks to see if a column exists.
|
@@ -566,8 +625,8 @@ module ActiveRecord
|
|
566
625
|
# t.index([:branch_id, :party_id], unique: true, name: 'by_branch_party')
|
567
626
|
#
|
568
627
|
# 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)
|
628
|
+
def index(column_name, **options)
|
629
|
+
@base.add_index(name, column_name, **options)
|
571
630
|
end
|
572
631
|
|
573
632
|
# Checks to see if an index exists.
|
@@ -605,8 +664,8 @@ module ActiveRecord
|
|
605
664
|
# t.change(:description, :text)
|
606
665
|
#
|
607
666
|
# 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)
|
667
|
+
def change(column_name, type, **options)
|
668
|
+
@base.change_column(name, column_name, type, **options)
|
610
669
|
end
|
611
670
|
|
612
671
|
# Sets a new default value for a column.
|
@@ -620,14 +679,24 @@ module ActiveRecord
|
|
620
679
|
@base.change_column_default(name, column_name, default_or_changes)
|
621
680
|
end
|
622
681
|
|
682
|
+
# Sets or removes a NOT NULL constraint on a column.
|
683
|
+
#
|
684
|
+
# t.change_null(:qualification, true)
|
685
|
+
# t.change_null(:qualification, false, 0)
|
686
|
+
#
|
687
|
+
# See {connection.change_column_null}[rdoc-ref:SchemaStatements#change_column_null]
|
688
|
+
def change_null(column_name, null, default = nil)
|
689
|
+
@base.change_column_null(name, column_name, null, default)
|
690
|
+
end
|
691
|
+
|
623
692
|
# Removes the column(s) from the table definition.
|
624
693
|
#
|
625
694
|
# t.remove(:qualification)
|
626
695
|
# t.remove(:qualification, :experience)
|
627
696
|
#
|
628
697
|
# See {connection.remove_columns}[rdoc-ref:SchemaStatements#remove_columns]
|
629
|
-
def remove(*column_names)
|
630
|
-
@base.remove_columns(name, *column_names)
|
698
|
+
def remove(*column_names, **options)
|
699
|
+
@base.remove_columns(name, *column_names, **options)
|
631
700
|
end
|
632
701
|
|
633
702
|
# Removes the given index from the table.
|
@@ -635,10 +704,11 @@ module ActiveRecord
|
|
635
704
|
# t.remove_index(:branch_id)
|
636
705
|
# t.remove_index(column: [:branch_id, :party_id])
|
637
706
|
# t.remove_index(name: :by_branch_party)
|
707
|
+
# t.remove_index(:branch_id, name: :by_branch_party)
|
638
708
|
#
|
639
709
|
# See {connection.remove_index}[rdoc-ref:SchemaStatements#remove_index]
|
640
|
-
def remove_index(
|
641
|
-
@base.remove_index(name, options)
|
710
|
+
def remove_index(column_name = nil, **options)
|
711
|
+
@base.remove_index(name, column_name, **options)
|
642
712
|
end
|
643
713
|
|
644
714
|
# Removes the timestamp columns (+created_at+ and +updated_at+) from the table.
|
@@ -713,6 +783,24 @@ module ActiveRecord
|
|
713
783
|
def foreign_key_exists?(*args, **options)
|
714
784
|
@base.foreign_key_exists?(name, *args, **options)
|
715
785
|
end
|
786
|
+
|
787
|
+
# Adds a check constraint.
|
788
|
+
#
|
789
|
+
# t.check_constraint("price > 0", name: "price_check")
|
790
|
+
#
|
791
|
+
# See {connection.add_check_constraint}[rdoc-ref:SchemaStatements#add_check_constraint]
|
792
|
+
def check_constraint(*args)
|
793
|
+
@base.add_check_constraint(name, *args)
|
794
|
+
end
|
795
|
+
|
796
|
+
# Removes the given check constraint from the table.
|
797
|
+
#
|
798
|
+
# t.remove_check_constraint(name: "price_check")
|
799
|
+
#
|
800
|
+
# See {connection.remove_check_constraint}[rdoc-ref:SchemaStatements#remove_check_constraint]
|
801
|
+
def remove_check_constraint(*args)
|
802
|
+
@base.remove_check_constraint(name, *args)
|
803
|
+
end
|
716
804
|
end
|
717
805
|
end
|
718
806
|
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
|