activerecord 6.0.0 → 6.1.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 +872 -582
- data/MIT-LICENSE +1 -1
- data/README.rdoc +3 -3
- data/lib/active_record.rb +7 -13
- data/lib/active_record/aggregations.rb +1 -2
- data/lib/active_record/association_relation.rb +22 -12
- data/lib/active_record/associations.rb +116 -13
- data/lib/active_record/associations/alias_tracker.rb +19 -16
- data/lib/active_record/associations/association.rb +49 -29
- data/lib/active_record/associations/association_scope.rb +17 -15
- data/lib/active_record/associations/belongs_to_association.rb +15 -5
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +1 -1
- data/lib/active_record/associations/builder/association.rb +9 -3
- data/lib/active_record/associations/builder/belongs_to.rb +10 -7
- data/lib/active_record/associations/builder/collection_association.rb +5 -4
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +0 -3
- 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 +25 -8
- data/lib/active_record/associations/collection_proxy.rb +14 -7
- data/lib/active_record/associations/foreign_association.rb +13 -0
- data/lib/active_record/associations/has_many_association.rb +24 -3
- data/lib/active_record/associations/has_many_through_association.rb +10 -4
- data/lib/active_record/associations/has_one_association.rb +15 -1
- data/lib/active_record/associations/join_dependency.rb +77 -42
- data/lib/active_record/associations/join_dependency/join_association.rb +36 -14
- data/lib/active_record/associations/join_dependency/join_part.rb +3 -3
- data/lib/active_record/associations/preloader.rb +13 -8
- data/lib/active_record/associations/preloader/association.rb +51 -25
- data/lib/active_record/associations/preloader/through_association.rb +2 -2
- data/lib/active_record/associations/singular_association.rb +1 -1
- data/lib/active_record/associations/through_association.rb +1 -1
- data/lib/active_record/attribute_assignment.rb +10 -9
- data/lib/active_record/attribute_methods.rb +64 -54
- data/lib/active_record/attribute_methods/before_type_cast.rb +13 -10
- data/lib/active_record/attribute_methods/dirty.rb +3 -13
- data/lib/active_record/attribute_methods/primary_key.rb +6 -4
- data/lib/active_record/attribute_methods/query.rb +3 -6
- data/lib/active_record/attribute_methods/read.rb +8 -12
- data/lib/active_record/attribute_methods/serialization.rb +11 -6
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +12 -15
- data/lib/active_record/attribute_methods/write.rb +12 -21
- data/lib/active_record/attributes.rb +32 -8
- data/lib/active_record/autosave_association.rb +63 -44
- data/lib/active_record/base.rb +2 -14
- data/lib/active_record/callbacks.rb +153 -24
- data/lib/active_record/coders/yaml_column.rb +1 -2
- data/lib/active_record/connection_adapters.rb +50 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +202 -138
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +2 -44
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +86 -37
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +4 -9
- 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 +152 -116
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +137 -52
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +3 -3
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +263 -107
- data/lib/active_record/connection_adapters/abstract/transaction.rb +82 -35
- data/lib/active_record/connection_adapters/abstract_adapter.rb +74 -76
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +149 -115
- data/lib/active_record/connection_adapters/column.rb +15 -1
- data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
- data/lib/active_record/connection_adapters/legacy_pool_manager.rb +31 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +30 -36
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -2
- data/lib/active_record/connection_adapters/mysql/quoting.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +32 -7
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +8 -0
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +17 -13
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +10 -1
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +31 -13
- data/lib/active_record/connection_adapters/pool_config.rb +63 -0
- data/lib/active_record/connection_adapters/pool_manager.rb +43 -0
- data/lib/active_record/connection_adapters/postgresql/column.rb +24 -1
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +21 -56
- data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -5
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +10 -2
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -3
- data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
- data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -3
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +24 -6
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +11 -2
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +4 -4
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +7 -3
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +72 -54
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +8 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +81 -57
- data/lib/active_record/connection_adapters/schema_cache.rb +98 -15
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +10 -0
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +38 -12
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +1 -2
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -1
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +38 -5
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +61 -57
- data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
- data/lib/active_record/connection_handling.rb +211 -81
- data/lib/active_record/core.rb +237 -69
- data/lib/active_record/counter_cache.rb +4 -1
- data/lib/active_record/database_configurations.rb +124 -85
- data/lib/active_record/database_configurations/connection_url_resolver.rb +98 -0
- data/lib/active_record/database_configurations/database_config.rb +52 -9
- data/lib/active_record/database_configurations/hash_config.rb +54 -8
- data/lib/active_record/database_configurations/url_config.rb +15 -41
- data/lib/active_record/delegated_type.rb +209 -0
- data/lib/active_record/destroy_association_async_job.rb +36 -0
- data/lib/active_record/dynamic_matchers.rb +2 -3
- data/lib/active_record/enum.rb +40 -16
- data/lib/active_record/errors.rb +47 -12
- data/lib/active_record/explain.rb +9 -5
- 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 -3
- data/lib/active_record/fixture_set/table_rows.rb +0 -1
- data/lib/active_record/fixtures.rb +54 -11
- data/lib/active_record/gem_version.rb +1 -1
- data/lib/active_record/inheritance.rb +40 -21
- data/lib/active_record/insert_all.rb +39 -10
- data/lib/active_record/integration.rb +3 -5
- data/lib/active_record/internal_metadata.rb +16 -7
- data/lib/active_record/legacy_yaml_adapter.rb +7 -3
- data/lib/active_record/locking/optimistic.rb +22 -17
- data/lib/active_record/locking/pessimistic.rb +6 -2
- data/lib/active_record/log_subscriber.rb +27 -9
- data/lib/active_record/middleware/database_selector.rb +4 -2
- data/lib/active_record/middleware/database_selector/resolver.rb +14 -14
- data/lib/active_record/middleware/database_selector/resolver/session.rb +3 -0
- data/lib/active_record/migration.rb +114 -84
- data/lib/active_record/migration/command_recorder.rb +53 -45
- data/lib/active_record/migration/compatibility.rb +70 -20
- data/lib/active_record/migration/join_table.rb +0 -1
- data/lib/active_record/model_schema.rb +120 -15
- data/lib/active_record/nested_attributes.rb +2 -5
- data/lib/active_record/no_touching.rb +1 -1
- data/lib/active_record/null_relation.rb +0 -1
- data/lib/active_record/persistence.rb +50 -46
- data/lib/active_record/query_cache.rb +15 -5
- data/lib/active_record/querying.rb +12 -7
- data/lib/active_record/railtie.rb +65 -45
- data/lib/active_record/railties/databases.rake +267 -93
- data/lib/active_record/readonly_attributes.rb +4 -0
- data/lib/active_record/reflection.rb +77 -63
- data/lib/active_record/relation.rb +108 -67
- data/lib/active_record/relation/batches.rb +38 -32
- data/lib/active_record/relation/batches/batch_enumerator.rb +25 -9
- data/lib/active_record/relation/calculations.rb +102 -45
- data/lib/active_record/relation/delegation.rb +9 -7
- data/lib/active_record/relation/finder_methods.rb +55 -17
- data/lib/active_record/relation/from_clause.rb +5 -1
- data/lib/active_record/relation/merger.rb +27 -26
- data/lib/active_record/relation/predicate_builder.rb +55 -35
- 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 +3 -3
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
- data/lib/active_record/relation/query_methods.rb +340 -180
- data/lib/active_record/relation/record_fetch_warning.rb +3 -3
- data/lib/active_record/relation/spawn_methods.rb +8 -8
- data/lib/active_record/relation/where_clause.rb +104 -58
- data/lib/active_record/result.rb +41 -34
- 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.rb +0 -1
- data/lib/active_record/scoping/default.rb +0 -1
- data/lib/active_record/scoping/named.rb +7 -18
- 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 +3 -3
- data/lib/active_record/suppressor.rb +2 -2
- data/lib/active_record/table_metadata.rb +39 -36
- data/lib/active_record/tasks/database_tasks.rb +139 -113
- data/lib/active_record/tasks/mysql_database_tasks.rb +34 -36
- data/lib/active_record/tasks/postgresql_database_tasks.rb +24 -27
- data/lib/active_record/tasks/sqlite_database_tasks.rb +13 -10
- data/lib/active_record/test_databases.rb +5 -4
- data/lib/active_record/test_fixtures.rb +38 -16
- data/lib/active_record/timestamp.rb +4 -7
- data/lib/active_record/touch_later.rb +20 -21
- data/lib/active_record/transactions.rb +22 -71
- data/lib/active_record/type.rb +8 -2
- data/lib/active_record/type/adapter_specific_registry.rb +2 -5
- data/lib/active_record/type/hash_lookup_type_map.rb +0 -1
- data/lib/active_record/type/serialized.rb +6 -3
- data/lib/active_record/type/time.rb +10 -0
- data/lib/active_record/type/type_map.rb +0 -1
- data/lib/active_record/type/unsigned_integer.rb +0 -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.rb +3 -3
- data/lib/active_record/validations/associated.rb +1 -2
- data/lib/active_record/validations/numericality.rb +35 -0
- data/lib/active_record/validations/uniqueness.rb +24 -4
- data/lib/arel.rb +15 -12
- data/lib/arel/attributes/attribute.rb +4 -0
- data/lib/arel/collectors/bind.rb +5 -0
- data/lib/arel/collectors/composite.rb +8 -0
- data/lib/arel/collectors/sql_string.rb +7 -0
- data/lib/arel/collectors/substitute_binds.rb +7 -0
- data/lib/arel/nodes.rb +3 -1
- data/lib/arel/nodes/binary.rb +82 -8
- data/lib/arel/nodes/bind_param.rb +8 -0
- data/lib/arel/nodes/casted.rb +21 -9
- data/lib/arel/nodes/equality.rb +6 -9
- data/lib/arel/nodes/grouping.rb +3 -0
- data/lib/arel/nodes/homogeneous_in.rb +72 -0
- data/lib/arel/nodes/in.rb +8 -1
- data/lib/arel/nodes/infix_operation.rb +13 -1
- data/lib/arel/nodes/join_source.rb +1 -1
- data/lib/arel/nodes/node.rb +7 -6
- data/lib/arel/nodes/ordering.rb +27 -0
- data/lib/arel/nodes/sql_literal.rb +3 -0
- data/lib/arel/nodes/table_alias.rb +7 -3
- data/lib/arel/nodes/unary.rb +0 -1
- data/lib/arel/predications.rb +17 -24
- data/lib/arel/select_manager.rb +1 -2
- data/lib/arel/table.rb +13 -5
- data/lib/arel/visitors.rb +0 -7
- data/lib/arel/visitors/dot.rb +14 -3
- data/lib/arel/visitors/mysql.rb +11 -1
- data/lib/arel/visitors/postgresql.rb +15 -5
- data/lib/arel/visitors/sqlite.rb +0 -1
- data/lib/arel/visitors/to_sql.rb +89 -79
- data/lib/arel/visitors/visitor.rb +0 -1
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
- data/lib/rails/generators/active_record/migration.rb +6 -2
- 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 +4 -4
- data/lib/rails/generators/active_record/model/model_generator.rb +38 -2
- data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
- metadata +27 -24
- data/lib/active_record/attribute_decorators.rb +0 -90
- data/lib/active_record/connection_adapters/connection_specification.rb +0 -297
- 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 -204
- data/lib/arel/visitors/ibm_db.rb +0 -34
- data/lib/arel/visitors/informix.rb +0 -62
- data/lib/arel/visitors/mssql.rb +0 -157
- data/lib/arel/visitors/oracle.rb +0 -159
- data/lib/arel/visitors/oracle12.rb +0 -66
- data/lib/arel/visitors/where_sql.rb +0 -23
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "active_support/deprecation"
|
4
|
-
|
5
3
|
module ActiveRecord
|
6
4
|
module ConnectionAdapters # :nodoc:
|
7
5
|
module DatabaseLimits
|
@@ -14,18 +12,6 @@ module ActiveRecord
|
|
14
12
|
max_identifier_length
|
15
13
|
end
|
16
14
|
|
17
|
-
# Returns the maximum length of a column name.
|
18
|
-
def column_name_length
|
19
|
-
max_identifier_length
|
20
|
-
end
|
21
|
-
deprecate :column_name_length
|
22
|
-
|
23
|
-
# Returns the maximum length of a table name.
|
24
|
-
def table_name_length
|
25
|
-
max_identifier_length
|
26
|
-
end
|
27
|
-
deprecate :table_name_length
|
28
|
-
|
29
15
|
# Returns the maximum allowed length for an index name. This
|
30
16
|
# limit is enforced by \Rails and is less than or equal to
|
31
17
|
# #index_name_length. The gap between
|
@@ -34,47 +20,19 @@ module ActiveRecord
|
|
34
20
|
def allowed_index_name_length
|
35
21
|
index_name_length
|
36
22
|
end
|
23
|
+
deprecate :allowed_index_name_length
|
37
24
|
|
38
25
|
# Returns the maximum length of an index name.
|
39
26
|
def index_name_length
|
40
27
|
max_identifier_length
|
41
28
|
end
|
42
29
|
|
43
|
-
# Returns the maximum number of columns per table.
|
44
|
-
def columns_per_table
|
45
|
-
1024
|
46
|
-
end
|
47
|
-
deprecate :columns_per_table
|
48
|
-
|
49
|
-
# Returns the maximum number of indexes per table.
|
50
|
-
def indexes_per_table
|
51
|
-
16
|
52
|
-
end
|
53
|
-
deprecate :indexes_per_table
|
54
|
-
|
55
|
-
# Returns the maximum number of columns in a multicolumn index.
|
56
|
-
def columns_per_multicolumn_index
|
57
|
-
16
|
58
|
-
end
|
59
|
-
deprecate :columns_per_multicolumn_index
|
60
|
-
|
61
30
|
# Returns the maximum number of elements in an IN (x,y,z) clause.
|
62
31
|
# +nil+ means no limit.
|
63
32
|
def in_clause_length
|
64
33
|
nil
|
65
34
|
end
|
66
|
-
|
67
|
-
# Returns the maximum length of an SQL query.
|
68
|
-
def sql_query_length
|
69
|
-
1048575
|
70
|
-
end
|
71
|
-
deprecate :sql_query_length
|
72
|
-
|
73
|
-
# Returns maximum number of joins in a single query.
|
74
|
-
def joins_per_query
|
75
|
-
256
|
76
|
-
end
|
77
|
-
deprecate :joins_per_query
|
35
|
+
deprecate :in_clause_length
|
78
36
|
|
79
37
|
private
|
80
38
|
def bind_params_length
|
@@ -14,29 +14,32 @@ module ActiveRecord
|
|
14
14
|
sql
|
15
15
|
end
|
16
16
|
|
17
|
-
def to_sql_and_binds(arel_or_sql_string, binds = []) # :nodoc:
|
17
|
+
def to_sql_and_binds(arel_or_sql_string, binds = [], preparable = nil) # :nodoc:
|
18
18
|
if arel_or_sql_string.respond_to?(:ast)
|
19
19
|
unless binds.empty?
|
20
20
|
raise "Passing bind parameters with an arel AST is forbidden. " \
|
21
21
|
"The values must be stored on the AST directly"
|
22
22
|
end
|
23
23
|
|
24
|
+
collector = collector()
|
25
|
+
|
24
26
|
if prepared_statements
|
27
|
+
collector.preparable = true
|
25
28
|
sql, binds = visitor.compile(arel_or_sql_string.ast, collector)
|
26
29
|
|
27
30
|
if binds.length > bind_params_length
|
28
31
|
unprepared_statement do
|
29
|
-
|
30
|
-
visitor.preparable = false
|
32
|
+
return to_sql_and_binds(arel_or_sql_string)
|
31
33
|
end
|
32
34
|
end
|
35
|
+
preparable = collector.preparable
|
33
36
|
else
|
34
37
|
sql = visitor.compile(arel_or_sql_string.ast, collector)
|
35
38
|
end
|
36
|
-
[sql.freeze, binds]
|
39
|
+
[sql.freeze, binds, preparable]
|
37
40
|
else
|
38
|
-
|
39
|
-
[arel_or_sql_string
|
41
|
+
arel_or_sql_string = arel_or_sql_string.dup.freeze unless arel_or_sql_string.frozen?
|
42
|
+
[arel_or_sql_string, binds, preparable]
|
40
43
|
end
|
41
44
|
end
|
42
45
|
private :to_sql_and_binds
|
@@ -58,17 +61,15 @@ module ActiveRecord
|
|
58
61
|
# Returns an ActiveRecord::Result instance.
|
59
62
|
def select_all(arel, name = nil, binds = [], preparable: nil)
|
60
63
|
arel = arel_from_relation(arel)
|
61
|
-
sql, binds = to_sql_and_binds(arel, binds)
|
62
|
-
|
63
|
-
if preparable.nil?
|
64
|
-
preparable = prepared_statements ? visitor.preparable : false
|
65
|
-
end
|
64
|
+
sql, binds, preparable = to_sql_and_binds(arel, binds, preparable)
|
66
65
|
|
67
66
|
if prepared_statements && preparable
|
68
67
|
select_prepared(sql, name, binds)
|
69
68
|
else
|
70
69
|
select(sql, name, binds)
|
71
70
|
end
|
71
|
+
rescue ::RangeError
|
72
|
+
ActiveRecord::Result.new([], [])
|
72
73
|
end
|
73
74
|
|
74
75
|
# Returns a record hash with the column names as keys and column values
|
@@ -149,6 +150,14 @@ module ActiveRecord
|
|
149
150
|
exec_query(sql, name, binds)
|
150
151
|
end
|
151
152
|
|
153
|
+
def exec_insert_all(sql, name) # :nodoc:
|
154
|
+
exec_query(sql, name)
|
155
|
+
end
|
156
|
+
|
157
|
+
def explain(arel, binds = []) # :nodoc:
|
158
|
+
raise NotImplementedError
|
159
|
+
end
|
160
|
+
|
152
161
|
# Executes an INSERT query and returns the new record's ID
|
153
162
|
#
|
154
163
|
# +id_value+ will be returned unless the value is +nil+, in
|
@@ -178,17 +187,18 @@ module ActiveRecord
|
|
178
187
|
|
179
188
|
# Executes the truncate statement.
|
180
189
|
def truncate(table_name, name = nil)
|
181
|
-
execute(
|
190
|
+
execute(build_truncate_statement(table_name), name)
|
182
191
|
end
|
183
192
|
|
184
193
|
def truncate_tables(*table_names) # :nodoc:
|
194
|
+
table_names -= [schema_migration.table_name, InternalMetadata.table_name]
|
195
|
+
|
185
196
|
return if table_names.empty?
|
186
197
|
|
187
198
|
with_multi_statements do
|
188
199
|
disable_referential_integrity do
|
189
|
-
|
190
|
-
|
191
|
-
end
|
200
|
+
statements = build_truncate_statements(table_names)
|
201
|
+
execute_batch(statements, "Truncate Tables")
|
192
202
|
end
|
193
203
|
end
|
194
204
|
end
|
@@ -198,15 +208,30 @@ module ActiveRecord
|
|
198
208
|
#
|
199
209
|
# == Nested transactions support
|
200
210
|
#
|
211
|
+
# #transaction calls can be nested. By default, this makes all database
|
212
|
+
# statements in the nested transaction block become part of the parent
|
213
|
+
# transaction. For example, the following behavior may be surprising:
|
214
|
+
#
|
215
|
+
# ActiveRecord::Base.transaction do
|
216
|
+
# Post.create(title: 'first')
|
217
|
+
# ActiveRecord::Base.transaction do
|
218
|
+
# Post.create(title: 'second')
|
219
|
+
# raise ActiveRecord::Rollback
|
220
|
+
# end
|
221
|
+
# end
|
222
|
+
#
|
223
|
+
# This creates both "first" and "second" posts. Reason is the
|
224
|
+
# ActiveRecord::Rollback exception in the nested block does not issue a
|
225
|
+
# ROLLBACK. Since these exceptions are captured in transaction blocks,
|
226
|
+
# the parent block does not see it and the real transaction is committed.
|
227
|
+
#
|
201
228
|
# Most databases don't support true nested transactions. At the time of
|
202
229
|
# writing, the only database that supports true nested transactions that
|
203
230
|
# we're aware of, is MS-SQL.
|
204
231
|
#
|
205
232
|
# In order to get around this problem, #transaction will emulate the effect
|
206
233
|
# of nested transactions, by using savepoints:
|
207
|
-
# https://dev.mysql.com/doc/refman/
|
208
|
-
# Savepoints are supported by MySQL and PostgreSQL. SQLite3 version >= '3.6.8'
|
209
|
-
# supports savepoints.
|
234
|
+
# https://dev.mysql.com/doc/refman/en/savepoint.html.
|
210
235
|
#
|
211
236
|
# It is safe to call this method if a database transaction is already open,
|
212
237
|
# i.e. if #transaction is called within another #transaction block. In case
|
@@ -218,6 +243,24 @@ module ActiveRecord
|
|
218
243
|
# - However, if +:requires_new+ is set, the block will be wrapped in a
|
219
244
|
# database savepoint acting as a sub-transaction.
|
220
245
|
#
|
246
|
+
# In order to get a ROLLBACK for the nested transaction you may ask for a
|
247
|
+
# real sub-transaction by passing <tt>requires_new: true</tt>.
|
248
|
+
# If anything goes wrong, the database rolls back to the beginning of
|
249
|
+
# the sub-transaction without rolling back the parent transaction.
|
250
|
+
# If we add it to the previous example:
|
251
|
+
#
|
252
|
+
# ActiveRecord::Base.transaction do
|
253
|
+
# Post.create(title: 'first')
|
254
|
+
# ActiveRecord::Base.transaction(requires_new: true) do
|
255
|
+
# Post.create(title: 'second')
|
256
|
+
# raise ActiveRecord::Rollback
|
257
|
+
# end
|
258
|
+
# end
|
259
|
+
#
|
260
|
+
# only post with title "first" is created.
|
261
|
+
#
|
262
|
+
# See ActiveRecord::Transactions to learn more.
|
263
|
+
#
|
221
264
|
# === Caveats
|
222
265
|
#
|
223
266
|
# MySQL doesn't support DDL transactions. If you perform a DDL operation,
|
@@ -257,7 +300,7 @@ module ActiveRecord
|
|
257
300
|
# semantics of these different levels:
|
258
301
|
#
|
259
302
|
# * https://www.postgresql.org/docs/current/static/transaction-iso.html
|
260
|
-
# * https://dev.mysql.com/doc/refman/
|
303
|
+
# * https://dev.mysql.com/doc/refman/en/set-transaction.html
|
261
304
|
#
|
262
305
|
# An ActiveRecord::TransactionIsolationError will be raised if:
|
263
306
|
#
|
@@ -286,6 +329,13 @@ module ActiveRecord
|
|
286
329
|
:commit_transaction, :rollback_transaction, :materialize_transactions,
|
287
330
|
:disable_lazy_transactions!, :enable_lazy_transactions!, to: :transaction_manager
|
288
331
|
|
332
|
+
def mark_transaction_written_if_write(sql) # :nodoc:
|
333
|
+
transaction = current_transaction
|
334
|
+
if transaction.open?
|
335
|
+
transaction.written ||= write_query?(sql)
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
289
339
|
def transaction_open?
|
290
340
|
current_transaction.open?
|
291
341
|
end
|
@@ -296,12 +346,8 @@ module ActiveRecord
|
|
296
346
|
|
297
347
|
# Register a record with the current transaction so that its after_commit and after_rollback callbacks
|
298
348
|
# can be called.
|
299
|
-
def add_transaction_record(record)
|
300
|
-
current_transaction.add_record(record)
|
301
|
-
end
|
302
|
-
|
303
|
-
def transaction_state
|
304
|
-
current_transaction.state
|
349
|
+
def add_transaction_record(record, ensure_finalize = true)
|
350
|
+
current_transaction.add_record(record, ensure_finalize)
|
305
351
|
end
|
306
352
|
|
307
353
|
# Begins the transaction (and turns off auto-committing).
|
@@ -348,7 +394,7 @@ module ActiveRecord
|
|
348
394
|
end
|
349
395
|
|
350
396
|
# Inserts the given fixture into the table. Overridden in adapters that require
|
351
|
-
# something beyond a simple insert (
|
397
|
+
# something beyond a simple insert (e.g. Oracle).
|
352
398
|
# Most of adapters should implement `insert_fixtures_set` that leverages bulk SQL insert.
|
353
399
|
# We keep this method to provide fallback
|
354
400
|
# for databases like sqlite that do not support bulk inserts.
|
@@ -359,14 +405,12 @@ module ActiveRecord
|
|
359
405
|
def insert_fixtures_set(fixture_set, tables_to_delete = [])
|
360
406
|
fixture_inserts = build_fixture_statements(fixture_set)
|
361
407
|
table_deletes = tables_to_delete.map { |table| "DELETE FROM #{quote_table_name(table)}" }
|
362
|
-
|
408
|
+
statements = table_deletes + fixture_inserts
|
363
409
|
|
364
410
|
with_multi_statements do
|
365
411
|
disable_referential_integrity do
|
366
412
|
transaction(requires_new: true) do
|
367
|
-
|
368
|
-
execute_batch(sql, "Fixtures Load")
|
369
|
-
end
|
413
|
+
execute_batch(statements, "Fixtures Load")
|
370
414
|
end
|
371
415
|
end
|
372
416
|
end
|
@@ -402,8 +446,10 @@ module ActiveRecord
|
|
402
446
|
end
|
403
447
|
|
404
448
|
private
|
405
|
-
def execute_batch(
|
406
|
-
|
449
|
+
def execute_batch(statements, name = nil)
|
450
|
+
statements.each do |statement|
|
451
|
+
execute(statement, name)
|
452
|
+
end
|
407
453
|
end
|
408
454
|
|
409
455
|
DEFAULT_INSERT_VALUE = Arel.sql("DEFAULT").freeze
|
@@ -453,7 +499,7 @@ module ActiveRecord
|
|
453
499
|
end
|
454
500
|
|
455
501
|
manager.values = manager.create_values_list(values_list)
|
456
|
-
manager.
|
502
|
+
visitor.compile(manager.ast)
|
457
503
|
end
|
458
504
|
|
459
505
|
def build_fixture_statements(fixture_set)
|
@@ -463,11 +509,14 @@ module ActiveRecord
|
|
463
509
|
end.compact
|
464
510
|
end
|
465
511
|
|
466
|
-
def
|
467
|
-
|
468
|
-
|
512
|
+
def build_truncate_statement(table_name)
|
513
|
+
"TRUNCATE TABLE #{quote_table_name(table_name)}"
|
514
|
+
end
|
515
|
+
|
516
|
+
def build_truncate_statements(table_names)
|
517
|
+
table_names.map do |table_name|
|
518
|
+
build_truncate_statement(table_name)
|
469
519
|
end
|
470
|
-
combine_multi_statements(truncate_tables)
|
471
520
|
end
|
472
521
|
|
473
522
|
def with_multi_statements
|
@@ -8,7 +8,7 @@ module ActiveRecord
|
|
8
8
|
class << self
|
9
9
|
def included(base) #:nodoc:
|
10
10
|
dirties_query_cache base, :insert, :update, :delete, :truncate, :truncate_tables,
|
11
|
-
:rollback_to_savepoint, :rollback_db_transaction
|
11
|
+
:rollback_to_savepoint, :rollback_db_transaction, :exec_insert_all
|
12
12
|
|
13
13
|
base.set_callback :checkout, :after, :configure_query_cache!
|
14
14
|
base.set_callback :checkin, :after, :disable_query_cache!
|
@@ -18,7 +18,7 @@ module ActiveRecord
|
|
18
18
|
method_names.each do |method_name|
|
19
19
|
base.class_eval <<-end_code, __FILE__, __LINE__ + 1
|
20
20
|
def #{method_name}(*)
|
21
|
-
ActiveRecord::Base.clear_query_caches_for_current_thread
|
21
|
+
ActiveRecord::Base.clear_query_caches_for_current_thread
|
22
22
|
super
|
23
23
|
end
|
24
24
|
end_code
|
@@ -96,11 +96,7 @@ module ActiveRecord
|
|
96
96
|
def select_all(arel, name = nil, binds = [], preparable: nil)
|
97
97
|
if @query_cache_enabled && !locked?(arel)
|
98
98
|
arel = arel_from_relation(arel)
|
99
|
-
sql, binds = to_sql_and_binds(arel, binds)
|
100
|
-
|
101
|
-
if preparable.nil?
|
102
|
-
preparable = prepared_statements ? visitor.preparable : false
|
103
|
-
end
|
99
|
+
sql, binds, preparable = to_sql_and_binds(arel, binds, preparable)
|
104
100
|
|
105
101
|
cache_sql(sql, name, binds) { super(sql, name, binds, preparable: preparable) }
|
106
102
|
else
|
@@ -109,7 +105,6 @@ module ActiveRecord
|
|
109
105
|
end
|
110
106
|
|
111
107
|
private
|
112
|
-
|
113
108
|
def cache_sql(sql, name, binds)
|
114
109
|
@lock.synchronize do
|
115
110
|
result =
|
@@ -134,7 +129,7 @@ module ActiveRecord
|
|
134
129
|
binds: binds,
|
135
130
|
type_casted_binds: -> { type_casted_binds(binds) },
|
136
131
|
name: name,
|
137
|
-
|
132
|
+
connection: self,
|
138
133
|
cached: true
|
139
134
|
}
|
140
135
|
end
|
@@ -9,10 +9,12 @@ module ActiveRecord
|
|
9
9
|
# Quotes the column value to help prevent
|
10
10
|
# {SQL injection attacks}[https://en.wikipedia.org/wiki/SQL_injection].
|
11
11
|
def quote(value)
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
if value.is_a?(Base)
|
13
|
+
ActiveSupport::Deprecation.warn(<<~MSG)
|
14
|
+
Passing an Active Record object to `quote` directly is deprecated
|
15
|
+
and will be no longer quoted as id value in Rails 6.2.
|
16
|
+
MSG
|
17
|
+
value = value.id_for_database
|
16
18
|
end
|
17
19
|
|
18
20
|
_quote(value)
|
@@ -22,16 +24,23 @@ module ActiveRecord
|
|
22
24
|
# SQLite does not understand dates, so this method will convert a Date
|
23
25
|
# to a String.
|
24
26
|
def type_cast(value, column = nil)
|
25
|
-
|
27
|
+
if value.is_a?(Base)
|
28
|
+
ActiveSupport::Deprecation.warn(<<~MSG)
|
29
|
+
Passing an Active Record object to `type_cast` directly is deprecated
|
30
|
+
and will be no longer type casted as id value in Rails 6.2.
|
31
|
+
MSG
|
32
|
+
value = value.id_for_database
|
33
|
+
end
|
26
34
|
|
27
35
|
if column
|
28
|
-
|
36
|
+
ActiveSupport::Deprecation.warn(<<~MSG)
|
37
|
+
Passing a column to `type_cast` is deprecated and will be removed in Rails 6.2.
|
38
|
+
MSG
|
39
|
+
type = lookup_cast_type_from_column(column)
|
40
|
+
value = type.serialize(value)
|
29
41
|
end
|
30
42
|
|
31
43
|
_type_cast(value)
|
32
|
-
rescue TypeError
|
33
|
-
to_type = column ? " to #{column.type}" : ""
|
34
|
-
raise TypeError, "can't cast #{value.class}#{to_type}"
|
35
44
|
end
|
36
45
|
|
37
46
|
# If you are having to call this function, you are likely doing something
|
@@ -43,16 +52,6 @@ module ActiveRecord
|
|
43
52
|
# represent the type doesn't sufficiently reflect the differences
|
44
53
|
# (varchar vs binary) for example. The type used to get this primitive
|
45
54
|
# should have been provided before reaching the connection adapter.
|
46
|
-
def type_cast_from_column(column, value) # :nodoc:
|
47
|
-
if column
|
48
|
-
type = lookup_cast_type_from_column(column)
|
49
|
-
type.serialize(value)
|
50
|
-
else
|
51
|
-
value
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
# See docs for #type_cast_from_column
|
56
55
|
def lookup_cast_type_from_column(column) # :nodoc:
|
57
56
|
lookup_cast_type(column.sql_type)
|
58
57
|
end
|
@@ -114,16 +113,16 @@ module ActiveRecord
|
|
114
113
|
# if the value is a Time responding to usec.
|
115
114
|
def quoted_date(value)
|
116
115
|
if value.acts_like?(:time)
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
value = value.
|
116
|
+
if ActiveRecord::Base.default_timezone == :utc
|
117
|
+
value = value.getutc if value.respond_to?(:getutc) && !value.utc?
|
118
|
+
else
|
119
|
+
value = value.getlocal if value.respond_to?(:getlocal)
|
121
120
|
end
|
122
121
|
end
|
123
122
|
|
124
123
|
result = value.to_s(:db)
|
125
124
|
if value.respond_to?(:usec) && value.usec > 0
|
126
|
-
"
|
125
|
+
result << "." << sprintf("%06d", value.usec)
|
127
126
|
else
|
128
127
|
result
|
129
128
|
end
|
@@ -162,7 +161,7 @@ module ActiveRecord
|
|
162
161
|
# table_name.column_name | function(one or no argument)
|
163
162
|
((?:\w+\.)?\w+) | \w+\((?:|\g<2>)\)
|
164
163
|
)
|
165
|
-
(?:\s+AS
|
164
|
+
(?:(?:\s+AS)?\s+\w+)?
|
166
165
|
)
|
167
166
|
(?:\s*,\s*\g<1>)*
|
168
167
|
\z
|
@@ -197,10 +196,17 @@ module ActiveRecord
|
|
197
196
|
|
198
197
|
private
|
199
198
|
def type_casted_binds(binds)
|
200
|
-
|
199
|
+
case binds.first
|
200
|
+
when Array
|
201
201
|
binds.map { |column, value| type_cast(value, column) }
|
202
202
|
else
|
203
|
-
binds.map
|
203
|
+
binds.map do |value|
|
204
|
+
if ActiveModel::Attribute === value
|
205
|
+
type_cast(value.value_for_database)
|
206
|
+
else
|
207
|
+
type_cast(value)
|
208
|
+
end
|
209
|
+
end
|
204
210
|
end
|
205
211
|
end
|
206
212
|
|
@@ -208,12 +214,6 @@ module ActiveRecord
|
|
208
214
|
type_map.lookup(sql_type)
|
209
215
|
end
|
210
216
|
|
211
|
-
def id_value_for_database(value)
|
212
|
-
if primary_key = value.class.primary_key
|
213
|
-
value.instance_variable_get(:@attributes)[primary_key].value_for_database
|
214
|
-
end
|
215
|
-
end
|
216
|
-
|
217
217
|
def _quote(value)
|
218
218
|
case value
|
219
219
|
when String, Symbol, ActiveSupport::Multibyte::Chars
|
@@ -243,7 +243,7 @@ module ActiveRecord
|
|
243
243
|
when nil, Numeric, String then value
|
244
244
|
when Type::Time::Value then quoted_time(value)
|
245
245
|
when Date, Time then quoted_date(value)
|
246
|
-
else raise TypeError
|
246
|
+
else raise TypeError, "can't cast #{value.class.name}"
|
247
247
|
end
|
248
248
|
end
|
249
249
|
end
|