activerecord 5.2.4.4 → 6.0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +777 -552
- data/MIT-LICENSE +3 -1
- data/README.rdoc +5 -3
- data/examples/performance.rb +1 -1
- data/lib/active_record.rb +10 -2
- data/lib/active_record/advisory_lock_base.rb +18 -0
- data/lib/active_record/aggregations.rb +4 -3
- data/lib/active_record/association_relation.rb +10 -8
- data/lib/active_record/associations.rb +21 -16
- data/lib/active_record/associations/alias_tracker.rb +0 -1
- data/lib/active_record/associations/association.rb +56 -19
- data/lib/active_record/associations/association_scope.rb +4 -6
- data/lib/active_record/associations/belongs_to_association.rb +36 -42
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +0 -4
- data/lib/active_record/associations/builder/association.rb +14 -18
- data/lib/active_record/associations/builder/belongs_to.rb +19 -52
- data/lib/active_record/associations/builder/collection_association.rb +3 -13
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +17 -40
- data/lib/active_record/associations/builder/has_many.rb +2 -0
- data/lib/active_record/associations/builder/has_one.rb +35 -1
- data/lib/active_record/associations/builder/singular_association.rb +2 -0
- data/lib/active_record/associations/collection_association.rb +12 -23
- data/lib/active_record/associations/collection_proxy.rb +13 -17
- data/lib/active_record/associations/foreign_association.rb +7 -0
- data/lib/active_record/associations/has_many_association.rb +2 -11
- data/lib/active_record/associations/has_many_through_association.rb +14 -14
- data/lib/active_record/associations/has_one_association.rb +28 -30
- data/lib/active_record/associations/has_one_through_association.rb +5 -5
- data/lib/active_record/associations/join_dependency.rb +37 -28
- data/lib/active_record/associations/join_dependency/join_association.rb +9 -10
- data/lib/active_record/associations/join_dependency/join_part.rb +2 -2
- data/lib/active_record/associations/preloader.rb +39 -32
- data/lib/active_record/associations/preloader/association.rb +38 -36
- data/lib/active_record/associations/preloader/through_association.rb +48 -39
- data/lib/active_record/associations/singular_association.rb +2 -16
- data/lib/active_record/attribute_assignment.rb +7 -11
- data/lib/active_record/attribute_decorators.rb +0 -2
- data/lib/active_record/attribute_methods.rb +28 -100
- data/lib/active_record/attribute_methods/before_type_cast.rb +4 -2
- data/lib/active_record/attribute_methods/dirty.rb +111 -40
- data/lib/active_record/attribute_methods/primary_key.rb +15 -24
- data/lib/active_record/attribute_methods/query.rb +2 -3
- data/lib/active_record/attribute_methods/read.rb +15 -54
- data/lib/active_record/attribute_methods/serialization.rb +1 -2
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +1 -3
- data/lib/active_record/attribute_methods/write.rb +17 -25
- data/lib/active_record/attributes.rb +13 -1
- data/lib/active_record/autosave_association.rb +3 -5
- data/lib/active_record/base.rb +2 -3
- data/lib/active_record/callbacks.rb +6 -21
- data/lib/active_record/coders/yaml_column.rb +0 -1
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +103 -18
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +17 -4
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +102 -124
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +18 -9
- data/lib/active_record/connection_adapters/abstract/quoting.rb +68 -17
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +20 -14
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +100 -72
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +1 -3
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +175 -79
- data/lib/active_record/connection_adapters/abstract/transaction.rb +96 -57
- data/lib/active_record/connection_adapters/abstract_adapter.rb +191 -43
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +142 -215
- data/lib/active_record/connection_adapters/column.rb +17 -13
- data/lib/active_record/connection_adapters/connection_specification.rb +54 -45
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +6 -10
- data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +70 -14
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +0 -1
- data/lib/active_record/connection_adapters/mysql/quoting.rb +44 -7
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +4 -6
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +40 -32
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +14 -6
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +132 -16
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +6 -10
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +26 -10
- data/lib/active_record/connection_adapters/postgresql/column.rb +17 -31
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +26 -1
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -2
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +1 -4
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +1 -2
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +1 -2
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +1 -2
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +1 -2
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +9 -7
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +5 -3
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +44 -7
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +14 -3
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -91
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +63 -75
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +24 -27
- data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +168 -75
- data/lib/active_record/connection_adapters/schema_cache.rb +37 -14
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +11 -8
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +119 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +42 -7
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +43 -12
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +135 -146
- data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
- data/lib/active_record/connection_handling.rb +139 -26
- data/lib/active_record/core.rb +103 -61
- data/lib/active_record/counter_cache.rb +8 -30
- data/lib/active_record/database_configurations.rb +233 -0
- data/lib/active_record/database_configurations/database_config.rb +37 -0
- data/lib/active_record/database_configurations/hash_config.rb +50 -0
- data/lib/active_record/database_configurations/url_config.rb +78 -0
- data/lib/active_record/dynamic_matchers.rb +3 -4
- data/lib/active_record/enum.rb +37 -7
- data/lib/active_record/errors.rb +15 -7
- data/lib/active_record/explain.rb +1 -2
- data/lib/active_record/fixture_set/model_metadata.rb +33 -0
- data/lib/active_record/fixture_set/render_context.rb +17 -0
- data/lib/active_record/fixture_set/table_row.rb +152 -0
- data/lib/active_record/fixture_set/table_rows.rb +46 -0
- data/lib/active_record/fixtures.rb +144 -474
- data/lib/active_record/gem_version.rb +3 -3
- data/lib/active_record/inheritance.rb +13 -6
- data/lib/active_record/insert_all.rb +179 -0
- data/lib/active_record/integration.rb +68 -16
- data/lib/active_record/internal_metadata.rb +11 -3
- data/lib/active_record/locking/optimistic.rb +5 -7
- data/lib/active_record/locking/pessimistic.rb +3 -3
- data/lib/active_record/log_subscriber.rb +8 -27
- data/lib/active_record/middleware/database_selector.rb +74 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +87 -0
- data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
- data/lib/active_record/migration.rb +104 -85
- data/lib/active_record/migration/command_recorder.rb +54 -22
- data/lib/active_record/migration/compatibility.rb +79 -52
- data/lib/active_record/migration/join_table.rb +0 -1
- data/lib/active_record/model_schema.rb +33 -11
- data/lib/active_record/nested_attributes.rb +2 -4
- data/lib/active_record/no_touching.rb +9 -2
- data/lib/active_record/null_relation.rb +0 -1
- data/lib/active_record/persistence.rb +232 -29
- data/lib/active_record/query_cache.rb +11 -4
- data/lib/active_record/querying.rb +33 -21
- data/lib/active_record/railtie.rb +80 -43
- data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
- data/lib/active_record/railties/controller_runtime.rb +30 -35
- data/lib/active_record/railties/databases.rake +199 -46
- data/lib/active_record/reflection.rb +40 -38
- data/lib/active_record/relation.rb +322 -80
- data/lib/active_record/relation/batches.rb +13 -11
- data/lib/active_record/relation/calculations.rb +54 -48
- data/lib/active_record/relation/delegation.rb +33 -49
- data/lib/active_record/relation/finder_methods.rb +23 -28
- data/lib/active_record/relation/from_clause.rb +4 -0
- data/lib/active_record/relation/merger.rb +11 -21
- data/lib/active_record/relation/predicate_builder.rb +5 -11
- data/lib/active_record/relation/predicate_builder/array_handler.rb +5 -4
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +1 -4
- data/lib/active_record/relation/predicate_builder/base_handler.rb +1 -2
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +1 -2
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +1 -4
- data/lib/active_record/relation/predicate_builder/range_handler.rb +3 -23
- data/lib/active_record/relation/query_attribute.rb +13 -8
- data/lib/active_record/relation/query_methods.rb +221 -70
- data/lib/active_record/relation/spawn_methods.rb +1 -2
- data/lib/active_record/relation/where_clause.rb +14 -11
- data/lib/active_record/relation/where_clause_factory.rb +1 -2
- data/lib/active_record/result.rb +30 -12
- data/lib/active_record/sanitization.rb +32 -40
- data/lib/active_record/schema.rb +2 -11
- data/lib/active_record/schema_dumper.rb +22 -7
- data/lib/active_record/schema_migration.rb +6 -2
- data/lib/active_record/scoping.rb +8 -9
- data/lib/active_record/scoping/default.rb +4 -6
- data/lib/active_record/scoping/named.rb +21 -17
- data/lib/active_record/statement_cache.rb +30 -3
- data/lib/active_record/store.rb +87 -8
- data/lib/active_record/suppressor.rb +2 -2
- data/lib/active_record/table_metadata.rb +23 -15
- data/lib/active_record/tasks/database_tasks.rb +194 -25
- data/lib/active_record/tasks/mysql_database_tasks.rb +5 -6
- data/lib/active_record/tasks/postgresql_database_tasks.rb +5 -8
- data/lib/active_record/tasks/sqlite_database_tasks.rb +2 -9
- data/lib/active_record/test_databases.rb +23 -0
- data/lib/active_record/test_fixtures.rb +225 -0
- data/lib/active_record/timestamp.rb +39 -26
- data/lib/active_record/touch_later.rb +5 -4
- data/lib/active_record/transactions.rb +64 -73
- data/lib/active_record/translation.rb +1 -1
- data/lib/active_record/type.rb +3 -5
- data/lib/active_record/type/adapter_specific_registry.rb +3 -13
- data/lib/active_record/type/hash_lookup_type_map.rb +0 -1
- data/lib/active_record/type/serialized.rb +0 -1
- data/lib/active_record/type/type_map.rb +0 -1
- data/lib/active_record/type/unsigned_integer.rb +0 -1
- data/lib/active_record/type_caster/connection.rb +15 -14
- data/lib/active_record/type_caster/map.rb +1 -4
- data/lib/active_record/validations.rb +3 -3
- data/lib/active_record/validations/associated.rb +1 -2
- data/lib/active_record/validations/uniqueness.rb +15 -27
- data/lib/arel.rb +62 -0
- data/lib/arel/alias_predication.rb +9 -0
- data/lib/arel/attributes.rb +22 -0
- data/lib/arel/attributes/attribute.rb +37 -0
- data/lib/arel/collectors/bind.rb +24 -0
- data/lib/arel/collectors/composite.rb +31 -0
- data/lib/arel/collectors/plain_string.rb +20 -0
- data/lib/arel/collectors/sql_string.rb +20 -0
- data/lib/arel/collectors/substitute_binds.rb +28 -0
- data/lib/arel/crud.rb +42 -0
- data/lib/arel/delete_manager.rb +18 -0
- data/lib/arel/errors.rb +9 -0
- data/lib/arel/expressions.rb +29 -0
- data/lib/arel/factory_methods.rb +49 -0
- data/lib/arel/insert_manager.rb +49 -0
- data/lib/arel/math.rb +45 -0
- data/lib/arel/nodes.rb +68 -0
- data/lib/arel/nodes/and.rb +32 -0
- data/lib/arel/nodes/ascending.rb +23 -0
- data/lib/arel/nodes/binary.rb +52 -0
- data/lib/arel/nodes/bind_param.rb +36 -0
- data/lib/arel/nodes/case.rb +55 -0
- data/lib/arel/nodes/casted.rb +50 -0
- data/lib/arel/nodes/comment.rb +29 -0
- data/lib/arel/nodes/count.rb +12 -0
- data/lib/arel/nodes/delete_statement.rb +45 -0
- data/lib/arel/nodes/descending.rb +23 -0
- data/lib/arel/nodes/equality.rb +18 -0
- data/lib/arel/nodes/extract.rb +24 -0
- data/lib/arel/nodes/false.rb +16 -0
- data/lib/arel/nodes/full_outer_join.rb +8 -0
- data/lib/arel/nodes/function.rb +44 -0
- data/lib/arel/nodes/grouping.rb +8 -0
- data/lib/arel/nodes/in.rb +8 -0
- data/lib/arel/nodes/infix_operation.rb +80 -0
- data/lib/arel/nodes/inner_join.rb +8 -0
- data/lib/arel/nodes/insert_statement.rb +37 -0
- data/lib/arel/nodes/join_source.rb +20 -0
- data/lib/arel/nodes/matches.rb +18 -0
- data/lib/arel/nodes/named_function.rb +23 -0
- data/lib/arel/nodes/node.rb +50 -0
- data/lib/arel/nodes/node_expression.rb +13 -0
- data/lib/arel/nodes/outer_join.rb +8 -0
- data/lib/arel/nodes/over.rb +15 -0
- data/lib/arel/nodes/regexp.rb +16 -0
- data/lib/arel/nodes/right_outer_join.rb +8 -0
- data/lib/arel/nodes/select_core.rb +67 -0
- data/lib/arel/nodes/select_statement.rb +41 -0
- data/lib/arel/nodes/sql_literal.rb +16 -0
- data/lib/arel/nodes/string_join.rb +11 -0
- data/lib/arel/nodes/table_alias.rb +27 -0
- data/lib/arel/nodes/terminal.rb +16 -0
- data/lib/arel/nodes/true.rb +16 -0
- data/lib/arel/nodes/unary.rb +45 -0
- data/lib/arel/nodes/unary_operation.rb +20 -0
- data/lib/arel/nodes/unqualified_column.rb +22 -0
- data/lib/arel/nodes/update_statement.rb +41 -0
- data/lib/arel/nodes/values_list.rb +9 -0
- data/lib/arel/nodes/window.rb +126 -0
- data/lib/arel/nodes/with.rb +11 -0
- data/lib/arel/order_predications.rb +13 -0
- data/lib/arel/predications.rb +256 -0
- data/lib/arel/select_manager.rb +271 -0
- data/lib/arel/table.rb +110 -0
- data/lib/arel/tree_manager.rb +72 -0
- data/lib/arel/update_manager.rb +34 -0
- data/lib/arel/visitors.rb +20 -0
- data/lib/arel/visitors/depth_first.rb +203 -0
- data/lib/arel/visitors/dot.rb +296 -0
- data/lib/arel/visitors/ibm_db.rb +34 -0
- data/lib/arel/visitors/informix.rb +62 -0
- data/lib/arel/visitors/mssql.rb +156 -0
- data/lib/arel/visitors/mysql.rb +83 -0
- data/lib/arel/visitors/oracle.rb +158 -0
- data/lib/arel/visitors/oracle12.rb +65 -0
- data/lib/arel/visitors/postgresql.rb +109 -0
- data/lib/arel/visitors/sqlite.rb +38 -0
- data/lib/arel/visitors/to_sql.rb +888 -0
- data/lib/arel/visitors/visitor.rb +45 -0
- data/lib/arel/visitors/where_sql.rb +22 -0
- data/lib/arel/window_predications.rb +9 -0
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
- data/lib/rails/generators/active_record/migration.rb +14 -2
- data/lib/rails/generators/active_record/migration/migration_generator.rb +2 -5
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +1 -1
- data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +4 -2
- data/lib/rails/generators/active_record/model/model_generator.rb +1 -1
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +10 -1
- metadata +115 -29
- data/lib/active_record/collection_cache_key.rb +0 -53
@@ -40,15 +40,16 @@ module ActiveRecord
|
|
40
40
|
include ActiveModel::Validations
|
41
41
|
|
42
42
|
# The validation process on save can be skipped by passing <tt>validate: false</tt>.
|
43
|
+
# The validation context can be changed by passing <tt>context: context</tt>.
|
43
44
|
# The regular {ActiveRecord::Base#save}[rdoc-ref:Persistence#save] method is replaced
|
44
45
|
# with this when the validations module is mixed in, which it is by default.
|
45
|
-
def save(options
|
46
|
+
def save(**options)
|
46
47
|
perform_validations(options) ? super : false
|
47
48
|
end
|
48
49
|
|
49
50
|
# Attempts to save the record just like {ActiveRecord::Base#save}[rdoc-ref:Base#save] but
|
50
51
|
# will raise an ActiveRecord::RecordInvalid exception instead of returning +false+ if the record is not valid.
|
51
|
-
def save!(options
|
52
|
+
def save!(**options)
|
52
53
|
perform_validations(options) ? super : raise_validation_error
|
53
54
|
end
|
54
55
|
|
@@ -71,7 +72,6 @@ module ActiveRecord
|
|
71
72
|
alias_method :validate, :valid?
|
72
73
|
|
73
74
|
private
|
74
|
-
|
75
75
|
def default_validation_context
|
76
76
|
new_record? ? :create : :update
|
77
77
|
end
|
@@ -5,12 +5,11 @@ module ActiveRecord
|
|
5
5
|
class AssociatedValidator < ActiveModel::EachValidator #:nodoc:
|
6
6
|
def validate_each(record, attribute, value)
|
7
7
|
if Array(value).reject { |r| valid_object?(r) }.any?
|
8
|
-
record.errors.add(attribute, :invalid, options.merge(value: value))
|
8
|
+
record.errors.add(attribute, :invalid, **options.merge(value: value))
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
12
|
private
|
13
|
-
|
14
13
|
def valid_object?(record)
|
15
14
|
(record.respond_to?(:marked_for_destruction?) && record.marked_for_destruction?) || record.valid?
|
16
15
|
end
|
@@ -12,7 +12,7 @@ module ActiveRecord
|
|
12
12
|
raise ArgumentError, "#{options[:scope]} is not supported format for :scope option. " \
|
13
13
|
"Pass a symbol or an array of symbols instead: `scope: :user_id`"
|
14
14
|
end
|
15
|
-
super
|
15
|
+
super
|
16
16
|
@klass = options[:class]
|
17
17
|
end
|
18
18
|
|
@@ -25,7 +25,7 @@ module ActiveRecord
|
|
25
25
|
if finder_class.primary_key
|
26
26
|
relation = relation.where.not(finder_class.primary_key => record.id_in_database)
|
27
27
|
else
|
28
|
-
raise UnknownPrimaryKey.new(finder_class, "
|
28
|
+
raise UnknownPrimaryKey.new(finder_class, "Cannot validate uniqueness for persisted record without primary key.")
|
29
29
|
end
|
30
30
|
end
|
31
31
|
relation = scope_relation(record, relation)
|
@@ -56,33 +56,21 @@ module ActiveRecord
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def build_relation(klass, attribute, value)
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
59
|
+
relation = klass.unscoped
|
60
|
+
comparison = relation.bind_attribute(attribute, value) do |attr, bind|
|
61
|
+
return relation.none! if bind.unboundable?
|
62
|
+
|
63
|
+
if !options.key?(:case_sensitive) || bind.nil?
|
64
|
+
klass.connection.default_uniqueness_comparison(attr, bind, klass)
|
65
|
+
elsif options[:case_sensitive]
|
66
|
+
klass.connection.case_sensitive_comparison(attr, bind)
|
67
|
+
else
|
68
|
+
# will use SQL LOWER function before comparison, unless it detects a case insensitive collation
|
69
|
+
klass.connection.case_insensitive_comparison(attr, bind)
|
70
|
+
end
|
71
71
|
end
|
72
72
|
|
73
|
-
|
74
|
-
value = klass.predicate_builder.build_bind_attribute(attribute_name, value)
|
75
|
-
|
76
|
-
table = klass.arel_table
|
77
|
-
column = klass.columns_hash[attribute_name]
|
78
|
-
|
79
|
-
comparison = if !options[:case_sensitive]
|
80
|
-
# will use SQL LOWER function before comparison, unless it detects a case insensitive collation
|
81
|
-
klass.connection.case_insensitive_comparison(table, attribute, column, value)
|
82
|
-
else
|
83
|
-
klass.connection.case_sensitive_comparison(table, attribute, column, value)
|
84
|
-
end
|
85
|
-
klass.unscoped.where!(comparison)
|
73
|
+
relation.where!(comparison)
|
86
74
|
end
|
87
75
|
|
88
76
|
def scope_relation(record, relation)
|
data/lib/arel.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "arel/errors"
|
4
|
+
|
5
|
+
require "arel/crud"
|
6
|
+
require "arel/factory_methods"
|
7
|
+
|
8
|
+
require "arel/expressions"
|
9
|
+
require "arel/predications"
|
10
|
+
require "arel/window_predications"
|
11
|
+
require "arel/math"
|
12
|
+
require "arel/alias_predication"
|
13
|
+
require "arel/order_predications"
|
14
|
+
require "arel/table"
|
15
|
+
require "arel/attributes"
|
16
|
+
|
17
|
+
require "arel/visitors"
|
18
|
+
require "arel/collectors/sql_string"
|
19
|
+
|
20
|
+
require "arel/tree_manager"
|
21
|
+
require "arel/insert_manager"
|
22
|
+
require "arel/select_manager"
|
23
|
+
require "arel/update_manager"
|
24
|
+
require "arel/delete_manager"
|
25
|
+
require "arel/nodes"
|
26
|
+
|
27
|
+
module Arel
|
28
|
+
VERSION = "10.0.0"
|
29
|
+
|
30
|
+
# Wrap a known-safe SQL string for passing to query methods, e.g.
|
31
|
+
#
|
32
|
+
# Post.order(Arel.sql("length(title)")).last
|
33
|
+
#
|
34
|
+
# Great caution should be taken to avoid SQL injection vulnerabilities.
|
35
|
+
# This method should not be used with unsafe values such as request
|
36
|
+
# parameters or model attributes.
|
37
|
+
def self.sql(raw_sql)
|
38
|
+
Arel::Nodes::SqlLiteral.new raw_sql
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.star # :nodoc:
|
42
|
+
sql "*"
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.arel_node?(value) # :nodoc:
|
46
|
+
value.is_a?(Arel::Node) || value.is_a?(Arel::Attribute) || value.is_a?(Arel::Nodes::SqlLiteral)
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.fetch_attribute(value) # :nodoc:
|
50
|
+
case value
|
51
|
+
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
|
52
|
+
if value.left.is_a?(Arel::Attributes::Attribute)
|
53
|
+
yield value.left
|
54
|
+
elsif value.right.is_a?(Arel::Attributes::Attribute)
|
55
|
+
yield value.right
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
## Convenience Alias
|
61
|
+
Node = Arel::Nodes::Node # :nodoc:
|
62
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "arel/attributes/attribute"
|
4
|
+
|
5
|
+
module Arel # :nodoc: all
|
6
|
+
module Attributes
|
7
|
+
###
|
8
|
+
# Factory method to wrap a raw database +column+ to an Arel Attribute.
|
9
|
+
def self.for(column)
|
10
|
+
case column.type
|
11
|
+
when :string, :text, :binary then String
|
12
|
+
when :integer then Integer
|
13
|
+
when :float then Float
|
14
|
+
when :decimal then Decimal
|
15
|
+
when :date, :datetime, :timestamp, :time then Time
|
16
|
+
when :boolean then Boolean
|
17
|
+
else
|
18
|
+
Undefined
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Arel # :nodoc: all
|
4
|
+
module Attributes
|
5
|
+
class Attribute < Struct.new :relation, :name
|
6
|
+
include Arel::Expressions
|
7
|
+
include Arel::Predications
|
8
|
+
include Arel::AliasPredication
|
9
|
+
include Arel::OrderPredications
|
10
|
+
include Arel::Math
|
11
|
+
|
12
|
+
###
|
13
|
+
# Create a node for lowering this attribute
|
14
|
+
def lower
|
15
|
+
relation.lower self
|
16
|
+
end
|
17
|
+
|
18
|
+
def type_cast_for_database(value)
|
19
|
+
relation.type_cast_for_database(name, value)
|
20
|
+
end
|
21
|
+
|
22
|
+
def able_to_type_cast?
|
23
|
+
relation.able_to_type_cast?
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class String < Attribute; end
|
28
|
+
class Time < Attribute; end
|
29
|
+
class Boolean < Attribute; end
|
30
|
+
class Decimal < Attribute; end
|
31
|
+
class Float < Attribute; end
|
32
|
+
class Integer < Attribute; end
|
33
|
+
class Undefined < Attribute; end
|
34
|
+
end
|
35
|
+
|
36
|
+
Attribute = Attributes::Attribute
|
37
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Arel # :nodoc: all
|
4
|
+
module Collectors
|
5
|
+
class Bind
|
6
|
+
def initialize
|
7
|
+
@binds = []
|
8
|
+
end
|
9
|
+
|
10
|
+
def <<(str)
|
11
|
+
self
|
12
|
+
end
|
13
|
+
|
14
|
+
def add_bind(bind)
|
15
|
+
@binds << bind
|
16
|
+
self
|
17
|
+
end
|
18
|
+
|
19
|
+
def value
|
20
|
+
@binds
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Arel # :nodoc: all
|
4
|
+
module Collectors
|
5
|
+
class Composite
|
6
|
+
def initialize(left, right)
|
7
|
+
@left = left
|
8
|
+
@right = right
|
9
|
+
end
|
10
|
+
|
11
|
+
def <<(str)
|
12
|
+
left << str
|
13
|
+
right << str
|
14
|
+
self
|
15
|
+
end
|
16
|
+
|
17
|
+
def add_bind(bind, &block)
|
18
|
+
left.add_bind bind, &block
|
19
|
+
right.add_bind bind, &block
|
20
|
+
self
|
21
|
+
end
|
22
|
+
|
23
|
+
def value
|
24
|
+
[left.value, right.value]
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
attr_reader :left, :right
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "arel/collectors/plain_string"
|
4
|
+
|
5
|
+
module Arel # :nodoc: all
|
6
|
+
module Collectors
|
7
|
+
class SQLString < PlainString
|
8
|
+
def initialize(*)
|
9
|
+
super
|
10
|
+
@bind_index = 1
|
11
|
+
end
|
12
|
+
|
13
|
+
def add_bind(bind)
|
14
|
+
self << yield(@bind_index)
|
15
|
+
@bind_index += 1
|
16
|
+
self
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Arel # :nodoc: all
|
4
|
+
module Collectors
|
5
|
+
class SubstituteBinds
|
6
|
+
def initialize(quoter, delegate_collector)
|
7
|
+
@quoter = quoter
|
8
|
+
@delegate = delegate_collector
|
9
|
+
end
|
10
|
+
|
11
|
+
def <<(str)
|
12
|
+
delegate << str
|
13
|
+
self
|
14
|
+
end
|
15
|
+
|
16
|
+
def add_bind(bind)
|
17
|
+
self << quoter.quote(bind)
|
18
|
+
end
|
19
|
+
|
20
|
+
def value
|
21
|
+
delegate.value
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
attr_reader :quoter, :delegate
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/arel/crud.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Arel # :nodoc: all
|
4
|
+
###
|
5
|
+
# FIXME hopefully we can remove this
|
6
|
+
module Crud
|
7
|
+
def compile_update(values, pk)
|
8
|
+
um = UpdateManager.new
|
9
|
+
|
10
|
+
if Nodes::SqlLiteral === values
|
11
|
+
relation = @ctx.from
|
12
|
+
else
|
13
|
+
relation = values.first.first.relation
|
14
|
+
end
|
15
|
+
um.key = pk
|
16
|
+
um.table relation
|
17
|
+
um.set values
|
18
|
+
um.take @ast.limit.expr if @ast.limit
|
19
|
+
um.order(*@ast.orders)
|
20
|
+
um.wheres = @ctx.wheres
|
21
|
+
um
|
22
|
+
end
|
23
|
+
|
24
|
+
def compile_insert(values)
|
25
|
+
im = create_insert
|
26
|
+
im.insert values
|
27
|
+
im
|
28
|
+
end
|
29
|
+
|
30
|
+
def create_insert
|
31
|
+
InsertManager.new
|
32
|
+
end
|
33
|
+
|
34
|
+
def compile_delete
|
35
|
+
dm = DeleteManager.new
|
36
|
+
dm.take @ast.limit.expr if @ast.limit
|
37
|
+
dm.wheres = @ctx.wheres
|
38
|
+
dm.from @ctx.froms
|
39
|
+
dm
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Arel # :nodoc: all
|
4
|
+
class DeleteManager < Arel::TreeManager
|
5
|
+
include TreeManager::StatementMethods
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
super
|
9
|
+
@ast = Nodes::DeleteStatement.new
|
10
|
+
@ctx = @ast
|
11
|
+
end
|
12
|
+
|
13
|
+
def from(relation)
|
14
|
+
@ast.relation = relation
|
15
|
+
self
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|