activerecord 6.0.0.beta1 → 6.0.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 +455 -9
- data/README.rdoc +3 -1
- data/lib/active_record/associations/association.rb +18 -1
- data/lib/active_record/associations/builder/association.rb +14 -18
- data/lib/active_record/associations/builder/belongs_to.rb +5 -2
- data/lib/active_record/associations/builder/collection_association.rb +5 -15
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +1 -1
- 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 +5 -6
- data/lib/active_record/associations/collection_proxy.rb +13 -42
- data/lib/active_record/associations/has_many_association.rb +1 -9
- data/lib/active_record/associations/has_many_through_association.rb +4 -11
- data/lib/active_record/associations/join_dependency/join_association.rb +21 -7
- data/lib/active_record/associations/join_dependency.rb +10 -9
- data/lib/active_record/associations/preloader/association.rb +37 -34
- data/lib/active_record/associations/preloader/through_association.rb +48 -39
- data/lib/active_record/associations/preloader.rb +11 -6
- data/lib/active_record/associations.rb +3 -2
- data/lib/active_record/attribute_methods/before_type_cast.rb +4 -1
- data/lib/active_record/attribute_methods/dirty.rb +47 -14
- data/lib/active_record/attribute_methods/primary_key.rb +7 -15
- data/lib/active_record/attribute_methods/query.rb +2 -3
- data/lib/active_record/attribute_methods/read.rb +3 -9
- data/lib/active_record/attribute_methods/write.rb +6 -12
- data/lib/active_record/attribute_methods.rb +3 -53
- data/lib/active_record/attributes.rb +13 -0
- data/lib/active_record/autosave_association.rb +15 -5
- data/lib/active_record/base.rb +0 -1
- data/lib/active_record/callbacks.rb +3 -3
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +124 -23
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +8 -4
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +101 -70
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +11 -5
- data/lib/active_record/connection_adapters/abstract/quoting.rb +63 -6
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +5 -2
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +51 -40
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +95 -30
- data/lib/active_record/connection_adapters/abstract/transaction.rb +17 -6
- data/lib/active_record/connection_adapters/abstract_adapter.rb +108 -39
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +93 -134
- data/lib/active_record/connection_adapters/column.rb +17 -13
- data/lib/active_record/connection_adapters/connection_specification.rb +1 -1
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +3 -3
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +45 -7
- data/lib/active_record/connection_adapters/mysql/quoting.rb +44 -7
- 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 +66 -5
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +6 -10
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +18 -5
- data/lib/active_record/connection_adapters/postgresql/column.rb +17 -30
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +5 -1
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +6 -3
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +40 -3
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +36 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +98 -89
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +47 -63
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +23 -27
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +91 -24
- data/lib/active_record/connection_adapters/schema_cache.rb +32 -14
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +11 -8
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +118 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +38 -2
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +28 -2
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +69 -118
- data/lib/active_record/connection_handling.rb +32 -16
- data/lib/active_record/core.rb +27 -20
- data/lib/active_record/database_configurations/hash_config.rb +11 -11
- data/lib/active_record/database_configurations/url_config.rb +21 -16
- data/lib/active_record/database_configurations.rb +99 -50
- data/lib/active_record/dynamic_matchers.rb +1 -1
- data/lib/active_record/enum.rb +15 -0
- data/lib/active_record/errors.rb +18 -13
- data/lib/active_record/fixtures.rb +11 -6
- data/lib/active_record/gem_version.rb +1 -1
- data/lib/active_record/inheritance.rb +1 -1
- data/lib/active_record/insert_all.rb +179 -0
- data/lib/active_record/integration.rb +13 -1
- data/lib/active_record/internal_metadata.rb +5 -1
- data/lib/active_record/locking/optimistic.rb +3 -4
- data/lib/active_record/log_subscriber.rb +1 -1
- data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
- data/lib/active_record/middleware/database_selector.rb +75 -0
- data/lib/active_record/migration/command_recorder.rb +28 -14
- data/lib/active_record/migration/compatibility.rb +72 -63
- data/lib/active_record/migration.rb +62 -44
- data/lib/active_record/persistence.rb +212 -19
- data/lib/active_record/querying.rb +18 -14
- data/lib/active_record/railtie.rb +9 -1
- data/lib/active_record/railties/collection_cache_association_loading.rb +3 -3
- data/lib/active_record/railties/databases.rake +124 -25
- data/lib/active_record/reflection.rb +18 -32
- data/lib/active_record/relation/calculations.rb +40 -44
- data/lib/active_record/relation/delegation.rb +23 -31
- data/lib/active_record/relation/finder_methods.rb +13 -13
- data/lib/active_record/relation/merger.rb +11 -16
- data/lib/active_record/relation/query_attribute.rb +5 -3
- data/lib/active_record/relation/query_methods.rb +217 -68
- data/lib/active_record/relation/spawn_methods.rb +1 -1
- data/lib/active_record/relation/where_clause.rb +10 -10
- data/lib/active_record/relation.rb +184 -35
- data/lib/active_record/sanitization.rb +33 -4
- data/lib/active_record/schema.rb +1 -1
- data/lib/active_record/schema_dumper.rb +10 -1
- data/lib/active_record/schema_migration.rb +1 -1
- data/lib/active_record/scoping/default.rb +7 -15
- data/lib/active_record/scoping/named.rb +10 -2
- data/lib/active_record/scoping.rb +6 -7
- data/lib/active_record/statement_cache.rb +2 -2
- data/lib/active_record/store.rb +48 -0
- data/lib/active_record/table_metadata.rb +9 -13
- data/lib/active_record/tasks/database_tasks.rb +109 -6
- data/lib/active_record/tasks/mysql_database_tasks.rb +3 -1
- data/lib/active_record/test_databases.rb +1 -16
- data/lib/active_record/test_fixtures.rb +2 -2
- data/lib/active_record/timestamp.rb +35 -19
- data/lib/active_record/touch_later.rb +4 -2
- data/lib/active_record/transactions.rb +55 -45
- data/lib/active_record/type_caster/connection.rb +16 -10
- data/lib/active_record/validations/uniqueness.rb +4 -4
- data/lib/active_record/validations.rb +1 -0
- data/lib/active_record.rb +7 -1
- data/lib/arel/insert_manager.rb +3 -3
- data/lib/arel/nodes/and.rb +1 -1
- data/lib/arel/nodes/case.rb +1 -1
- data/lib/arel/nodes/comment.rb +29 -0
- data/lib/arel/nodes/select_core.rb +16 -12
- data/lib/arel/nodes/unary.rb +1 -0
- data/lib/arel/nodes/values_list.rb +2 -17
- data/lib/arel/nodes.rb +2 -1
- data/lib/arel/select_manager.rb +10 -10
- data/lib/arel/visitors/depth_first.rb +7 -2
- data/lib/arel/visitors/dot.rb +7 -2
- data/lib/arel/visitors/ibm_db.rb +13 -0
- data/lib/arel/visitors/informix.rb +6 -0
- data/lib/arel/visitors/mssql.rb +15 -1
- data/lib/arel/visitors/oracle12.rb +4 -5
- data/lib/arel/visitors/postgresql.rb +4 -10
- data/lib/arel/visitors/to_sql.rb +107 -131
- data/lib/arel/visitors/visitor.rb +9 -5
- data/lib/arel.rb +7 -0
- data/lib/rails/generators/active_record/migration/migration_generator.rb +1 -1
- 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 +17 -13
- data/lib/active_record/collection_cache_key.rb +0 -53
- data/lib/arel/nodes/values.rb +0 -16
data/lib/arel/visitors/to_sql.rb
CHANGED
@@ -9,59 +9,6 @@ module Arel # :nodoc: all
|
|
9
9
|
end
|
10
10
|
|
11
11
|
class ToSql < Arel::Visitors::Visitor
|
12
|
-
##
|
13
|
-
# This is some roflscale crazy stuff. I'm roflscaling this because
|
14
|
-
# building SQL queries is a hotspot. I will explain the roflscale so that
|
15
|
-
# others will not rm this code.
|
16
|
-
#
|
17
|
-
# In YARV, string literals in a method body will get duped when the byte
|
18
|
-
# code is executed. Let's take a look:
|
19
|
-
#
|
20
|
-
# > puts RubyVM::InstructionSequence.new('def foo; "bar"; end').disasm
|
21
|
-
#
|
22
|
-
# == disasm: <RubyVM::InstructionSequence:foo@<compiled>>=====
|
23
|
-
# 0000 trace 8
|
24
|
-
# 0002 trace 1
|
25
|
-
# 0004 putstring "bar"
|
26
|
-
# 0006 trace 16
|
27
|
-
# 0008 leave
|
28
|
-
#
|
29
|
-
# The `putstring` bytecode will dup the string and push it on the stack.
|
30
|
-
# In many cases in our SQL visitor, that string is never mutated, so there
|
31
|
-
# is no need to dup the literal.
|
32
|
-
#
|
33
|
-
# If we change to a constant lookup, the string will not be duped, and we
|
34
|
-
# can reduce the objects in our system:
|
35
|
-
#
|
36
|
-
# > puts RubyVM::InstructionSequence.new('BAR = "bar"; def foo; BAR; end').disasm
|
37
|
-
#
|
38
|
-
# == disasm: <RubyVM::InstructionSequence:foo@<compiled>>========
|
39
|
-
# 0000 trace 8
|
40
|
-
# 0002 trace 1
|
41
|
-
# 0004 getinlinecache 11, <ic:0>
|
42
|
-
# 0007 getconstant :BAR
|
43
|
-
# 0009 setinlinecache <ic:0>
|
44
|
-
# 0011 trace 16
|
45
|
-
# 0013 leave
|
46
|
-
#
|
47
|
-
# `getconstant` should be a hash lookup, and no object is duped when the
|
48
|
-
# value of the constant is pushed on the stack. Hence the crazy
|
49
|
-
# constants below.
|
50
|
-
#
|
51
|
-
# `matches` and `doesNotMatch` operate case-insensitively via Visitor subclasses
|
52
|
-
# specialized for specific databases when necessary.
|
53
|
-
#
|
54
|
-
|
55
|
-
WHERE = " WHERE " # :nodoc:
|
56
|
-
SPACE = " " # :nodoc:
|
57
|
-
COMMA = ", " # :nodoc:
|
58
|
-
GROUP_BY = " GROUP BY " # :nodoc:
|
59
|
-
ORDER_BY = " ORDER BY " # :nodoc:
|
60
|
-
WINDOW = " WINDOW " # :nodoc:
|
61
|
-
AND = " AND " # :nodoc:
|
62
|
-
|
63
|
-
DISTINCT = "DISTINCT" # :nodoc:
|
64
|
-
|
65
12
|
def initialize(connection)
|
66
13
|
super()
|
67
14
|
@connection = connection
|
@@ -105,10 +52,14 @@ module Arel # :nodoc: all
|
|
105
52
|
def visit_Arel_Nodes_InsertStatement(o, collector)
|
106
53
|
collector << "INSERT INTO "
|
107
54
|
collector = visit o.relation, collector
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
55
|
+
|
56
|
+
unless o.columns.empty?
|
57
|
+
collector << " ("
|
58
|
+
o.columns.each_with_index do |x, i|
|
59
|
+
collector << ", " unless i == 0
|
60
|
+
collector << quote_column_name(x.name)
|
61
|
+
end
|
62
|
+
collector << ")"
|
112
63
|
end
|
113
64
|
|
114
65
|
if o.values
|
@@ -150,48 +101,27 @@ module Arel # :nodoc: all
|
|
150
101
|
def visit_Arel_Nodes_ValuesList(o, collector)
|
151
102
|
collector << "VALUES "
|
152
103
|
|
153
|
-
|
154
|
-
|
104
|
+
o.rows.each_with_index do |row, i|
|
105
|
+
collector << ", " unless i == 0
|
155
106
|
collector << "("
|
156
|
-
row_len = row.length - 1
|
157
107
|
row.each_with_index do |value, k|
|
108
|
+
collector << ", " unless k == 0
|
158
109
|
case value
|
159
110
|
when Nodes::SqlLiteral, Nodes::BindParam
|
160
111
|
collector = visit(value, collector)
|
161
112
|
else
|
162
|
-
collector << quote(value)
|
113
|
+
collector << quote(value).to_s
|
163
114
|
end
|
164
|
-
collector << COMMA unless k == row_len
|
165
115
|
end
|
166
116
|
collector << ")"
|
167
|
-
|
168
|
-
}
|
117
|
+
end
|
169
118
|
collector
|
170
119
|
end
|
171
120
|
|
172
|
-
def visit_Arel_Nodes_Values(o, collector)
|
173
|
-
collector << "VALUES ("
|
174
|
-
|
175
|
-
len = o.expressions.length - 1
|
176
|
-
o.expressions.each_with_index { |value, i|
|
177
|
-
case value
|
178
|
-
when Nodes::SqlLiteral, Nodes::BindParam
|
179
|
-
collector = visit value, collector
|
180
|
-
else
|
181
|
-
collector << quote(value).to_s
|
182
|
-
end
|
183
|
-
unless i == len
|
184
|
-
collector << COMMA
|
185
|
-
end
|
186
|
-
}
|
187
|
-
|
188
|
-
collector << ")"
|
189
|
-
end
|
190
|
-
|
191
121
|
def visit_Arel_Nodes_SelectStatement(o, collector)
|
192
122
|
if o.with
|
193
123
|
collector = visit o.with, collector
|
194
|
-
collector <<
|
124
|
+
collector << " "
|
195
125
|
end
|
196
126
|
|
197
127
|
collector = o.cores.inject(collector) { |c, x|
|
@@ -199,12 +129,11 @@ module Arel # :nodoc: all
|
|
199
129
|
}
|
200
130
|
|
201
131
|
unless o.orders.empty?
|
202
|
-
collector <<
|
203
|
-
|
204
|
-
|
132
|
+
collector << " ORDER BY "
|
133
|
+
o.orders.each_with_index do |x, i|
|
134
|
+
collector << ", " unless i == 0
|
205
135
|
collector = visit(x, collector)
|
206
|
-
|
207
|
-
}
|
136
|
+
end
|
208
137
|
end
|
209
138
|
|
210
139
|
visit_Arel_Nodes_SelectOptions(o, collector)
|
@@ -219,24 +148,34 @@ module Arel # :nodoc: all
|
|
219
148
|
def visit_Arel_Nodes_SelectCore(o, collector)
|
220
149
|
collector << "SELECT"
|
221
150
|
|
151
|
+
collector = collect_optimizer_hints(o, collector)
|
222
152
|
collector = maybe_visit o.set_quantifier, collector
|
223
153
|
|
224
|
-
collect_nodes_for o.projections, collector,
|
154
|
+
collect_nodes_for o.projections, collector, " "
|
225
155
|
|
226
156
|
if o.source && !o.source.empty?
|
227
157
|
collector << " FROM "
|
228
158
|
collector = visit o.source, collector
|
229
159
|
end
|
230
160
|
|
231
|
-
collect_nodes_for o.wheres, collector, WHERE, AND
|
232
|
-
collect_nodes_for o.groups, collector,
|
233
|
-
collect_nodes_for o.havings, collector, " HAVING ", AND
|
234
|
-
collect_nodes_for o.windows, collector, WINDOW
|
161
|
+
collect_nodes_for o.wheres, collector, " WHERE ", " AND "
|
162
|
+
collect_nodes_for o.groups, collector, " GROUP BY "
|
163
|
+
collect_nodes_for o.havings, collector, " HAVING ", " AND "
|
164
|
+
collect_nodes_for o.windows, collector, " WINDOW "
|
235
165
|
|
236
|
-
collector
|
166
|
+
maybe_visit o.comment, collector
|
167
|
+
end
|
168
|
+
|
169
|
+
def visit_Arel_Nodes_OptimizerHints(o, collector)
|
170
|
+
hints = o.expr.map { |v| sanitize_as_sql_comment(v) }.join(" ")
|
171
|
+
collector << "/*+ #{hints} */"
|
172
|
+
end
|
173
|
+
|
174
|
+
def visit_Arel_Nodes_Comment(o, collector)
|
175
|
+
collector << o.values.map { |v| "/* #{sanitize_as_sql_comment(v)} */" }.join(" ")
|
237
176
|
end
|
238
177
|
|
239
|
-
def collect_nodes_for(nodes, collector, spacer, connector =
|
178
|
+
def collect_nodes_for(nodes, collector, spacer, connector = ", ")
|
240
179
|
unless nodes.empty?
|
241
180
|
collector << spacer
|
242
181
|
inject_join nodes, collector, connector
|
@@ -248,7 +187,7 @@ module Arel # :nodoc: all
|
|
248
187
|
end
|
249
188
|
|
250
189
|
def visit_Arel_Nodes_Distinct(o, collector)
|
251
|
-
collector << DISTINCT
|
190
|
+
collector << "DISTINCT"
|
252
191
|
end
|
253
192
|
|
254
193
|
def visit_Arel_Nodes_DistinctOn(o, collector)
|
@@ -257,12 +196,12 @@ module Arel # :nodoc: all
|
|
257
196
|
|
258
197
|
def visit_Arel_Nodes_With(o, collector)
|
259
198
|
collector << "WITH "
|
260
|
-
inject_join o.children, collector,
|
199
|
+
inject_join o.children, collector, ", "
|
261
200
|
end
|
262
201
|
|
263
202
|
def visit_Arel_Nodes_WithRecursive(o, collector)
|
264
203
|
collector << "WITH RECURSIVE "
|
265
|
-
inject_join o.children, collector,
|
204
|
+
inject_join o.children, collector, ", "
|
266
205
|
end
|
267
206
|
|
268
207
|
def visit_Arel_Nodes_Union(o, collector)
|
@@ -295,13 +234,13 @@ module Arel # :nodoc: all
|
|
295
234
|
collect_nodes_for o.partitions, collector, "PARTITION BY "
|
296
235
|
|
297
236
|
if o.orders.any?
|
298
|
-
collector <<
|
237
|
+
collector << " " if o.partitions.any?
|
299
238
|
collector << "ORDER BY "
|
300
239
|
collector = inject_join o.orders, collector, ", "
|
301
240
|
end
|
302
241
|
|
303
242
|
if o.framing
|
304
|
-
collector <<
|
243
|
+
collector << " " if o.partitions.any? || o.orders.any?
|
305
244
|
collector = visit o.framing, collector
|
306
245
|
end
|
307
246
|
|
@@ -506,8 +445,8 @@ module Arel # :nodoc: all
|
|
506
445
|
collector = visit o.left, collector
|
507
446
|
end
|
508
447
|
if o.right.any?
|
509
|
-
collector <<
|
510
|
-
collector = inject_join o.right, collector,
|
448
|
+
collector << " " if o.left
|
449
|
+
collector = inject_join o.right, collector, " "
|
511
450
|
end
|
512
451
|
collector
|
513
452
|
end
|
@@ -527,7 +466,7 @@ module Arel # :nodoc: all
|
|
527
466
|
def visit_Arel_Nodes_FullOuterJoin(o, collector)
|
528
467
|
collector << "FULL OUTER JOIN "
|
529
468
|
collector = visit o.left, collector
|
530
|
-
collector <<
|
469
|
+
collector << " "
|
531
470
|
visit o.right, collector
|
532
471
|
end
|
533
472
|
|
@@ -541,7 +480,7 @@ module Arel # :nodoc: all
|
|
541
480
|
def visit_Arel_Nodes_RightOuterJoin(o, collector)
|
542
481
|
collector << "RIGHT OUTER JOIN "
|
543
482
|
collector = visit o.left, collector
|
544
|
-
collector <<
|
483
|
+
collector << " "
|
545
484
|
visit o.right, collector
|
546
485
|
end
|
547
486
|
|
@@ -549,7 +488,7 @@ module Arel # :nodoc: all
|
|
549
488
|
collector << "INNER JOIN "
|
550
489
|
collector = visit o.left, collector
|
551
490
|
if o.right
|
552
|
-
collector <<
|
491
|
+
collector << " "
|
553
492
|
visit(o.right, collector)
|
554
493
|
else
|
555
494
|
collector
|
@@ -568,41 +507,73 @@ module Arel # :nodoc: all
|
|
568
507
|
|
569
508
|
def visit_Arel_Table(o, collector)
|
570
509
|
if o.table_alias
|
571
|
-
collector <<
|
510
|
+
collector << quote_table_name(o.name) << " " << quote_table_name(o.table_alias)
|
572
511
|
else
|
573
512
|
collector << quote_table_name(o.name)
|
574
513
|
end
|
575
514
|
end
|
576
515
|
|
577
516
|
def visit_Arel_Nodes_In(o, collector)
|
578
|
-
|
517
|
+
unless Array === o.right
|
518
|
+
return collect_in_clause(o.left, o.right, collector)
|
519
|
+
end
|
520
|
+
|
521
|
+
unless o.right.empty?
|
579
522
|
o.right.delete_if { |value| unboundable?(value) }
|
580
523
|
end
|
581
524
|
|
582
|
-
|
583
|
-
|
525
|
+
return collector << "1=0" if o.right.empty?
|
526
|
+
|
527
|
+
in_clause_length = @connection.in_clause_length
|
528
|
+
|
529
|
+
if !in_clause_length || o.right.length <= in_clause_length
|
530
|
+
collect_in_clause(o.left, o.right, collector)
|
584
531
|
else
|
585
|
-
collector
|
586
|
-
|
587
|
-
|
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)
|
536
|
+
end
|
537
|
+
collector << ")"
|
588
538
|
end
|
589
539
|
end
|
590
540
|
|
541
|
+
def collect_in_clause(left, right, collector)
|
542
|
+
collector = visit left, collector
|
543
|
+
collector << " IN ("
|
544
|
+
visit(right, collector) << ")"
|
545
|
+
end
|
546
|
+
|
591
547
|
def visit_Arel_Nodes_NotIn(o, collector)
|
592
|
-
|
548
|
+
unless Array === o.right
|
549
|
+
return collect_not_in_clause(o.left, o.right, collector)
|
550
|
+
end
|
551
|
+
|
552
|
+
unless o.right.empty?
|
593
553
|
o.right.delete_if { |value| unboundable?(value) }
|
594
554
|
end
|
595
555
|
|
596
|
-
|
597
|
-
|
556
|
+
return collector << "1=1" if o.right.empty?
|
557
|
+
|
558
|
+
in_clause_length = @connection.in_clause_length
|
559
|
+
|
560
|
+
if !in_clause_length || o.right.length <= in_clause_length
|
561
|
+
collect_not_in_clause(o.left, o.right, collector)
|
598
562
|
else
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
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)
|
566
|
+
end
|
567
|
+
collector
|
603
568
|
end
|
604
569
|
end
|
605
570
|
|
571
|
+
def collect_not_in_clause(left, right, collector)
|
572
|
+
collector = visit left, collector
|
573
|
+
collector << " NOT IN ("
|
574
|
+
visit(right, collector) << ")"
|
575
|
+
end
|
576
|
+
|
606
577
|
def visit_Arel_Nodes_And(o, collector)
|
607
578
|
inject_join o.children, collector, " AND "
|
608
579
|
end
|
@@ -712,13 +683,12 @@ module Arel # :nodoc: all
|
|
712
683
|
end
|
713
684
|
|
714
685
|
def visit_Arel_Nodes_UnqualifiedColumn(o, collector)
|
715
|
-
collector <<
|
716
|
-
collector
|
686
|
+
collector << quote_column_name(o.name)
|
717
687
|
end
|
718
688
|
|
719
689
|
def visit_Arel_Attributes_Attribute(o, collector)
|
720
690
|
join_name = o.relation.table_alias || o.relation.name
|
721
|
-
collector <<
|
691
|
+
collector << quote_table_name(join_name) << "." << quote_column_name(o.name)
|
722
692
|
end
|
723
693
|
alias :visit_Arel_Attributes_Integer :visit_Arel_Attributes_Attribute
|
724
694
|
alias :visit_Arel_Attributes_Float :visit_Arel_Attributes_Attribute
|
@@ -799,6 +769,15 @@ module Arel # :nodoc: all
|
|
799
769
|
@connection.quote_column_name(name)
|
800
770
|
end
|
801
771
|
|
772
|
+
def sanitize_as_sql_comment(value)
|
773
|
+
return value if Arel::Nodes::SqlLiteral === value
|
774
|
+
@connection.sanitize_as_sql_comment(value)
|
775
|
+
end
|
776
|
+
|
777
|
+
def collect_optimizer_hints(o, collector)
|
778
|
+
maybe_visit o.optimizer_hints, collector
|
779
|
+
end
|
780
|
+
|
802
781
|
def maybe_visit(thing, collector)
|
803
782
|
return collector unless thing
|
804
783
|
collector << " "
|
@@ -806,14 +785,11 @@ module Arel # :nodoc: all
|
|
806
785
|
end
|
807
786
|
|
808
787
|
def inject_join(list, collector, join_str)
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
visit(x, c) << join_str
|
815
|
-
end
|
816
|
-
}
|
788
|
+
list.each_with_index do |x, i|
|
789
|
+
collector << join_str unless i == 0
|
790
|
+
collector = visit(x, collector)
|
791
|
+
end
|
792
|
+
collector
|
817
793
|
end
|
818
794
|
|
819
795
|
def unboundable?(value)
|
@@ -7,8 +7,8 @@ module Arel # :nodoc: all
|
|
7
7
|
@dispatch = get_dispatch_cache
|
8
8
|
end
|
9
9
|
|
10
|
-
def accept(object,
|
11
|
-
visit object,
|
10
|
+
def accept(object, collector = nil)
|
11
|
+
visit object, collector
|
12
12
|
end
|
13
13
|
|
14
14
|
private
|
@@ -16,7 +16,7 @@ module Arel # :nodoc: all
|
|
16
16
|
attr_reader :dispatch
|
17
17
|
|
18
18
|
def self.dispatch_cache
|
19
|
-
Hash.new do |hash, klass|
|
19
|
+
@dispatch_cache ||= Hash.new do |hash, klass|
|
20
20
|
hash[klass] = "visit_#{(klass.name || '').gsub('::', '_')}"
|
21
21
|
end
|
22
22
|
end
|
@@ -25,9 +25,13 @@ module Arel # :nodoc: all
|
|
25
25
|
self.class.dispatch_cache
|
26
26
|
end
|
27
27
|
|
28
|
-
def visit(object,
|
28
|
+
def visit(object, collector = nil)
|
29
29
|
dispatch_method = dispatch[object.class]
|
30
|
-
|
30
|
+
if collector
|
31
|
+
send dispatch_method, object, collector
|
32
|
+
else
|
33
|
+
send dispatch_method, object
|
34
|
+
end
|
31
35
|
rescue NoMethodError => e
|
32
36
|
raise e if respond_to?(dispatch_method, true)
|
33
37
|
superklass = object.class.ancestors.find { |klass|
|
data/lib/arel.rb
CHANGED
@@ -39,6 +39,13 @@ module Arel # :nodoc: all
|
|
39
39
|
value.is_a?(Arel::Node) || value.is_a?(Arel::Attribute) || value.is_a?(Arel::Nodes::SqlLiteral)
|
40
40
|
end
|
41
41
|
|
42
|
+
def self.fetch_attribute(value)
|
43
|
+
case value
|
44
|
+
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
|
45
|
+
yield value.left.is_a?(Arel::Attributes::Attribute) ? value.left : value.right
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
42
49
|
## Convenience Alias
|
43
50
|
Node = Arel::Nodes::Node
|
44
51
|
end
|
@@ -8,7 +8,7 @@ module ActiveRecord
|
|
8
8
|
argument :attributes, type: :array, default: [], banner: "field[:type][:index] field[:type][:index]"
|
9
9
|
|
10
10
|
class_option :primary_key_type, type: :string, desc: "The type for primary key"
|
11
|
-
class_option :database, type: :string, aliases: %i(db), desc: "The database for your migration. By default, the current environment's primary database is used."
|
11
|
+
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
12
|
|
13
13
|
def create_migration_file
|
14
14
|
set_local_assigns!
|
@@ -6,7 +6,7 @@ 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
|
-
<%
|
9
|
+
<% elsif !attribute.virtual? -%>
|
10
10
|
t.<%= attribute.type %> :<%= attribute.name %><%= attribute.inject_options %>
|
11
11
|
<% end -%>
|
12
12
|
<% end -%>
|
@@ -7,7 +7,7 @@ class <%= migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Mi
|
|
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
|
10
|
-
<%-
|
10
|
+
<%- elsif !attribute.virtual? -%>
|
11
11
|
add_column :<%= table_name %>, :<%= attribute.name %>, :<%= attribute.type %><%= attribute.inject_options %>
|
12
12
|
<%- if attribute.has_index? -%>
|
13
13
|
add_index :<%= table_name %>, :<%= attribute.index_name %><%= attribute.inject_index_options %>
|
@@ -21,7 +21,7 @@ class <%= migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Mi
|
|
21
21
|
<%- attributes.each do |attribute| -%>
|
22
22
|
<%- if attribute.reference? -%>
|
23
23
|
t.references :<%= attribute.name %><%= attribute.inject_options %>
|
24
|
-
<%-
|
24
|
+
<%- elsif !attribute.virtual? -%>
|
25
25
|
<%= '# ' unless attribute.has_index? -%>t.index <%= attribute.index_name %><%= attribute.inject_index_options %>
|
26
26
|
<%- end -%>
|
27
27
|
<%- end -%>
|
@@ -37,7 +37,9 @@ class <%= migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Mi
|
|
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
41
|
remove_column :<%= table_name %>, :<%= attribute.name %>, :<%= attribute.type %><%= attribute.inject_options %>
|
42
|
+
<%- end -%>
|
41
43
|
<%- end -%>
|
42
44
|
<%- end -%>
|
43
45
|
<%- end -%>
|
@@ -14,7 +14,7 @@ module ActiveRecord
|
|
14
14
|
class_option :parent, type: :string, desc: "The parent class for the generated model"
|
15
15
|
class_option :indexes, type: :boolean, default: true, desc: "Add indexes for references and belongs_to columns"
|
16
16
|
class_option :primary_key_type, type: :string, desc: "The type for primary key"
|
17
|
-
class_option :database, type: :string, aliases: %i(db), desc: "The database for your model's migration. By default, the current environment's primary database is used."
|
17
|
+
class_option :database, type: :string, aliases: %i(--db), desc: "The database for your model's migration. By default, the current environment's primary database is used."
|
18
18
|
|
19
19
|
# creates the migration file for the model.
|
20
20
|
def create_migration_file
|
@@ -1,7 +1,16 @@
|
|
1
1
|
<% module_namespacing do -%>
|
2
2
|
class <%= class_name %> < <%= parent_class_name.classify %>
|
3
3
|
<% attributes.select(&:reference?).each do |attribute| -%>
|
4
|
-
belongs_to :<%= attribute.name %><%= ', polymorphic: true' if attribute.polymorphic?
|
4
|
+
belongs_to :<%= attribute.name %><%= ', polymorphic: true' if attribute.polymorphic? %>
|
5
|
+
<% end -%>
|
6
|
+
<% attributes.select(&:rich_text?).each do |attribute| -%>
|
7
|
+
has_rich_text :<%= attribute.name %>
|
8
|
+
<% end -%>
|
9
|
+
<% attributes.select(&:attachment?).each do |attribute| -%>
|
10
|
+
has_one_attached :<%= attribute.name %>
|
11
|
+
<% end -%>
|
12
|
+
<% attributes.select(&:attachments?).each do |attribute| -%>
|
13
|
+
has_many_attached :<%= attribute.name %>
|
5
14
|
<% end -%>
|
6
15
|
<% attributes.select(&:token?).each do |attribute| -%>
|
7
16
|
has_secure_token<% if attribute.name != "token" %> :<%= attribute.name %><% end %>
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.0.0
|
4
|
+
version: 6.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Heinemeier Hansson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-08-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -16,28 +16,28 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 6.0.0
|
19
|
+
version: 6.0.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 6.0.0
|
26
|
+
version: 6.0.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: activemodel
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - '='
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 6.0.0
|
33
|
+
version: 6.0.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - '='
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 6.0.0
|
40
|
+
version: 6.0.0
|
41
41
|
description: Databases on Rails. Build a persistent domain model by mapping database
|
42
42
|
tables to Ruby classes. Strong conventions for associations, validations, aggregations,
|
43
43
|
migrations, and testing come baked-in.
|
@@ -101,7 +101,6 @@ files:
|
|
101
101
|
- lib/active_record/callbacks.rb
|
102
102
|
- lib/active_record/coders/json.rb
|
103
103
|
- lib/active_record/coders/yaml_column.rb
|
104
|
-
- lib/active_record/collection_cache_key.rb
|
105
104
|
- lib/active_record/connection_adapters/abstract/connection_pool.rb
|
106
105
|
- lib/active_record/connection_adapters/abstract/database_limits.rb
|
107
106
|
- lib/active_record/connection_adapters/abstract/database_statements.rb
|
@@ -165,6 +164,7 @@ files:
|
|
165
164
|
- lib/active_record/connection_adapters/postgresql_adapter.rb
|
166
165
|
- lib/active_record/connection_adapters/schema_cache.rb
|
167
166
|
- lib/active_record/connection_adapters/sql_type_metadata.rb
|
167
|
+
- lib/active_record/connection_adapters/sqlite3/database_statements.rb
|
168
168
|
- lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb
|
169
169
|
- lib/active_record/connection_adapters/sqlite3/quoting.rb
|
170
170
|
- lib/active_record/connection_adapters/sqlite3/schema_creation.rb
|
@@ -195,6 +195,7 @@ files:
|
|
195
195
|
- lib/active_record/fixtures.rb
|
196
196
|
- lib/active_record/gem_version.rb
|
197
197
|
- lib/active_record/inheritance.rb
|
198
|
+
- lib/active_record/insert_all.rb
|
198
199
|
- lib/active_record/integration.rb
|
199
200
|
- lib/active_record/internal_metadata.rb
|
200
201
|
- lib/active_record/legacy_yaml_adapter.rb
|
@@ -202,6 +203,9 @@ files:
|
|
202
203
|
- lib/active_record/locking/optimistic.rb
|
203
204
|
- lib/active_record/locking/pessimistic.rb
|
204
205
|
- lib/active_record/log_subscriber.rb
|
206
|
+
- lib/active_record/middleware/database_selector.rb
|
207
|
+
- lib/active_record/middleware/database_selector/resolver.rb
|
208
|
+
- lib/active_record/middleware/database_selector/resolver/session.rb
|
205
209
|
- lib/active_record/migration.rb
|
206
210
|
- lib/active_record/migration/command_recorder.rb
|
207
211
|
- lib/active_record/migration/compatibility.rb
|
@@ -313,6 +317,7 @@ files:
|
|
313
317
|
- lib/arel/nodes/bind_param.rb
|
314
318
|
- lib/arel/nodes/case.rb
|
315
319
|
- lib/arel/nodes/casted.rb
|
320
|
+
- lib/arel/nodes/comment.rb
|
316
321
|
- lib/arel/nodes/count.rb
|
317
322
|
- lib/arel/nodes/delete_statement.rb
|
318
323
|
- lib/arel/nodes/descending.rb
|
@@ -346,7 +351,6 @@ files:
|
|
346
351
|
- lib/arel/nodes/unary_operation.rb
|
347
352
|
- lib/arel/nodes/unqualified_column.rb
|
348
353
|
- lib/arel/nodes/update_statement.rb
|
349
|
-
- lib/arel/nodes/values.rb
|
350
354
|
- lib/arel/nodes/values_list.rb
|
351
355
|
- lib/arel/nodes/window.rb
|
352
356
|
- lib/arel/nodes/with.rb
|
@@ -381,12 +385,12 @@ files:
|
|
381
385
|
- lib/rails/generators/active_record/model/model_generator.rb
|
382
386
|
- lib/rails/generators/active_record/model/templates/model.rb.tt
|
383
387
|
- lib/rails/generators/active_record/model/templates/module.rb.tt
|
384
|
-
homepage:
|
388
|
+
homepage: https://rubyonrails.org
|
385
389
|
licenses:
|
386
390
|
- MIT
|
387
391
|
metadata:
|
388
|
-
source_code_uri: https://github.com/rails/rails/tree/v6.0.0
|
389
|
-
changelog_uri: https://github.com/rails/rails/blob/v6.0.0
|
392
|
+
source_code_uri: https://github.com/rails/rails/tree/v6.0.0/activerecord
|
393
|
+
changelog_uri: https://github.com/rails/rails/blob/v6.0.0/activerecord/CHANGELOG.md
|
390
394
|
post_install_message:
|
391
395
|
rdoc_options:
|
392
396
|
- "--main"
|
@@ -400,9 +404,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
400
404
|
version: 2.5.0
|
401
405
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
402
406
|
requirements:
|
403
|
-
- - "
|
407
|
+
- - ">="
|
404
408
|
- !ruby/object:Gem::Version
|
405
|
-
version:
|
409
|
+
version: '0'
|
406
410
|
requirements: []
|
407
411
|
rubygems_version: 3.0.1
|
408
412
|
signing_key:
|