activerecord 5.1.7 → 5.2.8.1
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 +629 -661
- 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 +7 -5
- data/lib/active_record/associations/alias_tracker.rb +19 -27
- data/lib/active_record/associations/association.rb +41 -37
- data/lib/active_record/associations/association_scope.rb +38 -50
- data/lib/active_record/associations/belongs_to_association.rb +27 -8
- 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 +12 -4
- data/lib/active_record/associations/builder/collection_association.rb +3 -3
- 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 +59 -47
- data/lib/active_record/associations/collection_proxy.rb +20 -49
- data/lib/active_record/associations/foreign_association.rb +2 -0
- data/lib/active_record/associations/has_many_association.rb +12 -1
- data/lib/active_record/associations/has_many_through_association.rb +36 -30
- data/lib/active_record/associations/has_one_association.rb +12 -1
- data/lib/active_record/associations/has_one_through_association.rb +13 -8
- data/lib/active_record/associations/join_dependency/join_association.rb +39 -63
- 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/join_dependency.rb +48 -93
- 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 +18 -38
- data/lib/active_record/associations/singular_association.rb +14 -16
- data/lib/active_record/associations/through_association.rb +26 -11
- data/lib/active_record/associations.rb +40 -63
- 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 +30 -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 +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 +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 +35 -19
- data/lib/active_record/base.rb +2 -0
- data/lib/active_record/callbacks.rb +8 -6
- data/lib/active_record/coders/json.rb +2 -0
- data/lib/active_record/coders/yaml_column.rb +15 -1
- data/lib/active_record/collection_cache_key.rb +12 -8
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +139 -41
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +7 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +174 -33
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +15 -5
- data/lib/active_record/connection_adapters/abstract/quoting.rb +13 -31
- 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 +64 -6
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +31 -53
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +152 -81
- data/lib/active_record/connection_adapters/abstract/transaction.rb +66 -21
- data/lib/active_record/connection_adapters/abstract_adapter.rb +84 -97
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +92 -165
- 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 +13 -2
- data/lib/active_record/connection_adapters/mysql/column.rb +2 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +47 -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 +2 -0
- 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 +5 -3
- 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 -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/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 +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 +233 -111
- 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 +57 -73
- 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 +22 -0
- 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 +81 -94
- 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 +51 -61
- data/lib/active_record/counter_cache.rb +10 -3
- 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 +42 -3
- 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 +5 -3
- 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 +47 -9
- 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 +167 -16
- data/lib/active_record/query_cache.rb +6 -8
- data/lib/active_record/querying.rb +4 -2
- data/lib/active_record/railtie.rb +80 -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 +46 -36
- data/lib/active_record/readonly_attributes.rb +3 -2
- data/lib/active_record/reflection.rb +108 -194
- 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 +45 -19
- data/lib/active_record/relation/delegation.rb +45 -27
- data/lib/active_record/relation/finder_methods.rb +75 -76
- 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/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 +60 -79
- data/lib/active_record/relation/query_attribute.rb +28 -2
- data/lib/active_record/relation/query_methods.rb +128 -99
- 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 -68
- data/lib/active_record/relation/where_clause_factory.rb +5 -48
- data/lib/active_record/relation.rb +120 -214
- 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 +8 -9
- data/lib/active_record/scoping/named.rb +23 -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 +23 -13
- 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 +25 -14
- 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 +6 -6
- data/lib/active_record/touch_later.rb +2 -0
- data/lib/active_record/transactions.rb +33 -28
- 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 -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.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 +26 -39
- 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,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_record/connection_adapters/abstract_adapter"
|
2
4
|
require "active_record/connection_adapters/statement_pool"
|
3
5
|
require "active_record/connection_adapters/sqlite3/explain_pretty_printer"
|
@@ -55,11 +57,10 @@ module ActiveRecord
|
|
55
57
|
ADAPTER_NAME = "SQLite".freeze
|
56
58
|
|
57
59
|
include SQLite3::Quoting
|
58
|
-
include SQLite3::ColumnDumper
|
59
60
|
include SQLite3::SchemaStatements
|
60
61
|
|
61
62
|
NATIVE_DATABASE_TYPES = {
|
62
|
-
primary_key: "
|
63
|
+
primary_key: "integer PRIMARY KEY AUTOINCREMENT NOT NULL",
|
63
64
|
string: { name: "varchar" },
|
64
65
|
text: { name: "text" },
|
65
66
|
integer: { name: "integer" },
|
@@ -69,33 +70,38 @@ module ActiveRecord
|
|
69
70
|
time: { name: "time" },
|
70
71
|
date: { name: "date" },
|
71
72
|
binary: { name: "blob" },
|
72
|
-
boolean: { name: "boolean" }
|
73
|
+
boolean: { name: "boolean" },
|
74
|
+
json: { name: "json" },
|
73
75
|
}
|
74
76
|
|
75
|
-
|
76
|
-
|
77
|
+
##
|
78
|
+
# :singleton-method:
|
79
|
+
# Indicates whether boolean values are stored in sqlite3 databases as 1
|
80
|
+
# and 0 or 't' and 'f'. Leaving <tt>ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer</tt>
|
81
|
+
# set to false is deprecated. SQLite databases have used 't' and 'f' to
|
82
|
+
# serialize boolean values and must have old data converted to 1 and 0
|
83
|
+
# (its native boolean serialization) before setting this flag to true.
|
84
|
+
# Conversion can be accomplished by setting up a rake task which runs
|
85
|
+
#
|
86
|
+
# ExampleModel.where("boolean_column = 't'").update_all(boolean_column: 1)
|
87
|
+
# ExampleModel.where("boolean_column = 'f'").update_all(boolean_column: 0)
|
88
|
+
# for all models and all boolean columns, after which the flag must be set
|
89
|
+
# to true by adding the following to your <tt>application.rb</tt> file:
|
90
|
+
#
|
91
|
+
# Rails.application.config.active_record.sqlite3.represent_boolean_as_integer = true
|
92
|
+
class_attribute :represent_boolean_as_integer, default: false
|
77
93
|
|
94
|
+
class StatementPool < ConnectionAdapters::StatementPool # :nodoc:
|
95
|
+
private
|
78
96
|
def dealloc(stmt)
|
79
97
|
stmt[:stmt].close unless stmt[:stmt].closed?
|
80
98
|
end
|
81
99
|
end
|
82
100
|
|
83
|
-
def update_table_definition(table_name, base) # :nodoc:
|
84
|
-
SQLite3::Table.new(table_name, base)
|
85
|
-
end
|
86
|
-
|
87
|
-
def schema_creation # :nodoc:
|
88
|
-
SQLite3::SchemaCreation.new self
|
89
|
-
end
|
90
|
-
|
91
|
-
def arel_visitor # :nodoc:
|
92
|
-
Arel::Visitors::SQLite.new(self)
|
93
|
-
end
|
94
|
-
|
95
101
|
def initialize(connection, logger, connection_options, config)
|
96
102
|
super(connection, logger, config)
|
97
103
|
|
98
|
-
@active =
|
104
|
+
@active = true
|
99
105
|
@statements = StatementPool.new(self.class.type_cast_config_to_integer(config[:statement_limit]))
|
100
106
|
|
101
107
|
configure_connection
|
@@ -113,12 +119,6 @@ module ActiveRecord
|
|
113
119
|
sqlite_version >= "3.8.0"
|
114
120
|
end
|
115
121
|
|
116
|
-
# Returns true, since this connection adapter supports prepared statement
|
117
|
-
# caching.
|
118
|
-
def supports_statement_cache?
|
119
|
-
true
|
120
|
-
end
|
121
|
-
|
122
122
|
def requires_reloading?
|
123
123
|
true
|
124
124
|
end
|
@@ -135,12 +135,16 @@ module ActiveRecord
|
|
135
135
|
true
|
136
136
|
end
|
137
137
|
|
138
|
+
def supports_json?
|
139
|
+
true
|
140
|
+
end
|
141
|
+
|
138
142
|
def supports_multi_insert?
|
139
143
|
sqlite_version >= "3.7.11"
|
140
144
|
end
|
141
145
|
|
142
146
|
def active?
|
143
|
-
@active
|
147
|
+
@active
|
144
148
|
end
|
145
149
|
|
146
150
|
# Disconnects from the database if already connected. Otherwise, this
|
@@ -267,53 +271,6 @@ module ActiveRecord
|
|
267
271
|
|
268
272
|
# SCHEMA STATEMENTS ========================================
|
269
273
|
|
270
|
-
def new_column_from_field(table_name, field) # :nondoc:
|
271
|
-
case field["dflt_value"]
|
272
|
-
when /^null$/i
|
273
|
-
field["dflt_value"] = nil
|
274
|
-
when /^'(.*)'$/m
|
275
|
-
field["dflt_value"] = $1.gsub("''", "'")
|
276
|
-
when /^"(.*)"$/m
|
277
|
-
field["dflt_value"] = $1.gsub('""', '"')
|
278
|
-
end
|
279
|
-
|
280
|
-
collation = field["collation"]
|
281
|
-
sql_type = field["type"]
|
282
|
-
type_metadata = fetch_type_metadata(sql_type)
|
283
|
-
new_column(field["name"], field["dflt_value"], type_metadata, field["notnull"].to_i == 0, table_name, nil, collation)
|
284
|
-
end
|
285
|
-
|
286
|
-
# Returns an array of indexes for the given table.
|
287
|
-
def indexes(table_name, name = nil) #:nodoc:
|
288
|
-
if name
|
289
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
290
|
-
Passing name to #indexes is deprecated without replacement.
|
291
|
-
MSG
|
292
|
-
end
|
293
|
-
|
294
|
-
exec_query("PRAGMA index_list(#{quote_table_name(table_name)})", "SCHEMA").map do |row|
|
295
|
-
sql = <<-SQL
|
296
|
-
SELECT sql
|
297
|
-
FROM sqlite_master
|
298
|
-
WHERE name=#{quote(row['name'])} AND type='index'
|
299
|
-
UNION ALL
|
300
|
-
SELECT sql
|
301
|
-
FROM sqlite_temp_master
|
302
|
-
WHERE name=#{quote(row['name'])} AND type='index'
|
303
|
-
SQL
|
304
|
-
index_sql = exec_query(sql).first["sql"]
|
305
|
-
match = /\sWHERE\s+(.+)$/i.match(index_sql)
|
306
|
-
where = match[1] if match
|
307
|
-
IndexDefinition.new(
|
308
|
-
table_name,
|
309
|
-
row["name"],
|
310
|
-
row["unique"] != 0,
|
311
|
-
exec_query("PRAGMA index_info('#{row['name']}')", "SCHEMA").map { |col|
|
312
|
-
col["name"]
|
313
|
-
}, nil, nil, where)
|
314
|
-
end
|
315
|
-
end
|
316
|
-
|
317
274
|
def primary_keys(table_name) # :nodoc:
|
318
275
|
pks = table_structure(table_name).select { |f| f["pk"] > 0 }
|
319
276
|
pks.sort_by { |f| f["pk"] }.map { |f| f["name"] }
|
@@ -333,19 +290,18 @@ module ActiveRecord
|
|
333
290
|
rename_table_indexes(table_name, new_name)
|
334
291
|
end
|
335
292
|
|
336
|
-
|
337
|
-
|
338
|
-
def valid_alter_table_type?(type)
|
339
|
-
type.to_sym != :primary_key
|
293
|
+
def valid_alter_table_type?(type, options = {})
|
294
|
+
!invalid_alter_table_type?(type, options)
|
340
295
|
end
|
296
|
+
deprecate :valid_alter_table_type?
|
341
297
|
|
342
298
|
def add_column(table_name, column_name, type, options = {}) #:nodoc:
|
343
|
-
if
|
344
|
-
super(table_name, column_name, type, options)
|
345
|
-
else
|
299
|
+
if invalid_alter_table_type?(type, options)
|
346
300
|
alter_table(table_name) do |definition|
|
347
301
|
definition.column(column_name, type, options)
|
348
302
|
end
|
303
|
+
else
|
304
|
+
super
|
349
305
|
end
|
350
306
|
end
|
351
307
|
|
@@ -410,7 +366,31 @@ module ActiveRecord
|
|
410
366
|
end
|
411
367
|
end
|
412
368
|
|
369
|
+
def insert_fixtures(rows, table_name)
|
370
|
+
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
371
|
+
`insert_fixtures` is deprecated and will be removed in the next version of Rails.
|
372
|
+
Consider using `insert_fixtures_set` for performance improvement.
|
373
|
+
MSG
|
374
|
+
insert_fixtures_set(table_name => rows)
|
375
|
+
end
|
376
|
+
|
377
|
+
def insert_fixtures_set(fixture_set, tables_to_delete = [])
|
378
|
+
disable_referential_integrity do
|
379
|
+
transaction(requires_new: true) do
|
380
|
+
tables_to_delete.each { |table| delete "DELETE FROM #{quote_table_name(table)}", "Fixture Delete" }
|
381
|
+
|
382
|
+
fixture_set.each do |table_name, rows|
|
383
|
+
rows.each { |row| insert_fixture(row, table_name) }
|
384
|
+
end
|
385
|
+
end
|
386
|
+
end
|
387
|
+
end
|
388
|
+
|
413
389
|
private
|
390
|
+
def initialize_type_map(m = type_map)
|
391
|
+
super
|
392
|
+
register_class_with_limit m, %r(int)i, SQLite3Integer
|
393
|
+
end
|
414
394
|
|
415
395
|
def table_structure(table_name)
|
416
396
|
structure = exec_query("PRAGMA table_info(#{quote_table_name(table_name)})", "SCHEMA")
|
@@ -419,6 +399,12 @@ module ActiveRecord
|
|
419
399
|
end
|
420
400
|
alias column_definitions table_structure
|
421
401
|
|
402
|
+
# See: https://www.sqlite.org/lang_altertable.html
|
403
|
+
# SQLite has an additional restriction on the ALTER TABLE statement
|
404
|
+
def invalid_alter_table_type?(type, options)
|
405
|
+
type.to_sym == :primary_key || options[:primary_key]
|
406
|
+
end
|
407
|
+
|
422
408
|
def alter_table(table_name, options = {})
|
423
409
|
altered_table_name = "a#{table_name}"
|
424
410
|
caller = lambda { |definition| yield definition if block_given? }
|
@@ -467,9 +453,6 @@ module ActiveRecord
|
|
467
453
|
def copy_table_indexes(from, to, rename = {})
|
468
454
|
indexes(from).each do |index|
|
469
455
|
name = index.name
|
470
|
-
# indexes sqlite creates for internal use start with `sqlite_` and
|
471
|
-
# don't need to be copied
|
472
|
-
next if name.starts_with?("sqlite_")
|
473
456
|
if to == "a#{from}"
|
474
457
|
name = "t#{name}"
|
475
458
|
elsif from == "a#{to}"
|
@@ -542,9 +525,9 @@ module ActiveRecord
|
|
542
525
|
result = exec_query(sql, "SCHEMA").first
|
543
526
|
|
544
527
|
if result
|
545
|
-
# Splitting with left parentheses and
|
528
|
+
# Splitting with left parentheses and discarding the first part will return all
|
546
529
|
# columns separated with comma(,).
|
547
|
-
columns_string = result["sql"].split("(").last
|
530
|
+
columns_string = result["sql"].split("(", 2).last
|
548
531
|
|
549
532
|
columns_string.split(",").each do |column_string|
|
550
533
|
# This regex will match the column name and collation type and will save
|
@@ -566,21 +549,25 @@ module ActiveRecord
|
|
566
549
|
end
|
567
550
|
end
|
568
551
|
|
569
|
-
def
|
570
|
-
|
571
|
-
end
|
572
|
-
|
573
|
-
def extract_foreign_key_action(specifier)
|
574
|
-
case specifier
|
575
|
-
when "CASCADE"; :cascade
|
576
|
-
when "SET NULL"; :nullify
|
577
|
-
when "RESTRICT"; :restrict
|
578
|
-
end
|
552
|
+
def arel_visitor
|
553
|
+
Arel::Visitors::SQLite.new(self)
|
579
554
|
end
|
580
555
|
|
581
556
|
def configure_connection
|
582
557
|
execute("PRAGMA foreign_keys = ON", "SCHEMA")
|
583
558
|
end
|
559
|
+
|
560
|
+
class SQLite3Integer < Type::Integer # :nodoc:
|
561
|
+
private
|
562
|
+
def _limit
|
563
|
+
# INTEGER storage class can be stored 8 bytes value.
|
564
|
+
# See https://www.sqlite.org/datatype3.html#storage_classes_and_datatypes
|
565
|
+
limit || 8
|
566
|
+
end
|
567
|
+
end
|
568
|
+
|
569
|
+
ActiveRecord::Type.register(:integer, SQLite3Integer, adapter: :sqlite3)
|
584
570
|
end
|
571
|
+
ActiveSupport.run_load_hooks(:active_record_sqlite3adapter, SQLite3Adapter)
|
585
572
|
end
|
586
573
|
end
|
@@ -1,6 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module ConnectionHandling
|
3
|
-
RAILS_ENV = -> { (Rails.env if defined?(Rails.env)) || ENV["RAILS_ENV"] || ENV["RACK_ENV"] }
|
5
|
+
RAILS_ENV = -> { (Rails.env if defined?(Rails.env)) || ENV["RAILS_ENV"].presence || ENV["RACK_ENV"].presence }
|
4
6
|
DEFAULT_ENV = -> { RAILS_ENV.call || "default_env" }
|
5
7
|
|
6
8
|
# Establishes the connection to the database. Accepts a hash as input where
|
@@ -138,6 +140,6 @@ module ActiveRecord
|
|
138
140
|
end
|
139
141
|
|
140
142
|
delegate :clear_active_connections!, :clear_reloadable_connections!,
|
141
|
-
:clear_all_connections!, to: :connection_handler
|
143
|
+
:clear_all_connections!, :flush_idle_connections!, to: :connection_handler
|
142
144
|
end
|
143
145
|
end
|
data/lib/active_record/core.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require "active_support/core_ext/hash/indifferent_access"
|
3
|
-
require "active_support/core_ext/object/duplicable"
|
4
4
|
require "active_support/core_ext/string/filters"
|
5
|
+
require "concurrent/map"
|
5
6
|
|
6
7
|
module ActiveRecord
|
7
8
|
module Core
|
@@ -16,6 +17,13 @@ module ActiveRecord
|
|
16
17
|
# retrieved on both a class and instance level by calling +logger+.
|
17
18
|
mattr_accessor :logger, instance_writer: false
|
18
19
|
|
20
|
+
##
|
21
|
+
# :singleton-method:
|
22
|
+
#
|
23
|
+
# Specifies if the methods calling database queries should be logged below
|
24
|
+
# their relevant queries. Defaults to false.
|
25
|
+
mattr_accessor :verbose_query_logs, instance_writer: false, default: false
|
26
|
+
|
19
27
|
##
|
20
28
|
# Contains the database configuration - as is typically stored in config/database.yml -
|
21
29
|
# as a Hash.
|
@@ -56,8 +64,7 @@ module ActiveRecord
|
|
56
64
|
# :singleton-method:
|
57
65
|
# Determines whether to use Time.utc (using :utc) or Time.local (using :local) when pulling
|
58
66
|
# dates and times from the database. This is set to :utc by default.
|
59
|
-
mattr_accessor :default_timezone, instance_writer: false
|
60
|
-
self.default_timezone = :utc
|
67
|
+
mattr_accessor :default_timezone, instance_writer: false, default: :utc
|
61
68
|
|
62
69
|
##
|
63
70
|
# :singleton-method:
|
@@ -67,42 +74,27 @@ module ActiveRecord
|
|
67
74
|
# ActiveRecord::Schema file which can be loaded into any database that
|
68
75
|
# supports migrations. Use :ruby if you want to have different database
|
69
76
|
# adapters for, e.g., your development and test environments.
|
70
|
-
mattr_accessor :schema_format, instance_writer: false
|
71
|
-
self.schema_format = :ruby
|
77
|
+
mattr_accessor :schema_format, instance_writer: false, default: :ruby
|
72
78
|
|
73
79
|
##
|
74
80
|
# :singleton-method:
|
75
81
|
# Specifies if an error should be raised if the query has an order being
|
76
82
|
# ignored when doing batch queries. Useful in applications where the
|
77
83
|
# scope being ignored is error-worthy, rather than a warning.
|
78
|
-
mattr_accessor :error_on_ignored_order, instance_writer: false
|
79
|
-
self.error_on_ignored_order = false
|
80
|
-
|
81
|
-
def self.error_on_ignored_order_or_limit
|
82
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
83
|
-
The flag error_on_ignored_order_or_limit is deprecated. Limits are
|
84
|
-
now supported. Please use error_on_ignored_order instead.
|
85
|
-
MSG
|
86
|
-
error_on_ignored_order
|
87
|
-
end
|
88
|
-
|
89
|
-
def error_on_ignored_order_or_limit
|
90
|
-
self.class.error_on_ignored_order_or_limit
|
91
|
-
end
|
84
|
+
mattr_accessor :error_on_ignored_order, instance_writer: false, default: false
|
92
85
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
86
|
+
# :singleton-method:
|
87
|
+
# Specify the behavior for unsafe raw query methods. Values are as follows
|
88
|
+
# deprecated - Warnings are logged when unsafe raw SQL is passed to
|
89
|
+
# query methods.
|
90
|
+
# disabled - Unsafe raw SQL passed to query methods results in
|
91
|
+
# UnknownAttributeReference exception.
|
92
|
+
mattr_accessor :allow_unsafe_raw_sql, instance_writer: false, default: :deprecated
|
100
93
|
|
101
94
|
##
|
102
95
|
# :singleton-method:
|
103
96
|
# Specify whether or not to use timestamps for migration versions
|
104
|
-
mattr_accessor :timestamped_migrations, instance_writer: false
|
105
|
-
self.timestamped_migrations = true
|
97
|
+
mattr_accessor :timestamped_migrations, instance_writer: false, default: true
|
106
98
|
|
107
99
|
##
|
108
100
|
# :singleton-method:
|
@@ -110,8 +102,7 @@ module ActiveRecord
|
|
110
102
|
# db:migrate rake task. This is true by default, which is useful for the
|
111
103
|
# development environment. This should ideally be false in the production
|
112
104
|
# environment where dumping schema is rarely needed.
|
113
|
-
mattr_accessor :dump_schema_after_migration, instance_writer: false
|
114
|
-
self.dump_schema_after_migration = true
|
105
|
+
mattr_accessor :dump_schema_after_migration, instance_writer: false, default: true
|
115
106
|
|
116
107
|
##
|
117
108
|
# :singleton-method:
|
@@ -120,8 +111,7 @@ module ActiveRecord
|
|
120
111
|
# schema_search_path are dumped. Use :all to dump all schemas regardless
|
121
112
|
# of schema_search_path, or a string of comma separated schemas for a
|
122
113
|
# custom list.
|
123
|
-
mattr_accessor :dump_schemas, instance_writer: false
|
124
|
-
self.dump_schemas = :schema_search_path
|
114
|
+
mattr_accessor :dump_schemas, instance_writer: false, default: :schema_search_path
|
125
115
|
|
126
116
|
##
|
127
117
|
# :singleton-method:
|
@@ -130,12 +120,21 @@ module ActiveRecord
|
|
130
120
|
# be used to identify queries which load thousands of records and
|
131
121
|
# potentially cause memory bloat.
|
132
122
|
mattr_accessor :warn_on_records_fetched_greater_than, instance_writer: false
|
133
|
-
self.warn_on_records_fetched_greater_than = nil
|
134
123
|
|
135
124
|
mattr_accessor :maintain_test_schema, instance_accessor: false
|
136
125
|
|
137
126
|
mattr_accessor :belongs_to_required_by_default, instance_accessor: false
|
138
127
|
|
128
|
+
##
|
129
|
+
# :singleton-method:
|
130
|
+
# Application configurable boolean that instructs the YAML Coder to use
|
131
|
+
# an unsafe load if set to true.
|
132
|
+
mattr_accessor :use_yaml_unsafe_load, instance_writer: false, default: false
|
133
|
+
|
134
|
+
# Application configurable array that provides additional permitted classes
|
135
|
+
# to Psych safe_load in the YAML Coder
|
136
|
+
mattr_accessor :yaml_column_permitted_classes, instance_writer: false, default: []
|
137
|
+
|
139
138
|
class_attribute :default_connection_handler, instance_writer: false
|
140
139
|
|
141
140
|
def self.connection_handler
|
@@ -149,14 +148,14 @@ module ActiveRecord
|
|
149
148
|
self.default_connection_handler = ConnectionAdapters::ConnectionHandler.new
|
150
149
|
end
|
151
150
|
|
152
|
-
module ClassMethods
|
151
|
+
module ClassMethods # :nodoc:
|
153
152
|
def allocate
|
154
153
|
define_attribute_methods
|
155
154
|
super
|
156
155
|
end
|
157
156
|
|
158
157
|
def initialize_find_by_cache # :nodoc:
|
159
|
-
@find_by_statement_cache = { true =>
|
158
|
+
@find_by_statement_cache = { true => Concurrent::Map.new, false => Concurrent::Map.new }
|
160
159
|
end
|
161
160
|
|
162
161
|
def inherited(child_class) # :nodoc:
|
@@ -175,8 +174,7 @@ module ActiveRecord
|
|
175
174
|
|
176
175
|
id = ids.first
|
177
176
|
|
178
|
-
return super if
|
179
|
-
id.is_a?(ActiveRecord::Base)
|
177
|
+
return super if StatementCache.unsupported_value?(id)
|
180
178
|
|
181
179
|
key = primary_key
|
182
180
|
|
@@ -184,7 +182,7 @@ module ActiveRecord
|
|
184
182
|
where(key => params.bind).limit(1)
|
185
183
|
}
|
186
184
|
|
187
|
-
record = statement.execute([id],
|
185
|
+
record = statement.execute([id], connection).first
|
188
186
|
unless record
|
189
187
|
raise RecordNotFound.new("Couldn't find #{name} with '#{primary_key}'=#{id}",
|
190
188
|
name, primary_key, id)
|
@@ -196,12 +194,13 @@ module ActiveRecord
|
|
196
194
|
end
|
197
195
|
|
198
196
|
def find_by(*args) # :nodoc:
|
199
|
-
return super if scope_attributes? || reflect_on_all_aggregations.any?
|
197
|
+
return super if scope_attributes? || reflect_on_all_aggregations.any? ||
|
198
|
+
columns_hash.key?(inheritance_column) && base_class != self
|
200
199
|
|
201
200
|
hash = args.first
|
202
201
|
|
203
202
|
return super if !(Hash === hash) || hash.values.any? { |v|
|
204
|
-
|
203
|
+
StatementCache.unsupported_value?(v)
|
205
204
|
}
|
206
205
|
|
207
206
|
# We can't cache Post.find_by(author: david) ...yet
|
@@ -216,7 +215,7 @@ module ActiveRecord
|
|
216
215
|
where(wheres).limit(1)
|
217
216
|
}
|
218
217
|
begin
|
219
|
-
statement.execute(hash.values,
|
218
|
+
statement.execute(hash.values, connection).first
|
220
219
|
rescue TypeError
|
221
220
|
raise ActiveRecord::StatementInvalid
|
222
221
|
rescue ::RangeError
|
@@ -258,7 +257,7 @@ module ActiveRecord
|
|
258
257
|
end
|
259
258
|
end
|
260
259
|
|
261
|
-
# Overwrite the default class equality method to provide support for
|
260
|
+
# Overwrite the default class equality method to provide support for decorated models.
|
262
261
|
def ===(object)
|
263
262
|
object.is_a?(self)
|
264
263
|
end
|
@@ -272,16 +271,6 @@ module ActiveRecord
|
|
272
271
|
@arel_table ||= Arel::Table.new(table_name, type_caster: type_caster)
|
273
272
|
end
|
274
273
|
|
275
|
-
# Returns the Arel engine.
|
276
|
-
def arel_engine # :nodoc:
|
277
|
-
@arel_engine ||=
|
278
|
-
if Base == self || connection_handler.retrieve_connection_pool(connection_specification_name)
|
279
|
-
self
|
280
|
-
else
|
281
|
-
superclass.arel_engine
|
282
|
-
end
|
283
|
-
end
|
284
|
-
|
285
274
|
def arel_attribute(name, table = arel_table) # :nodoc:
|
286
275
|
name = attribute_alias(name) if attribute_alias?(name)
|
287
276
|
table[name]
|
@@ -299,16 +288,15 @@ module ActiveRecord
|
|
299
288
|
|
300
289
|
def cached_find_by_statement(key, &block)
|
301
290
|
cache = @find_by_statement_cache[connection.prepared_statements]
|
302
|
-
cache
|
303
|
-
cache[key] ||= StatementCache.create(connection, &block)
|
304
|
-
}
|
291
|
+
cache.compute_if_absent(key) { StatementCache.create(connection, &block) }
|
305
292
|
end
|
306
293
|
|
307
294
|
def relation
|
308
|
-
relation = Relation.create(self
|
295
|
+
relation = Relation.create(self)
|
309
296
|
|
310
297
|
if finder_needs_type_condition? && !ignore_default_scope?
|
311
|
-
relation.where(type_condition)
|
298
|
+
relation.where!(type_condition)
|
299
|
+
relation.create_with!(inheritance_column.to_s => sti_name)
|
312
300
|
else
|
313
301
|
relation
|
314
302
|
end
|
@@ -405,8 +393,10 @@ module ActiveRecord
|
|
405
393
|
|
406
394
|
_run_initialize_callbacks
|
407
395
|
|
408
|
-
@new_record
|
409
|
-
@destroyed
|
396
|
+
@new_record = true
|
397
|
+
@destroyed = false
|
398
|
+
@_start_transaction_state = {}
|
399
|
+
@transaction_state = nil
|
410
400
|
|
411
401
|
super
|
412
402
|
end
|
@@ -548,7 +538,7 @@ module ActiveRecord
|
|
548
538
|
#
|
549
539
|
# So we can avoid the +method_missing+ hit by explicitly defining +#to_ary+ as +nil+ here.
|
550
540
|
#
|
551
|
-
# See also
|
541
|
+
# See also https://tenderlovemaking.com/2011/06/28/til-its-ok-to-return-nil-from-to_ary.html
|
552
542
|
def to_ary
|
553
543
|
nil
|
554
544
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
# = Active Record Counter Cache
|
3
5
|
module CounterCache
|
@@ -55,7 +57,7 @@ module ActiveRecord
|
|
55
57
|
unscoped.where(primary_key => object.id).update_all(updates)
|
56
58
|
end
|
57
59
|
|
58
|
-
|
60
|
+
true
|
59
61
|
end
|
60
62
|
|
61
63
|
# A generic "counter updater" implementation, intended primarily to be
|
@@ -114,7 +116,13 @@ module ActiveRecord
|
|
114
116
|
updates << sanitize_sql_for_assignment(touch_updates) unless touch_updates.empty?
|
115
117
|
end
|
116
118
|
|
117
|
-
|
119
|
+
if id.is_a?(Relation) && self == id.klass
|
120
|
+
relation = id
|
121
|
+
else
|
122
|
+
relation = unscoped.where!(primary_key => id)
|
123
|
+
end
|
124
|
+
|
125
|
+
relation.update_all updates.join(", ")
|
118
126
|
end
|
119
127
|
|
120
128
|
# Increment a numeric field by one, via a direct SQL update.
|
@@ -178,7 +186,6 @@ module ActiveRecord
|
|
178
186
|
each_counter_cached_associations do |association|
|
179
187
|
if send(association.reflection.name)
|
180
188
|
association.increment_counters
|
181
|
-
@_after_create_counter_called = true
|
182
189
|
end
|
183
190
|
end
|
184
191
|
|
@@ -1,7 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
|
-
# This module exists because
|
3
|
-
# define callbacks, but continue to have its version of
|
4
|
-
# method of
|
4
|
+
# This module exists because ActiveRecord::AttributeMethods::Dirty needs to
|
5
|
+
# define callbacks, but continue to have its version of +save+ be the super
|
6
|
+
# method of ActiveRecord::Callbacks. This will be removed when the removal
|
5
7
|
# of deprecated code removes this need.
|
6
8
|
module DefineCallbacks
|
7
9
|
extend ActiveSupport::Concern
|
@@ -1,16 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
|
2
3
|
module ActiveRecord
|
3
4
|
module DynamicMatchers #:nodoc:
|
4
|
-
def respond_to_missing?(name, include_private = false)
|
5
|
-
if self == Base
|
6
|
-
super
|
7
|
-
else
|
8
|
-
match = Method.match(self, name)
|
9
|
-
match && match.valid? || super
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
5
|
private
|
6
|
+
def respond_to_missing?(name, _)
|
7
|
+
if self == Base
|
8
|
+
super
|
9
|
+
else
|
10
|
+
match = Method.match(self, name)
|
11
|
+
match && match.valid? || super
|
12
|
+
end
|
13
|
+
end
|
14
14
|
|
15
15
|
def method_missing(name, *arguments, &block)
|
16
16
|
match = Method.match(self, name)
|