activerecord 5.1.7 → 5.2.0.beta1
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 +221 -900
- data/README.rdoc +3 -3
- data/examples/performance.rb +2 -0
- data/examples/simple.rb +2 -0
- data/lib/active_record.rb +10 -3
- data/lib/active_record/aggregations.rb +2 -0
- data/lib/active_record/association_relation.rb +2 -0
- data/lib/active_record/associations.rb +13 -42
- data/lib/active_record/associations/alias_tracker.rb +17 -17
- data/lib/active_record/associations/association.rb +11 -22
- data/lib/active_record/associations/association_scope.rb +32 -44
- data/lib/active_record/associations/belongs_to_association.rb +6 -4
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +3 -1
- data/lib/active_record/associations/builder/association.rb +2 -5
- data/lib/active_record/associations/builder/belongs_to.rb +7 -12
- 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 +41 -33
- data/lib/active_record/associations/collection_proxy.rb +11 -14
- data/lib/active_record/associations/foreign_association.rb +2 -0
- data/lib/active_record/associations/has_many_association.rb +4 -2
- data/lib/active_record/associations/has_many_through_association.rb +4 -2
- data/lib/active_record/associations/has_one_association.rb +3 -1
- data/lib/active_record/associations/has_one_through_association.rb +3 -1
- data/lib/active_record/associations/join_dependency.rb +22 -40
- data/lib/active_record/associations/join_dependency/join_association.rb +17 -56
- data/lib/active_record/associations/join_dependency/join_base.rb +9 -8
- data/lib/active_record/associations/join_dependency/join_part.rb +2 -9
- data/lib/active_record/associations/preloader.rb +17 -37
- data/lib/active_record/associations/preloader/association.rb +42 -58
- data/lib/active_record/associations/preloader/through_association.rb +71 -79
- data/lib/active_record/associations/singular_association.rb +14 -10
- data/lib/active_record/associations/through_association.rb +3 -1
- data/lib/active_record/attribute_assignment.rb +2 -0
- data/lib/active_record/attribute_decorators.rb +3 -2
- data/lib/active_record/attribute_methods.rb +47 -7
- data/lib/active_record/attribute_methods/before_type_cast.rb +2 -0
- data/lib/active_record/attribute_methods/dirty.rb +25 -214
- data/lib/active_record/attribute_methods/primary_key.rb +7 -6
- data/lib/active_record/attribute_methods/query.rb +2 -0
- data/lib/active_record/attribute_methods/read.rb +8 -2
- data/lib/active_record/attribute_methods/serialization.rb +23 -0
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +6 -8
- data/lib/active_record/attribute_methods/write.rb +21 -9
- data/lib/active_record/attributes.rb +7 -6
- data/lib/active_record/autosave_association.rb +5 -11
- data/lib/active_record/base.rb +2 -0
- data/lib/active_record/callbacks.rb +6 -8
- 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 +10 -5
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +110 -35
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +2 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +120 -28
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +7 -2
- data/lib/active_record/connection_adapters/abstract/quoting.rb +14 -33
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +13 -5
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +40 -2
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +31 -53
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +103 -63
- data/lib/active_record/connection_adapters/abstract/transaction.rb +45 -9
- data/lib/active_record/connection_adapters/abstract_adapter.rb +62 -90
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +75 -138
- data/lib/active_record/connection_adapters/column.rb +3 -1
- data/lib/active_record/connection_adapters/connection_specification.rb +17 -3
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +2 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +2 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +3 -1
- 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 -6
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +30 -30
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +91 -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.rb +2 -1
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +3 -11
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_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 -1
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +3 -5
- 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 +10 -0
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +19 -25
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +11 -7
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +20 -13
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +79 -65
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +47 -82
- data/lib/active_record/connection_adapters/schema_cache.rb +2 -0
- 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 +19 -2
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +2 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +6 -15
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +3 -2
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +71 -1
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +34 -89
- 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 +27 -57
- data/lib/active_record/counter_cache.rb +15 -12
- data/lib/active_record/define_callbacks.rb +5 -3
- data/lib/active_record/dynamic_matchers.rb +9 -9
- data/lib/active_record/enum.rb +15 -13
- data/lib/active_record/errors.rb +54 -21
- data/lib/active_record/explain.rb +3 -1
- data/lib/active_record/explain_registry.rb +2 -0
- data/lib/active_record/explain_subscriber.rb +2 -0
- data/lib/active_record/fixture_set/file.rb +2 -0
- data/lib/active_record/fixtures.rb +40 -24
- data/lib/active_record/gem_version.rb +5 -3
- data/lib/active_record/inheritance.rb +6 -5
- 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 +31 -20
- data/lib/active_record/locking/pessimistic.rb +10 -7
- data/lib/active_record/log_subscriber.rb +2 -0
- data/lib/active_record/migration.rb +47 -21
- data/lib/active_record/migration/command_recorder.rb +11 -9
- data/lib/active_record/migration/compatibility.rb +20 -2
- data/lib/active_record/migration/join_table.rb +2 -0
- data/lib/active_record/model_schema.rb +29 -38
- 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 +184 -40
- data/lib/active_record/query_cache.rb +17 -12
- data/lib/active_record/querying.rb +3 -1
- data/lib/active_record/railtie.rb +54 -1
- 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 +41 -28
- data/lib/active_record/readonly_attributes.rb +3 -2
- data/lib/active_record/reflection.rb +100 -182
- data/lib/active_record/relation.rb +61 -193
- data/lib/active_record/relation/batches.rb +20 -5
- data/lib/active_record/relation/batches/batch_enumerator.rb +2 -0
- data/lib/active_record/relation/calculations.rb +40 -23
- data/lib/active_record/relation/delegation.rb +10 -27
- data/lib/active_record/relation/finder_methods.rb +53 -49
- data/lib/active_record/relation/from_clause.rb +2 -8
- data/lib/active_record/relation/merger.rb +22 -19
- data/lib/active_record/relation/predicate_builder.rb +42 -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 +54 -0
- data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -6
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
- data/lib/active_record/relation/query_attribute.rb +9 -2
- data/lib/active_record/relation/query_methods.rb +80 -69
- data/lib/active_record/relation/record_fetch_warning.rb +2 -0
- data/lib/active_record/relation/spawn_methods.rb +2 -0
- data/lib/active_record/relation/where_clause.rb +50 -67
- data/lib/active_record/relation/where_clause_factory.rb +4 -46
- data/lib/active_record/result.rb +2 -0
- data/lib/active_record/runtime_registry.rb +2 -0
- data/lib/active_record/sanitization.rb +15 -9
- data/lib/active_record/schema.rb +3 -1
- data/lib/active_record/schema_dumper.rb +24 -23
- data/lib/active_record/schema_migration.rb +2 -0
- data/lib/active_record/scoping.rb +9 -8
- data/lib/active_record/scoping/default.rb +6 -7
- data/lib/active_record/scoping/named.rb +15 -7
- 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 +2 -0
- data/lib/active_record/suppressor.rb +2 -0
- data/lib/active_record/table_metadata.rb +3 -1
- data/lib/active_record/tasks/database_tasks.rb +23 -12
- data/lib/active_record/tasks/mysql_database_tasks.rb +9 -48
- data/lib/active_record/tasks/postgresql_database_tasks.rb +10 -2
- data/lib/active_record/tasks/sqlite_database_tasks.rb +25 -3
- data/lib/active_record/timestamp.rb +5 -12
- data/lib/active_record/touch_later.rb +2 -0
- data/lib/active_record/transactions.rb +9 -7
- data/lib/active_record/translation.rb +2 -0
- data/lib/active_record/type.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 +2 -4
- data/lib/active_record/type/text.rb +2 -0
- data/lib/active_record/type/time.rb +2 -0
- data/lib/active_record/type/type_map.rb +2 -0
- data/lib/active_record/type/unsigned_integer.rb +2 -0
- data/lib/active_record/type_caster.rb +2 -0
- data/lib/active_record/type_caster/connection.rb +2 -0
- data/lib/active_record/type_caster/map.rb +2 -0
- 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 +25 -38
- 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 -122
- data/lib/active_record/attribute_set.rb +0 -113
- 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/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,43 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
class Relation
|
3
5
|
class WhereClause # :nodoc:
|
4
|
-
attr_reader :binds
|
5
|
-
|
6
6
|
delegate :any?, :empty?, to: :predicates
|
7
7
|
|
8
|
-
def initialize(predicates
|
8
|
+
def initialize(predicates)
|
9
9
|
@predicates = predicates
|
10
|
-
@binds = binds
|
11
10
|
end
|
12
11
|
|
13
12
|
def +(other)
|
14
13
|
WhereClause.new(
|
15
14
|
predicates + other.predicates,
|
16
|
-
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
18
|
+
def -(other)
|
19
|
+
WhereClause.new(
|
20
|
+
predicates - other.predicates,
|
17
21
|
)
|
18
22
|
end
|
19
23
|
|
20
24
|
def merge(other)
|
21
25
|
WhereClause.new(
|
22
26
|
predicates_unreferenced_by(other) + other.predicates,
|
23
|
-
non_conflicting_binds(other) + other.binds,
|
24
27
|
)
|
25
28
|
end
|
26
29
|
|
27
30
|
def except(*columns)
|
28
|
-
WhereClause.new(
|
31
|
+
WhereClause.new(except_predicates(columns))
|
29
32
|
end
|
30
33
|
|
31
34
|
def or(other)
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
35
|
+
left = self - other
|
36
|
+
common = self - left
|
37
|
+
right = other - common
|
38
|
+
|
39
|
+
if left.empty? || right.empty?
|
40
|
+
common
|
36
41
|
else
|
37
|
-
WhereClause.new(
|
38
|
-
[ast.or(
|
39
|
-
binds + other.binds
|
42
|
+
or_clause = WhereClause.new(
|
43
|
+
[left.ast.or(right.ast)],
|
40
44
|
)
|
45
|
+
common + or_clause
|
41
46
|
end
|
42
47
|
end
|
43
48
|
|
@@ -49,17 +54,10 @@ module ActiveRecord
|
|
49
54
|
end
|
50
55
|
end
|
51
56
|
|
52
|
-
binds = self.binds.map { |attr| [attr.name, attr.value] }.to_h
|
53
|
-
|
54
57
|
equalities.map { |node|
|
55
|
-
name = node.left.name
|
56
|
-
|
57
|
-
|
58
|
-
when Array then node.right.map(&:val)
|
59
|
-
when Arel::Nodes::Casted, Arel::Nodes::Quoted
|
60
|
-
node.right.val
|
61
|
-
end
|
62
|
-
}]
|
58
|
+
name = node.left.name.to_s
|
59
|
+
value = extract_node_value(node.right)
|
60
|
+
[name, value]
|
63
61
|
}.to_h
|
64
62
|
end
|
65
63
|
|
@@ -69,20 +67,17 @@ module ActiveRecord
|
|
69
67
|
|
70
68
|
def ==(other)
|
71
69
|
other.is_a?(WhereClause) &&
|
72
|
-
predicates == other.predicates
|
73
|
-
binds == other.binds
|
70
|
+
predicates == other.predicates
|
74
71
|
end
|
75
72
|
|
76
73
|
def invert
|
77
|
-
WhereClause.new(inverted_predicates
|
74
|
+
WhereClause.new(inverted_predicates)
|
78
75
|
end
|
79
76
|
|
80
77
|
def self.empty
|
81
|
-
@empty ||= new([]
|
78
|
+
@empty ||= new([])
|
82
79
|
end
|
83
80
|
|
84
|
-
# TODO Change this to private once we've dropped Ruby 2.2 support.
|
85
|
-
# Workaround for Ruby 2.2 "private attribute?" warning.
|
86
81
|
protected
|
87
82
|
|
88
83
|
attr_reader :predicates
|
@@ -106,12 +101,6 @@ module ActiveRecord
|
|
106
101
|
node.respond_to?(:operator) && node.operator == :==
|
107
102
|
end
|
108
103
|
|
109
|
-
def non_conflicting_binds(other)
|
110
|
-
conflicts = referenced_columns & other.referenced_columns
|
111
|
-
conflicts.map! { |node| node.name.to_s }
|
112
|
-
binds.reject { |attr| conflicts.include?(attr.name) }
|
113
|
-
end
|
114
|
-
|
115
104
|
def inverted_predicates
|
116
105
|
predicates.map { |node| invert_predicate(node) }
|
117
106
|
end
|
@@ -131,44 +120,22 @@ module ActiveRecord
|
|
131
120
|
end
|
132
121
|
end
|
133
122
|
|
134
|
-
def
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
except = \
|
142
|
-
case node
|
143
|
-
when Arel::Nodes::Between, Arel::Nodes::In, Arel::Nodes::NotIn, Arel::Nodes::Equality, Arel::Nodes::NotEqual, Arel::Nodes::LessThan, Arel::Nodes::LessThanOrEqual, Arel::Nodes::GreaterThan, Arel::Nodes::GreaterThanOrEqual
|
144
|
-
subrelation = (node.left.kind_of?(Arel::Attributes::Attribute) ? node.left : node.right)
|
145
|
-
columns.include?(subrelation.name.to_s)
|
146
|
-
end
|
147
|
-
|
148
|
-
if except && binds_contains > 0
|
149
|
-
(binds_index...(binds_index + binds_contains)).each do |i|
|
150
|
-
except_binds[i] = true
|
151
|
-
end
|
123
|
+
def except_predicates(columns)
|
124
|
+
self.predicates.reject do |node|
|
125
|
+
case node
|
126
|
+
when Arel::Nodes::Between, Arel::Nodes::In, Arel::Nodes::NotIn, Arel::Nodes::Equality, Arel::Nodes::NotEqual, Arel::Nodes::LessThan, Arel::Nodes::LessThanOrEqual, Arel::Nodes::GreaterThan, Arel::Nodes::GreaterThanOrEqual
|
127
|
+
subrelation = (node.left.kind_of?(Arel::Attributes::Attribute) ? node.left : node.right)
|
128
|
+
columns.include?(subrelation.name.to_s)
|
152
129
|
end
|
153
|
-
|
154
|
-
binds_index += binds_contains if binds_contains
|
155
|
-
|
156
|
-
except
|
157
130
|
end
|
158
|
-
|
159
|
-
binds = self.binds.reject.with_index do |_, i|
|
160
|
-
except_binds[i]
|
161
|
-
end
|
162
|
-
|
163
|
-
[predicates, binds]
|
164
131
|
end
|
165
132
|
|
166
133
|
def predicates_with_wrapped_sql_literals
|
167
134
|
non_empty_predicates.map do |node|
|
168
|
-
|
169
|
-
|
170
|
-
else
|
135
|
+
case node
|
136
|
+
when Arel::Nodes::SqlLiteral, ::String
|
171
137
|
wrap_sql_literal(node)
|
138
|
+
else node
|
172
139
|
end
|
173
140
|
end
|
174
141
|
end
|
@@ -184,6 +151,22 @@ module ActiveRecord
|
|
184
151
|
end
|
185
152
|
Arel::Nodes::Grouping.new(node)
|
186
153
|
end
|
154
|
+
|
155
|
+
def extract_node_value(node)
|
156
|
+
case node
|
157
|
+
when Array
|
158
|
+
node.map { |v| extract_node_value(v) }
|
159
|
+
when Arel::Nodes::Casted, Arel::Nodes::Quoted
|
160
|
+
node.val
|
161
|
+
when Arel::Nodes::BindParam
|
162
|
+
value = node.value
|
163
|
+
if value.respond_to?(:value_before_type_cast)
|
164
|
+
value.value_before_type_cast
|
165
|
+
else
|
166
|
+
value
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
187
170
|
end
|
188
171
|
end
|
189
172
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
class Relation
|
3
5
|
class WhereClauseFactory # :nodoc:
|
@@ -15,63 +17,19 @@ module ActiveRecord
|
|
15
17
|
attributes = klass.send(:expand_hash_conditions_for_aggregates, attributes)
|
16
18
|
attributes.stringify_keys!
|
17
19
|
|
18
|
-
|
19
|
-
parts, binds = build_for_case_sensitive(attributes, options)
|
20
|
-
else
|
21
|
-
attributes, binds = predicate_builder.create_binds(attributes)
|
22
|
-
parts = predicate_builder.build_from_hash(attributes)
|
23
|
-
end
|
20
|
+
parts = predicate_builder.build_from_hash(attributes)
|
24
21
|
when Arel::Nodes::Node
|
25
22
|
parts = [opts]
|
26
23
|
else
|
27
24
|
raise ArgumentError, "Unsupported argument type: #{opts} (#{opts.class})"
|
28
25
|
end
|
29
26
|
|
30
|
-
WhereClause.new(parts
|
27
|
+
WhereClause.new(parts)
|
31
28
|
end
|
32
29
|
|
33
|
-
# TODO Change this to private once we've dropped Ruby 2.2 support.
|
34
|
-
# Workaround for Ruby 2.2 "private attribute?" warning.
|
35
30
|
protected
|
36
31
|
|
37
32
|
attr_reader :klass, :predicate_builder
|
38
|
-
|
39
|
-
private
|
40
|
-
|
41
|
-
def perform_case_sensitive?(options)
|
42
|
-
options && options.key?(:case_sensitive)
|
43
|
-
end
|
44
|
-
|
45
|
-
def build_for_case_sensitive(attributes, options)
|
46
|
-
parts, binds = [], []
|
47
|
-
table = klass.arel_table
|
48
|
-
|
49
|
-
attributes.each do |attribute, value|
|
50
|
-
if reflection = klass._reflect_on_association(attribute)
|
51
|
-
attribute = reflection.foreign_key.to_s
|
52
|
-
value = value[reflection.klass.primary_key] unless value.nil?
|
53
|
-
end
|
54
|
-
|
55
|
-
if value.nil?
|
56
|
-
parts << table[attribute].eq(value)
|
57
|
-
else
|
58
|
-
column = klass.column_for_attribute(attribute)
|
59
|
-
|
60
|
-
binds << predicate_builder.send(:build_bind_param, attribute, value)
|
61
|
-
value = Arel::Nodes::BindParam.new
|
62
|
-
|
63
|
-
predicate = if options[:case_sensitive]
|
64
|
-
klass.connection.case_sensitive_comparison(table, attribute, column, value)
|
65
|
-
else
|
66
|
-
klass.connection.case_insensitive_comparison(table, attribute, column, value)
|
67
|
-
end
|
68
|
-
|
69
|
-
parts << predicate
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
[parts, binds]
|
74
|
-
end
|
75
33
|
end
|
76
34
|
end
|
77
35
|
end
|
data/lib/active_record/result.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module Sanitization
|
3
5
|
extend ActiveSupport::Concern
|
@@ -28,8 +30,6 @@ module ActiveRecord
|
|
28
30
|
end
|
29
31
|
end
|
30
32
|
alias :sanitize_sql :sanitize_sql_for_conditions
|
31
|
-
alias :sanitize_conditions :sanitize_sql
|
32
|
-
deprecate sanitize_conditions: :sanitize_sql
|
33
33
|
|
34
34
|
# Accepts an array, hash, or string of SQL conditions and sanitizes
|
35
35
|
# them into a valid SQL fragment for a SET clause.
|
@@ -63,7 +63,17 @@ module ActiveRecord
|
|
63
63
|
# # => "id ASC"
|
64
64
|
def sanitize_sql_for_order(condition) # :doc:
|
65
65
|
if condition.is_a?(Array) && condition.first.to_s.include?("?")
|
66
|
-
|
66
|
+
enforce_raw_sql_whitelist([condition.first],
|
67
|
+
whitelist: AttributeMethods::ClassMethods::COLUMN_NAME_ORDER_WHITELIST
|
68
|
+
)
|
69
|
+
|
70
|
+
# Ensure we aren't dealing with a subclass of String that might
|
71
|
+
# override methods we use (eg. Arel::Nodes::SqlLiteral).
|
72
|
+
if condition.first.kind_of?(String) && !condition.first.instance_of?(String)
|
73
|
+
condition = [String.new(condition.first), *condition[1..-1]]
|
74
|
+
end
|
75
|
+
|
76
|
+
Arel.sql(sanitize_sql_array(condition))
|
67
77
|
else
|
68
78
|
condition
|
69
79
|
end
|
@@ -110,7 +120,8 @@ module ActiveRecord
|
|
110
120
|
def sanitize_sql_hash_for_assignment(attrs, table) # :doc:
|
111
121
|
c = connection
|
112
122
|
attrs.map do |attr, value|
|
113
|
-
|
123
|
+
type = type_for_attribute(attr.to_s)
|
124
|
+
value = type.serialize(type.cast(value))
|
114
125
|
"#{c.quote_table_name_for_assignment(table, attr)} = #{c.quote(value)}"
|
115
126
|
end.join(", ")
|
116
127
|
end
|
@@ -205,10 +216,5 @@ module ActiveRecord
|
|
205
216
|
end
|
206
217
|
end
|
207
218
|
end
|
208
|
-
|
209
|
-
def quoted_id # :nodoc:
|
210
|
-
self.class.connection.quote(@attributes[self.class.primary_key].value_for_database)
|
211
|
-
end
|
212
|
-
deprecate :quoted_id
|
213
219
|
end
|
214
220
|
end
|
data/lib/active_record/schema.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
# = Active Record \Schema
|
3
5
|
#
|
@@ -37,7 +39,7 @@ module ActiveRecord
|
|
37
39
|
# The +info+ hash is optional, and if given is used to define metadata
|
38
40
|
# about the current schema (currently, only the schema's version):
|
39
41
|
#
|
40
|
-
# ActiveRecord::Schema.define(version:
|
42
|
+
# ActiveRecord::Schema.define(version: 2038_01_19_000001) do
|
41
43
|
# ...
|
42
44
|
# end
|
43
45
|
def self.define(info = {}, &block)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "stringio"
|
2
4
|
|
3
5
|
module ActiveRecord
|
@@ -11,14 +13,13 @@ module ActiveRecord
|
|
11
13
|
##
|
12
14
|
# :singleton-method:
|
13
15
|
# A list of tables which should not be dumped to the schema.
|
14
|
-
# Acceptable values are strings as well as regexp.
|
15
|
-
#
|
16
|
-
cattr_accessor :ignore_tables
|
17
|
-
@@ignore_tables = []
|
16
|
+
# Acceptable values are strings as well as regexp if ActiveRecord::Base.schema_format == :ruby.
|
17
|
+
# Only strings are accepted if ActiveRecord::Base.schema_format == :sql.
|
18
|
+
cattr_accessor :ignore_tables, default: []
|
18
19
|
|
19
20
|
class << self
|
20
21
|
def dump(connection = ActiveRecord::Base.connection, stream = STDOUT, config = ActiveRecord::Base)
|
21
|
-
|
22
|
+
connection.create_schema_dumper(generate_options(config)).dump(stream)
|
22
23
|
stream
|
23
24
|
end
|
24
25
|
|
@@ -47,9 +48,18 @@ module ActiveRecord
|
|
47
48
|
@options = options
|
48
49
|
end
|
49
50
|
|
50
|
-
|
51
|
-
|
51
|
+
# turns 20170404131909 into "2017_04_04_131909"
|
52
|
+
def formatted_version
|
53
|
+
stringified = @version.to_s
|
54
|
+
return stringified unless stringified.length == 14
|
55
|
+
stringified.insert(4, "_").insert(7, "_").insert(10, "_")
|
56
|
+
end
|
52
57
|
|
58
|
+
def define_params
|
59
|
+
@version ? "version: #{formatted_version}" : ""
|
60
|
+
end
|
61
|
+
|
62
|
+
def header(stream)
|
53
63
|
stream.puts <<HEADER
|
54
64
|
# This file is auto-generated from the current state of the database. Instead
|
55
65
|
# of editing this file, please use the migrations feature of Active Record to
|
@@ -72,16 +82,8 @@ HEADER
|
|
72
82
|
stream.puts "end"
|
73
83
|
end
|
74
84
|
|
85
|
+
# extensions are only supported by PostgreSQL
|
75
86
|
def extensions(stream)
|
76
|
-
return unless @connection.supports_extensions?
|
77
|
-
extensions = @connection.extensions
|
78
|
-
if extensions.any?
|
79
|
-
stream.puts " # These are extensions that must be enabled in order to support this database"
|
80
|
-
extensions.each do |extension|
|
81
|
-
stream.puts " enable_extension #{extension.inspect}"
|
82
|
-
end
|
83
|
-
stream.puts
|
84
|
-
end
|
85
87
|
end
|
86
88
|
|
87
89
|
def tables(stream)
|
@@ -113,7 +115,7 @@ HEADER
|
|
113
115
|
when String
|
114
116
|
tbl.print ", primary_key: #{pk.inspect}" unless pk == "id"
|
115
117
|
pkcol = columns.detect { |c| c.name == pk }
|
116
|
-
pkcolspec =
|
118
|
+
pkcolspec = column_spec_for_primary_key(pkcol)
|
117
119
|
if pkcolspec.present?
|
118
120
|
tbl.print ", #{format_colspec(pkcolspec)}"
|
119
121
|
end
|
@@ -122,20 +124,19 @@ HEADER
|
|
122
124
|
else
|
123
125
|
tbl.print ", id: false"
|
124
126
|
end
|
125
|
-
tbl.print ", force: :cascade"
|
126
127
|
|
127
128
|
table_options = @connection.table_options(table)
|
128
129
|
if table_options.present?
|
129
130
|
tbl.print ", #{format_options(table_options)}"
|
130
131
|
end
|
131
132
|
|
132
|
-
tbl.puts " do |t|"
|
133
|
+
tbl.puts ", force: :cascade do |t|"
|
133
134
|
|
134
135
|
# then dump all non-primary key columns
|
135
136
|
columns.each do |column|
|
136
137
|
raise StandardError, "Unknown type '#{column.sql_type}' for column '#{column.name}'" unless @connection.valid_type?(column.type)
|
137
138
|
next if column.name == pk
|
138
|
-
type, colspec =
|
139
|
+
type, colspec = column_spec(column)
|
139
140
|
tbl.print " t.#{type} #{column.name.inspect}"
|
140
141
|
tbl.print ", #{format_colspec(colspec)}" if colspec.present?
|
141
142
|
tbl.puts
|
@@ -153,8 +154,6 @@ HEADER
|
|
153
154
|
stream.puts "# #{e.message}"
|
154
155
|
stream.puts
|
155
156
|
end
|
156
|
-
|
157
|
-
stream
|
158
157
|
end
|
159
158
|
|
160
159
|
# Keep it for indexing materialized views
|
@@ -233,7 +232,9 @@ HEADER
|
|
233
232
|
end
|
234
233
|
|
235
234
|
def remove_prefix_and_suffix(table)
|
236
|
-
|
235
|
+
prefix = Regexp.escape(@options[:table_name_prefix].to_s)
|
236
|
+
suffix = Regexp.escape(@options[:table_name_suffix].to_s)
|
237
|
+
table.sub(/\A#{prefix}(.+)#{suffix}\z/, "\\1")
|
237
238
|
end
|
238
239
|
|
239
240
|
def ignored?(table_name)
|