arel_toolkit 0.1.0 → 0.2.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 +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
|