arel_extensions 0.8.3 → 0.8.4
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/.travis/oracle/download.js +116 -0
- data/.travis/oracle/download.sh +16 -0
- data/.travis/oracle/install.sh +32 -0
- data/.travis.yml +72 -69
- data/Rakefile +29 -4
- data/arel_extensions.gemspec +1 -1
- data/functions.html +21 -12
- data/gemfiles/rails4.gemfile +11 -3
- data/gemfiles/rails5.gemfile +8 -4
- data/lib/arel_extensions/math.rb +2 -2
- data/lib/arel_extensions/math_functions.rb +1 -1
- data/lib/arel_extensions/nodes/concat.rb +16 -0
- data/lib/arel_extensions/nodes/date_diff.rb +37 -25
- data/lib/arel_extensions/nodes/function.rb +30 -0
- data/lib/arel_extensions/nodes/is_null.rb +6 -0
- data/lib/arel_extensions/nodes/replace.rb +8 -26
- data/lib/arel_extensions/nodes/round.rb +6 -6
- data/lib/arel_extensions/nodes.rb +1 -1
- data/lib/arel_extensions/null_functions.rb +2 -2
- data/lib/arel_extensions/string_functions.rb +5 -1
- data/lib/arel_extensions/version.rb +1 -1
- data/lib/arel_extensions/visitors/mysql.rb +89 -113
- data/lib/arel_extensions/visitors/oracle.rb +28 -65
- data/lib/arel_extensions/visitors/postgresql.rb +82 -121
- data/lib/arel_extensions/visitors/sqlite.rb +60 -55
- data/lib/arel_extensions/visitors/to_sql.rb +30 -5
- data/test/database.yml +15 -3
- data/test/real_db_test.rb +0 -1
- data/test/visitors/test_bulk_insert_sqlite.rb +2 -1
- data/test/visitors/test_oracle.rb +2 -2
- data/test/visitors/test_to_sql.rb +3 -4
- data/test/with_ar/all_agnostic_test.rb +294 -0
- data/test/with_ar/insert_agnostic_test.rb +52 -0
- data/test/with_ar/test_bulk_sqlite.rb +3 -2
- metadata +10 -5
- data/lib/arel_extensions/nodes/isnull.rb +0 -30
- data/test/with_ar/test_string_postgresql.rb +0 -81
@@ -41,6 +41,36 @@ module ArelExtensions
|
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
|
+
def convert_to_date_node(object)
|
45
|
+
case object
|
46
|
+
when Arel::Attributes::Attribute, Arel::Nodes::Node
|
47
|
+
object
|
48
|
+
when DateTime, Time
|
49
|
+
Arel::Nodes.build_quoted(Date.new(object.year, object.month, object.day), self)
|
50
|
+
when String
|
51
|
+
Arel::Nodes.build_quoted(Date.parse(object), self)
|
52
|
+
when Date
|
53
|
+
Arel::Nodes.build_quoted(object, self)
|
54
|
+
else
|
55
|
+
raise(ArgumentError, "#{object.class} can not be converted to Date")
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def convert_to_number(object)
|
60
|
+
case object
|
61
|
+
when Arel::Attributes::Attribute, Arel::Nodes::Node
|
62
|
+
object
|
63
|
+
when Fixnum, Integer
|
64
|
+
object.to_i.abs
|
65
|
+
when DateTime, Date, Time, String, ActiveSupport::Duration
|
66
|
+
object.to_i.abs
|
67
|
+
when NilClass
|
68
|
+
0
|
69
|
+
else
|
70
|
+
raise(ArgumentError, "#{object.class} can not be converted to NUMBER arg")
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
44
74
|
end
|
45
75
|
end
|
46
76
|
end
|
@@ -1,34 +1,16 @@
|
|
1
1
|
module ArelExtensions
|
2
2
|
module Nodes
|
3
|
-
class Replace <
|
3
|
+
class Replace < Function
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
tab
|
10
|
-
tab << right
|
11
|
-
super(tab, aliaz)
|
12
|
-
end
|
13
|
-
|
14
|
-
|
15
|
-
def expr
|
16
|
-
@expressions.first
|
5
|
+
def initialize expr
|
6
|
+
tab = expr.map { |arg|
|
7
|
+
convert_to_node(arg)
|
8
|
+
}
|
9
|
+
return super(tab)
|
17
10
|
end
|
18
11
|
|
19
|
-
|
20
|
-
|
21
|
-
@expressions[1]
|
22
|
-
end
|
23
|
-
|
24
|
-
|
25
|
-
def right
|
26
|
-
@expressions[2]
|
27
|
-
end
|
28
|
-
|
29
|
-
|
30
|
-
def as other
|
31
|
-
Arel::Nodes::As.new self, Arel::Nodes::SqlLiteral.new(other)
|
12
|
+
def +(other)
|
13
|
+
return ArelExtensions::Nodes::Concat.new(self.expressions + [other])
|
32
14
|
end
|
33
15
|
|
34
16
|
end
|
@@ -2,14 +2,14 @@ module ArelExtensions
|
|
2
2
|
module Nodes
|
3
3
|
class Round < Function
|
4
4
|
|
5
|
-
def
|
6
|
-
|
5
|
+
def initialize expr
|
6
|
+
if expr && expr.length == 1
|
7
|
+
super [convert_to_node(expr.first)]
|
8
|
+
else
|
9
|
+
super [convert_to_node(expr.first), convert_to_number(expr[1])]
|
10
|
+
end
|
7
11
|
end
|
8
12
|
|
9
|
-
|
10
|
-
def right
|
11
|
-
@expressions[1]
|
12
|
-
end
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
@@ -2,8 +2,8 @@ module ArelExtensions
|
|
2
2
|
module NullFunctions
|
3
3
|
|
4
4
|
#ISNULL function lets you return an alternative value when an expression is NULL.
|
5
|
-
def
|
6
|
-
ArelExtensions::Nodes::
|
5
|
+
def is_null
|
6
|
+
ArelExtensions::Nodes::IsNull.new [self]
|
7
7
|
end
|
8
8
|
# returns the first non-null expr in the expression list. You must specify at least two expressions.
|
9
9
|
#If all occurrences of expr evaluate to null, then the function returns null.
|
@@ -48,7 +48,11 @@ module ArelExtensions
|
|
48
48
|
|
49
49
|
#REPLACE function replaces a sequence of characters in a string with another set of characters, not case-sensitive.
|
50
50
|
def replace left, right
|
51
|
-
ArelExtensions::Nodes::Replace.new self, left, right
|
51
|
+
ArelExtensions::Nodes::Replace.new [self, left, right]
|
52
|
+
end
|
53
|
+
|
54
|
+
def group_concat sep = nil
|
55
|
+
ArelExtensions::Nodes::GroupConcat.new [self, sep]
|
52
56
|
end
|
53
57
|
|
54
58
|
#Function returns a string after removing left, right or the both prefixes or suffixes int argument
|
@@ -2,39 +2,31 @@ module ArelExtensions
|
|
2
2
|
module Visitors
|
3
3
|
Arel::Visitors::MySQL.class_eval do
|
4
4
|
|
5
|
-
|
6
|
-
def
|
7
|
-
collector << "DATEDIFF("
|
5
|
+
#String functions
|
6
|
+
def visit_ArelExtensions_Nodes_IMatches o, collector # insensitive on ASCII
|
8
7
|
collector = visit o.left, collector
|
9
|
-
collector <<
|
8
|
+
collector << ' LIKE '
|
10
9
|
collector = visit o.right, collector
|
11
|
-
|
12
|
-
|
10
|
+
if o.escape
|
11
|
+
collector << ' ESCAPE '
|
12
|
+
visit o.escape, collector
|
13
|
+
else
|
14
|
+
collector
|
15
|
+
end
|
13
16
|
end
|
14
17
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
elsif (o.left == "w")
|
23
|
-
collector << "WEEK("
|
24
|
-
elsif (o.left == "y")
|
25
|
-
collector << "YEAR("
|
26
|
-
end
|
27
|
-
#visit right
|
28
|
-
if(o.right.is_a?(Arel::Attributes::Attribute))
|
29
|
-
collector = visit o.right, collector
|
18
|
+
def visit_ArelExtensions_Nodes_IDoesNotMatch o, collector
|
19
|
+
collector = visit o.left.lower, collector
|
20
|
+
collector << ' NOT LIKE '
|
21
|
+
collector = visit o.right.lower(o.right), collector
|
22
|
+
if o.escape
|
23
|
+
collector << ' ESCAPE '
|
24
|
+
visit o.escape, collector
|
30
25
|
else
|
31
|
-
collector
|
26
|
+
collector
|
32
27
|
end
|
33
|
-
collector << ")"
|
34
|
-
collector
|
35
28
|
end
|
36
29
|
|
37
|
-
#****************************************************************#
|
38
30
|
def visit_ArelExtensions_Nodes_Concat o, collector
|
39
31
|
collector << "CONCAT("
|
40
32
|
o.expressions.each_with_index { |arg, i|
|
@@ -45,123 +37,107 @@ module ArelExtensions
|
|
45
37
|
collector
|
46
38
|
end
|
47
39
|
|
48
|
-
|
49
|
-
|
50
|
-
collector
|
51
|
-
if
|
52
|
-
collector
|
53
|
-
|
54
|
-
collector << "#{o.left}"
|
40
|
+
def visit_ArelExtensions_Nodes_GroupConcat o, collector
|
41
|
+
collector << "GROUP_CONCAT("
|
42
|
+
collector = visit o.left, collector
|
43
|
+
if o.right
|
44
|
+
collector << ' SEPARATOR '
|
45
|
+
collector = visit o.right, collector
|
55
46
|
end
|
56
|
-
o.other.each { |a|
|
57
|
-
collector << ","
|
58
|
-
if(a.is_a?(Arel::Attributes::Attribute))
|
59
|
-
collector = visit a, collector
|
60
|
-
else
|
61
|
-
collector << "#{a}"
|
62
|
-
end
|
63
|
-
}
|
64
|
-
collector << ")"
|
65
|
-
collector
|
66
|
-
end
|
67
|
-
|
68
|
-
def visit_ArelExtensions_Nodes_Isnull o, collector
|
69
|
-
collector << "IFNULL("
|
70
|
-
collector = visit o.left, collector
|
71
|
-
collector << ","
|
72
|
-
if(o.right.is_a?(Arel::Attributes::Attribute))
|
73
|
-
collector = visit o.right, collector
|
74
|
-
else
|
75
|
-
collector << "'#{o.right}'"
|
76
|
-
end
|
77
|
-
collector << ")"
|
78
|
-
collector
|
79
|
-
end
|
80
|
-
|
81
|
-
|
82
|
-
def visit_ArelExtensions_Nodes_Replace o, collector
|
83
|
-
collector << "REPLACE("
|
84
|
-
collector = visit o.expr,collector
|
85
|
-
collector << ","
|
86
|
-
if(o.left.is_a?(Arel::Attributes::Attribute))
|
87
|
-
collector = visit o.left, collector
|
88
|
-
else
|
89
|
-
collector << "'#{o.left}'"
|
90
|
-
end
|
91
|
-
collector << ","
|
92
|
-
if(o.right.is_a?(Arel::Attributes::Attribute))
|
93
|
-
collector = visit o.right, collector
|
94
|
-
else
|
95
|
-
collector << "'#{o.right}'"
|
96
|
-
end
|
97
|
-
collector << ")"
|
98
|
-
collector
|
99
|
-
end
|
100
|
-
|
101
|
-
|
102
|
-
def visit_ArelExtensions_Nodes_Soundex o, collector
|
103
|
-
collector << "SOUNDEX("
|
104
|
-
if((o.expr).is_a?(Arel::Attributes::Attribute))
|
105
|
-
collector = visit o.expr, collector
|
106
|
-
else
|
107
|
-
collector << "'#{o.expr}'"
|
108
|
-
end
|
109
47
|
collector << ")"
|
110
48
|
collector
|
111
49
|
end
|
112
50
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
collector << 'TRIM(BOTH '
|
117
|
-
if(o.right.is_a?(Arel::Attributes::Attribute))
|
118
|
-
collector = visit o.right, collector
|
119
|
-
else
|
120
|
-
collector << "'#{o.right}'"
|
121
|
-
end
|
51
|
+
def visit_ArelExtensions_Nodes_Trim o, collector
|
52
|
+
collector << 'TRIM(' # BOTH
|
53
|
+
collector = visit o.right, collector
|
122
54
|
collector << " FROM "
|
123
55
|
collector = visit o.left, collector
|
124
|
-
|
125
56
|
collector << ")"
|
126
57
|
collector
|
127
58
|
end
|
128
59
|
|
129
60
|
def visit_ArelExtensions_Nodes_Ltrim o , collector
|
130
61
|
collector << 'TRIM(LEADING '
|
131
|
-
|
132
|
-
collector = visit o.right, collector
|
133
|
-
else
|
134
|
-
collector << "'#{o.right}'"
|
135
|
-
end
|
62
|
+
collector = visit o.right, collector
|
136
63
|
collector << " FROM "
|
137
64
|
collector = visit o.left, collector
|
138
|
-
|
139
65
|
collector << ")"
|
140
66
|
collector
|
141
67
|
end
|
142
68
|
|
143
|
-
|
144
69
|
def visit_ArelExtensions_Nodes_Rtrim o , collector
|
145
|
-
|
146
|
-
|
147
|
-
collector = visit o.right, collector
|
148
|
-
else
|
149
|
-
collector << "'#{o.right}'"
|
150
|
-
end
|
70
|
+
collector << 'TRIM(TRAILING '
|
71
|
+
collector = visit o.right, collector
|
151
72
|
collector << " FROM "
|
152
73
|
collector = visit o.left, collector
|
74
|
+
collector << ")"
|
75
|
+
collector
|
76
|
+
end
|
77
|
+
def visit_ArelExtensions_Nodes_DateDiff o, collector
|
78
|
+
collector << "DATEDIFF("
|
79
|
+
collector = visit o.left, collector
|
80
|
+
collector << Arel::Visitors::MySQL::COMMA
|
81
|
+
collector = visit o.right, collector
|
82
|
+
collector << ")"
|
83
|
+
collector
|
84
|
+
end
|
153
85
|
|
86
|
+
def visit_ArelExtensions_Nodes_DateAdd o, collector
|
87
|
+
collector << "DATE_ADD("
|
88
|
+
collector = visit o.left, collector
|
89
|
+
collector << Arel::Visitors::MySQL::COMMA
|
90
|
+
collector = visit o.mysql_value(o.right), collector
|
154
91
|
collector << ")"
|
155
92
|
collector
|
156
93
|
end
|
157
94
|
|
95
|
+
|
96
|
+
def visit_ArelExtensions_Nodes_Duration o, collector
|
97
|
+
#visit left for period
|
98
|
+
if o.left == "d"
|
99
|
+
collector << "DAY("
|
100
|
+
elsif(o.left == "m")
|
101
|
+
collector << "MONTH("
|
102
|
+
elsif (o.left == "w")
|
103
|
+
collector << "WEEK("
|
104
|
+
elsif (o.left == "y")
|
105
|
+
collector << "YEAR("
|
106
|
+
end
|
107
|
+
#visit right
|
108
|
+
collector = visit o.right, collector
|
109
|
+
collector << ")"
|
110
|
+
collector
|
111
|
+
end
|
112
|
+
|
113
|
+
#****************************************************************#
|
114
|
+
|
115
|
+
def visit_ArelExtensions_Nodes_IsNull o, collector
|
116
|
+
collector << "ISNULL("
|
117
|
+
collector = visit o.left, collector
|
118
|
+
if o.right
|
119
|
+
collector << Arel::Visitors::MySQL::COMMA
|
120
|
+
collector = visit o.right, collector
|
121
|
+
end
|
122
|
+
collector << ")"
|
123
|
+
collector
|
124
|
+
end
|
125
|
+
|
126
|
+
|
127
|
+
def visit_ArelExtensions_Nodes_Replace o, collector
|
128
|
+
collector << "REPLACE("
|
129
|
+
o.expressions.each_with_index { |arg, i|
|
130
|
+
collector << Arel::Visitors::MySQL::COMMA unless i == 0
|
131
|
+
collector = visit arg, collector
|
132
|
+
}
|
133
|
+
collector << ")"
|
134
|
+
collector
|
135
|
+
end
|
136
|
+
|
137
|
+
|
158
138
|
def visit_ArelExtensions_Nodes_Wday o, collector
|
159
139
|
collector << "(WEEKDAY("
|
160
|
-
|
161
|
-
collector = visit o.date, collector
|
162
|
-
else
|
163
|
-
collector << "'#{o.date}'"
|
164
|
-
end
|
140
|
+
collector = visit o.date, collector
|
165
141
|
collector << ") + 1) % 7"
|
166
142
|
collector
|
167
143
|
end
|
@@ -26,47 +26,27 @@ module ArelExtensions
|
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
collector << "DATEADD("
|
40
|
-
collector = visit o.left, collector
|
41
|
-
collector << ", + interval '#{o.right}' DAY)"
|
42
|
-
else
|
43
|
-
collector << "CONCAT("
|
44
|
-
collector = visit o.left, collector
|
45
|
-
collector << ","
|
46
|
-
collector << "#{o.right})"
|
47
|
-
end
|
48
|
-
collector
|
49
|
-
end
|
50
|
-
|
29
|
+
def visit_ArelExtensions_Nodes_GroupConcat o, collector
|
30
|
+
collector << "LISTAGG("
|
31
|
+
collector = visit o.left, collector
|
32
|
+
if o.right
|
33
|
+
collector << Arel::Visitors::Oracle::COMMA
|
34
|
+
collector = visit o.right, collector
|
35
|
+
end
|
36
|
+
collector << ")"
|
37
|
+
collector
|
38
|
+
end
|
51
39
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
if(a.is_a?(Arel::Attributes::Attribute))
|
62
|
-
collector = visit a, collector
|
63
|
-
else
|
64
|
-
collector << "#{a}"
|
40
|
+
def visit_ArelExtensions_Nodes_Coalesce o, collector
|
41
|
+
collector << "COALESCE("
|
42
|
+
collector = visit o.left, collector
|
43
|
+
o.other.each { |a|
|
44
|
+
collector << Arel::Visitors::Oracle::COMMA
|
45
|
+
collector = visit a, collector
|
46
|
+
}
|
47
|
+
collector << ")"
|
48
|
+
collector
|
65
49
|
end
|
66
|
-
}
|
67
|
-
collector << ")"
|
68
|
-
collector
|
69
|
-
end
|
70
50
|
|
71
51
|
def visit_ArelExtensions_Nodes_DateDiff o, collector
|
72
52
|
collector << '('
|
@@ -90,11 +70,7 @@ module ArelExtensions
|
|
90
70
|
collector << "YEAR("
|
91
71
|
end
|
92
72
|
#visit right
|
93
|
-
|
94
|
-
collector = visit o.right, collector
|
95
|
-
else
|
96
|
-
collector << "'#{o.right}'"
|
97
|
-
end
|
73
|
+
collector = visit o.right, collector
|
98
74
|
collector << ")"
|
99
75
|
collector
|
100
76
|
end
|
@@ -108,25 +84,20 @@ module ArelExtensions
|
|
108
84
|
end
|
109
85
|
|
110
86
|
|
111
|
-
def
|
87
|
+
def visit_ArelExtensions_Nodes_IsNull o, collector
|
112
88
|
collector << "NVL("
|
113
89
|
collector = visit o.left, collector
|
114
|
-
collector <<
|
115
|
-
|
116
|
-
collector = visit o.right, collector
|
117
|
-
else
|
118
|
-
collector << "'#{o.right}'"
|
119
|
-
end
|
90
|
+
collector << Arel::Visitors::Oracle::COMMA
|
91
|
+
collector = visit Arel::Nodes.build_quoted(true), collector
|
120
92
|
collector << ")"
|
121
93
|
collector
|
122
94
|
end
|
123
95
|
|
124
|
-
|
125
96
|
def visit_ArelExtensions_Nodes_Rand o, collector
|
126
97
|
collector << "dbms_random.value("
|
127
98
|
if(o.left != nil && o.right != nil)
|
128
99
|
collector << "'#{o.left}'"
|
129
|
-
collector <<
|
100
|
+
collector << Arel::Visitors::Oracle::COMMA
|
130
101
|
collector << "'#{o.right}'"
|
131
102
|
end
|
132
103
|
collector << ")"
|
@@ -136,18 +107,10 @@ module ArelExtensions
|
|
136
107
|
def visit_ArelExtensions_Nodes_Replace o, collector
|
137
108
|
collector << "REPLACE("
|
138
109
|
collector = visit o.expr,collector
|
139
|
-
collector <<
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
collector << "'#{o.left}'"
|
144
|
-
end
|
145
|
-
collector << ","
|
146
|
-
if(o.right.is_a?(Arel::Attributes::Attribute))
|
147
|
-
collector = visit o.right, collector
|
148
|
-
else
|
149
|
-
collector << "'#{o.right}'"
|
150
|
-
end
|
110
|
+
collector << Arel::Visitors::Oracle::COMMA
|
111
|
+
collector = visit o.left, collector
|
112
|
+
collector << Arel::Visitors::Oracle::COMMA
|
113
|
+
collector = visit o.right, collector
|
151
114
|
collector << ")"
|
152
115
|
collector
|
153
116
|
end
|