activerecord 5.1.7 → 5.2.0
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 +372 -765
- 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/aggregations.rb +6 -5
- data/lib/active_record/association_relation.rb +4 -2
- data/lib/active_record/associations/alias_tracker.rb +19 -27
- data/lib/active_record/associations/association.rb +16 -27
- data/lib/active_record/associations/association_scope.rb +38 -50
- data/lib/active_record/associations/belongs_to_association.rb +20 -10
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +4 -7
- data/lib/active_record/associations/builder/association.rb +4 -7
- data/lib/active_record/associations/builder/belongs_to.rb +4 -5
- 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 +43 -35
- data/lib/active_record/associations/collection_proxy.rb +12 -15
- data/lib/active_record/associations/foreign_association.rb +2 -0
- data/lib/active_record/associations/has_many_association.rb +3 -1
- data/lib/active_record/associations/has_many_through_association.rb +7 -18
- data/lib/active_record/associations/has_one_association.rb +4 -1
- data/lib/active_record/associations/has_one_through_association.rb +8 -7
- data/lib/active_record/associations/join_dependency/join_association.rb +17 -56
- data/lib/active_record/associations/join_dependency/join_base.rb +9 -8
- data/lib/active_record/associations/join_dependency/join_part.rb +2 -9
- data/lib/active_record/associations/join_dependency.rb +23 -43
- data/lib/active_record/associations/preloader/association.rb +45 -61
- data/lib/active_record/associations/preloader/through_association.rb +71 -79
- data/lib/active_record/associations/preloader.rb +17 -37
- data/lib/active_record/associations/singular_association.rb +14 -10
- data/lib/active_record/associations/through_association.rb +25 -10
- data/lib/active_record/associations.rb +31 -54
- data/lib/active_record/attribute_assignment.rb +2 -5
- data/lib/active_record/attribute_decorators.rb +3 -2
- data/lib/active_record/attribute_methods/before_type_cast.rb +2 -0
- data/lib/active_record/attribute_methods/dirty.rb +25 -214
- data/lib/active_record/attribute_methods/primary_key.rb +7 -6
- data/lib/active_record/attribute_methods/query.rb +2 -0
- data/lib/active_record/attribute_methods/read.rb +8 -2
- 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 +21 -9
- data/lib/active_record/attribute_methods.rb +65 -24
- data/lib/active_record/attributes.rb +6 -5
- data/lib/active_record/autosave_association.rb +8 -11
- data/lib/active_record/base.rb +2 -0
- data/lib/active_record/callbacks.rb +8 -10
- 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 +11 -7
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +111 -38
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +2 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +157 -29
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +7 -2
- data/lib/active_record/connection_adapters/abstract/quoting.rb +13 -32
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +14 -5
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +57 -2
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +31 -53
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +158 -78
- data/lib/active_record/connection_adapters/abstract/transaction.rb +45 -9
- data/lib/active_record/connection_adapters/abstract_adapter.rb +81 -96
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +111 -183
- data/lib/active_record/connection_adapters/column.rb +3 -1
- data/lib/active_record/connection_adapters/connection_specification.rb +17 -3
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +2 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +2 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +11 -2
- 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 -30
- 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 +2 -0
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +6 -0
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +3 -11
- 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 +2 -0
- 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 -1
- 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 +4 -6
- 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/oid.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +18 -0
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +19 -25
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +14 -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 +246 -110
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +58 -82
- 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 +18 -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 +71 -1
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +80 -90
- 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 +39 -60
- data/lib/active_record/counter_cache.rb +15 -12
- data/lib/active_record/define_callbacks.rb +5 -3
- data/lib/active_record/dynamic_matchers.rb +9 -9
- data/lib/active_record/enum.rb +17 -13
- data/lib/active_record/errors.rb +54 -21
- 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 +14 -17
- data/lib/active_record/locking/pessimistic.rb +9 -6
- data/lib/active_record/log_subscriber.rb +43 -0
- data/lib/active_record/migration/command_recorder.rb +11 -9
- data/lib/active_record/migration/compatibility.rb +40 -2
- data/lib/active_record/migration/join_table.rb +2 -0
- data/lib/active_record/migration.rb +189 -139
- data/lib/active_record/model_schema.rb +16 -21
- 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 +166 -16
- data/lib/active_record/query_cache.rb +11 -6
- data/lib/active_record/querying.rb +3 -1
- data/lib/active_record/railtie.rb +61 -3
- 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 +46 -36
- data/lib/active_record/readonly_attributes.rb +3 -2
- data/lib/active_record/reflection.rb +110 -192
- data/lib/active_record/relation/batches/batch_enumerator.rb +2 -0
- data/lib/active_record/relation/batches.rb +20 -5
- data/lib/active_record/relation/calculations.rb +30 -8
- data/lib/active_record/relation/delegation.rb +15 -27
- data/lib/active_record/relation/finder_methods.rb +75 -78
- data/lib/active_record/relation/from_clause.rb +2 -8
- data/lib/active_record/relation/merger.rb +51 -20
- 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/predicate_builder.rb +53 -78
- data/lib/active_record/relation/query_attribute.rb +26 -2
- data/lib/active_record/relation/query_methods.rb +89 -88
- data/lib/active_record/relation/record_fetch_warning.rb +2 -0
- data/lib/active_record/relation/spawn_methods.rb +3 -1
- data/lib/active_record/relation/where_clause.rb +65 -68
- data/lib/active_record/relation/where_clause_factory.rb +5 -48
- data/lib/active_record/relation.rb +95 -208
- 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/default.rb +6 -7
- data/lib/active_record/scoping/named.rb +21 -7
- data/lib/active_record/scoping.rb +9 -8
- 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 +26 -15
- data/lib/active_record/tasks/mysql_database_tasks.rb +9 -48
- data/lib/active_record/tasks/postgresql_database_tasks.rb +10 -2
- data/lib/active_record/tasks/sqlite_database_tasks.rb +25 -3
- data/lib/active_record/timestamp.rb +5 -12
- data/lib/active_record/touch_later.rb +2 -0
- data/lib/active_record/transactions.rb +9 -7
- data/lib/active_record/translation.rb +2 -0
- 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 +2 -4
- 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.rb +4 -1
- data/lib/active_record/type_caster/connection.rb +2 -0
- data/lib/active_record/type_caster/map.rb +3 -1
- data/lib/active_record/type_caster.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 +35 -5
- data/lib/active_record/validations.rb +2 -0
- data/lib/active_record/version.rb +2 -0
- data/lib/active_record.rb +11 -4
- 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/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/migration.rb +2 -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
- data/lib/rails/generators/active_record.rb +3 -1
- 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/user_provided_default.rb +0 -30
- data/lib/active_record/attribute.rb +0 -240
- data/lib/active_record/attribute_mutation_tracker.rb +0 -122
- data/lib/active_record/attribute_set/builder.rb +0 -126
- data/lib/active_record/attribute_set/yaml_encoder.rb +0 -41
- data/lib/active_record/attribute_set.rb +0 -113
- 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 -37
@@ -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:
|
@@ -77,7 +79,7 @@ module ActiveRecord
|
|
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
|
@@ -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,28 @@ 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
|
+
#
|
745
|
+
# generates:
|
746
|
+
#
|
747
|
+
# CREATE INDEX developers_on_name ON developers USING gist (name gist_trgm_ops) -- PostgreSQL
|
748
|
+
#
|
749
|
+
# add_index(:developers, [:name, :city], using: 'gist', opclass: { city: :gist_trgm_ops })
|
750
|
+
#
|
751
|
+
# generates:
|
752
|
+
#
|
753
|
+
# CREATE INDEX developers_on_name_and_city ON developers USING gist (name, city gist_trgm_ops) -- PostgreSQL
|
754
|
+
#
|
755
|
+
# add_index(:developers, [:name, :city], using: 'gist', opclass: :gist_trgm_ops)
|
756
|
+
#
|
757
|
+
# generates:
|
758
|
+
#
|
759
|
+
# CREATE INDEX developers_on_name_and_city ON developers USING gist (name gist_trgm_ops, city gist_trgm_ops) -- PostgreSQL
|
760
|
+
#
|
761
|
+
# Note: only supported by PostgreSQL
|
762
|
+
#
|
714
763
|
# ====== Creating an index with a specific type
|
715
764
|
#
|
716
765
|
# add_index(:developers, :name, type: :fulltext)
|
@@ -757,7 +806,7 @@ module ActiveRecord
|
|
757
806
|
def rename_index(table_name, old_name, new_name)
|
758
807
|
validate_index_length!(table_name, new_name)
|
759
808
|
|
760
|
-
# this is a naive implementation; some DBs may support this more efficiently (
|
809
|
+
# this is a naive implementation; some DBs may support this more efficiently (PostgreSQL, for instance)
|
761
810
|
old_index_def = indexes(table_name).detect { |i| i.name == old_name }
|
762
811
|
return unless old_index_def
|
763
812
|
add_index(table_name, old_index_def.columns, name: new_name, unique: old_index_def.unique)
|
@@ -779,24 +828,19 @@ module ActiveRecord
|
|
779
828
|
end
|
780
829
|
|
781
830
|
# 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
|
831
|
+
def index_name_exists?(table_name, index_name)
|
788
832
|
index_name = index_name.to_s
|
789
833
|
indexes(table_name).detect { |i| i.name == index_name }
|
790
834
|
end
|
791
835
|
|
792
|
-
# Adds a reference. The reference column is
|
836
|
+
# Adds a reference. The reference column is a bigint by default,
|
793
837
|
# the <tt>:type</tt> option can be used to specify a different type.
|
794
838
|
# Optionally adds a +_type+ column, if <tt>:polymorphic</tt> option is provided.
|
795
839
|
# #add_reference and #add_belongs_to are acceptable.
|
796
840
|
#
|
797
841
|
# The +options+ hash can include the following keys:
|
798
842
|
# [<tt>:type</tt>]
|
799
|
-
# The reference column type. Defaults to +:
|
843
|
+
# The reference column type. Defaults to +:bigint+.
|
800
844
|
# [<tt>:index</tt>]
|
801
845
|
# Add an appropriate index. Defaults to true.
|
802
846
|
# See #add_index for usage of this option.
|
@@ -807,7 +851,7 @@ module ActiveRecord
|
|
807
851
|
# [<tt>:null</tt>]
|
808
852
|
# Whether the column allows nulls. Defaults to true.
|
809
853
|
#
|
810
|
-
# ====== Create a user_id
|
854
|
+
# ====== Create a user_id bigint column
|
811
855
|
#
|
812
856
|
# add_reference(:products, :user)
|
813
857
|
#
|
@@ -920,6 +964,8 @@ module ActiveRecord
|
|
920
964
|
# Action that happens <tt>ON DELETE</tt>. Valid values are +:nullify+, +:cascade+ and +:restrict+
|
921
965
|
# [<tt>:on_update</tt>]
|
922
966
|
# Action that happens <tt>ON UPDATE</tt>. Valid values are +:nullify+, +:cascade+ and +:restrict+
|
967
|
+
# [<tt>:validate</tt>]
|
968
|
+
# (Postgres only) Specify whether or not the constraint should be validated. Defaults to +true+.
|
923
969
|
def add_foreign_key(from_table, to_table, options = {})
|
924
970
|
return unless supports_foreign_keys?
|
925
971
|
|
@@ -974,16 +1020,6 @@ module ActiveRecord
|
|
974
1020
|
foreign_key_for(from_table, options_or_to_table).present?
|
975
1021
|
end
|
976
1022
|
|
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
1023
|
def foreign_key_column_for(table_name) # :nodoc:
|
988
1024
|
prefix = Base.table_name_prefix
|
989
1025
|
suffix = Base.table_name_suffix
|
@@ -1003,29 +1039,6 @@ module ActiveRecord
|
|
1003
1039
|
insert_versions_sql(versions) if versions.any?
|
1004
1040
|
end
|
1005
1041
|
|
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
|
1026
|
-
end
|
1027
|
-
deprecate :initialize_internal_metadata_table
|
1028
|
-
|
1029
1042
|
def internal_string_options_for_primary_key # :nodoc:
|
1030
1043
|
{ primary_key: true }
|
1031
1044
|
end
|
@@ -1036,8 +1049,8 @@ module ActiveRecord
|
|
1036
1049
|
sm_table = quote_table_name(ActiveRecord::SchemaMigration.table_name)
|
1037
1050
|
|
1038
1051
|
migrated = ActiveRecord::SchemaMigration.all_versions.map(&:to_i)
|
1039
|
-
versions =
|
1040
|
-
|
1052
|
+
versions = migration_context.migration_files.map do |file|
|
1053
|
+
migration_context.parse_migration_filename(file).first.to_i
|
1041
1054
|
end
|
1042
1055
|
|
1043
1056
|
unless migrated.include?(version)
|
@@ -1131,7 +1144,7 @@ module ActiveRecord
|
|
1131
1144
|
def add_index_options(table_name, column_name, comment: nil, **options) # :nodoc:
|
1132
1145
|
column_names = index_column_names(column_name)
|
1133
1146
|
|
1134
|
-
options.assert_valid_keys(:unique, :order, :name, :where, :length, :internal, :using, :algorithm, :type)
|
1147
|
+
options.assert_valid_keys(:unique, :order, :name, :where, :length, :internal, :using, :algorithm, :type, :opclass)
|
1135
1148
|
|
1136
1149
|
index_type = options[:type].to_s if options.key?(:type)
|
1137
1150
|
index_type ||= options[:unique] ? "UNIQUE" : ""
|
@@ -1170,30 +1183,36 @@ module ActiveRecord
|
|
1170
1183
|
end
|
1171
1184
|
|
1172
1185
|
# Changes the comment for a column or removes it if +nil+.
|
1173
|
-
def change_column_comment(table_name, column_name, comment)
|
1186
|
+
def change_column_comment(table_name, column_name, comment)
|
1174
1187
|
raise NotImplementedError, "#{self.class} does not support changing column comments"
|
1175
1188
|
end
|
1176
1189
|
|
1190
|
+
def create_schema_dumper(options) # :nodoc:
|
1191
|
+
SchemaDumper.create(self, options)
|
1192
|
+
end
|
1193
|
+
|
1177
1194
|
private
|
1178
1195
|
def column_options_keys
|
1179
1196
|
[:limit, :precision, :scale, :default, :null, :collation, :comment]
|
1180
1197
|
end
|
1181
1198
|
|
1182
1199
|
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
|
1200
|
+
orders = options_for_index_columns(options[:order])
|
1201
|
+
quoted_columns.each do |name, column|
|
1202
|
+
column << " #{orders[name].upcase}" if orders[name].present?
|
1191
1203
|
end
|
1204
|
+
end
|
1192
1205
|
|
1193
|
-
|
1206
|
+
def options_for_index_columns(options)
|
1207
|
+
if options.is_a?(Hash)
|
1208
|
+
options.symbolize_keys
|
1209
|
+
else
|
1210
|
+
Hash.new { |hash, column| hash[column] = options }
|
1211
|
+
end
|
1194
1212
|
end
|
1195
1213
|
|
1196
|
-
# Overridden by the MySQL adapter for supporting index lengths
|
1214
|
+
# Overridden by the MySQL adapter for supporting index lengths and by
|
1215
|
+
# the PostgreSQL adapter for supporting operator classes.
|
1197
1216
|
def add_options_for_index_columns(quoted_columns, **options)
|
1198
1217
|
if supports_index_sort_order?
|
1199
1218
|
quoted_columns = add_index_sort_order(quoted_columns, options)
|
@@ -1261,6 +1280,10 @@ module ActiveRecord
|
|
1261
1280
|
end
|
1262
1281
|
end
|
1263
1282
|
|
1283
|
+
def schema_creation
|
1284
|
+
SchemaCreation.new(self)
|
1285
|
+
end
|
1286
|
+
|
1264
1287
|
def create_table_definition(*args)
|
1265
1288
|
TableDefinition.new(*args)
|
1266
1289
|
end
|
@@ -1269,6 +1292,17 @@ module ActiveRecord
|
|
1269
1292
|
AlterTable.new create_table_definition(name)
|
1270
1293
|
end
|
1271
1294
|
|
1295
|
+
def fetch_type_metadata(sql_type)
|
1296
|
+
cast_type = lookup_cast_type(sql_type)
|
1297
|
+
SqlTypeMetadata.new(
|
1298
|
+
sql_type: sql_type,
|
1299
|
+
type: cast_type.type,
|
1300
|
+
limit: cast_type.limit,
|
1301
|
+
precision: cast_type.precision,
|
1302
|
+
scale: cast_type.scale,
|
1303
|
+
)
|
1304
|
+
end
|
1305
|
+
|
1272
1306
|
def index_column_names(column_names)
|
1273
1307
|
if column_names.is_a?(String) && /\W/.match?(column_names)
|
1274
1308
|
column_names
|
@@ -1286,13 +1320,32 @@ module ActiveRecord
|
|
1286
1320
|
end
|
1287
1321
|
|
1288
1322
|
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
1323
|
options.fetch(:name) do
|
1324
|
+
identifier = "#{table_name}_#{options.fetch(:column)}_fk"
|
1325
|
+
hashed_identifier = Digest::SHA256.hexdigest(identifier).first(10)
|
1326
|
+
|
1292
1327
|
"fk_rails_#{hashed_identifier}"
|
1293
1328
|
end
|
1294
1329
|
end
|
1295
1330
|
|
1331
|
+
def foreign_key_for(from_table, options_or_to_table = {})
|
1332
|
+
return unless supports_foreign_keys?
|
1333
|
+
foreign_keys(from_table).detect { |fk| fk.defined_for? options_or_to_table }
|
1334
|
+
end
|
1335
|
+
|
1336
|
+
def foreign_key_for!(from_table, options_or_to_table = {})
|
1337
|
+
foreign_key_for(from_table, options_or_to_table) || \
|
1338
|
+
raise(ArgumentError, "Table '#{from_table}' has no foreign key for #{options_or_to_table}")
|
1339
|
+
end
|
1340
|
+
|
1341
|
+
def extract_foreign_key_action(specifier)
|
1342
|
+
case specifier
|
1343
|
+
when "CASCADE"; :cascade
|
1344
|
+
when "SET NULL"; :nullify
|
1345
|
+
when "RESTRICT"; :restrict
|
1346
|
+
end
|
1347
|
+
end
|
1348
|
+
|
1296
1349
|
def validate_index_length!(table_name, new_name, internal = false)
|
1297
1350
|
max_index_length = internal ? index_name_length : allowed_index_name_length
|
1298
1351
|
|
@@ -1313,6 +1366,33 @@ module ActiveRecord
|
|
1313
1366
|
options.is_a?(Hash) && options.key?(:name) && options.except(:name, :algorithm).empty?
|
1314
1367
|
end
|
1315
1368
|
|
1369
|
+
def add_column_for_alter(table_name, column_name, type, options = {})
|
1370
|
+
td = create_table_definition(table_name)
|
1371
|
+
cd = td.new_column_definition(column_name, type, options)
|
1372
|
+
schema_creation.accept(AddColumnDefinition.new(cd))
|
1373
|
+
end
|
1374
|
+
|
1375
|
+
def remove_column_for_alter(table_name, column_name, type = nil, options = {})
|
1376
|
+
"DROP COLUMN #{quote_column_name(column_name)}"
|
1377
|
+
end
|
1378
|
+
|
1379
|
+
def remove_columns_for_alter(table_name, *column_names)
|
1380
|
+
column_names.map { |column_name| remove_column_for_alter(table_name, column_name) }
|
1381
|
+
end
|
1382
|
+
|
1383
|
+
def insert_versions_sql(versions)
|
1384
|
+
sm_table = quote_table_name(ActiveRecord::SchemaMigration.table_name)
|
1385
|
+
|
1386
|
+
if versions.is_a?(Array)
|
1387
|
+
sql = "INSERT INTO #{sm_table} (version) VALUES\n".dup
|
1388
|
+
sql << versions.map { |v| "(#{quote(v)})" }.join(",\n")
|
1389
|
+
sql << ";\n\n"
|
1390
|
+
sql
|
1391
|
+
else
|
1392
|
+
"INSERT INTO #{sm_table} (version) VALUES (#{quote(versions)});"
|
1393
|
+
end
|
1394
|
+
end
|
1395
|
+
|
1316
1396
|
def data_source_sql(name = nil, type: nil)
|
1317
1397
|
raise NotImplementedError
|
1318
1398
|
end
|
@@ -1,10 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module ConnectionAdapters
|
3
5
|
class TransactionState
|
4
|
-
VALID_STATES = Set.new([:committed, :rolledback, nil])
|
5
|
-
|
6
6
|
def initialize(state = nil)
|
7
7
|
@state = state
|
8
|
+
@children = []
|
9
|
+
end
|
10
|
+
|
11
|
+
def add_child(state)
|
12
|
+
@children << state
|
8
13
|
end
|
9
14
|
|
10
15
|
def finalized?
|
@@ -19,15 +24,43 @@ module ActiveRecord
|
|
19
24
|
@state == :rolledback
|
20
25
|
end
|
21
26
|
|
27
|
+
def fully_completed?
|
28
|
+
completed?
|
29
|
+
end
|
30
|
+
|
22
31
|
def completed?
|
23
32
|
committed? || rolledback?
|
24
33
|
end
|
25
34
|
|
26
35
|
def set_state(state)
|
27
|
-
|
36
|
+
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
37
|
+
The set_state method is deprecated and will be removed in
|
38
|
+
Rails 6.0. Please use rollback! or commit! to set transaction
|
39
|
+
state directly.
|
40
|
+
MSG
|
41
|
+
case state
|
42
|
+
when :rolledback
|
43
|
+
rollback!
|
44
|
+
when :committed
|
45
|
+
commit!
|
46
|
+
when nil
|
47
|
+
nullify!
|
48
|
+
else
|
28
49
|
raise ArgumentError, "Invalid transaction state: #{state}"
|
29
50
|
end
|
30
|
-
|
51
|
+
end
|
52
|
+
|
53
|
+
def rollback!
|
54
|
+
@children.each { |c| c.rollback! }
|
55
|
+
@state = :rolledback
|
56
|
+
end
|
57
|
+
|
58
|
+
def commit!
|
59
|
+
@state = :committed
|
60
|
+
end
|
61
|
+
|
62
|
+
def nullify!
|
63
|
+
@state = nil
|
31
64
|
end
|
32
65
|
end
|
33
66
|
|
@@ -57,7 +90,7 @@ module ActiveRecord
|
|
57
90
|
end
|
58
91
|
|
59
92
|
def rollback
|
60
|
-
@state.
|
93
|
+
@state.rollback!
|
61
94
|
end
|
62
95
|
|
63
96
|
def rollback_records
|
@@ -72,7 +105,7 @@ module ActiveRecord
|
|
72
105
|
end
|
73
106
|
|
74
107
|
def commit
|
75
|
-
@state.
|
108
|
+
@state.commit!
|
76
109
|
end
|
77
110
|
|
78
111
|
def before_commit_records
|
@@ -100,8 +133,11 @@ module ActiveRecord
|
|
100
133
|
end
|
101
134
|
|
102
135
|
class SavepointTransaction < Transaction
|
103
|
-
def initialize(connection, savepoint_name, options, *args)
|
136
|
+
def initialize(connection, savepoint_name, parent_transaction, options, *args)
|
104
137
|
super(connection, options, *args)
|
138
|
+
|
139
|
+
parent_transaction.state.add_child(@state)
|
140
|
+
|
105
141
|
if options[:isolation]
|
106
142
|
raise ActiveRecord::TransactionIsolationError, "cannot set transaction isolation in a nested transaction"
|
107
143
|
end
|
@@ -155,7 +191,7 @@ module ActiveRecord
|
|
155
191
|
if @stack.empty?
|
156
192
|
RealTransaction.new(@connection, options, run_commit_callbacks: run_commit_callbacks)
|
157
193
|
else
|
158
|
-
SavepointTransaction.new(@connection, "active_record_#{@stack.size}", options,
|
194
|
+
SavepointTransaction.new(@connection, "active_record_#{@stack.size}", @stack.last, options,
|
159
195
|
run_commit_callbacks: run_commit_callbacks)
|
160
196
|
end
|
161
197
|
|
@@ -204,7 +240,7 @@ module ActiveRecord
|
|
204
240
|
rollback_transaction if transaction
|
205
241
|
else
|
206
242
|
begin
|
207
|
-
commit_transaction
|
243
|
+
commit_transaction if transaction
|
208
244
|
rescue Exception
|
209
245
|
rollback_transaction(transaction) unless transaction.state.completed?
|
210
246
|
raise
|