arel_toolkit 0.3.0 → 0.4.0
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.
- checksums.yaml +4 -4
- data/.codeclimate.yml +3 -0
- data/.gitignore +4 -1
- data/.rubocop.yml +13 -5
- data/.travis.yml +7 -2
- data/Appraisals +9 -0
- data/CHANGELOG.md +19 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +22 -5
- data/README.md +59 -18
- data/arel_toolkit.gemspec +5 -1
- data/gemfiles/.bundle/config +2 -0
- data/gemfiles/arel_gems.gemfile +10 -0
- data/gemfiles/arel_gems.gemfile.lock +274 -0
- data/gemfiles/default.gemfile +5 -0
- data/gemfiles/default.gemfile.lock +198 -0
- data/lib/arel/enhance.rb +16 -0
- data/lib/arel/enhance/context_enhancer/arel_table.rb +75 -0
- data/lib/arel/enhance/node.rb +189 -0
- data/lib/arel/enhance/path.rb +38 -0
- data/lib/arel/enhance/path_node.rb +26 -0
- data/lib/arel/enhance/query.rb +36 -0
- data/lib/arel/enhance/visitor.rb +81 -0
- data/lib/arel/extensions.rb +24 -4
- data/lib/arel/extensions/active_record_type_caster_map.rb +7 -0
- data/lib/arel/extensions/array.rb +2 -9
- data/lib/arel/extensions/at_time_zone.rb +10 -3
- data/lib/arel/extensions/binary.rb +7 -0
- data/lib/arel/extensions/bit_string.rb +2 -9
- data/lib/arel/extensions/case.rb +17 -0
- data/lib/arel/extensions/conflict.rb +9 -0
- data/lib/arel/extensions/contains.rb +27 -5
- data/lib/arel/extensions/current_catalog.rb +4 -0
- data/lib/arel/extensions/current_date.rb +4 -0
- data/lib/arel/extensions/current_of_expression.rb +2 -9
- data/lib/arel/extensions/current_role.rb +4 -0
- data/lib/arel/extensions/current_row.rb +7 -0
- data/lib/arel/extensions/current_schema.rb +4 -0
- data/lib/arel/extensions/current_user.rb +4 -0
- data/lib/arel/extensions/dealocate.rb +31 -0
- data/lib/arel/extensions/default_values.rb +4 -0
- data/lib/arel/extensions/delete_manager.rb +22 -6
- data/lib/arel/extensions/delete_statement.rb +26 -9
- data/lib/arel/extensions/dot.rb +11 -0
- data/lib/arel/extensions/extract_from.rb +3 -10
- data/lib/arel/extensions/factorial.rb +10 -2
- data/lib/arel/extensions/false.rb +7 -0
- data/lib/arel/extensions/function.rb +42 -13
- data/lib/arel/extensions/indirection.rb +3 -12
- data/lib/arel/extensions/infer.rb +6 -6
- data/lib/arel/extensions/infix_operation.rb +17 -0
- data/lib/arel/extensions/insert_manager.rb +19 -3
- data/lib/arel/extensions/insert_statement.rb +30 -11
- data/lib/arel/extensions/into.rb +21 -0
- data/lib/arel/extensions/named_argument.rb +3 -8
- data/lib/arel/extensions/named_function.rb +7 -0
- data/lib/arel/extensions/ordering.rb +21 -6
- data/lib/arel/extensions/overlaps.rb +9 -0
- data/lib/arel/extensions/overlay.rb +9 -0
- data/lib/arel/extensions/position.rb +3 -8
- data/lib/arel/extensions/prepare.rb +39 -0
- data/lib/arel/extensions/row.rb +3 -8
- data/lib/arel/extensions/select_core.rb +58 -0
- data/lib/arel/extensions/select_manager.rb +22 -6
- data/lib/arel/extensions/select_statement.rb +31 -9
- data/lib/arel/extensions/session_user.rb +4 -0
- data/lib/arel/extensions/set_to_default.rb +4 -0
- data/lib/arel/extensions/substring.rb +8 -0
- data/lib/arel/extensions/table.rb +43 -10
- data/lib/arel/extensions/time_with_precision.rb +6 -0
- data/lib/arel/extensions/to_sql.rb +27 -0
- data/lib/arel/extensions/transaction.rb +3 -8
- data/lib/arel/extensions/tree_manager.rb +10 -0
- data/lib/arel/extensions/trim.rb +8 -0
- data/lib/arel/extensions/true.rb +7 -0
- data/lib/arel/extensions/type_cast.rb +7 -0
- data/lib/arel/extensions/unary.rb +7 -0
- data/lib/arel/extensions/unary_operation.rb +16 -0
- data/lib/arel/extensions/unknown.rb +4 -0
- data/lib/arel/extensions/update_manager.rb +22 -6
- data/lib/arel/extensions/update_statement.rb +27 -10
- data/lib/arel/extensions/user.rb +4 -0
- data/lib/arel/extensions/values_list.rb +15 -0
- data/lib/arel/extensions/variable_set.rb +9 -0
- data/lib/arel/extensions/variable_show.rb +3 -8
- data/lib/arel/middleware/chain.rb +1 -5
- data/lib/arel/middleware/railtie.rb +10 -0
- data/lib/arel/sql_to_arel.rb +6 -3
- data/lib/arel/sql_to_arel/pg_query_visitor.rb +43 -15
- data/lib/arel/sql_to_arel/pg_query_visitor/frame_options.rb +1 -1
- data/lib/arel/sql_to_arel/result.rb +0 -4
- data/lib/arel/transformer.rb +7 -0
- data/lib/arel/transformer/add_schema_to_table.rb +26 -0
- data/lib/arel/transformer/remove_active_record_info.rb +42 -0
- data/lib/arel_toolkit.rb +8 -1
- data/lib/arel_toolkit/version.rb +1 -1
- metadata +81 -8
- data/lib/arel/extensions/unbound_column_reference.rb +0 -5
- data/lib/arel/sql_formatter.rb +0 -59
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# rubocop:disable Naming/MethodName
|
|
2
|
+
# rubocop:disable Naming/UncommunicativeMethodParamName
|
|
3
|
+
|
|
4
|
+
module Arel
|
|
5
|
+
module Visitors
|
|
6
|
+
class ToSql
|
|
7
|
+
def visit_Arel_Attributes_Attribute(o, collector)
|
|
8
|
+
if o.relation
|
|
9
|
+
join_name = o.relation.table_alias || o.relation.name
|
|
10
|
+
collector << "#{quote_table_name join_name}.#{quote_column_name o.name}"
|
|
11
|
+
else
|
|
12
|
+
visit_Arel_Nodes_UnqualifiedColumn o, collector
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
alias visit_Arel_Attributes_Integer visit_Arel_Attributes_Attribute
|
|
17
|
+
alias visit_Arel_Attributes_Float visit_Arel_Attributes_Attribute
|
|
18
|
+
alias visit_Arel_Attributes_Decimal visit_Arel_Attributes_Attribute
|
|
19
|
+
alias visit_Arel_Attributes_String visit_Arel_Attributes_Attribute
|
|
20
|
+
alias visit_Arel_Attributes_Time visit_Arel_Attributes_Attribute
|
|
21
|
+
alias visit_Arel_Attributes_Boolean visit_Arel_Attributes_Attribute
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# rubocop:enable Naming/MethodName
|
|
27
|
+
# rubocop:enable Naming/UncommunicativeMethodParamName
|
|
@@ -6,14 +6,9 @@
|
|
|
6
6
|
module Arel
|
|
7
7
|
module Nodes
|
|
8
8
|
# https://www.postgresql.org/docs/8.3/tutorial-transactions.html
|
|
9
|
-
class Transaction < Arel::Nodes::
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
def initialize(type, options)
|
|
14
|
-
@type = type
|
|
15
|
-
@options = options
|
|
16
|
-
end
|
|
9
|
+
class Transaction < Arel::Nodes::Binary
|
|
10
|
+
alias type left
|
|
11
|
+
alias options right
|
|
17
12
|
end
|
|
18
13
|
end
|
|
19
14
|
|
data/lib/arel/extensions/trim.rb
CHANGED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# rubocop:disable Naming/MethodName
|
|
2
|
+
# rubocop:disable Naming/UncommunicativeMethodParamName
|
|
3
|
+
|
|
4
|
+
module Arel
|
|
5
|
+
module Visitors
|
|
6
|
+
class Dot
|
|
7
|
+
def visit_Arel_Nodes_UnaryOperation(o)
|
|
8
|
+
visit_edge o, 'operator'
|
|
9
|
+
visit_edge o, 'expr'
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# rubocop:enable Naming/MethodName
|
|
16
|
+
# rubocop:enable Naming/UncommunicativeMethodParamName
|
|
@@ -1,9 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
# rubocop:disable Naming/MethodName
|
|
2
|
+
# rubocop:disable Naming/UncommunicativeMethodParamName
|
|
3
|
+
|
|
4
|
+
module Arel
|
|
5
|
+
class UpdateManager < Arel::TreeManager
|
|
6
|
+
def ==(other)
|
|
7
|
+
other.is_a?(self.class) && @ast == other.ast && @ctx == other.ctx
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
protected
|
|
5
11
|
|
|
6
|
-
|
|
12
|
+
attr_reader :ctx
|
|
13
|
+
end
|
|
7
14
|
|
|
8
|
-
|
|
15
|
+
module Visitors
|
|
16
|
+
class Dot
|
|
17
|
+
def visit_Arel_UpdateManager(o)
|
|
18
|
+
visit_edge o, 'ast'
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
9
22
|
end
|
|
23
|
+
|
|
24
|
+
# rubocop:enable Naming/MethodName
|
|
25
|
+
# rubocop:enable Naming/UncommunicativeMethodParamName
|
|
@@ -3,19 +3,22 @@
|
|
|
3
3
|
|
|
4
4
|
module Arel
|
|
5
5
|
module Nodes
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
class UpdateStatement
|
|
7
|
+
module UpdateStatementExtension
|
|
8
|
+
# https://www.postgresql.org/docs/10/sql-update.html
|
|
9
|
+
attr_accessor :with
|
|
10
|
+
attr_accessor :froms
|
|
11
|
+
attr_accessor :returning
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
old_initialize
|
|
13
|
+
def initialize
|
|
14
|
+
super
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
@froms = []
|
|
17
|
+
@returning = []
|
|
18
|
+
end
|
|
18
19
|
end
|
|
20
|
+
|
|
21
|
+
prepend UpdateStatementExtension
|
|
19
22
|
end
|
|
20
23
|
end
|
|
21
24
|
|
|
@@ -64,6 +67,20 @@ module Arel
|
|
|
64
67
|
# rubocop:enable Metrics/CyclomaticComplexity
|
|
65
68
|
# rubocop:enable Metrics/PerceivedComplexity
|
|
66
69
|
end
|
|
70
|
+
|
|
71
|
+
class Dot
|
|
72
|
+
module UpdateStatementExtension
|
|
73
|
+
def visit_Arel_Nodes_UpdateStatement(o)
|
|
74
|
+
super
|
|
75
|
+
|
|
76
|
+
visit_edge o, 'with'
|
|
77
|
+
visit_edge o, 'froms'
|
|
78
|
+
visit_edge o, 'returning'
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
prepend UpdateStatementExtension
|
|
83
|
+
end
|
|
67
84
|
end
|
|
68
85
|
end
|
|
69
86
|
|
data/lib/arel/extensions/user.rb
CHANGED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# rubocop:disable Naming/MethodName
|
|
2
|
+
# rubocop:disable Naming/UncommunicativeMethodParamName
|
|
3
|
+
|
|
4
|
+
module Arel
|
|
5
|
+
module Visitors
|
|
6
|
+
class Dot
|
|
7
|
+
def visit_Arel_Nodes_ValuesList(o)
|
|
8
|
+
visit_edge o, 'rows'
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# rubocop:enable Naming/MethodName
|
|
15
|
+
# rubocop:enable Naming/UncommunicativeMethodParamName
|
|
@@ -4,12 +4,7 @@
|
|
|
4
4
|
module Arel
|
|
5
5
|
module Nodes
|
|
6
6
|
# https://www.postgresql.org/docs/9.1/sql-show.html
|
|
7
|
-
class VariableShow < Arel::Nodes::
|
|
8
|
-
attr_reader :name
|
|
9
|
-
|
|
10
|
-
def initialize(name)
|
|
11
|
-
@name = name
|
|
12
|
-
end
|
|
7
|
+
class VariableShow < Arel::Nodes::Unary
|
|
13
8
|
end
|
|
14
9
|
end
|
|
15
10
|
|
|
@@ -17,10 +12,10 @@ module Arel
|
|
|
17
12
|
class ToSql
|
|
18
13
|
def visit_Arel_Nodes_VariableShow(o, collector)
|
|
19
14
|
collector << 'SHOW '
|
|
20
|
-
collector << if o.
|
|
15
|
+
collector << if o.expr == 'timezone'
|
|
21
16
|
'TIME ZONE'
|
|
22
17
|
else
|
|
23
|
-
o.
|
|
18
|
+
o.expr
|
|
24
19
|
end
|
|
25
20
|
end
|
|
26
21
|
end
|
|
@@ -14,7 +14,7 @@ module Arel
|
|
|
14
14
|
|
|
15
15
|
internal_middleware.each do |middleware_item|
|
|
16
16
|
result = result.map do |arel|
|
|
17
|
-
middleware_item.call(arel, updated_context)
|
|
17
|
+
middleware_item.call(arel, updated_context.dup)
|
|
18
18
|
end
|
|
19
19
|
end
|
|
20
20
|
|
|
@@ -88,10 +88,6 @@ module Arel
|
|
|
88
88
|
ensure
|
|
89
89
|
Arel::Middleware.current_chain = previous_chain
|
|
90
90
|
end
|
|
91
|
-
|
|
92
|
-
def current_chain
|
|
93
|
-
Arel::Middleware.current_chain
|
|
94
|
-
end
|
|
95
91
|
end
|
|
96
92
|
end
|
|
97
93
|
end
|
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
module Arel
|
|
2
2
|
module Middleware
|
|
3
|
+
if defined? Rails::Railtie
|
|
4
|
+
class Railtie < Rails::Railtie
|
|
5
|
+
initializer 'arel.middleware.insert' do
|
|
6
|
+
ActiveSupport.on_load :active_record do
|
|
7
|
+
Arel::Middleware::Railtie.insert_postgresql
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
3
13
|
class Railtie
|
|
4
14
|
def self.insert_postgresql
|
|
5
15
|
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend(
|
data/lib/arel/sql_to_arel.rb
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
require_relative './sql_to_arel/result'
|
|
2
|
+
require_relative './sql_to_arel/error'
|
|
3
|
+
require_relative './sql_to_arel/pg_query_visitor'
|
|
4
4
|
|
|
5
5
|
module Arel
|
|
6
|
+
module SqlToArel
|
|
7
|
+
end
|
|
8
|
+
|
|
6
9
|
def self.sql_to_arel(sql, binds: [])
|
|
7
10
|
SqlToArel::PgQueryVisitor.new.accept(sql, binds)
|
|
8
11
|
end
|
|
@@ -278,17 +278,21 @@ module Arel
|
|
|
278
278
|
end
|
|
279
279
|
|
|
280
280
|
def visit_ColumnRef(fields:)
|
|
281
|
-
|
|
281
|
+
case fields.length
|
|
282
|
+
when 1
|
|
283
|
+
visited_field = visit(fields[0], :operator)
|
|
284
|
+
Arel::Nodes::UnqualifiedColumn.new Arel::Attribute.new(nil, visited_field)
|
|
282
285
|
|
|
283
|
-
|
|
286
|
+
when 2
|
|
284
287
|
table_reference, column_reference = fields
|
|
285
288
|
table_reference = visit(table_reference, :operator)
|
|
286
289
|
table = Arel::Table.new(table_reference)
|
|
287
290
|
|
|
288
291
|
column_reference = visit(column_reference, :operator)
|
|
289
292
|
table[column_reference]
|
|
293
|
+
|
|
290
294
|
else
|
|
291
|
-
|
|
295
|
+
raise 'Can\'t deal with column refs that have more than 2 fields'
|
|
292
296
|
end
|
|
293
297
|
end
|
|
294
298
|
|
|
@@ -423,11 +427,20 @@ module Arel
|
|
|
423
427
|
[Arel::Nodes::Overlaps.new(start1, end1, start2, end2)]
|
|
424
428
|
|
|
425
429
|
else
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
430
|
+
case function_names.length
|
|
431
|
+
when 2
|
|
432
|
+
if function_names.first == PG_CATALOG
|
|
433
|
+
boom "Missing postgres function `#{function_names.last}`"
|
|
434
|
+
end
|
|
429
435
|
|
|
430
|
-
|
|
436
|
+
func = Arel::Nodes::NamedFunction.new(function_names.last, args)
|
|
437
|
+
func.schema_name = function_names.first
|
|
438
|
+
func
|
|
439
|
+
when 1
|
|
440
|
+
Arel::Nodes::NamedFunction.new(function_names.first, args)
|
|
441
|
+
else
|
|
442
|
+
boom "Don't know how to handle function names length `#{function_names.length}`"
|
|
443
|
+
end
|
|
431
444
|
end
|
|
432
445
|
|
|
433
446
|
func.distinct = (agg_distinct.nil? ? false : true) unless func.is_a?(::Array)
|
|
@@ -444,17 +457,16 @@ module Arel
|
|
|
444
457
|
end
|
|
445
458
|
|
|
446
459
|
def visit_InferClause(conname: nil, index_elems: nil)
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
infer
|
|
460
|
+
left = Arel.sql(conname) if conname
|
|
461
|
+
right = visit(index_elems) if index_elems
|
|
462
|
+
Arel::Nodes::Infer.new left, right
|
|
451
463
|
end
|
|
452
464
|
|
|
453
465
|
def visit_IndexElem(name:, ordering:, nulls_ordering:)
|
|
454
466
|
boom "Unknown ordering `#{ordering}`" unless ordering.zero?
|
|
455
467
|
boom "Unknown nulls ordering `#{ordering}`" unless nulls_ordering.zero?
|
|
456
468
|
|
|
457
|
-
Arel.sql(name)
|
|
469
|
+
Arel.sql visit_String(str: name)
|
|
458
470
|
end
|
|
459
471
|
|
|
460
472
|
def visit_InsertStmt(
|
|
@@ -494,6 +506,12 @@ module Arel
|
|
|
494
506
|
ival
|
|
495
507
|
end
|
|
496
508
|
|
|
509
|
+
def visit_IntoClause(rel:, on_commit:)
|
|
510
|
+
raise "Unknown on_commit `#{on_commit}`" unless on_commit.zero?
|
|
511
|
+
|
|
512
|
+
Arel::Nodes::Into.new(visit(rel))
|
|
513
|
+
end
|
|
514
|
+
|
|
497
515
|
def visit_JoinExpr(jointype:, is_natural: nil, larg:, rarg:, quals: nil)
|
|
498
516
|
join_class = case jointype
|
|
499
517
|
when 0
|
|
@@ -531,12 +549,12 @@ module Arel
|
|
|
531
549
|
1 => 'FOR KEY SHARE',
|
|
532
550
|
2 => 'FOR SHARE',
|
|
533
551
|
3 => 'FOR NO KEY UPDATE',
|
|
534
|
-
4 => 'FOR UPDATE'
|
|
552
|
+
4 => 'FOR UPDATE',
|
|
535
553
|
}.fetch(strength)
|
|
536
554
|
wait_policy_clause = {
|
|
537
555
|
0 => '',
|
|
538
556
|
1 => ' SKIP LOCKED',
|
|
539
|
-
2 => ' NOWAIT'
|
|
557
|
+
2 => ' NOWAIT',
|
|
540
558
|
}.fetch(wait_policy)
|
|
541
559
|
|
|
542
560
|
Arel::Nodes::Lock.new Arel.sql("#{strength_clause}#{wait_policy_clause}")
|
|
@@ -669,6 +687,7 @@ module Arel
|
|
|
669
687
|
op:,
|
|
670
688
|
window_clause: nil,
|
|
671
689
|
values_lists: nil,
|
|
690
|
+
into_clause: nil,
|
|
672
691
|
all: nil,
|
|
673
692
|
larg: nil,
|
|
674
693
|
rarg: nil
|
|
@@ -702,6 +721,7 @@ module Arel
|
|
|
702
721
|
select_core.groups = visit(group_clause) if group_clause
|
|
703
722
|
select_core.havings = [visit(having_clause)] if having_clause
|
|
704
723
|
select_core.windows = visit(window_clause) if window_clause
|
|
724
|
+
select_core.into = visit(into_clause) if into_clause
|
|
705
725
|
|
|
706
726
|
if distinct_clause == [nil]
|
|
707
727
|
select_core.set_quantifier = Arel::Nodes::Distinct.new
|
|
@@ -726,7 +746,7 @@ module Arel
|
|
|
726
746
|
value
|
|
727
747
|
when Integer
|
|
728
748
|
Arel.sql(value.to_s)
|
|
729
|
-
when Arel::Nodes::TypeCast
|
|
749
|
+
when Arel::Nodes::TypeCast, Arel::Nodes::UnqualifiedColumn
|
|
730
750
|
Arel.sql(value.to_sql)
|
|
731
751
|
when Arel::Nodes::BindParam
|
|
732
752
|
value
|
|
@@ -1077,6 +1097,14 @@ module Arel
|
|
|
1077
1097
|
end
|
|
1078
1098
|
end
|
|
1079
1099
|
|
|
1100
|
+
def visit_DeallocateStmt(name: nil)
|
|
1101
|
+
Arel::Nodes::Dealocate.new name
|
|
1102
|
+
end
|
|
1103
|
+
|
|
1104
|
+
def visit_PrepareStmt(name:, argtypes: nil, query:)
|
|
1105
|
+
Arel::Nodes::Prepare.new name, argtypes && visit(argtypes), visit(query)
|
|
1106
|
+
end
|
|
1107
|
+
|
|
1080
1108
|
def visit(attribute, context = nil)
|
|
1081
1109
|
return attribute.map { |attr| visit(attr, context) } if attribute.is_a? Array
|
|
1082
1110
|
|