activerecord 6.0.0 → 6.1.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +872 -582
- data/MIT-LICENSE +1 -1
- data/README.rdoc +3 -3
- data/lib/active_record.rb +7 -13
- data/lib/active_record/aggregations.rb +1 -2
- data/lib/active_record/association_relation.rb +22 -12
- data/lib/active_record/associations.rb +116 -13
- data/lib/active_record/associations/alias_tracker.rb +19 -16
- data/lib/active_record/associations/association.rb +49 -29
- data/lib/active_record/associations/association_scope.rb +17 -15
- data/lib/active_record/associations/belongs_to_association.rb +15 -5
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +1 -1
- data/lib/active_record/associations/builder/association.rb +9 -3
- data/lib/active_record/associations/builder/belongs_to.rb +10 -7
- data/lib/active_record/associations/builder/collection_association.rb +5 -4
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +0 -3
- data/lib/active_record/associations/builder/has_many.rb +6 -2
- data/lib/active_record/associations/builder/has_one.rb +11 -14
- data/lib/active_record/associations/builder/singular_association.rb +1 -1
- data/lib/active_record/associations/collection_association.rb +25 -8
- data/lib/active_record/associations/collection_proxy.rb +14 -7
- data/lib/active_record/associations/foreign_association.rb +13 -0
- data/lib/active_record/associations/has_many_association.rb +24 -3
- data/lib/active_record/associations/has_many_through_association.rb +10 -4
- data/lib/active_record/associations/has_one_association.rb +15 -1
- data/lib/active_record/associations/join_dependency.rb +77 -42
- data/lib/active_record/associations/join_dependency/join_association.rb +36 -14
- data/lib/active_record/associations/join_dependency/join_part.rb +3 -3
- data/lib/active_record/associations/preloader.rb +13 -8
- data/lib/active_record/associations/preloader/association.rb +51 -25
- data/lib/active_record/associations/preloader/through_association.rb +2 -2
- data/lib/active_record/associations/singular_association.rb +1 -1
- data/lib/active_record/associations/through_association.rb +1 -1
- data/lib/active_record/attribute_assignment.rb +10 -9
- data/lib/active_record/attribute_methods.rb +64 -54
- data/lib/active_record/attribute_methods/before_type_cast.rb +13 -10
- data/lib/active_record/attribute_methods/dirty.rb +3 -13
- data/lib/active_record/attribute_methods/primary_key.rb +6 -4
- data/lib/active_record/attribute_methods/query.rb +3 -6
- data/lib/active_record/attribute_methods/read.rb +8 -12
- data/lib/active_record/attribute_methods/serialization.rb +11 -6
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +12 -15
- data/lib/active_record/attribute_methods/write.rb +12 -21
- data/lib/active_record/attributes.rb +32 -8
- data/lib/active_record/autosave_association.rb +63 -44
- data/lib/active_record/base.rb +2 -14
- data/lib/active_record/callbacks.rb +153 -24
- data/lib/active_record/coders/yaml_column.rb +1 -2
- data/lib/active_record/connection_adapters.rb +50 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +202 -138
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +2 -44
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +86 -37
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +4 -9
- data/lib/active_record/connection_adapters/abstract/quoting.rb +34 -34
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +152 -116
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +137 -52
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +3 -3
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +263 -107
- data/lib/active_record/connection_adapters/abstract/transaction.rb +82 -35
- data/lib/active_record/connection_adapters/abstract_adapter.rb +74 -76
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +149 -115
- data/lib/active_record/connection_adapters/column.rb +15 -1
- data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
- data/lib/active_record/connection_adapters/legacy_pool_manager.rb +31 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +30 -36
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -2
- data/lib/active_record/connection_adapters/mysql/quoting.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +32 -7
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +8 -0
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +17 -13
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +10 -1
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +31 -13
- data/lib/active_record/connection_adapters/pool_config.rb +63 -0
- data/lib/active_record/connection_adapters/pool_manager.rb +43 -0
- data/lib/active_record/connection_adapters/postgresql/column.rb +24 -1
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +21 -56
- data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -5
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +10 -2
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -3
- data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
- data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -3
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +24 -6
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +11 -2
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +4 -4
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +7 -3
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +72 -54
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +8 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +81 -57
- data/lib/active_record/connection_adapters/schema_cache.rb +98 -15
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +10 -0
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +38 -12
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +1 -2
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -1
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +38 -5
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +61 -57
- data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
- data/lib/active_record/connection_handling.rb +211 -81
- data/lib/active_record/core.rb +237 -69
- data/lib/active_record/counter_cache.rb +4 -1
- data/lib/active_record/database_configurations.rb +124 -85
- data/lib/active_record/database_configurations/connection_url_resolver.rb +98 -0
- data/lib/active_record/database_configurations/database_config.rb +52 -9
- data/lib/active_record/database_configurations/hash_config.rb +54 -8
- data/lib/active_record/database_configurations/url_config.rb +15 -41
- data/lib/active_record/delegated_type.rb +209 -0
- data/lib/active_record/destroy_association_async_job.rb +36 -0
- data/lib/active_record/dynamic_matchers.rb +2 -3
- data/lib/active_record/enum.rb +40 -16
- data/lib/active_record/errors.rb +47 -12
- data/lib/active_record/explain.rb +9 -5
- data/lib/active_record/explain_subscriber.rb +1 -1
- data/lib/active_record/fixture_set/file.rb +10 -17
- data/lib/active_record/fixture_set/model_metadata.rb +1 -2
- data/lib/active_record/fixture_set/render_context.rb +1 -1
- data/lib/active_record/fixture_set/table_row.rb +2 -3
- data/lib/active_record/fixture_set/table_rows.rb +0 -1
- data/lib/active_record/fixtures.rb +54 -11
- data/lib/active_record/gem_version.rb +1 -1
- data/lib/active_record/inheritance.rb +40 -21
- data/lib/active_record/insert_all.rb +39 -10
- data/lib/active_record/integration.rb +3 -5
- data/lib/active_record/internal_metadata.rb +16 -7
- data/lib/active_record/legacy_yaml_adapter.rb +7 -3
- data/lib/active_record/locking/optimistic.rb +22 -17
- data/lib/active_record/locking/pessimistic.rb +6 -2
- data/lib/active_record/log_subscriber.rb +27 -9
- data/lib/active_record/middleware/database_selector.rb +4 -2
- data/lib/active_record/middleware/database_selector/resolver.rb +14 -14
- data/lib/active_record/middleware/database_selector/resolver/session.rb +3 -0
- data/lib/active_record/migration.rb +114 -84
- data/lib/active_record/migration/command_recorder.rb +53 -45
- data/lib/active_record/migration/compatibility.rb +70 -20
- data/lib/active_record/migration/join_table.rb +0 -1
- data/lib/active_record/model_schema.rb +120 -15
- data/lib/active_record/nested_attributes.rb +2 -5
- data/lib/active_record/no_touching.rb +1 -1
- data/lib/active_record/null_relation.rb +0 -1
- data/lib/active_record/persistence.rb +50 -46
- data/lib/active_record/query_cache.rb +15 -5
- data/lib/active_record/querying.rb +12 -7
- data/lib/active_record/railtie.rb +65 -45
- data/lib/active_record/railties/databases.rake +267 -93
- data/lib/active_record/readonly_attributes.rb +4 -0
- data/lib/active_record/reflection.rb +77 -63
- data/lib/active_record/relation.rb +108 -67
- data/lib/active_record/relation/batches.rb +38 -32
- data/lib/active_record/relation/batches/batch_enumerator.rb +25 -9
- data/lib/active_record/relation/calculations.rb +102 -45
- data/lib/active_record/relation/delegation.rb +9 -7
- data/lib/active_record/relation/finder_methods.rb +55 -17
- data/lib/active_record/relation/from_clause.rb +5 -1
- data/lib/active_record/relation/merger.rb +27 -26
- data/lib/active_record/relation/predicate_builder.rb +55 -35
- data/lib/active_record/relation/predicate_builder/array_handler.rb +8 -9
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +4 -5
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +3 -3
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
- data/lib/active_record/relation/query_methods.rb +340 -180
- data/lib/active_record/relation/record_fetch_warning.rb +3 -3
- data/lib/active_record/relation/spawn_methods.rb +8 -8
- data/lib/active_record/relation/where_clause.rb +104 -58
- data/lib/active_record/result.rb +41 -34
- data/lib/active_record/runtime_registry.rb +2 -2
- data/lib/active_record/sanitization.rb +6 -17
- data/lib/active_record/schema_dumper.rb +34 -4
- data/lib/active_record/schema_migration.rb +2 -8
- data/lib/active_record/scoping.rb +0 -1
- data/lib/active_record/scoping/default.rb +0 -1
- data/lib/active_record/scoping/named.rb +7 -18
- data/lib/active_record/secure_token.rb +16 -8
- data/lib/active_record/serialization.rb +5 -3
- data/lib/active_record/signed_id.rb +116 -0
- data/lib/active_record/statement_cache.rb +20 -4
- data/lib/active_record/store.rb +3 -3
- data/lib/active_record/suppressor.rb +2 -2
- data/lib/active_record/table_metadata.rb +39 -36
- data/lib/active_record/tasks/database_tasks.rb +139 -113
- data/lib/active_record/tasks/mysql_database_tasks.rb +34 -36
- data/lib/active_record/tasks/postgresql_database_tasks.rb +24 -27
- data/lib/active_record/tasks/sqlite_database_tasks.rb +13 -10
- data/lib/active_record/test_databases.rb +5 -4
- data/lib/active_record/test_fixtures.rb +38 -16
- data/lib/active_record/timestamp.rb +4 -7
- data/lib/active_record/touch_later.rb +20 -21
- data/lib/active_record/transactions.rb +22 -71
- data/lib/active_record/type.rb +8 -2
- data/lib/active_record/type/adapter_specific_registry.rb +2 -5
- data/lib/active_record/type/hash_lookup_type_map.rb +0 -1
- data/lib/active_record/type/serialized.rb +6 -3
- data/lib/active_record/type/time.rb +10 -0
- data/lib/active_record/type/type_map.rb +0 -1
- data/lib/active_record/type/unsigned_integer.rb +0 -1
- data/lib/active_record/type_caster/connection.rb +0 -1
- data/lib/active_record/type_caster/map.rb +8 -5
- data/lib/active_record/validations.rb +3 -3
- data/lib/active_record/validations/associated.rb +1 -2
- data/lib/active_record/validations/numericality.rb +35 -0
- data/lib/active_record/validations/uniqueness.rb +24 -4
- data/lib/arel.rb +15 -12
- data/lib/arel/attributes/attribute.rb +4 -0
- data/lib/arel/collectors/bind.rb +5 -0
- data/lib/arel/collectors/composite.rb +8 -0
- data/lib/arel/collectors/sql_string.rb +7 -0
- data/lib/arel/collectors/substitute_binds.rb +7 -0
- data/lib/arel/nodes.rb +3 -1
- data/lib/arel/nodes/binary.rb +82 -8
- data/lib/arel/nodes/bind_param.rb +8 -0
- data/lib/arel/nodes/casted.rb +21 -9
- data/lib/arel/nodes/equality.rb +6 -9
- data/lib/arel/nodes/grouping.rb +3 -0
- data/lib/arel/nodes/homogeneous_in.rb +72 -0
- data/lib/arel/nodes/in.rb +8 -1
- data/lib/arel/nodes/infix_operation.rb +13 -1
- data/lib/arel/nodes/join_source.rb +1 -1
- data/lib/arel/nodes/node.rb +7 -6
- data/lib/arel/nodes/ordering.rb +27 -0
- data/lib/arel/nodes/sql_literal.rb +3 -0
- data/lib/arel/nodes/table_alias.rb +7 -3
- data/lib/arel/nodes/unary.rb +0 -1
- data/lib/arel/predications.rb +17 -24
- data/lib/arel/select_manager.rb +1 -2
- data/lib/arel/table.rb +13 -5
- data/lib/arel/visitors.rb +0 -7
- data/lib/arel/visitors/dot.rb +14 -3
- data/lib/arel/visitors/mysql.rb +11 -1
- data/lib/arel/visitors/postgresql.rb +15 -5
- data/lib/arel/visitors/sqlite.rb +0 -1
- data/lib/arel/visitors/to_sql.rb +89 -79
- data/lib/arel/visitors/visitor.rb +0 -1
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
- data/lib/rails/generators/active_record/migration.rb +6 -2
- data/lib/rails/generators/active_record/migration/migration_generator.rb +1 -0
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +2 -0
- data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +4 -4
- data/lib/rails/generators/active_record/model/model_generator.rb +38 -2
- data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
- metadata +27 -24
- data/lib/active_record/attribute_decorators.rb +0 -90
- data/lib/active_record/connection_adapters/connection_specification.rb +0 -297
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -29
- data/lib/active_record/define_callbacks.rb +0 -22
- data/lib/active_record/railties/collection_cache_association_loading.rb +0 -34
- data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -18
- data/lib/active_record/relation/where_clause_factory.rb +0 -33
- data/lib/arel/attributes.rb +0 -22
- data/lib/arel/visitors/depth_first.rb +0 -204
- data/lib/arel/visitors/ibm_db.rb +0 -34
- data/lib/arel/visitors/informix.rb +0 -62
- data/lib/arel/visitors/mssql.rb +0 -157
- data/lib/arel/visitors/oracle.rb +0 -159
- data/lib/arel/visitors/oracle12.rb +0 -66
- data/lib/arel/visitors/where_sql.rb +0 -23
data/lib/arel/visitors/mysql.rb
CHANGED
@@ -15,7 +15,9 @@ module Arel # :nodoc: all
|
|
15
15
|
|
16
16
|
###
|
17
17
|
# :'(
|
18
|
-
#
|
18
|
+
# To retrieve all rows from a certain offset up to the end of the result set,
|
19
|
+
# you can use some large number for the second parameter.
|
20
|
+
# https://dev.mysql.com/doc/refman/en/select.html
|
19
21
|
def visit_Arel_Nodes_SelectStatement(o, collector)
|
20
22
|
if o.offset && !o.limit
|
21
23
|
o.limit = Arel::Nodes::Limit.new(18446744073709551615)
|
@@ -48,6 +50,14 @@ module Arel # :nodoc: all
|
|
48
50
|
visit_Arel_Nodes_IsNotDistinctFrom o, collector
|
49
51
|
end
|
50
52
|
|
53
|
+
def visit_Arel_Nodes_Regexp(o, collector)
|
54
|
+
infix_value o, collector, " REGEXP "
|
55
|
+
end
|
56
|
+
|
57
|
+
def visit_Arel_Nodes_NotRegexp(o, collector)
|
58
|
+
infix_value o, collector, " NOT REGEXP "
|
59
|
+
end
|
60
|
+
|
51
61
|
# In the simple case, MySQL allows us to place JOINs directly into the UPDATE
|
52
62
|
# query. However, this does not allow for LIMIT, OFFSET and ORDER. To support
|
53
63
|
# these, we must use a subquery.
|
@@ -4,7 +4,6 @@ module Arel # :nodoc: all
|
|
4
4
|
module Visitors
|
5
5
|
class PostgreSQL < Arel::Visitors::ToSql
|
6
6
|
private
|
7
|
-
|
8
7
|
def visit_Arel_Nodes_Matches(o, collector)
|
9
8
|
op = o.case_sensitive ? " LIKE " : " ILIKE "
|
10
9
|
collector = infix_value o, collector, op
|
@@ -42,10 +41,6 @@ module Arel # :nodoc: all
|
|
42
41
|
visit(o.expr, collector) << " )"
|
43
42
|
end
|
44
43
|
|
45
|
-
def visit_Arel_Nodes_BindParam(o, collector)
|
46
|
-
collector.add_bind(o.value) { |i| "$#{i}" }
|
47
|
-
end
|
48
|
-
|
49
44
|
def visit_Arel_Nodes_GroupingElement(o, collector)
|
50
45
|
collector << "( "
|
51
46
|
visit(o.expr, collector) << " )"
|
@@ -83,6 +78,21 @@ module Arel # :nodoc: all
|
|
83
78
|
visit o.right, collector
|
84
79
|
end
|
85
80
|
|
81
|
+
def visit_Arel_Nodes_NullsFirst(o, collector)
|
82
|
+
visit o.expr, collector
|
83
|
+
collector << " NULLS FIRST"
|
84
|
+
end
|
85
|
+
|
86
|
+
def visit_Arel_Nodes_NullsLast(o, collector)
|
87
|
+
visit o.expr, collector
|
88
|
+
collector << " NULLS LAST"
|
89
|
+
end
|
90
|
+
|
91
|
+
BIND_BLOCK = proc { |i| "$#{i}" }
|
92
|
+
private_constant :BIND_BLOCK
|
93
|
+
|
94
|
+
def bind_block; BIND_BLOCK; end
|
95
|
+
|
86
96
|
# Used by Lateral visitor to enclose select queries in parentheses
|
87
97
|
def grouping_parentheses(o, collector)
|
88
98
|
if o.expr.is_a? Nodes::SelectStatement
|
data/lib/arel/visitors/sqlite.rb
CHANGED
data/lib/arel/visitors/to_sql.rb
CHANGED
@@ -19,7 +19,6 @@ module Arel # :nodoc: all
|
|
19
19
|
end
|
20
20
|
|
21
21
|
private
|
22
|
-
|
23
22
|
def visit_Arel_Nodes_DeleteStatement(o, collector)
|
24
23
|
o = prepare_delete_statement(o)
|
25
24
|
|
@@ -83,12 +82,9 @@ module Arel # :nodoc: all
|
|
83
82
|
end
|
84
83
|
|
85
84
|
def visit_Arel_Nodes_Casted(o, collector)
|
86
|
-
collector <<
|
87
|
-
end
|
88
|
-
|
89
|
-
def visit_Arel_Nodes_Quoted(o, collector)
|
90
|
-
collector << quoted(o.expr, nil).to_s
|
85
|
+
collector << quote(o.value_for_database).to_s
|
91
86
|
end
|
87
|
+
alias :visit_Arel_Nodes_Quoted :visit_Arel_Nodes_Casted
|
92
88
|
|
93
89
|
def visit_Arel_Nodes_True(o, collector)
|
94
90
|
collector << "TRUE"
|
@@ -196,12 +192,12 @@ module Arel # :nodoc: all
|
|
196
192
|
|
197
193
|
def visit_Arel_Nodes_With(o, collector)
|
198
194
|
collector << "WITH "
|
199
|
-
|
195
|
+
collect_ctes(o.children, collector)
|
200
196
|
end
|
201
197
|
|
202
198
|
def visit_Arel_Nodes_WithRecursive(o, collector)
|
203
199
|
collector << "WITH RECURSIVE "
|
204
|
-
|
200
|
+
collect_ctes(o.children, collector)
|
205
201
|
end
|
206
202
|
|
207
203
|
def visit_Arel_Nodes_Union(o, collector)
|
@@ -325,6 +321,29 @@ module Arel # :nodoc: all
|
|
325
321
|
end
|
326
322
|
end
|
327
323
|
|
324
|
+
def visit_Arel_Nodes_HomogeneousIn(o, collector)
|
325
|
+
collector.preparable = false
|
326
|
+
|
327
|
+
collector << quote_table_name(o.table_name) << "." << quote_column_name(o.column_name)
|
328
|
+
|
329
|
+
if o.type == :in
|
330
|
+
collector << " IN ("
|
331
|
+
else
|
332
|
+
collector << " NOT IN ("
|
333
|
+
end
|
334
|
+
|
335
|
+
values = o.casted_values
|
336
|
+
|
337
|
+
if values.empty?
|
338
|
+
collector << @connection.quote(nil)
|
339
|
+
else
|
340
|
+
collector.add_binds(values, &bind_block)
|
341
|
+
end
|
342
|
+
|
343
|
+
collector << ")"
|
344
|
+
collector
|
345
|
+
end
|
346
|
+
|
328
347
|
def visit_Arel_SelectManager(o, collector)
|
329
348
|
collector << "("
|
330
349
|
visit(o.ast, collector) << ")"
|
@@ -514,64 +533,35 @@ module Arel # :nodoc: all
|
|
514
533
|
end
|
515
534
|
|
516
535
|
def visit_Arel_Nodes_In(o, collector)
|
517
|
-
|
518
|
-
|
519
|
-
end
|
520
|
-
|
521
|
-
unless o.right.empty?
|
522
|
-
o.right.delete_if { |value| unboundable?(value) }
|
523
|
-
end
|
524
|
-
|
525
|
-
return collector << "1=0" if o.right.empty?
|
526
|
-
|
527
|
-
in_clause_length = @connection.in_clause_length
|
536
|
+
collector.preparable = false
|
537
|
+
attr, values = o.left, o.right
|
528
538
|
|
529
|
-
if
|
530
|
-
|
531
|
-
|
532
|
-
collector << "("
|
533
|
-
o.right.each_slice(in_clause_length).each_with_index do |right, i|
|
534
|
-
collector << " OR " unless i == 0
|
535
|
-
collect_in_clause(o.left, right, collector)
|
539
|
+
if Array === values
|
540
|
+
unless values.empty?
|
541
|
+
values.delete_if { |value| unboundable?(value) }
|
536
542
|
end
|
537
|
-
|
543
|
+
|
544
|
+
return collector << "1=0" if values.empty?
|
538
545
|
end
|
539
|
-
end
|
540
546
|
|
541
|
-
|
542
|
-
|
543
|
-
collector << " IN ("
|
544
|
-
visit(right, collector) << ")"
|
547
|
+
visit(attr, collector) << " IN ("
|
548
|
+
visit(values, collector) << ")"
|
545
549
|
end
|
546
550
|
|
547
551
|
def visit_Arel_Nodes_NotIn(o, collector)
|
548
|
-
|
549
|
-
|
550
|
-
end
|
551
|
-
|
552
|
-
unless o.right.empty?
|
553
|
-
o.right.delete_if { |value| unboundable?(value) }
|
554
|
-
end
|
555
|
-
|
556
|
-
return collector << "1=1" if o.right.empty?
|
552
|
+
collector.preparable = false
|
553
|
+
attr, values = o.left, o.right
|
557
554
|
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
collect_not_in_clause(o.left, o.right, collector)
|
562
|
-
else
|
563
|
-
o.right.each_slice(in_clause_length).each_with_index do |right, i|
|
564
|
-
collector << " AND " unless i == 0
|
565
|
-
collect_not_in_clause(o.left, right, collector)
|
555
|
+
if Array === values
|
556
|
+
unless values.empty?
|
557
|
+
values.delete_if { |value| unboundable?(value) }
|
566
558
|
end
|
567
|
-
|
559
|
+
|
560
|
+
return collector << "1=1" if values.empty?
|
568
561
|
end
|
569
|
-
end
|
570
562
|
|
571
|
-
|
572
|
-
|
573
|
-
collector << " NOT IN ("
|
574
|
-
visit(right, collector) << ")"
|
563
|
+
visit(attr, collector) << " NOT IN ("
|
564
|
+
visit(values, collector) << ")"
|
575
565
|
end
|
576
566
|
|
577
567
|
def visit_Arel_Nodes_And(o, collector)
|
@@ -579,9 +569,18 @@ module Arel # :nodoc: all
|
|
579
569
|
end
|
580
570
|
|
581
571
|
def visit_Arel_Nodes_Or(o, collector)
|
582
|
-
|
583
|
-
|
584
|
-
|
572
|
+
stack = [o.right, o.left]
|
573
|
+
|
574
|
+
while o = stack.pop
|
575
|
+
if o.is_a?(Arel::Nodes::Or)
|
576
|
+
stack.push o.right, o.left
|
577
|
+
else
|
578
|
+
visit o, collector
|
579
|
+
collector << " OR " unless stack.empty?
|
580
|
+
end
|
581
|
+
end
|
582
|
+
|
583
|
+
collector
|
585
584
|
end
|
586
585
|
|
587
586
|
def visit_Arel_Nodes_Assignment(o, collector)
|
@@ -690,28 +689,23 @@ module Arel # :nodoc: all
|
|
690
689
|
join_name = o.relation.table_alias || o.relation.name
|
691
690
|
collector << quote_table_name(join_name) << "." << quote_column_name(o.name)
|
692
691
|
end
|
693
|
-
alias :visit_Arel_Attributes_Integer :visit_Arel_Attributes_Attribute
|
694
|
-
alias :visit_Arel_Attributes_Float :visit_Arel_Attributes_Attribute
|
695
|
-
alias :visit_Arel_Attributes_Decimal :visit_Arel_Attributes_Attribute
|
696
|
-
alias :visit_Arel_Attributes_String :visit_Arel_Attributes_Attribute
|
697
|
-
alias :visit_Arel_Attributes_Time :visit_Arel_Attributes_Attribute
|
698
|
-
alias :visit_Arel_Attributes_Boolean :visit_Arel_Attributes_Attribute
|
699
692
|
|
700
|
-
|
693
|
+
BIND_BLOCK = proc { "?" }
|
694
|
+
private_constant :BIND_BLOCK
|
695
|
+
|
696
|
+
def bind_block; BIND_BLOCK; end
|
701
697
|
|
702
698
|
def visit_Arel_Nodes_BindParam(o, collector)
|
703
|
-
collector.add_bind(o.value)
|
699
|
+
collector.add_bind(o.value, &bind_block)
|
704
700
|
end
|
705
701
|
|
706
|
-
|
707
|
-
|
702
|
+
def visit_Arel_Nodes_SqlLiteral(o, collector)
|
703
|
+
collector.preparable = false
|
704
|
+
collector << o.to_s
|
705
|
+
end
|
708
706
|
|
709
|
-
def
|
710
|
-
|
711
|
-
quote(a.type_cast_for_database(o))
|
712
|
-
else
|
713
|
-
quote(o)
|
714
|
-
end
|
707
|
+
def visit_Integer(o, collector)
|
708
|
+
collector << o.to_s
|
715
709
|
end
|
716
710
|
|
717
711
|
def unsupported(o, collector)
|
@@ -739,11 +733,6 @@ module Arel # :nodoc: all
|
|
739
733
|
visit o.right, collector
|
740
734
|
end
|
741
735
|
|
742
|
-
alias :visit_Arel_Nodes_Addition :visit_Arel_Nodes_InfixOperation
|
743
|
-
alias :visit_Arel_Nodes_Subtraction :visit_Arel_Nodes_InfixOperation
|
744
|
-
alias :visit_Arel_Nodes_Multiplication :visit_Arel_Nodes_InfixOperation
|
745
|
-
alias :visit_Arel_Nodes_Division :visit_Arel_Nodes_InfixOperation
|
746
|
-
|
747
736
|
def visit_Arel_Nodes_UnaryOperation(o, collector)
|
748
737
|
collector << " #{o.operator} "
|
749
738
|
visit o.expr, collector
|
@@ -884,6 +873,27 @@ module Arel # :nodoc: all
|
|
884
873
|
collector << " IS NULL)"
|
885
874
|
collector << " THEN 0 ELSE 1 END"
|
886
875
|
end
|
876
|
+
|
877
|
+
def collect_ctes(children, collector)
|
878
|
+
children.each_with_index do |child, i|
|
879
|
+
collector << ", " unless i == 0
|
880
|
+
|
881
|
+
case child
|
882
|
+
when Arel::Nodes::As
|
883
|
+
name = child.left.name
|
884
|
+
relation = child.right
|
885
|
+
when Arel::Nodes::TableAlias
|
886
|
+
name = child.name
|
887
|
+
relation = child.relation
|
888
|
+
end
|
889
|
+
|
890
|
+
collector << quote_table_name(name)
|
891
|
+
collector << " AS "
|
892
|
+
visit relation, collector
|
893
|
+
end
|
894
|
+
|
895
|
+
collector
|
896
|
+
end
|
887
897
|
end
|
888
898
|
end
|
889
899
|
end
|
@@ -17,12 +17,16 @@ module ActiveRecord
|
|
17
17
|
end
|
18
18
|
|
19
19
|
private
|
20
|
-
|
21
20
|
def primary_key_type
|
22
21
|
key_type = options[:primary_key_type]
|
23
22
|
", id: :#{key_type}" if key_type
|
24
23
|
end
|
25
24
|
|
25
|
+
def foreign_key_type
|
26
|
+
key_type = options[:primary_key_type]
|
27
|
+
", type: :#{key_type}" if key_type
|
28
|
+
end
|
29
|
+
|
26
30
|
def db_migrate_path
|
27
31
|
if defined?(Rails.application) && Rails.application
|
28
32
|
configured_migrate_path || default_migrate_path
|
@@ -39,7 +43,7 @@ module ActiveRecord
|
|
39
43
|
return unless database = options[:database]
|
40
44
|
config = ActiveRecord::Base.configurations.configs_for(
|
41
45
|
env_name: Rails.env,
|
42
|
-
|
46
|
+
name: database
|
43
47
|
)
|
44
48
|
config&.migrations_paths
|
45
49
|
end
|
@@ -7,6 +7,7 @@ module ActiveRecord
|
|
7
7
|
class MigrationGenerator < Base # :nodoc:
|
8
8
|
argument :attributes, type: :array, default: [], banner: "field[:type][:index] field[:type][:index]"
|
9
9
|
|
10
|
+
class_option :timestamps, type: :boolean
|
10
11
|
class_option :primary_key_type, type: :string, desc: "The type for primary key"
|
11
12
|
class_option :database, type: :string, aliases: %i(--db), desc: "The database for your migration. By default, the current environment's primary database is used."
|
12
13
|
|
@@ -6,6 +6,8 @@ class <%= migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Mi
|
|
6
6
|
t.string :password_digest<%= attribute.inject_options %>
|
7
7
|
<% elsif attribute.token? -%>
|
8
8
|
t.string :<%= attribute.name %><%= attribute.inject_options %>
|
9
|
+
<% elsif attribute.reference? -%>
|
10
|
+
t.<%= attribute.type %> :<%= attribute.name %><%= attribute.inject_options %><%= foreign_key_type %>
|
9
11
|
<% elsif !attribute.virtual? -%>
|
10
12
|
t.<%= attribute.type %> :<%= attribute.name %><%= attribute.inject_options %>
|
11
13
|
<% end -%>
|
@@ -3,7 +3,7 @@ class <%= migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Mi
|
|
3
3
|
def change
|
4
4
|
<% attributes.each do |attribute| -%>
|
5
5
|
<%- if attribute.reference? -%>
|
6
|
-
add_reference :<%= table_name %>, :<%= attribute.name %><%= attribute.inject_options %>
|
6
|
+
add_reference :<%= table_name %>, :<%= attribute.name %><%= attribute.inject_options %><%= foreign_key_type %>
|
7
7
|
<%- elsif attribute.token? -%>
|
8
8
|
add_column :<%= table_name %>, :<%= attribute.name %>, :string<%= attribute.inject_options %>
|
9
9
|
add_index :<%= table_name %>, :<%= attribute.index_name %><%= attribute.inject_index_options %>, unique: true
|
@@ -20,7 +20,7 @@ class <%= migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Mi
|
|
20
20
|
create_join_table :<%= join_tables.first %>, :<%= join_tables.second %> do |t|
|
21
21
|
<%- attributes.each do |attribute| -%>
|
22
22
|
<%- if attribute.reference? -%>
|
23
|
-
t.references :<%= attribute.name %><%= attribute.inject_options %>
|
23
|
+
t.references :<%= attribute.name %><%= attribute.inject_options %><%= foreign_key_type %>
|
24
24
|
<%- elsif !attribute.virtual? -%>
|
25
25
|
<%= '# ' unless attribute.has_index? -%>t.index <%= attribute.index_name %><%= attribute.inject_index_options %>
|
26
26
|
<%- end -%>
|
@@ -32,12 +32,12 @@ class <%= migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Mi
|
|
32
32
|
<% attributes.each do |attribute| -%>
|
33
33
|
<%- if migration_action -%>
|
34
34
|
<%- if attribute.reference? -%>
|
35
|
-
remove_reference :<%= table_name %>, :<%= attribute.name %><%= attribute.inject_options %>
|
35
|
+
remove_reference :<%= table_name %>, :<%= attribute.name %><%= attribute.inject_options %><%= foreign_key_type %>
|
36
36
|
<%- else -%>
|
37
37
|
<%- if attribute.has_index? -%>
|
38
38
|
remove_index :<%= table_name %>, :<%= attribute.index_name %><%= attribute.inject_index_options %>
|
39
39
|
<%- end -%>
|
40
|
-
<%- if !attribute.virtual?
|
40
|
+
<%- if !attribute.virtual? -%>
|
41
41
|
remove_column :<%= table_name %>, :<%= attribute.name %>, :<%= attribute.type %><%= attribute.inject_options %>
|
42
42
|
<%- end -%>
|
43
43
|
<%- end -%>
|
@@ -18,12 +18,13 @@ module ActiveRecord
|
|
18
18
|
|
19
19
|
# creates the migration file for the model.
|
20
20
|
def create_migration_file
|
21
|
-
return
|
21
|
+
return if skip_migration_creation?
|
22
22
|
attributes.each { |a| a.attr_options.delete(:index) if a.reference? && !a.has_index? } if options[:indexes] == false
|
23
23
|
migration_template "../../migration/templates/create_table_migration.rb", File.join(db_migrate_path, "create_#{table_name}.rb")
|
24
24
|
end
|
25
25
|
|
26
26
|
def create_model_file
|
27
|
+
generate_abstract_class if database && !parent
|
27
28
|
template "model.rb", File.join("app/models", class_path, "#{file_name}.rb")
|
28
29
|
end
|
29
30
|
|
@@ -35,6 +36,12 @@ module ActiveRecord
|
|
35
36
|
hook_for :test_framework
|
36
37
|
|
37
38
|
private
|
39
|
+
# Skip creating migration file if:
|
40
|
+
# - options parent is present and database option is not present
|
41
|
+
# - migrations option is nil or false
|
42
|
+
def skip_migration_creation?
|
43
|
+
parent && !database || !migration
|
44
|
+
end
|
38
45
|
|
39
46
|
def attributes_with_index
|
40
47
|
attributes.select { |a| !a.reference? && a.has_index? }
|
@@ -42,7 +49,36 @@ module ActiveRecord
|
|
42
49
|
|
43
50
|
# Used by the migration template to determine the parent name of the model
|
44
51
|
def parent_class_name
|
45
|
-
|
52
|
+
if parent
|
53
|
+
parent
|
54
|
+
elsif database
|
55
|
+
abstract_class_name
|
56
|
+
else
|
57
|
+
"ApplicationRecord"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def generate_abstract_class
|
62
|
+
path = File.join("app/models", "#{database.underscore}_record.rb")
|
63
|
+
return if File.exist?(path)
|
64
|
+
|
65
|
+
template "abstract_base_class.rb", path
|
66
|
+
end
|
67
|
+
|
68
|
+
def abstract_class_name
|
69
|
+
"#{database.camelize}Record"
|
70
|
+
end
|
71
|
+
|
72
|
+
def database
|
73
|
+
options[:database]
|
74
|
+
end
|
75
|
+
|
76
|
+
def parent
|
77
|
+
options[:parent]
|
78
|
+
end
|
79
|
+
|
80
|
+
def migration
|
81
|
+
options[:migration]
|
46
82
|
end
|
47
83
|
end
|
48
84
|
end
|