arel_toolkit 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.codeclimate.yml +29 -0
- data/.gitignore +5 -0
- data/.rubocop.yml +34 -0
- data/.ruby-version +1 -1
- data/.travis.yml +16 -2
- data/CHANGELOG.md +10 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +94 -1
- data/Guardfile +42 -0
- data/README.md +23 -4
- data/Rakefile +3 -3
- data/arel_toolkit.gemspec +32 -15
- data/bin/console +4 -7
- data/lib/arel/extensions.rb +71 -0
- data/lib/arel/extensions/absolute.rb +10 -0
- data/lib/arel/extensions/all.rb +23 -0
- data/lib/arel/extensions/any.rb +23 -0
- data/lib/arel/extensions/array.rb +29 -0
- data/lib/arel/extensions/array_subselect.rb +23 -0
- data/lib/arel/extensions/between_symmetric.rb +23 -0
- data/lib/arel/extensions/bit_string.rb +27 -0
- data/lib/arel/extensions/bitwise_xor.rb +10 -0
- data/lib/arel/extensions/coalesce.rb +9 -0
- data/lib/arel/extensions/conflict.rb +47 -0
- data/lib/arel/extensions/contained_by.rb +10 -0
- data/lib/arel/extensions/contains.rb +10 -0
- data/lib/arel/extensions/cross_join.rb +21 -0
- data/lib/arel/extensions/cube_root.rb +10 -0
- data/lib/arel/extensions/current_catalog.rb +20 -0
- data/lib/arel/extensions/current_date.rb +20 -0
- data/lib/arel/extensions/current_of_expression.rb +29 -0
- data/lib/arel/extensions/current_role.rb +20 -0
- data/lib/arel/extensions/current_schema.rb +20 -0
- data/lib/arel/extensions/current_time.rb +22 -0
- data/lib/arel/extensions/current_timestamp.rb +22 -0
- data/lib/arel/extensions/current_user.rb +20 -0
- data/lib/arel/extensions/default_values.rb +21 -0
- data/lib/arel/extensions/delete_statement.rb +49 -0
- data/lib/arel/extensions/distinct_from.rb +22 -0
- data/lib/arel/extensions/equality.rb +30 -0
- data/lib/arel/extensions/except_all.rb +21 -0
- data/lib/arel/extensions/exponentiation.rb +10 -0
- data/lib/arel/extensions/factorial.rb +33 -0
- data/lib/arel/extensions/function.rb +68 -0
- data/lib/arel/extensions/generate_series.rb +9 -0
- data/lib/arel/extensions/greatest.rb +9 -0
- data/lib/arel/extensions/indirection.rb +32 -0
- data/lib/arel/extensions/infer.rb +35 -0
- data/lib/arel/extensions/insert_statement.rb +69 -0
- data/lib/arel/extensions/intersect_all.rb +21 -0
- data/lib/arel/extensions/lateral.rb +34 -0
- data/lib/arel/extensions/least.rb +9 -0
- data/lib/arel/extensions/local_time.rb +22 -0
- data/lib/arel/extensions/local_timestamp.rb +22 -0
- data/lib/arel/extensions/modulo.rb +10 -0
- data/lib/arel/extensions/named_function.rb +15 -0
- data/lib/arel/extensions/natural_join.rb +21 -0
- data/lib/arel/extensions/not_between.rb +22 -0
- data/lib/arel/extensions/not_between_symmetric.rb +23 -0
- data/lib/arel/extensions/not_distinct_from.rb +22 -0
- data/lib/arel/extensions/not_equal.rb +30 -0
- data/lib/arel/extensions/not_similar.rb +29 -0
- data/lib/arel/extensions/null_if.rb +24 -0
- data/lib/arel/extensions/ordering.rb +47 -0
- data/lib/arel/extensions/overlap.rb +10 -0
- data/lib/arel/extensions/range_function.rb +23 -0
- data/lib/arel/extensions/rank.rb +9 -0
- data/lib/arel/extensions/row.rb +30 -0
- data/lib/arel/extensions/select_statement.rb +26 -0
- data/lib/arel/extensions/session_user.rb +20 -0
- data/lib/arel/extensions/set_to_default.rb +21 -0
- data/lib/arel/extensions/similar.rb +32 -0
- data/lib/arel/extensions/square_root.rb +10 -0
- data/lib/arel/extensions/table.rb +49 -0
- data/lib/arel/extensions/time_with_precision.rb +13 -0
- data/lib/arel/extensions/type_cast.rb +30 -0
- data/lib/arel/extensions/unknown.rb +20 -0
- data/lib/arel/extensions/update_statement.rb +63 -0
- data/lib/arel/extensions/user.rb +20 -0
- data/lib/arel/extensions/with_ordinality.rb +22 -0
- data/lib/arel/sql_to_arel.rb +8 -0
- data/lib/arel/sql_to_arel/frame_options.rb +110 -0
- data/lib/arel/sql_to_arel/pg_query_visitor.rb +1005 -0
- data/lib/arel/sql_to_arel/unbound_column_reference.rb +5 -0
- data/lib/arel_toolkit.rb +4 -3
- data/lib/arel_toolkit/version.rb +1 -1
- metadata +250 -4
@@ -0,0 +1,22 @@
|
|
1
|
+
# rubocop:disable Naming/MethodName
|
2
|
+
# rubocop:disable Naming/UncommunicativeMethodParamName
|
3
|
+
|
4
|
+
module Arel
|
5
|
+
module Nodes
|
6
|
+
class CurrentTimestamp < TimeWithPrecision
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
module Visitors
|
11
|
+
class ToSql
|
12
|
+
def visit_Arel_Nodes_CurrentTimestamp(o, collector)
|
13
|
+
collector << 'current_timestamp'
|
14
|
+
collector << "(#{o.precision.to_i})" if o.precision
|
15
|
+
collector
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# rubocop:enable Naming/MethodName
|
22
|
+
# rubocop:enable Naming/UncommunicativeMethodParamName
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# rubocop:disable Naming/MethodName
|
2
|
+
# rubocop:disable Naming/UncommunicativeMethodParamName
|
3
|
+
|
4
|
+
module Arel
|
5
|
+
module Nodes
|
6
|
+
class CurrentUser < Arel::Nodes::Node
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
module Visitors
|
11
|
+
class ToSql
|
12
|
+
def visit_Arel_Nodes_CurrentUser(_o, collector)
|
13
|
+
collector << 'current_user'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# rubocop:enable Naming/MethodName
|
20
|
+
# rubocop:enable Naming/UncommunicativeMethodParamName
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# rubocop:disable Naming/MethodName
|
2
|
+
# rubocop:disable Naming/UncommunicativeMethodParamName
|
3
|
+
|
4
|
+
module Arel
|
5
|
+
module Nodes
|
6
|
+
# https://www.postgresql.org/docs/9.5/sql-insert.html
|
7
|
+
class DefaultValues < Arel::Nodes::Node
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
module Visitors
|
12
|
+
class ToSql
|
13
|
+
def visit_Arel_Nodes_DefaultValues(_o, collector)
|
14
|
+
collector << 'DEFAULT VALUES'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# rubocop:enable Naming/MethodName
|
21
|
+
# rubocop:enable Naming/UncommunicativeMethodParamName
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# rubocop:disable Naming/MethodName
|
2
|
+
# rubocop:disable Naming/UncommunicativeMethodParamName
|
3
|
+
|
4
|
+
module Arel
|
5
|
+
module Nodes
|
6
|
+
# https://www.postgresql.org/docs/9.5/sql-insert.html
|
7
|
+
Arel::Nodes::DeleteStatement.class_eval do
|
8
|
+
attr_accessor :using
|
9
|
+
attr_accessor :with
|
10
|
+
attr_accessor :returning
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
module Visitors
|
15
|
+
class ToSql
|
16
|
+
# rubocop:disable Metrics/AbcSize
|
17
|
+
def visit_Arel_Nodes_DeleteStatement(o, collector)
|
18
|
+
if o.with
|
19
|
+
collector = visit o.with, collector
|
20
|
+
collector << SPACE
|
21
|
+
end
|
22
|
+
|
23
|
+
collector << 'DELETE FROM '
|
24
|
+
collector = visit o.relation, collector
|
25
|
+
|
26
|
+
if o.using
|
27
|
+
collector << ' USING '
|
28
|
+
collector = inject_join o.using, collector, ', '
|
29
|
+
end
|
30
|
+
|
31
|
+
if o.wheres.any?
|
32
|
+
collector << WHERE
|
33
|
+
collector = inject_join o.wheres, collector, AND
|
34
|
+
end
|
35
|
+
|
36
|
+
unless o.returning.empty?
|
37
|
+
collector << ' RETURNING '
|
38
|
+
collector = inject_join o.returning, collector, ', '
|
39
|
+
end
|
40
|
+
|
41
|
+
maybe_visit o.limit, collector
|
42
|
+
end
|
43
|
+
# rubocop:enable Metrics/AbcSize
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# rubocop:enable Naming/MethodName
|
49
|
+
# rubocop:enable Naming/UncommunicativeMethodParamName
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# rubocop:disable Naming/MethodName
|
2
|
+
# rubocop:disable Naming/UncommunicativeMethodParamName
|
3
|
+
|
4
|
+
module Arel
|
5
|
+
module Nodes
|
6
|
+
class DistinctFrom < Arel::Nodes::Binary
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
module Visitors
|
11
|
+
class ToSql
|
12
|
+
def visit_Arel_Nodes_DistinctFrom(o, collector)
|
13
|
+
visit o.left, collector
|
14
|
+
collector << ' IS DISTINCT FROM '
|
15
|
+
visit o.right, collector
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# rubocop:enable Naming/MethodName
|
22
|
+
# rubocop:enable Naming/UncommunicativeMethodParamName
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# rubocop:disable Naming/MethodName
|
2
|
+
# rubocop:disable Naming/UncommunicativeMethodParamName
|
3
|
+
|
4
|
+
module Arel
|
5
|
+
module Visitors
|
6
|
+
class ToSql
|
7
|
+
def visit_Arel_Nodes_Equality(o, collector)
|
8
|
+
right = o.right
|
9
|
+
|
10
|
+
collector = visit o.left, collector
|
11
|
+
|
12
|
+
case right
|
13
|
+
when Arel::Nodes::Unknown, Arel::Nodes::False, Arel::Nodes::True
|
14
|
+
collector << ' IS '
|
15
|
+
visit right, collector
|
16
|
+
|
17
|
+
when NilClass
|
18
|
+
collector << ' IS NULL'
|
19
|
+
|
20
|
+
else
|
21
|
+
collector << ' = '
|
22
|
+
visit right, collector
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# rubocop:enable Naming/MethodName
|
30
|
+
# rubocop:enable Naming/UncommunicativeMethodParamName
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# rubocop:disable Naming/MethodName
|
2
|
+
# rubocop:disable Naming/UncommunicativeMethodParamName
|
3
|
+
|
4
|
+
module Arel
|
5
|
+
module Nodes
|
6
|
+
class ExceptAll < Binary
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
module Visitors
|
11
|
+
class ToSql
|
12
|
+
def visit_Arel_Nodes_ExceptAll(o, collector)
|
13
|
+
collector << '( '
|
14
|
+
infix_value(o, collector, ' EXCEPT ALL ') << ' )'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# rubocop:enable Naming/MethodName
|
21
|
+
# rubocop:enable Naming/UncommunicativeMethodParamName
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# rubocop:disable Naming/MethodName
|
2
|
+
# rubocop:disable Naming/UncommunicativeMethodParamName
|
3
|
+
|
4
|
+
module Arel
|
5
|
+
module Nodes
|
6
|
+
# https://www.postgresql.org/docs/9.4/functions-math.html
|
7
|
+
class Factorial < Arel::Nodes::Unary
|
8
|
+
attr_accessor :prefix
|
9
|
+
|
10
|
+
def initialize(expr, prefix)
|
11
|
+
super(expr)
|
12
|
+
@prefix = prefix
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
module Visitors
|
18
|
+
class ToSql
|
19
|
+
def visit_Arel_Nodes_Factorial(o, collector)
|
20
|
+
if o.prefix
|
21
|
+
collector << '!! '
|
22
|
+
visit o.expr, collector
|
23
|
+
else
|
24
|
+
visit o.expr, collector
|
25
|
+
collector << ' !'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# rubocop:enable Naming/UncommunicativeMethodParamName
|
33
|
+
# rubocop:enable Naming/MethodName
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# rubocop:disable Naming/UncommunicativeMethodParamName
|
2
|
+
|
3
|
+
module Arel
|
4
|
+
module Nodes
|
5
|
+
# Postgres: https://www.postgresql.org/docs/9.1/functions-comparison.html
|
6
|
+
Arel::Nodes::Function.class_eval do
|
7
|
+
# postgres only: https://www.postgresql.org/docs/9.5/functions-aggregate.html
|
8
|
+
attr_accessor :orders
|
9
|
+
attr_accessor :filter
|
10
|
+
attr_accessor :within_group
|
11
|
+
attr_accessor :variardic
|
12
|
+
|
13
|
+
def initialize(expr, aliaz = nil)
|
14
|
+
super()
|
15
|
+
@expressions = expr
|
16
|
+
@alias = aliaz && SqlLiteral.new(aliaz)
|
17
|
+
@distinct = false
|
18
|
+
@orders = []
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
module Visitors
|
24
|
+
class ToSql
|
25
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
26
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
27
|
+
# rubocop:disable Metrics/AbcSize
|
28
|
+
def aggregate(name, o, collector)
|
29
|
+
collector << "#{name}("
|
30
|
+
collector << 'DISTINCT ' if o.distinct
|
31
|
+
collector << 'VARIADIC ' if o.variardic
|
32
|
+
|
33
|
+
collector = inject_join(o.expressions, collector, ', ')
|
34
|
+
|
35
|
+
if o.within_group
|
36
|
+
collector << ')'
|
37
|
+
collector << ' WITHIN GROUP ('
|
38
|
+
end
|
39
|
+
|
40
|
+
if o.orders.any?
|
41
|
+
collector << SPACE unless o.within_group
|
42
|
+
collector << 'ORDER BY '
|
43
|
+
collector = inject_join o.orders, collector, ', '
|
44
|
+
end
|
45
|
+
|
46
|
+
collector << ')'
|
47
|
+
|
48
|
+
if o.filter
|
49
|
+
collector << ' FILTER(WHERE '
|
50
|
+
visit o.filter, collector
|
51
|
+
collector << ')'
|
52
|
+
end
|
53
|
+
|
54
|
+
if o.alias
|
55
|
+
collector << ' AS '
|
56
|
+
visit o.alias, collector
|
57
|
+
else
|
58
|
+
collector
|
59
|
+
end
|
60
|
+
end
|
61
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
62
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
63
|
+
# rubocop:enable Metrics/AbcSize
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# rubocop:enable Naming/UncommunicativeMethodParamName
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# rubocop:disable Naming/MethodName
|
2
|
+
# rubocop:disable Naming/UncommunicativeMethodParamName
|
3
|
+
|
4
|
+
module Arel
|
5
|
+
module Nodes
|
6
|
+
class Indirection < Arel::Nodes::Node
|
7
|
+
attr_reader :arg
|
8
|
+
attr_reader :indirection
|
9
|
+
|
10
|
+
def initialize(arg, indirection)
|
11
|
+
super()
|
12
|
+
|
13
|
+
@arg = arg
|
14
|
+
@indirection = indirection
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
module Visitors
|
20
|
+
class ToSql
|
21
|
+
def visit_Arel_Nodes_Indirection(o, collector)
|
22
|
+
visit(o.arg, collector)
|
23
|
+
collector << '['
|
24
|
+
visit(o.indirection, collector)
|
25
|
+
collector << ']'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# rubocop:enable Naming/MethodName
|
32
|
+
# rubocop:enable Naming/UncommunicativeMethodParamName
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# rubocop:disable Naming/MethodName
|
2
|
+
# rubocop:disable Naming/UncommunicativeMethodParamName
|
3
|
+
|
4
|
+
module Arel
|
5
|
+
module Nodes
|
6
|
+
# https://www.postgresql.org/docs/9.5/sql-insert.html
|
7
|
+
class Infer < Arel::Nodes::Node
|
8
|
+
attr_accessor :name
|
9
|
+
attr_accessor :indexes
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
module Visitors
|
14
|
+
class ToSql
|
15
|
+
def visit_Arel_Nodes_Infer(o, collector)
|
16
|
+
if o.name
|
17
|
+
collector << 'ON CONSTRAINT '
|
18
|
+
collector << o.name
|
19
|
+
collector << SPACE
|
20
|
+
end
|
21
|
+
|
22
|
+
if o.indexes
|
23
|
+
collector << '('
|
24
|
+
inject_join o.indexes, collector, ', '
|
25
|
+
collector << ') '
|
26
|
+
end
|
27
|
+
|
28
|
+
collector
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# rubocop:enable Naming/MethodName
|
35
|
+
# rubocop:enable Naming/UncommunicativeMethodParamName
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# rubocop:disable Naming/MethodName
|
2
|
+
# rubocop:disable Naming/UncommunicativeMethodParamName
|
3
|
+
|
4
|
+
module Arel
|
5
|
+
module Nodes
|
6
|
+
# https://www.postgresql.org/docs/9.5/sql-insert.html
|
7
|
+
Arel::Nodes::InsertStatement.class_eval do
|
8
|
+
attr_accessor :with
|
9
|
+
attr_accessor :on_conflict
|
10
|
+
attr_accessor :override
|
11
|
+
attr_accessor :returning
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
module Visitors
|
16
|
+
class ToSql
|
17
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
18
|
+
# rubocop:disable Metrics/AbcSize
|
19
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
20
|
+
def visit_Arel_Nodes_InsertStatement(o, collector)
|
21
|
+
if o.with
|
22
|
+
collector = visit o.with, collector
|
23
|
+
collector << SPACE
|
24
|
+
end
|
25
|
+
|
26
|
+
collector << 'INSERT INTO '
|
27
|
+
collector = visit o.relation, collector
|
28
|
+
if o.columns.any?
|
29
|
+
collector << " (#{o.columns.map do |x|
|
30
|
+
quote_column_name x.name
|
31
|
+
end.join ', '})"
|
32
|
+
end
|
33
|
+
|
34
|
+
case o.override
|
35
|
+
when 0
|
36
|
+
collector << ''
|
37
|
+
when 1
|
38
|
+
collector << ' OVERRIDING USER VALUE'
|
39
|
+
when 2
|
40
|
+
collector << ' OVERRIDING SYSTEM VALUE'
|
41
|
+
else
|
42
|
+
raise "Unknown override `#{o.override}`"
|
43
|
+
end
|
44
|
+
|
45
|
+
collector = if o.values
|
46
|
+
maybe_visit o.values, collector
|
47
|
+
elsif o.select
|
48
|
+
maybe_visit o.select, collector
|
49
|
+
else
|
50
|
+
collector
|
51
|
+
end
|
52
|
+
|
53
|
+
unless o.returning.empty?
|
54
|
+
collector << ' RETURNING '
|
55
|
+
collector = inject_join o.returning, collector, ', '
|
56
|
+
end
|
57
|
+
|
58
|
+
visit(o.on_conflict, collector) if o.on_conflict
|
59
|
+
collector
|
60
|
+
end
|
61
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
62
|
+
# rubocop:enable Metrics/AbcSize
|
63
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# rubocop:enable Naming/MethodName
|
69
|
+
# rubocop:enable Naming/UncommunicativeMethodParamName
|