activerecord 5.1.0 → 5.2.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 +5 -5
- data/CHANGELOG.md +596 -450
- data/MIT-LICENSE +1 -1
- data/README.rdoc +5 -5
- data/examples/performance.rb +2 -0
- data/examples/simple.rb +2 -0
- data/lib/active_record.rb +11 -4
- data/lib/active_record/aggregations.rb +6 -5
- data/lib/active_record/association_relation.rb +7 -5
- data/lib/active_record/associations.rb +77 -85
- data/lib/active_record/associations/alias_tracker.rb +23 -32
- data/lib/active_record/associations/association.rb +49 -35
- data/lib/active_record/associations/association_scope.rb +55 -55
- data/lib/active_record/associations/belongs_to_association.rb +30 -11
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -8
- data/lib/active_record/associations/builder/association.rb +4 -7
- data/lib/active_record/associations/builder/belongs_to.rb +21 -8
- data/lib/active_record/associations/builder/collection_association.rb +1 -1
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +3 -1
- data/lib/active_record/associations/builder/has_many.rb +2 -0
- data/lib/active_record/associations/builder/has_one.rb +2 -0
- data/lib/active_record/associations/builder/singular_association.rb +2 -0
- data/lib/active_record/associations/collection_association.rb +66 -53
- data/lib/active_record/associations/collection_proxy.rb +30 -73
- data/lib/active_record/associations/foreign_association.rb +2 -0
- data/lib/active_record/associations/has_many_association.rb +13 -2
- data/lib/active_record/associations/has_many_through_association.rb +37 -19
- data/lib/active_record/associations/has_one_association.rb +14 -1
- data/lib/active_record/associations/has_one_through_association.rb +13 -8
- data/lib/active_record/associations/join_dependency.rb +52 -96
- data/lib/active_record/associations/join_dependency/join_association.rb +22 -75
- data/lib/active_record/associations/join_dependency/join_base.rb +9 -8
- data/lib/active_record/associations/join_dependency/join_part.rb +9 -9
- data/lib/active_record/associations/preloader.rb +17 -37
- data/lib/active_record/associations/preloader/association.rb +53 -92
- data/lib/active_record/associations/preloader/through_association.rb +72 -73
- data/lib/active_record/associations/singular_association.rb +14 -16
- data/lib/active_record/associations/through_association.rb +27 -12
- data/lib/active_record/attribute_assignment.rb +2 -5
- data/lib/active_record/attribute_decorators.rb +3 -2
- data/lib/active_record/attribute_methods.rb +65 -24
- data/lib/active_record/attribute_methods/before_type_cast.rb +2 -0
- data/lib/active_record/attribute_methods/dirty.rb +33 -216
- data/lib/active_record/attribute_methods/primary_key.rb +10 -13
- data/lib/active_record/attribute_methods/query.rb +2 -0
- data/lib/active_record/attribute_methods/read.rb +9 -3
- data/lib/active_record/attribute_methods/serialization.rb +23 -0
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +6 -8
- data/lib/active_record/attribute_methods/write.rb +22 -19
- data/lib/active_record/attributes.rb +7 -6
- data/lib/active_record/autosave_association.rb +15 -13
- data/lib/active_record/base.rb +2 -0
- data/lib/active_record/callbacks.rb +12 -6
- data/lib/active_record/coders/json.rb +2 -0
- data/lib/active_record/coders/yaml_column.rb +2 -0
- data/lib/active_record/collection_cache_key.rb +15 -11
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +120 -39
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +7 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +192 -37
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +13 -2
- data/lib/active_record/connection_adapters/abstract/quoting.rb +15 -25
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +15 -6
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +65 -7
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +31 -53
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +158 -87
- data/lib/active_record/connection_adapters/abstract/transaction.rb +66 -21
- data/lib/active_record/connection_adapters/abstract_adapter.rb +86 -98
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +126 -189
- data/lib/active_record/connection_adapters/column.rb +4 -2
- data/lib/active_record/connection_adapters/connection_specification.rb +17 -3
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +13 -2
- data/lib/active_record/connection_adapters/mysql/column.rb +2 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +45 -15
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +2 -0
- data/lib/active_record/connection_adapters/mysql/quoting.rb +9 -10
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +5 -3
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +7 -10
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +30 -23
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +106 -1
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +2 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +8 -2
- data/lib/active_record/connection_adapters/postgresql/column.rb +30 -1
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +6 -32
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +13 -1
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +8 -2
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +4 -2
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +22 -1
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +19 -25
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +50 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +24 -11
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +20 -13
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +258 -129
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +75 -87
- data/lib/active_record/connection_adapters/schema_cache.rb +4 -2
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +2 -0
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +2 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +24 -1
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +2 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +6 -15
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +3 -2
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +75 -1
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +90 -96
- data/lib/active_record/connection_adapters/statement_pool.rb +2 -0
- data/lib/active_record/connection_handling.rb +4 -2
- data/lib/active_record/core.rb +41 -61
- data/lib/active_record/counter_cache.rb +20 -15
- data/lib/active_record/define_callbacks.rb +5 -3
- data/lib/active_record/dynamic_matchers.rb +9 -9
- data/lib/active_record/enum.rb +18 -13
- data/lib/active_record/errors.rb +60 -15
- data/lib/active_record/explain.rb +3 -1
- data/lib/active_record/explain_registry.rb +2 -0
- data/lib/active_record/explain_subscriber.rb +2 -0
- data/lib/active_record/fixture_set/file.rb +2 -0
- data/lib/active_record/fixtures.rb +67 -60
- data/lib/active_record/gem_version.rb +4 -2
- data/lib/active_record/inheritance.rb +49 -19
- data/lib/active_record/integration.rb +58 -19
- data/lib/active_record/internal_metadata.rb +2 -0
- data/lib/active_record/legacy_yaml_adapter.rb +3 -1
- data/lib/active_record/locking/optimistic.rb +30 -42
- data/lib/active_record/locking/pessimistic.rb +10 -7
- data/lib/active_record/log_subscriber.rb +46 -4
- data/lib/active_record/migration.rb +189 -139
- data/lib/active_record/migration/command_recorder.rb +11 -9
- data/lib/active_record/migration/compatibility.rb +81 -29
- data/lib/active_record/migration/join_table.rb +2 -0
- data/lib/active_record/model_schema.rb +74 -58
- data/lib/active_record/nested_attributes.rb +18 -6
- data/lib/active_record/no_touching.rb +3 -1
- data/lib/active_record/null_relation.rb +2 -0
- data/lib/active_record/persistence.rb +199 -54
- data/lib/active_record/query_cache.rb +8 -10
- data/lib/active_record/querying.rb +5 -3
- data/lib/active_record/railtie.rb +62 -6
- data/lib/active_record/railties/console_sandbox.rb +2 -0
- data/lib/active_record/railties/controller_runtime.rb +2 -0
- data/lib/active_record/railties/databases.rake +48 -38
- data/lib/active_record/readonly_attributes.rb +3 -2
- data/lib/active_record/reflection.rb +137 -207
- data/lib/active_record/relation.rb +132 -207
- data/lib/active_record/relation/batches.rb +32 -17
- data/lib/active_record/relation/batches/batch_enumerator.rb +2 -0
- data/lib/active_record/relation/calculations.rb +66 -25
- data/lib/active_record/relation/delegation.rb +45 -29
- data/lib/active_record/relation/finder_methods.rb +76 -85
- data/lib/active_record/relation/from_clause.rb +2 -8
- data/lib/active_record/relation/merger.rb +53 -23
- data/lib/active_record/relation/predicate_builder.rb +60 -79
- data/lib/active_record/relation/predicate_builder/array_handler.rb +10 -7
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +46 -0
- data/lib/active_record/relation/predicate_builder/base_handler.rb +2 -2
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +12 -1
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +56 -0
- data/lib/active_record/relation/predicate_builder/range_handler.rb +26 -9
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
- data/lib/active_record/relation/query_attribute.rb +28 -2
- data/lib/active_record/relation/query_methods.rb +135 -103
- data/lib/active_record/relation/record_fetch_warning.rb +2 -0
- data/lib/active_record/relation/spawn_methods.rb +4 -2
- data/lib/active_record/relation/where_clause.rb +65 -67
- data/lib/active_record/relation/where_clause_factory.rb +5 -48
- data/lib/active_record/result.rb +2 -0
- data/lib/active_record/runtime_registry.rb +2 -0
- data/lib/active_record/sanitization.rb +129 -121
- data/lib/active_record/schema.rb +4 -2
- data/lib/active_record/schema_dumper.rb +36 -26
- data/lib/active_record/schema_migration.rb +2 -0
- data/lib/active_record/scoping.rb +12 -10
- data/lib/active_record/scoping/default.rb +10 -7
- data/lib/active_record/scoping/named.rb +40 -12
- data/lib/active_record/secure_token.rb +2 -0
- data/lib/active_record/serialization.rb +2 -0
- data/lib/active_record/statement_cache.rb +22 -12
- data/lib/active_record/store.rb +3 -1
- data/lib/active_record/suppressor.rb +2 -0
- data/lib/active_record/table_metadata.rb +12 -3
- data/lib/active_record/tasks/database_tasks.rb +38 -26
- data/lib/active_record/tasks/mysql_database_tasks.rb +11 -50
- data/lib/active_record/tasks/postgresql_database_tasks.rb +11 -3
- data/lib/active_record/tasks/sqlite_database_tasks.rb +25 -3
- data/lib/active_record/timestamp.rb +13 -6
- data/lib/active_record/touch_later.rb +2 -0
- data/lib/active_record/transactions.rb +32 -27
- data/lib/active_record/translation.rb +2 -0
- data/lib/active_record/type.rb +4 -1
- data/lib/active_record/type/adapter_specific_registry.rb +2 -0
- data/lib/active_record/type/date.rb +2 -0
- data/lib/active_record/type/date_time.rb +2 -0
- data/lib/active_record/type/decimal_without_scale.rb +2 -0
- data/lib/active_record/type/hash_lookup_type_map.rb +2 -0
- data/lib/active_record/type/internal/timezone.rb +2 -0
- data/lib/active_record/type/json.rb +30 -0
- data/lib/active_record/type/serialized.rb +6 -0
- data/lib/active_record/type/text.rb +2 -0
- data/lib/active_record/type/time.rb +2 -0
- data/lib/active_record/type/type_map.rb +2 -0
- data/lib/active_record/type/unsigned_integer.rb +2 -0
- data/lib/active_record/type_caster.rb +2 -0
- data/lib/active_record/type_caster/connection.rb +2 -0
- data/lib/active_record/type_caster/map.rb +3 -1
- data/lib/active_record/validations.rb +2 -0
- data/lib/active_record/validations/absence.rb +2 -0
- data/lib/active_record/validations/associated.rb +2 -0
- data/lib/active_record/validations/length.rb +2 -0
- data/lib/active_record/validations/presence.rb +2 -0
- data/lib/active_record/validations/uniqueness.rb +36 -6
- data/lib/active_record/version.rb +2 -0
- data/lib/rails/generators/active_record.rb +3 -1
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
- data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
- data/lib/rails/generators/active_record/migration.rb +2 -0
- data/lib/rails/generators/active_record/migration/migration_generator.rb +3 -1
- data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +0 -0
- data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +0 -0
- data/lib/rails/generators/active_record/model/model_generator.rb +2 -23
- data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +0 -0
- data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
- metadata +24 -36
- data/lib/active_record/associations/preloader/belongs_to.rb +0 -15
- data/lib/active_record/associations/preloader/collection_association.rb +0 -17
- data/lib/active_record/associations/preloader/has_many.rb +0 -15
- data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
- data/lib/active_record/associations/preloader/has_one.rb +0 -15
- data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
- data/lib/active_record/associations/preloader/singular_association.rb +0 -18
- data/lib/active_record/attribute.rb +0 -240
- data/lib/active_record/attribute/user_provided_default.rb +0 -30
- data/lib/active_record/attribute_mutation_tracker.rb +0 -113
- data/lib/active_record/attribute_set.rb +0 -113
- data/lib/active_record/attribute_set/builder.rb +0 -124
- data/lib/active_record/attribute_set/yaml_encoder.rb +0 -41
- data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -10
- data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
- data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
- data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -59
- data/lib/active_record/type/internal/abstract_json.rb +0 -33
@@ -1,6 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_record/migration/join_table"
|
2
4
|
require "active_support/core_ext/string/access"
|
3
|
-
require "digest"
|
5
|
+
require "digest/sha2"
|
4
6
|
|
5
7
|
module ActiveRecord
|
6
8
|
module ConnectionAdapters # :nodoc:
|
@@ -31,7 +33,7 @@ module ActiveRecord
|
|
31
33
|
# Returns the relation names useable to back Active Record models.
|
32
34
|
# For most adapters this means all #tables and #views.
|
33
35
|
def data_sources
|
34
|
-
|
36
|
+
query_values(data_source_sql, "SCHEMA")
|
35
37
|
rescue NotImplementedError
|
36
38
|
tables | views
|
37
39
|
end
|
@@ -41,14 +43,14 @@ module ActiveRecord
|
|
41
43
|
# data_source_exists?(:ebooks)
|
42
44
|
#
|
43
45
|
def data_source_exists?(name)
|
44
|
-
|
46
|
+
query_values(data_source_sql(name), "SCHEMA").any? if name.present?
|
45
47
|
rescue NotImplementedError
|
46
48
|
data_sources.include?(name.to_s)
|
47
49
|
end
|
48
50
|
|
49
51
|
# Returns an array of table names defined in the database.
|
50
52
|
def tables
|
51
|
-
|
53
|
+
query_values(data_source_sql(type: "BASE TABLE"), "SCHEMA")
|
52
54
|
end
|
53
55
|
|
54
56
|
# Checks to see if the table +table_name+ exists on the database.
|
@@ -56,14 +58,14 @@ module ActiveRecord
|
|
56
58
|
# table_exists?(:developers)
|
57
59
|
#
|
58
60
|
def table_exists?(table_name)
|
59
|
-
|
61
|
+
query_values(data_source_sql(table_name, type: "BASE TABLE"), "SCHEMA").any? if table_name.present?
|
60
62
|
rescue NotImplementedError
|
61
63
|
tables.include?(table_name.to_s)
|
62
64
|
end
|
63
65
|
|
64
66
|
# Returns an array of view names defined in the database.
|
65
67
|
def views
|
66
|
-
|
68
|
+
query_values(data_source_sql(type: "VIEW"), "SCHEMA")
|
67
69
|
end
|
68
70
|
|
69
71
|
# Checks to see if the view +view_name+ exists on the database.
|
@@ -71,13 +73,13 @@ module ActiveRecord
|
|
71
73
|
# view_exists?(:ebooks)
|
72
74
|
#
|
73
75
|
def view_exists?(view_name)
|
74
|
-
|
76
|
+
query_values(data_source_sql(view_name, type: "VIEW"), "SCHEMA").any? if view_name.present?
|
75
77
|
rescue NotImplementedError
|
76
78
|
views.include?(view_name.to_s)
|
77
79
|
end
|
78
80
|
|
79
81
|
# Returns an array of indexes for the given table.
|
80
|
-
def indexes(table_name
|
82
|
+
def indexes(table_name)
|
81
83
|
raise NotImplementedError, "#indexes is not implemented"
|
82
84
|
end
|
83
85
|
|
@@ -105,10 +107,12 @@ module ActiveRecord
|
|
105
107
|
indexes(table_name).any? { |i| checks.all? { |check| check[i] } }
|
106
108
|
end
|
107
109
|
|
108
|
-
# Returns an array of Column objects for the table specified by +table_name+.
|
109
|
-
# See the concrete implementation for details on the expected parameter values.
|
110
|
+
# Returns an array of +Column+ objects for the table specified by +table_name+.
|
110
111
|
def columns(table_name)
|
111
|
-
|
112
|
+
table_name = table_name.to_s
|
113
|
+
column_definitions(table_name).map do |field|
|
114
|
+
new_column_from_field(table_name, field)
|
115
|
+
end
|
112
116
|
end
|
113
117
|
|
114
118
|
# Checks to see if a column exists in a given table.
|
@@ -186,6 +190,8 @@ module ActiveRecord
|
|
186
190
|
# The name of the primary key, if one is to be added automatically.
|
187
191
|
# Defaults to +id+. If <tt>:id</tt> is false, then this option is ignored.
|
188
192
|
#
|
193
|
+
# If an array is passed, a composite primary key will be created.
|
194
|
+
#
|
189
195
|
# Note that Active Record models will automatically detect their
|
190
196
|
# primary key. This can be avoided by using
|
191
197
|
# {self.primary_key=}[rdoc-ref:AttributeMethods::PrimaryKey::ClassMethods#primary_key=] on the model
|
@@ -210,7 +216,7 @@ module ActiveRecord
|
|
210
216
|
# generates:
|
211
217
|
#
|
212
218
|
# CREATE TABLE suppliers (
|
213
|
-
# id
|
219
|
+
# id bigint auto_increment PRIMARY KEY
|
214
220
|
# ) ENGINE=InnoDB DEFAULT CHARSET=utf8
|
215
221
|
#
|
216
222
|
# ====== Rename the primary key column
|
@@ -222,7 +228,7 @@ module ActiveRecord
|
|
222
228
|
# generates:
|
223
229
|
#
|
224
230
|
# CREATE TABLE objects (
|
225
|
-
# guid
|
231
|
+
# guid bigint auto_increment PRIMARY KEY,
|
226
232
|
# name varchar(80)
|
227
233
|
# )
|
228
234
|
#
|
@@ -239,18 +245,35 @@ module ActiveRecord
|
|
239
245
|
# label varchar
|
240
246
|
# )
|
241
247
|
#
|
248
|
+
# ====== Create a composite primary key
|
249
|
+
#
|
250
|
+
# create_table(:orders, primary_key: [:product_id, :client_id]) do |t|
|
251
|
+
# t.belongs_to :product
|
252
|
+
# t.belongs_to :client
|
253
|
+
# end
|
254
|
+
#
|
255
|
+
# generates:
|
256
|
+
#
|
257
|
+
# CREATE TABLE order (
|
258
|
+
# product_id bigint NOT NULL,
|
259
|
+
# client_id bigint NOT NULL
|
260
|
+
# );
|
261
|
+
#
|
262
|
+
# ALTER TABLE ONLY "orders"
|
263
|
+
# ADD CONSTRAINT orders_pkey PRIMARY KEY (product_id, client_id);
|
264
|
+
#
|
242
265
|
# ====== Do not add a primary key column
|
243
266
|
#
|
244
267
|
# create_table(:categories_suppliers, id: false) do |t|
|
245
|
-
# t.column :category_id, :
|
246
|
-
# t.column :supplier_id, :
|
268
|
+
# t.column :category_id, :bigint
|
269
|
+
# t.column :supplier_id, :bigint
|
247
270
|
# end
|
248
271
|
#
|
249
272
|
# generates:
|
250
273
|
#
|
251
274
|
# CREATE TABLE categories_suppliers (
|
252
|
-
# category_id
|
253
|
-
# supplier_id
|
275
|
+
# category_id bigint,
|
276
|
+
# supplier_id bigint
|
254
277
|
# )
|
255
278
|
#
|
256
279
|
# ====== Create a temporary table based on a query
|
@@ -282,7 +305,7 @@ module ActiveRecord
|
|
282
305
|
yield td if block_given?
|
283
306
|
|
284
307
|
if options[:force]
|
285
|
-
drop_table(table_name,
|
308
|
+
drop_table(table_name, options.merge(if_exists: true))
|
286
309
|
end
|
287
310
|
|
288
311
|
result = execute schema_creation.accept td
|
@@ -338,8 +361,8 @@ module ActiveRecord
|
|
338
361
|
# generates:
|
339
362
|
#
|
340
363
|
# CREATE TABLE assemblies_parts (
|
341
|
-
# assembly_id
|
342
|
-
# part_id
|
364
|
+
# assembly_id bigint NOT NULL,
|
365
|
+
# part_id bigint NOT NULL,
|
343
366
|
# ) ENGINE=InnoDB DEFAULT CHARSET=utf8
|
344
367
|
#
|
345
368
|
def create_join_table(table_1, table_2, column_options: {}, **options)
|
@@ -383,6 +406,8 @@ module ActiveRecord
|
|
383
406
|
#
|
384
407
|
# Defaults to false.
|
385
408
|
#
|
409
|
+
# Only supported on the MySQL and PostgreSQL adapter, ignored elsewhere.
|
410
|
+
#
|
386
411
|
# ====== Add a column
|
387
412
|
#
|
388
413
|
# change_table(:suppliers) do |t|
|
@@ -407,7 +432,7 @@ module ActiveRecord
|
|
407
432
|
# t.references :company
|
408
433
|
# end
|
409
434
|
#
|
410
|
-
# Creates a <tt>company_id(
|
435
|
+
# Creates a <tt>company_id(bigint)</tt> column.
|
411
436
|
#
|
412
437
|
# ====== Add a polymorphic foreign key column
|
413
438
|
#
|
@@ -415,7 +440,7 @@ module ActiveRecord
|
|
415
440
|
# t.belongs_to :company, polymorphic: true
|
416
441
|
# end
|
417
442
|
#
|
418
|
-
# Creates <tt>company_type(varchar)</tt> and <tt>company_id(
|
443
|
+
# Creates <tt>company_type(varchar)</tt> and <tt>company_id(bigint)</tt> columns.
|
419
444
|
#
|
420
445
|
# ====== Remove a column
|
421
446
|
#
|
@@ -488,15 +513,17 @@ module ActiveRecord
|
|
488
513
|
# * <tt>:limit</tt> -
|
489
514
|
# Requests a maximum column length. This is the number of characters for a <tt>:string</tt> column
|
490
515
|
# and number of bytes for <tt>:text</tt>, <tt>:binary</tt> and <tt>:integer</tt> columns.
|
516
|
+
# This option is ignored by some backends.
|
491
517
|
# * <tt>:default</tt> -
|
492
518
|
# The column's default value. Use +nil+ for +NULL+.
|
493
519
|
# * <tt>:null</tt> -
|
494
|
-
# Allows or disallows +NULL+ values in the column.
|
495
|
-
# have been named <tt>:null_allowed</tt>.
|
520
|
+
# Allows or disallows +NULL+ values in the column.
|
496
521
|
# * <tt>:precision</tt> -
|
497
522
|
# Specifies the precision for the <tt>:decimal</tt> and <tt>:numeric</tt> columns.
|
498
523
|
# * <tt>:scale</tt> -
|
499
524
|
# Specifies the scale for the <tt>:decimal</tt> and <tt>:numeric</tt> columns.
|
525
|
+
# * <tt>:comment</tt> -
|
526
|
+
# Specifies the comment for the column. This option is ignored by some backends.
|
500
527
|
#
|
501
528
|
# Note: The precision is the total number of significant digits,
|
502
529
|
# and the scale is the number of digits that can be stored following
|
@@ -573,7 +600,7 @@ module ActiveRecord
|
|
573
600
|
# to provide these in a migration's +change+ method so it can be reverted.
|
574
601
|
# In that case, +type+ and +options+ will be used by #add_column.
|
575
602
|
def remove_column(table_name, column_name, type = nil, options = {})
|
576
|
-
execute "ALTER TABLE #{quote_table_name(table_name)}
|
603
|
+
execute "ALTER TABLE #{quote_table_name(table_name)} #{remove_column_for_alter(table_name, column_name, type, options)}"
|
577
604
|
end
|
578
605
|
|
579
606
|
# Changes the column's definition according to the new options.
|
@@ -688,7 +715,7 @@ module ActiveRecord
|
|
688
715
|
#
|
689
716
|
# CREATE INDEX by_branch_desc_party ON accounts(branch_id DESC, party_id ASC, surname)
|
690
717
|
#
|
691
|
-
# Note: MySQL
|
718
|
+
# Note: MySQL only supports index order from 8.0.1 onwards (earlier versions accepted the syntax but ignored it).
|
692
719
|
#
|
693
720
|
# ====== Creating a partial index
|
694
721
|
#
|
@@ -711,6 +738,19 @@ module ActiveRecord
|
|
711
738
|
#
|
712
739
|
# Note: only supported by PostgreSQL and MySQL
|
713
740
|
#
|
741
|
+
# ====== Creating an index with a specific operator class
|
742
|
+
#
|
743
|
+
# add_index(:developers, :name, using: 'gist', opclass: :gist_trgm_ops)
|
744
|
+
# # CREATE INDEX developers_on_name ON developers USING gist (name gist_trgm_ops) -- PostgreSQL
|
745
|
+
#
|
746
|
+
# add_index(:developers, [:name, :city], using: 'gist', opclass: { city: :gist_trgm_ops })
|
747
|
+
# # CREATE INDEX developers_on_name_and_city ON developers USING gist (name, city gist_trgm_ops) -- PostgreSQL
|
748
|
+
#
|
749
|
+
# add_index(:developers, [:name, :city], using: 'gist', opclass: :gist_trgm_ops)
|
750
|
+
# # CREATE INDEX developers_on_name_and_city ON developers USING gist (name gist_trgm_ops, city gist_trgm_ops) -- PostgreSQL
|
751
|
+
#
|
752
|
+
# Note: only supported by PostgreSQL
|
753
|
+
#
|
714
754
|
# ====== Creating an index with a specific type
|
715
755
|
#
|
716
756
|
# add_index(:developers, :name, type: :fulltext)
|
@@ -757,7 +797,7 @@ module ActiveRecord
|
|
757
797
|
def rename_index(table_name, old_name, new_name)
|
758
798
|
validate_index_length!(table_name, new_name)
|
759
799
|
|
760
|
-
# this is a naive implementation; some DBs may support this more efficiently (
|
800
|
+
# this is a naive implementation; some DBs may support this more efficiently (PostgreSQL, for instance)
|
761
801
|
old_index_def = indexes(table_name).detect { |i| i.name == old_name }
|
762
802
|
return unless old_index_def
|
763
803
|
add_index(table_name, old_index_def.columns, name: new_name, unique: old_index_def.unique)
|
@@ -779,24 +819,19 @@ module ActiveRecord
|
|
779
819
|
end
|
780
820
|
|
781
821
|
# Verifies the existence of an index with a given name.
|
782
|
-
def index_name_exists?(table_name, index_name
|
783
|
-
unless default.nil?
|
784
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
785
|
-
Passing default to #index_name_exists? is deprecated without replacement.
|
786
|
-
MSG
|
787
|
-
end
|
822
|
+
def index_name_exists?(table_name, index_name)
|
788
823
|
index_name = index_name.to_s
|
789
824
|
indexes(table_name).detect { |i| i.name == index_name }
|
790
825
|
end
|
791
826
|
|
792
|
-
# Adds a reference. The reference column is
|
827
|
+
# Adds a reference. The reference column is a bigint by default,
|
793
828
|
# the <tt>:type</tt> option can be used to specify a different type.
|
794
829
|
# Optionally adds a +_type+ column, if <tt>:polymorphic</tt> option is provided.
|
795
830
|
# #add_reference and #add_belongs_to are acceptable.
|
796
831
|
#
|
797
832
|
# The +options+ hash can include the following keys:
|
798
833
|
# [<tt>:type</tt>]
|
799
|
-
# The reference column type. Defaults to +:
|
834
|
+
# The reference column type. Defaults to +:bigint+.
|
800
835
|
# [<tt>:index</tt>]
|
801
836
|
# Add an appropriate index. Defaults to true.
|
802
837
|
# See #add_index for usage of this option.
|
@@ -807,7 +842,7 @@ module ActiveRecord
|
|
807
842
|
# [<tt>:null</tt>]
|
808
843
|
# Whether the column allows nulls. Defaults to true.
|
809
844
|
#
|
810
|
-
# ====== Create a user_id
|
845
|
+
# ====== Create a user_id bigint column
|
811
846
|
#
|
812
847
|
# add_reference(:products, :user)
|
813
848
|
#
|
@@ -864,7 +899,7 @@ module ActiveRecord
|
|
864
899
|
foreign_key_options = { to_table: reference_name }
|
865
900
|
end
|
866
901
|
foreign_key_options[:column] ||= "#{ref_name}_id"
|
867
|
-
remove_foreign_key(table_name,
|
902
|
+
remove_foreign_key(table_name, foreign_key_options)
|
868
903
|
end
|
869
904
|
|
870
905
|
remove_column(table_name, "#{ref_name}_id")
|
@@ -920,6 +955,8 @@ module ActiveRecord
|
|
920
955
|
# Action that happens <tt>ON DELETE</tt>. Valid values are +:nullify+, +:cascade+ and +:restrict+
|
921
956
|
# [<tt>:on_update</tt>]
|
922
957
|
# Action that happens <tt>ON UPDATE</tt>. Valid values are +:nullify+, +:cascade+ and +:restrict+
|
958
|
+
# [<tt>:validate</tt>]
|
959
|
+
# (Postgres only) Specify whether or not the constraint should be validated. Defaults to +true+.
|
923
960
|
def add_foreign_key(from_table, to_table, options = {})
|
924
961
|
return unless supports_foreign_keys?
|
925
962
|
|
@@ -974,16 +1011,6 @@ module ActiveRecord
|
|
974
1011
|
foreign_key_for(from_table, options_or_to_table).present?
|
975
1012
|
end
|
976
1013
|
|
977
|
-
def foreign_key_for(from_table, options_or_to_table = {}) # :nodoc:
|
978
|
-
return unless supports_foreign_keys?
|
979
|
-
foreign_keys(from_table).detect { |fk| fk.defined_for? options_or_to_table }
|
980
|
-
end
|
981
|
-
|
982
|
-
def foreign_key_for!(from_table, options_or_to_table = {}) # :nodoc:
|
983
|
-
foreign_key_for(from_table, options_or_to_table) || \
|
984
|
-
raise(ArgumentError, "Table '#{from_table}' has no foreign key for #{options_or_to_table}")
|
985
|
-
end
|
986
|
-
|
987
1014
|
def foreign_key_column_for(table_name) # :nodoc:
|
988
1015
|
prefix = Base.table_name_prefix
|
989
1016
|
suffix = Base.table_name_suffix
|
@@ -1000,31 +1027,8 @@ module ActiveRecord
|
|
1000
1027
|
|
1001
1028
|
def dump_schema_information #:nodoc:
|
1002
1029
|
versions = ActiveRecord::SchemaMigration.all_versions
|
1003
|
-
insert_versions_sql(versions)
|
1004
|
-
end
|
1005
|
-
|
1006
|
-
def insert_versions_sql(versions) # :nodoc:
|
1007
|
-
sm_table = quote_table_name(ActiveRecord::SchemaMigration.table_name)
|
1008
|
-
|
1009
|
-
if versions.is_a?(Array)
|
1010
|
-
sql = "INSERT INTO #{sm_table} (version) VALUES\n"
|
1011
|
-
sql << versions.map { |v| "(#{quote(v)})" }.join(",\n")
|
1012
|
-
sql << ";\n\n"
|
1013
|
-
sql
|
1014
|
-
else
|
1015
|
-
"INSERT INTO #{sm_table} (version) VALUES (#{quote(versions)});"
|
1016
|
-
end
|
1017
|
-
end
|
1018
|
-
|
1019
|
-
def initialize_schema_migrations_table # :nodoc:
|
1020
|
-
ActiveRecord::SchemaMigration.create_table
|
1021
|
-
end
|
1022
|
-
deprecate :initialize_schema_migrations_table
|
1023
|
-
|
1024
|
-
def initialize_internal_metadata_table # :nodoc:
|
1025
|
-
ActiveRecord::InternalMetadata.create_table
|
1030
|
+
insert_versions_sql(versions) if versions.any?
|
1026
1031
|
end
|
1027
|
-
deprecate :initialize_internal_metadata_table
|
1028
1032
|
|
1029
1033
|
def internal_string_options_for_primary_key # :nodoc:
|
1030
1034
|
{ primary_key: true }
|
@@ -1036,8 +1040,8 @@ module ActiveRecord
|
|
1036
1040
|
sm_table = quote_table_name(ActiveRecord::SchemaMigration.table_name)
|
1037
1041
|
|
1038
1042
|
migrated = ActiveRecord::SchemaMigration.all_versions.map(&:to_i)
|
1039
|
-
versions =
|
1040
|
-
|
1043
|
+
versions = migration_context.migration_files.map do |file|
|
1044
|
+
migration_context.parse_migration_filename(file).first.to_i
|
1041
1045
|
end
|
1042
1046
|
|
1043
1047
|
unless migrated.include?(version)
|
@@ -1131,7 +1135,7 @@ module ActiveRecord
|
|
1131
1135
|
def add_index_options(table_name, column_name, comment: nil, **options) # :nodoc:
|
1132
1136
|
column_names = index_column_names(column_name)
|
1133
1137
|
|
1134
|
-
options.assert_valid_keys(:unique, :order, :name, :where, :length, :internal, :using, :algorithm, :type)
|
1138
|
+
options.assert_valid_keys(:unique, :order, :name, :where, :length, :internal, :using, :algorithm, :type, :opclass)
|
1135
1139
|
|
1136
1140
|
index_type = options[:type].to_s if options.key?(:type)
|
1137
1141
|
index_type ||= options[:unique] ? "UNIQUE" : ""
|
@@ -1170,30 +1174,36 @@ module ActiveRecord
|
|
1170
1174
|
end
|
1171
1175
|
|
1172
1176
|
# Changes the comment for a column or removes it if +nil+.
|
1173
|
-
def change_column_comment(table_name, column_name, comment)
|
1177
|
+
def change_column_comment(table_name, column_name, comment)
|
1174
1178
|
raise NotImplementedError, "#{self.class} does not support changing column comments"
|
1175
1179
|
end
|
1176
1180
|
|
1181
|
+
def create_schema_dumper(options) # :nodoc:
|
1182
|
+
SchemaDumper.create(self, options)
|
1183
|
+
end
|
1184
|
+
|
1177
1185
|
private
|
1178
1186
|
def column_options_keys
|
1179
1187
|
[:limit, :precision, :scale, :default, :null, :collation, :comment]
|
1180
1188
|
end
|
1181
1189
|
|
1182
1190
|
def add_index_sort_order(quoted_columns, **options)
|
1183
|
-
|
1184
|
-
|
1185
|
-
|
1186
|
-
order = order.symbolize_keys
|
1187
|
-
quoted_columns.each { |name, column| column << " #{order[name].upcase}" if order[name].present? }
|
1188
|
-
when String
|
1189
|
-
quoted_columns.each { |name, column| column << " #{order.upcase}" if order.present? }
|
1190
|
-
end
|
1191
|
+
orders = options_for_index_columns(options[:order])
|
1192
|
+
quoted_columns.each do |name, column|
|
1193
|
+
column << " #{orders[name].upcase}" if orders[name].present?
|
1191
1194
|
end
|
1195
|
+
end
|
1192
1196
|
|
1193
|
-
|
1197
|
+
def options_for_index_columns(options)
|
1198
|
+
if options.is_a?(Hash)
|
1199
|
+
options.symbolize_keys
|
1200
|
+
else
|
1201
|
+
Hash.new { |hash, column| hash[column] = options }
|
1202
|
+
end
|
1194
1203
|
end
|
1195
1204
|
|
1196
|
-
# Overridden by the MySQL adapter for supporting index lengths
|
1205
|
+
# Overridden by the MySQL adapter for supporting index lengths and by
|
1206
|
+
# the PostgreSQL adapter for supporting operator classes.
|
1197
1207
|
def add_options_for_index_columns(quoted_columns, **options)
|
1198
1208
|
if supports_index_sort_order?
|
1199
1209
|
quoted_columns = add_index_sort_order(quoted_columns, options)
|
@@ -1261,6 +1271,10 @@ module ActiveRecord
|
|
1261
1271
|
end
|
1262
1272
|
end
|
1263
1273
|
|
1274
|
+
def schema_creation
|
1275
|
+
SchemaCreation.new(self)
|
1276
|
+
end
|
1277
|
+
|
1264
1278
|
def create_table_definition(*args)
|
1265
1279
|
TableDefinition.new(*args)
|
1266
1280
|
end
|
@@ -1269,6 +1283,17 @@ module ActiveRecord
|
|
1269
1283
|
AlterTable.new create_table_definition(name)
|
1270
1284
|
end
|
1271
1285
|
|
1286
|
+
def fetch_type_metadata(sql_type)
|
1287
|
+
cast_type = lookup_cast_type(sql_type)
|
1288
|
+
SqlTypeMetadata.new(
|
1289
|
+
sql_type: sql_type,
|
1290
|
+
type: cast_type.type,
|
1291
|
+
limit: cast_type.limit,
|
1292
|
+
precision: cast_type.precision,
|
1293
|
+
scale: cast_type.scale,
|
1294
|
+
)
|
1295
|
+
end
|
1296
|
+
|
1272
1297
|
def index_column_names(column_names)
|
1273
1298
|
if column_names.is_a?(String) && /\W/.match?(column_names)
|
1274
1299
|
column_names
|
@@ -1286,13 +1311,32 @@ module ActiveRecord
|
|
1286
1311
|
end
|
1287
1312
|
|
1288
1313
|
def foreign_key_name(table_name, options)
|
1289
|
-
identifier = "#{table_name}_#{options.fetch(:column)}_fk"
|
1290
|
-
hashed_identifier = Digest::SHA256.hexdigest(identifier).first(10)
|
1291
1314
|
options.fetch(:name) do
|
1315
|
+
identifier = "#{table_name}_#{options.fetch(:column)}_fk"
|
1316
|
+
hashed_identifier = Digest::SHA256.hexdigest(identifier).first(10)
|
1317
|
+
|
1292
1318
|
"fk_rails_#{hashed_identifier}"
|
1293
1319
|
end
|
1294
1320
|
end
|
1295
1321
|
|
1322
|
+
def foreign_key_for(from_table, options_or_to_table = {})
|
1323
|
+
return unless supports_foreign_keys?
|
1324
|
+
foreign_keys(from_table).detect { |fk| fk.defined_for? options_or_to_table }
|
1325
|
+
end
|
1326
|
+
|
1327
|
+
def foreign_key_for!(from_table, options_or_to_table = {})
|
1328
|
+
foreign_key_for(from_table, options_or_to_table) || \
|
1329
|
+
raise(ArgumentError, "Table '#{from_table}' has no foreign key for #{options_or_to_table}")
|
1330
|
+
end
|
1331
|
+
|
1332
|
+
def extract_foreign_key_action(specifier)
|
1333
|
+
case specifier
|
1334
|
+
when "CASCADE"; :cascade
|
1335
|
+
when "SET NULL"; :nullify
|
1336
|
+
when "RESTRICT"; :restrict
|
1337
|
+
end
|
1338
|
+
end
|
1339
|
+
|
1296
1340
|
def validate_index_length!(table_name, new_name, internal = false)
|
1297
1341
|
max_index_length = internal ? index_name_length : allowed_index_name_length
|
1298
1342
|
|
@@ -1313,6 +1357,33 @@ module ActiveRecord
|
|
1313
1357
|
options.is_a?(Hash) && options.key?(:name) && options.except(:name, :algorithm).empty?
|
1314
1358
|
end
|
1315
1359
|
|
1360
|
+
def add_column_for_alter(table_name, column_name, type, options = {})
|
1361
|
+
td = create_table_definition(table_name)
|
1362
|
+
cd = td.new_column_definition(column_name, type, options)
|
1363
|
+
schema_creation.accept(AddColumnDefinition.new(cd))
|
1364
|
+
end
|
1365
|
+
|
1366
|
+
def remove_column_for_alter(table_name, column_name, type = nil, options = {})
|
1367
|
+
"DROP COLUMN #{quote_column_name(column_name)}"
|
1368
|
+
end
|
1369
|
+
|
1370
|
+
def remove_columns_for_alter(table_name, *column_names)
|
1371
|
+
column_names.map { |column_name| remove_column_for_alter(table_name, column_name) }
|
1372
|
+
end
|
1373
|
+
|
1374
|
+
def insert_versions_sql(versions)
|
1375
|
+
sm_table = quote_table_name(ActiveRecord::SchemaMigration.table_name)
|
1376
|
+
|
1377
|
+
if versions.is_a?(Array)
|
1378
|
+
sql = "INSERT INTO #{sm_table} (version) VALUES\n".dup
|
1379
|
+
sql << versions.map { |v| "(#{quote(v)})" }.join(",\n")
|
1380
|
+
sql << ";\n\n"
|
1381
|
+
sql
|
1382
|
+
else
|
1383
|
+
"INSERT INTO #{sm_table} (version) VALUES (#{quote(versions)});"
|
1384
|
+
end
|
1385
|
+
end
|
1386
|
+
|
1316
1387
|
def data_source_sql(name = nil, type: nil)
|
1317
1388
|
raise NotImplementedError
|
1318
1389
|
end
|