activerecord 5.1.0 → 5.2.3
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/CHANGELOG.md +596 -450
- data/MIT-LICENSE +1 -1
- data/README.rdoc +5 -5
- data/examples/performance.rb +2 -0
- data/examples/simple.rb +2 -0
- data/lib/active_record.rb +11 -4
- data/lib/active_record/aggregations.rb +6 -5
- data/lib/active_record/association_relation.rb +7 -5
- data/lib/active_record/associations.rb +77 -85
- data/lib/active_record/associations/alias_tracker.rb +23 -32
- data/lib/active_record/associations/association.rb +49 -35
- data/lib/active_record/associations/association_scope.rb +55 -55
- data/lib/active_record/associations/belongs_to_association.rb +30 -11
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -8
- data/lib/active_record/associations/builder/association.rb +4 -7
- data/lib/active_record/associations/builder/belongs_to.rb +21 -8
- data/lib/active_record/associations/builder/collection_association.rb +1 -1
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +3 -1
- data/lib/active_record/associations/builder/has_many.rb +2 -0
- data/lib/active_record/associations/builder/has_one.rb +2 -0
- data/lib/active_record/associations/builder/singular_association.rb +2 -0
- data/lib/active_record/associations/collection_association.rb +66 -53
- data/lib/active_record/associations/collection_proxy.rb +30 -73
- data/lib/active_record/associations/foreign_association.rb +2 -0
- data/lib/active_record/associations/has_many_association.rb +13 -2
- data/lib/active_record/associations/has_many_through_association.rb +37 -19
- data/lib/active_record/associations/has_one_association.rb +14 -1
- data/lib/active_record/associations/has_one_through_association.rb +13 -8
- data/lib/active_record/associations/join_dependency.rb +52 -96
- data/lib/active_record/associations/join_dependency/join_association.rb +22 -75
- data/lib/active_record/associations/join_dependency/join_base.rb +9 -8
- data/lib/active_record/associations/join_dependency/join_part.rb +9 -9
- data/lib/active_record/associations/preloader.rb +17 -37
- data/lib/active_record/associations/preloader/association.rb +53 -92
- data/lib/active_record/associations/preloader/through_association.rb +72 -73
- data/lib/active_record/associations/singular_association.rb +14 -16
- data/lib/active_record/associations/through_association.rb +27 -12
- data/lib/active_record/attribute_assignment.rb +2 -5
- data/lib/active_record/attribute_decorators.rb +3 -2
- data/lib/active_record/attribute_methods.rb +65 -24
- data/lib/active_record/attribute_methods/before_type_cast.rb +2 -0
- data/lib/active_record/attribute_methods/dirty.rb +33 -216
- data/lib/active_record/attribute_methods/primary_key.rb +10 -13
- data/lib/active_record/attribute_methods/query.rb +2 -0
- data/lib/active_record/attribute_methods/read.rb +9 -3
- data/lib/active_record/attribute_methods/serialization.rb +23 -0
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +6 -8
- data/lib/active_record/attribute_methods/write.rb +22 -19
- data/lib/active_record/attributes.rb +7 -6
- data/lib/active_record/autosave_association.rb +15 -13
- data/lib/active_record/base.rb +2 -0
- data/lib/active_record/callbacks.rb +12 -6
- data/lib/active_record/coders/json.rb +2 -0
- data/lib/active_record/coders/yaml_column.rb +2 -0
- data/lib/active_record/collection_cache_key.rb +15 -11
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +120 -39
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +7 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +192 -37
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +13 -2
- data/lib/active_record/connection_adapters/abstract/quoting.rb +15 -25
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +15 -6
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +65 -7
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +31 -53
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +158 -87
- data/lib/active_record/connection_adapters/abstract/transaction.rb +66 -21
- data/lib/active_record/connection_adapters/abstract_adapter.rb +86 -98
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +126 -189
- data/lib/active_record/connection_adapters/column.rb +4 -2
- data/lib/active_record/connection_adapters/connection_specification.rb +17 -3
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +13 -2
- data/lib/active_record/connection_adapters/mysql/column.rb +2 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +45 -15
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +2 -0
- data/lib/active_record/connection_adapters/mysql/quoting.rb +9 -10
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +5 -3
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +7 -10
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +30 -23
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +106 -1
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +2 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +8 -2
- data/lib/active_record/connection_adapters/postgresql/column.rb +30 -1
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +6 -32
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +13 -1
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +8 -2
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +4 -2
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +22 -1
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +19 -25
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +50 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +24 -11
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +20 -13
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +258 -129
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +75 -87
- data/lib/active_record/connection_adapters/schema_cache.rb +4 -2
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +2 -0
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +2 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +24 -1
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +2 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +6 -15
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +3 -2
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +75 -1
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +90 -96
- data/lib/active_record/connection_adapters/statement_pool.rb +2 -0
- data/lib/active_record/connection_handling.rb +4 -2
- data/lib/active_record/core.rb +41 -61
- data/lib/active_record/counter_cache.rb +20 -15
- data/lib/active_record/define_callbacks.rb +5 -3
- data/lib/active_record/dynamic_matchers.rb +9 -9
- data/lib/active_record/enum.rb +18 -13
- data/lib/active_record/errors.rb +60 -15
- data/lib/active_record/explain.rb +3 -1
- data/lib/active_record/explain_registry.rb +2 -0
- data/lib/active_record/explain_subscriber.rb +2 -0
- data/lib/active_record/fixture_set/file.rb +2 -0
- data/lib/active_record/fixtures.rb +67 -60
- data/lib/active_record/gem_version.rb +4 -2
- data/lib/active_record/inheritance.rb +49 -19
- data/lib/active_record/integration.rb +58 -19
- data/lib/active_record/internal_metadata.rb +2 -0
- data/lib/active_record/legacy_yaml_adapter.rb +3 -1
- data/lib/active_record/locking/optimistic.rb +30 -42
- data/lib/active_record/locking/pessimistic.rb +10 -7
- data/lib/active_record/log_subscriber.rb +46 -4
- data/lib/active_record/migration.rb +189 -139
- data/lib/active_record/migration/command_recorder.rb +11 -9
- data/lib/active_record/migration/compatibility.rb +81 -29
- data/lib/active_record/migration/join_table.rb +2 -0
- data/lib/active_record/model_schema.rb +74 -58
- data/lib/active_record/nested_attributes.rb +18 -6
- data/lib/active_record/no_touching.rb +3 -1
- data/lib/active_record/null_relation.rb +2 -0
- data/lib/active_record/persistence.rb +199 -54
- data/lib/active_record/query_cache.rb +8 -10
- data/lib/active_record/querying.rb +5 -3
- data/lib/active_record/railtie.rb +62 -6
- data/lib/active_record/railties/console_sandbox.rb +2 -0
- data/lib/active_record/railties/controller_runtime.rb +2 -0
- data/lib/active_record/railties/databases.rake +48 -38
- data/lib/active_record/readonly_attributes.rb +3 -2
- data/lib/active_record/reflection.rb +137 -207
- data/lib/active_record/relation.rb +132 -207
- data/lib/active_record/relation/batches.rb +32 -17
- data/lib/active_record/relation/batches/batch_enumerator.rb +2 -0
- data/lib/active_record/relation/calculations.rb +66 -25
- data/lib/active_record/relation/delegation.rb +45 -29
- data/lib/active_record/relation/finder_methods.rb +76 -85
- data/lib/active_record/relation/from_clause.rb +2 -8
- data/lib/active_record/relation/merger.rb +53 -23
- data/lib/active_record/relation/predicate_builder.rb +60 -79
- data/lib/active_record/relation/predicate_builder/array_handler.rb +10 -7
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +46 -0
- data/lib/active_record/relation/predicate_builder/base_handler.rb +2 -2
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +12 -1
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +56 -0
- data/lib/active_record/relation/predicate_builder/range_handler.rb +26 -9
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
- data/lib/active_record/relation/query_attribute.rb +28 -2
- data/lib/active_record/relation/query_methods.rb +135 -103
- data/lib/active_record/relation/record_fetch_warning.rb +2 -0
- data/lib/active_record/relation/spawn_methods.rb +4 -2
- data/lib/active_record/relation/where_clause.rb +65 -67
- data/lib/active_record/relation/where_clause_factory.rb +5 -48
- data/lib/active_record/result.rb +2 -0
- data/lib/active_record/runtime_registry.rb +2 -0
- data/lib/active_record/sanitization.rb +129 -121
- data/lib/active_record/schema.rb +4 -2
- data/lib/active_record/schema_dumper.rb +36 -26
- data/lib/active_record/schema_migration.rb +2 -0
- data/lib/active_record/scoping.rb +12 -10
- data/lib/active_record/scoping/default.rb +10 -7
- data/lib/active_record/scoping/named.rb +40 -12
- data/lib/active_record/secure_token.rb +2 -0
- data/lib/active_record/serialization.rb +2 -0
- data/lib/active_record/statement_cache.rb +22 -12
- data/lib/active_record/store.rb +3 -1
- data/lib/active_record/suppressor.rb +2 -0
- data/lib/active_record/table_metadata.rb +12 -3
- data/lib/active_record/tasks/database_tasks.rb +38 -26
- data/lib/active_record/tasks/mysql_database_tasks.rb +11 -50
- data/lib/active_record/tasks/postgresql_database_tasks.rb +11 -3
- data/lib/active_record/tasks/sqlite_database_tasks.rb +25 -3
- data/lib/active_record/timestamp.rb +13 -6
- data/lib/active_record/touch_later.rb +2 -0
- data/lib/active_record/transactions.rb +32 -27
- data/lib/active_record/translation.rb +2 -0
- data/lib/active_record/type.rb +4 -1
- data/lib/active_record/type/adapter_specific_registry.rb +2 -0
- data/lib/active_record/type/date.rb +2 -0
- data/lib/active_record/type/date_time.rb +2 -0
- data/lib/active_record/type/decimal_without_scale.rb +2 -0
- data/lib/active_record/type/hash_lookup_type_map.rb +2 -0
- data/lib/active_record/type/internal/timezone.rb +2 -0
- data/lib/active_record/type/json.rb +30 -0
- data/lib/active_record/type/serialized.rb +6 -0
- data/lib/active_record/type/text.rb +2 -0
- data/lib/active_record/type/time.rb +2 -0
- data/lib/active_record/type/type_map.rb +2 -0
- data/lib/active_record/type/unsigned_integer.rb +2 -0
- data/lib/active_record/type_caster.rb +2 -0
- data/lib/active_record/type_caster/connection.rb +2 -0
- data/lib/active_record/type_caster/map.rb +3 -1
- data/lib/active_record/validations.rb +2 -0
- data/lib/active_record/validations/absence.rb +2 -0
- data/lib/active_record/validations/associated.rb +2 -0
- data/lib/active_record/validations/length.rb +2 -0
- data/lib/active_record/validations/presence.rb +2 -0
- data/lib/active_record/validations/uniqueness.rb +36 -6
- data/lib/active_record/version.rb +2 -0
- data/lib/rails/generators/active_record.rb +3 -1
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
- data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
- data/lib/rails/generators/active_record/migration.rb +2 -0
- data/lib/rails/generators/active_record/migration/migration_generator.rb +3 -1
- data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +0 -0
- data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +0 -0
- data/lib/rails/generators/active_record/model/model_generator.rb +2 -23
- data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +0 -0
- data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
- metadata +24 -36
- data/lib/active_record/associations/preloader/belongs_to.rb +0 -15
- data/lib/active_record/associations/preloader/collection_association.rb +0 -17
- data/lib/active_record/associations/preloader/has_many.rb +0 -15
- data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
- data/lib/active_record/associations/preloader/has_one.rb +0 -15
- data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
- data/lib/active_record/associations/preloader/singular_association.rb +0 -18
- data/lib/active_record/attribute.rb +0 -240
- data/lib/active_record/attribute/user_provided_default.rb +0 -30
- data/lib/active_record/attribute_mutation_tracker.rb +0 -113
- data/lib/active_record/attribute_set.rb +0 -113
- data/lib/active_record/attribute_set/builder.rb +0 -124
- data/lib/active_record/attribute_set/yaml_encoder.rb +0 -41
- data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -10
- data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
- data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
- data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -59
- data/lib/active_record/type/internal/abstract_json.rb +0 -33
@@ -1,3 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "concurrent/map"
|
4
|
+
|
1
5
|
module ActiveRecord
|
2
6
|
module ConnectionAdapters # :nodoc:
|
3
7
|
module QueryCache
|
@@ -90,8 +94,13 @@ module ActiveRecord
|
|
90
94
|
|
91
95
|
def select_all(arel, name = nil, binds = [], preparable: nil)
|
92
96
|
if @query_cache_enabled && !locked?(arel)
|
93
|
-
arel
|
94
|
-
sql =
|
97
|
+
arel = arel_from_relation(arel)
|
98
|
+
sql, binds = to_sql_and_binds(arel, binds)
|
99
|
+
|
100
|
+
if preparable.nil?
|
101
|
+
preparable = prepared_statements ? visitor.preparable : false
|
102
|
+
end
|
103
|
+
|
95
104
|
cache_sql(sql, name, binds) { super(sql, name, binds, preparable: preparable) }
|
96
105
|
else
|
97
106
|
super
|
@@ -108,6 +117,7 @@ module ActiveRecord
|
|
108
117
|
"sql.active_record",
|
109
118
|
sql: sql,
|
110
119
|
binds: binds,
|
120
|
+
type_casted_binds: -> { type_casted_binds(binds) },
|
111
121
|
name: name,
|
112
122
|
connection_id: object_id,
|
113
123
|
cached: true,
|
@@ -123,6 +133,7 @@ module ActiveRecord
|
|
123
133
|
# If arel is locked this is a SELECT ... FOR UPDATE or somesuch. Such
|
124
134
|
# queries should not be cached.
|
125
135
|
def locked?(arel)
|
136
|
+
arel = arel.arel if arel.is_a?(Relation)
|
126
137
|
arel.respond_to?(:locked) && arel.locked
|
127
138
|
end
|
128
139
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/core_ext/big_decimal/conversions"
|
2
4
|
require "active_support/multibyte/chars"
|
3
5
|
|
@@ -5,14 +7,12 @@ module ActiveRecord
|
|
5
7
|
module ConnectionAdapters # :nodoc:
|
6
8
|
module Quoting
|
7
9
|
# Quotes the column value to help prevent
|
8
|
-
# {SQL injection attacks}[
|
10
|
+
# {SQL injection attacks}[https://en.wikipedia.org/wiki/SQL_injection].
|
9
11
|
def quote(value)
|
10
12
|
value = id_value_for_database(value) if value.is_a?(Base)
|
11
13
|
|
12
|
-
if value.respond_to?(:
|
13
|
-
|
14
|
-
"Using #quoted_id is deprecated and will be removed in Rails 5.2."
|
15
|
-
return value.quoted_id
|
14
|
+
if value.respond_to?(:value_for_database)
|
15
|
+
value = value.value_for_database
|
16
16
|
end
|
17
17
|
|
18
18
|
_quote(value)
|
@@ -24,10 +24,6 @@ module ActiveRecord
|
|
24
24
|
def type_cast(value, column = nil)
|
25
25
|
value = id_value_for_database(value) if value.is_a?(Base)
|
26
26
|
|
27
|
-
if value.respond_to?(:quoted_id) && value.respond_to?(:id)
|
28
|
-
return value.id
|
29
|
-
end
|
30
|
-
|
31
27
|
if column
|
32
28
|
value = type_cast_from_column(column, value)
|
33
29
|
end
|
@@ -61,17 +57,6 @@ module ActiveRecord
|
|
61
57
|
lookup_cast_type(column.sql_type)
|
62
58
|
end
|
63
59
|
|
64
|
-
def fetch_type_metadata(sql_type)
|
65
|
-
cast_type = lookup_cast_type(sql_type)
|
66
|
-
SqlTypeMetadata.new(
|
67
|
-
sql_type: sql_type,
|
68
|
-
type: cast_type.type,
|
69
|
-
limit: cast_type.limit,
|
70
|
-
precision: cast_type.precision,
|
71
|
-
scale: cast_type.scale,
|
72
|
-
)
|
73
|
-
end
|
74
|
-
|
75
60
|
# Quotes a string, escaping any ' (single quote) and \ (backslash)
|
76
61
|
# characters.
|
77
62
|
def quote_string(s)
|
@@ -110,19 +95,19 @@ module ActiveRecord
|
|
110
95
|
end
|
111
96
|
|
112
97
|
def quoted_true
|
113
|
-
"
|
98
|
+
"TRUE".freeze
|
114
99
|
end
|
115
100
|
|
116
101
|
def unquoted_true
|
117
|
-
|
102
|
+
true
|
118
103
|
end
|
119
104
|
|
120
105
|
def quoted_false
|
121
|
-
"
|
106
|
+
"FALSE".freeze
|
122
107
|
end
|
123
108
|
|
124
109
|
def unquoted_false
|
125
|
-
|
110
|
+
false
|
126
111
|
end
|
127
112
|
|
128
113
|
# Quote date/time values for use in SQL input. Includes microseconds
|
@@ -145,7 +130,8 @@ module ActiveRecord
|
|
145
130
|
end
|
146
131
|
|
147
132
|
def quoted_time(value) # :nodoc:
|
148
|
-
|
133
|
+
value = value.change(year: 2000, month: 1, day: 1)
|
134
|
+
quoted_date(value).sub(/\A\d\d\d\d-\d\d-\d\d /, "")
|
149
135
|
end
|
150
136
|
|
151
137
|
def quoted_binary(value) # :nodoc:
|
@@ -161,6 +147,10 @@ module ActiveRecord
|
|
161
147
|
end
|
162
148
|
|
163
149
|
private
|
150
|
+
def lookup_cast_type(sql_type)
|
151
|
+
type_map.lookup(sql_type)
|
152
|
+
end
|
153
|
+
|
164
154
|
def id_value_for_database(value)
|
165
155
|
if primary_key = value.class.primary_key
|
166
156
|
value.instance_variable_get(:@attributes)[primary_key].value_for_database
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/core_ext/string/strip"
|
2
4
|
|
3
5
|
module ActiveRecord
|
@@ -22,7 +24,7 @@ module ActiveRecord
|
|
22
24
|
private
|
23
25
|
|
24
26
|
def visit_AlterTable(o)
|
25
|
-
sql = "ALTER TABLE #{quote_table_name(o.name)} "
|
27
|
+
sql = "ALTER TABLE #{quote_table_name(o.name)} ".dup
|
26
28
|
sql << o.adds.map { |col| accept col }.join(" ")
|
27
29
|
sql << o.foreign_key_adds.map { |fk| visit_AddForeignKey fk }.join(" ")
|
28
30
|
sql << o.foreign_key_drops.map { |fk| visit_DropForeignKey fk }.join(" ")
|
@@ -30,17 +32,17 @@ module ActiveRecord
|
|
30
32
|
|
31
33
|
def visit_ColumnDefinition(o)
|
32
34
|
o.sql_type = type_to_sql(o.type, o.options)
|
33
|
-
column_sql = "#{quote_column_name(o.name)} #{o.sql_type}"
|
35
|
+
column_sql = "#{quote_column_name(o.name)} #{o.sql_type}".dup
|
34
36
|
add_column_options!(column_sql, column_options(o)) unless o.type == :primary_key
|
35
37
|
column_sql
|
36
38
|
end
|
37
39
|
|
38
40
|
def visit_AddColumnDefinition(o)
|
39
|
-
"ADD #{accept(o.column)}"
|
41
|
+
"ADD #{accept(o.column)}".dup
|
40
42
|
end
|
41
43
|
|
42
44
|
def visit_TableDefinition(o)
|
43
|
-
create_sql = "CREATE#{' TEMPORARY' if o.temporary} TABLE #{quote_table_name(o.name)} "
|
45
|
+
create_sql = "CREATE#{' TEMPORARY' if o.temporary} TABLE #{quote_table_name(o.name)} ".dup
|
44
46
|
|
45
47
|
statements = o.columns.map { |c| accept c }
|
46
48
|
statements << accept(o.primary_keys) if o.primary_keys
|
@@ -55,12 +57,12 @@ module ActiveRecord
|
|
55
57
|
|
56
58
|
create_sql << "(#{statements.join(', ')})" if statements.present?
|
57
59
|
add_table_options!(create_sql, table_options(o))
|
58
|
-
create_sql << " AS #{
|
60
|
+
create_sql << " AS #{to_sql(o.as)}" if o.as
|
59
61
|
create_sql
|
60
62
|
end
|
61
63
|
|
62
64
|
def visit_PrimaryKeyDefinition(o)
|
63
|
-
"PRIMARY KEY (#{o.name.join(', ')})"
|
65
|
+
"PRIMARY KEY (#{o.name.map { |name| quote_column_name(name) }.join(', ')})"
|
64
66
|
end
|
65
67
|
|
66
68
|
def visit_ForeignKeyDefinition(o)
|
@@ -93,6 +95,7 @@ module ActiveRecord
|
|
93
95
|
if options_sql = options[:options]
|
94
96
|
create_sql << " #{options_sql}"
|
95
97
|
end
|
98
|
+
create_sql
|
96
99
|
end
|
97
100
|
|
98
101
|
def column_options(o)
|
@@ -114,6 +117,11 @@ module ActiveRecord
|
|
114
117
|
sql
|
115
118
|
end
|
116
119
|
|
120
|
+
def to_sql(sql)
|
121
|
+
sql = sql.to_sql if sql.respond_to?(:to_sql)
|
122
|
+
sql
|
123
|
+
end
|
124
|
+
|
117
125
|
def foreign_key_in_create(from_table, to_table, options)
|
118
126
|
options = foreign_key_options(from_table, to_table, options)
|
119
127
|
accept ForeignKeyDefinition.new(from_table, to_table, options)
|
@@ -133,5 +141,6 @@ module ActiveRecord
|
|
133
141
|
end
|
134
142
|
end
|
135
143
|
end
|
144
|
+
SchemaCreation = AbstractAdapter::SchemaCreation # :nodoc:
|
136
145
|
end
|
137
146
|
end
|
@@ -1,9 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module ConnectionAdapters #:nodoc:
|
3
5
|
# Abstract representation of an index definition on a table. Instances of
|
4
6
|
# this type are typically created and returned by methods in database
|
5
|
-
# adapters. e.g. ActiveRecord::ConnectionAdapters::
|
6
|
-
IndexDefinition
|
7
|
+
# adapters. e.g. ActiveRecord::ConnectionAdapters::MySQL::SchemaStatements#indexes
|
8
|
+
class IndexDefinition # :nodoc:
|
9
|
+
attr_reader :table, :name, :unique, :columns, :lengths, :orders, :opclasses, :where, :type, :using, :comment
|
10
|
+
|
11
|
+
def initialize(
|
12
|
+
table, name,
|
13
|
+
unique = false,
|
14
|
+
columns = [],
|
15
|
+
lengths: {},
|
16
|
+
orders: {},
|
17
|
+
opclasses: {},
|
18
|
+
where: nil,
|
19
|
+
type: nil,
|
20
|
+
using: nil,
|
21
|
+
comment: nil
|
22
|
+
)
|
23
|
+
@table = table
|
24
|
+
@name = name
|
25
|
+
@unique = unique
|
26
|
+
@columns = columns
|
27
|
+
@lengths = concise_options(lengths)
|
28
|
+
@orders = concise_options(orders)
|
29
|
+
@opclasses = concise_options(opclasses)
|
30
|
+
@where = where
|
31
|
+
@type = type
|
32
|
+
@using = using
|
33
|
+
@comment = comment
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
def concise_options(options)
|
38
|
+
if columns.size == options.size && options.values.uniq.size == 1
|
39
|
+
options.values.first
|
40
|
+
else
|
41
|
+
options
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
7
45
|
|
8
46
|
# Abstract representation of a column definition. Instances of this type
|
9
47
|
# are typically created by methods in TableDefinition, and added to the
|
@@ -58,6 +96,11 @@ module ActiveRecord
|
|
58
96
|
options[:primary_key] != default_primary_key
|
59
97
|
end
|
60
98
|
|
99
|
+
def validate?
|
100
|
+
options.fetch(:validate, true)
|
101
|
+
end
|
102
|
+
alias validated? validate?
|
103
|
+
|
61
104
|
def defined_for?(to_table_ord = nil, to_table: nil, **options)
|
62
105
|
if to_table_ord
|
63
106
|
self.to_table == to_table_ord.to_s
|
@@ -121,7 +164,7 @@ module ActiveRecord
|
|
121
164
|
end
|
122
165
|
|
123
166
|
def polymorphic_options
|
124
|
-
as_options(polymorphic)
|
167
|
+
as_options(polymorphic).merge(options.slice(:null, :first, :after))
|
125
168
|
end
|
126
169
|
|
127
170
|
def index_options
|
@@ -177,6 +220,7 @@ module ActiveRecord
|
|
177
220
|
:decimal,
|
178
221
|
:float,
|
179
222
|
:integer,
|
223
|
+
:json,
|
180
224
|
:string,
|
181
225
|
:text,
|
182
226
|
:time,
|
@@ -369,6 +413,9 @@ module ActiveRecord
|
|
369
413
|
alias :belongs_to :references
|
370
414
|
|
371
415
|
def new_column_definition(name, type, **options) # :nodoc:
|
416
|
+
if integer_like_primary_key?(type, options)
|
417
|
+
type = integer_like_primary_key_type(type, options)
|
418
|
+
end
|
372
419
|
type = aliased_types(type.to_s, type)
|
373
420
|
options[:primary_key] ||= type == :primary_key
|
374
421
|
options[:null] = false if options[:primary_key]
|
@@ -383,6 +430,14 @@ module ActiveRecord
|
|
383
430
|
def aliased_types(name, fallback)
|
384
431
|
"timestamp" == name ? :datetime : fallback
|
385
432
|
end
|
433
|
+
|
434
|
+
def integer_like_primary_key?(type, options)
|
435
|
+
options[:primary_key] && [:integer, :bigint].include?(type) && !options.key?(:default)
|
436
|
+
end
|
437
|
+
|
438
|
+
def integer_like_primary_key_type(type, options)
|
439
|
+
type
|
440
|
+
end
|
386
441
|
end
|
387
442
|
|
388
443
|
class AlterTable # :nodoc:
|
@@ -443,6 +498,9 @@ module ActiveRecord
|
|
443
498
|
# t.date
|
444
499
|
# t.binary
|
445
500
|
# t.boolean
|
501
|
+
# t.foreign_key
|
502
|
+
# t.json
|
503
|
+
# t.virtual
|
446
504
|
# t.remove
|
447
505
|
# t.remove_references
|
448
506
|
# t.remove_belongs_to
|
@@ -607,19 +665,19 @@ module ActiveRecord
|
|
607
665
|
|
608
666
|
# Adds a foreign key.
|
609
667
|
#
|
610
|
-
#
|
668
|
+
# t.foreign_key(:authors)
|
611
669
|
#
|
612
670
|
# See {connection.add_foreign_key}[rdoc-ref:SchemaStatements#add_foreign_key]
|
613
|
-
def foreign_key(*args)
|
671
|
+
def foreign_key(*args)
|
614
672
|
@base.add_foreign_key(name, *args)
|
615
673
|
end
|
616
674
|
|
617
675
|
# Checks to see if a foreign key exists.
|
618
676
|
#
|
619
|
-
#
|
677
|
+
# t.foreign_key(:authors) unless t.foreign_key_exists?(:authors)
|
620
678
|
#
|
621
679
|
# See {connection.foreign_key_exists?}[rdoc-ref:SchemaStatements#foreign_key_exists?]
|
622
|
-
def foreign_key_exists?(*args)
|
680
|
+
def foreign_key_exists?(*args)
|
623
681
|
@base.foreign_key_exists?(name, *args)
|
624
682
|
end
|
625
683
|
end
|
@@ -1,63 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/hash/compact"
|
4
|
+
|
1
5
|
module ActiveRecord
|
2
6
|
module ConnectionAdapters # :nodoc:
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
# We can then redefine how certain data types may be handled in the schema dumper on the
|
7
|
-
# Adapter level by over-writing this code inside the database specific adapters
|
8
|
-
module ColumnDumper
|
9
|
-
def column_spec(column)
|
10
|
-
[schema_type_with_virtual(column), prepare_column_options(column)]
|
7
|
+
class SchemaDumper < SchemaDumper # :nodoc:
|
8
|
+
def self.create(connection, options)
|
9
|
+
new(connection, options)
|
11
10
|
end
|
12
11
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
spec.merge!(prepare_column_options(column).except!(:null))
|
17
|
-
spec[:default] ||= "nil" if explicit_primary_key_default?(column)
|
18
|
-
spec
|
19
|
-
end
|
20
|
-
|
21
|
-
# This can be overridden on an Adapter level basis to support other
|
22
|
-
# extended datatypes (Example: Adding an array option in the
|
23
|
-
# PostgreSQL::ColumnDumper)
|
24
|
-
def prepare_column_options(column)
|
25
|
-
spec = {}
|
26
|
-
|
27
|
-
if limit = schema_limit(column)
|
28
|
-
spec[:limit] = limit
|
12
|
+
private
|
13
|
+
def column_spec(column)
|
14
|
+
[schema_type_with_virtual(column), prepare_column_options(column)]
|
29
15
|
end
|
30
16
|
|
31
|
-
|
32
|
-
|
17
|
+
def column_spec_for_primary_key(column)
|
18
|
+
return {} if default_primary_key?(column)
|
19
|
+
spec = { id: schema_type(column).inspect }
|
20
|
+
spec.merge!(prepare_column_options(column).except!(:null))
|
21
|
+
spec[:default] ||= "nil" if explicit_primary_key_default?(column)
|
22
|
+
spec
|
33
23
|
end
|
34
24
|
|
35
|
-
|
36
|
-
spec
|
25
|
+
def prepare_column_options(column)
|
26
|
+
spec = {}
|
27
|
+
spec[:limit] = schema_limit(column)
|
28
|
+
spec[:precision] = schema_precision(column)
|
29
|
+
spec[:scale] = schema_scale(column)
|
30
|
+
spec[:default] = schema_default(column)
|
31
|
+
spec[:null] = "false" unless column.null
|
32
|
+
spec[:collation] = schema_collation(column)
|
33
|
+
spec[:comment] = column.comment.inspect if column.comment.present?
|
34
|
+
spec.compact!
|
35
|
+
spec
|
37
36
|
end
|
38
37
|
|
39
|
-
default = schema_default(column) if column.has_default?
|
40
|
-
spec[:default] = default unless default.nil?
|
41
|
-
|
42
|
-
spec[:null] = "false" unless column.null
|
43
|
-
|
44
|
-
if collation = schema_collation(column)
|
45
|
-
spec[:collation] = collation
|
46
|
-
end
|
47
|
-
|
48
|
-
spec[:comment] = column.comment.inspect if column.comment.present?
|
49
|
-
|
50
|
-
spec
|
51
|
-
end
|
52
|
-
|
53
|
-
# Lists the valid migration options
|
54
|
-
def migration_keys # :nodoc:
|
55
|
-
column_options_keys
|
56
|
-
end
|
57
|
-
deprecate :migration_keys
|
58
|
-
|
59
|
-
private
|
60
|
-
|
61
38
|
def default_primary_key?(column)
|
62
39
|
schema_type(column) == :bigint
|
63
40
|
end
|
@@ -67,7 +44,7 @@ module ActiveRecord
|
|
67
44
|
end
|
68
45
|
|
69
46
|
def schema_type_with_virtual(column)
|
70
|
-
if supports_virtual_columns? && column.virtual?
|
47
|
+
if @connection.supports_virtual_columns? && column.virtual?
|
71
48
|
:virtual
|
72
49
|
else
|
73
50
|
schema_type(column)
|
@@ -84,7 +61,7 @@ module ActiveRecord
|
|
84
61
|
|
85
62
|
def schema_limit(column)
|
86
63
|
limit = column.limit unless column.bigint?
|
87
|
-
limit.inspect if limit && limit != native_database_types[column.type][:limit]
|
64
|
+
limit.inspect if limit && limit != @connection.native_database_types[column.type][:limit]
|
88
65
|
end
|
89
66
|
|
90
67
|
def schema_precision(column)
|
@@ -96,7 +73,8 @@ module ActiveRecord
|
|
96
73
|
end
|
97
74
|
|
98
75
|
def schema_default(column)
|
99
|
-
|
76
|
+
return unless column.has_default?
|
77
|
+
type = @connection.lookup_cast_type_from_column(column)
|
100
78
|
default = type.deserialize(column.default)
|
101
79
|
if default.nil?
|
102
80
|
schema_expression(column)
|