arel_extensions 2.0.9 → 2.0.14
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.yml +2 -0
- data/Gemfile +10 -10
- data/Rakefile +4 -4
- data/gemfiles/rails3.gemfile +9 -9
- data/gemfiles/rails4.gemfile +13 -13
- data/gemfiles/rails5_0.gemfile +13 -13
- data/gemfiles/rails5_1_4.gemfile +13 -13
- data/gemfiles/rails5_2.gemfile +13 -13
- data/gemfiles/rails6.gemfile +13 -13
- data/lib/arel_extensions.rb +3 -3
- data/lib/arel_extensions/attributes.rb +0 -0
- data/lib/arel_extensions/boolean_functions.rb +21 -5
- data/lib/arel_extensions/common_sql_functions.rb +2 -4
- data/lib/arel_extensions/comparators.rb +11 -14
- data/lib/arel_extensions/date_duration.rb +4 -5
- data/lib/arel_extensions/insert_manager.rb +16 -17
- data/lib/arel_extensions/math.rb +8 -9
- data/lib/arel_extensions/math_functions.rb +15 -17
- data/lib/arel_extensions/nodes/abs.rb +0 -1
- data/lib/arel_extensions/nodes/aggregate_function.rb +0 -1
- data/lib/arel_extensions/nodes/blank.rb +0 -1
- data/lib/arel_extensions/nodes/case.rb +3 -4
- data/lib/arel_extensions/nodes/cast.rb +4 -2
- data/lib/arel_extensions/nodes/ceil.rb +1 -1
- data/lib/arel_extensions/nodes/change_case.rb +0 -0
- data/lib/arel_extensions/nodes/coalesce.rb +0 -1
- data/lib/arel_extensions/nodes/collate.rb +0 -1
- data/lib/arel_extensions/nodes/concat.rb +1 -3
- data/lib/arel_extensions/nodes/date_diff.rb +7 -8
- data/lib/arel_extensions/nodes/duration.rb +0 -1
- data/lib/arel_extensions/nodes/find_in_set.rb +0 -1
- data/lib/arel_extensions/nodes/floor.rb +1 -1
- data/lib/arel_extensions/nodes/format.rb +27 -1
- data/lib/arel_extensions/nodes/formatted_number.rb +0 -1
- data/lib/arel_extensions/nodes/function.rb +18 -15
- data/lib/arel_extensions/nodes/is_null.rb +0 -0
- data/lib/arel_extensions/nodes/json.rb +39 -30
- data/lib/arel_extensions/nodes/length.rb +0 -1
- data/lib/arel_extensions/nodes/levenshtein_distance.rb +0 -0
- data/lib/arel_extensions/nodes/locate.rb +0 -1
- data/lib/arel_extensions/nodes/log10.rb +1 -2
- data/lib/arel_extensions/nodes/matches.rb +0 -2
- data/lib/arel_extensions/nodes/md5.rb +0 -1
- data/lib/arel_extensions/nodes/power.rb +0 -1
- data/lib/arel_extensions/nodes/rand.rb +0 -1
- data/lib/arel_extensions/nodes/repeat.rb +0 -2
- data/lib/arel_extensions/nodes/replace.rb +0 -2
- data/lib/arel_extensions/nodes/round.rb +0 -1
- data/lib/arel_extensions/nodes/soundex.rb +0 -1
- data/lib/arel_extensions/nodes/std.rb +0 -1
- data/lib/arel_extensions/nodes/substring.rb +0 -1
- data/lib/arel_extensions/nodes/sum.rb +0 -0
- data/lib/arel_extensions/nodes/then.rb +0 -0
- data/lib/arel_extensions/nodes/trim.rb +0 -2
- data/lib/arel_extensions/nodes/union.rb +0 -2
- data/lib/arel_extensions/nodes/union_all.rb +0 -2
- data/lib/arel_extensions/nodes/wday.rb +0 -4
- data/lib/arel_extensions/null_functions.rb +3 -5
- data/lib/arel_extensions/predications.rb +5 -6
- data/lib/arel_extensions/railtie.rb +5 -5
- data/lib/arel_extensions/set_functions.rb +0 -2
- data/lib/arel_extensions/string_functions.rb +21 -22
- data/lib/arel_extensions/tasks.rb +1 -1
- data/lib/arel_extensions/version.rb +1 -1
- data/lib/arel_extensions/visitors.rb +9 -7
- data/lib/arel_extensions/visitors/convert_format.rb +37 -0
- data/lib/arel_extensions/visitors/ibm_db.rb +4 -11
- data/lib/arel_extensions/visitors/mssql.rb +48 -44
- data/lib/arel_extensions/visitors/mysql.rb +65 -67
- data/lib/arel_extensions/visitors/oracle.rb +58 -55
- data/lib/arel_extensions/visitors/oracle12.rb +2 -3
- data/lib/arel_extensions/visitors/postgresql.rb +41 -34
- data/lib/arel_extensions/visitors/sqlite.rb +23 -18
- data/lib/arel_extensions/visitors/to_sql.rb +69 -61
- data/test/arelx_test_helper.rb +0 -2
- data/test/real_db_test.rb +27 -42
- data/test/support/fake_record.rb +1 -1
- data/test/test_comparators.rb +0 -4
- data/test/visitors/test_bulk_insert_oracle.rb +0 -1
- data/test/visitors/test_bulk_insert_sqlite.rb +0 -2
- data/test/visitors/test_oracle.rb +1 -2
- data/test/visitors/test_to_sql.rb +16 -25
- data/test/with_ar/all_agnostic_test.rb +135 -139
- data/test/with_ar/insert_agnostic_test.rb +0 -2
- data/test/with_ar/test_bulk_sqlite.rb +0 -4
- data/test/with_ar/test_math_sqlite.rb +4 -8
- data/test/with_ar/test_string_mysql.rb +1 -5
- data/test/with_ar/test_string_sqlite.rb +1 -5
- data/version_v1.rb +1 -1
- data/version_v2.rb +1 -1
- metadata +3 -2
@@ -4,22 +4,22 @@ require 'arel_extensions/nodes/wday'
|
|
4
4
|
|
5
5
|
module ArelExtensions
|
6
6
|
module DateDuration
|
7
|
-
#function returns the year (as a number) given a date value.
|
7
|
+
# function returns the year (as a number) given a date value.
|
8
8
|
def year
|
9
9
|
ArelExtensions::Nodes::Duration.new "y", self
|
10
10
|
end
|
11
11
|
|
12
|
-
|
12
|
+
# function returns the month (as a number) given a date value.
|
13
13
|
def month
|
14
14
|
ArelExtensions::Nodes::Duration.new "m", self
|
15
15
|
end
|
16
16
|
|
17
|
-
#function returns the week (as a number) given a date value.
|
17
|
+
# function returns the week (as a number) given a date value.
|
18
18
|
def week
|
19
19
|
ArelExtensions::Nodes::Duration.new "w", self
|
20
20
|
end
|
21
21
|
|
22
|
-
#function returns the month (as a number) given a date value.
|
22
|
+
# function returns the month (as a number) given a date value.
|
23
23
|
def day
|
24
24
|
ArelExtensions::Nodes::Duration.new "d", self
|
25
25
|
end
|
@@ -43,6 +43,5 @@ module ArelExtensions
|
|
43
43
|
def format(tpl)
|
44
44
|
ArelExtensions::Nodes::Format.new [self, tpl]
|
45
45
|
end
|
46
|
-
|
47
46
|
end
|
48
47
|
end
|
@@ -2,34 +2,33 @@ require 'arel'
|
|
2
2
|
|
3
3
|
module ArelExtensions
|
4
4
|
module InsertManager
|
5
|
-
|
6
5
|
def bulk_insert(cols, data)
|
7
6
|
res_columns = []
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
end
|
19
|
-
when NilClass
|
20
|
-
res_columns = @ast.relation.columns
|
7
|
+
case cols.first
|
8
|
+
when String, Symbol
|
9
|
+
cols.each { |c|
|
10
|
+
res_columns << @ast.relation[c]
|
11
|
+
}
|
12
|
+
when Array
|
13
|
+
if String === cols.first.first
|
14
|
+
res_columns = cols.map {|c| [@ast.relation[c.first]] }
|
15
|
+
elsif Arel::Attributes::Attribute == cols.first.first
|
16
|
+
res_columns = cols
|
21
17
|
end
|
22
|
-
|
23
|
-
@ast.columns
|
18
|
+
when NilClass
|
19
|
+
res_columns = @ast.relation.columns
|
20
|
+
end
|
21
|
+
self.values = BulkValues.new(res_columns, data)
|
22
|
+
@ast.columns = res_columns
|
24
23
|
end
|
25
24
|
|
26
25
|
class BulkValues < Arel::Nodes::Node
|
27
26
|
attr_accessor :left, :cols
|
27
|
+
|
28
28
|
def initialize(cols, values)
|
29
29
|
@left = values
|
30
30
|
@cols = cols
|
31
31
|
end
|
32
32
|
end
|
33
|
-
|
34
33
|
end
|
35
34
|
end
|
data/lib/arel_extensions/math.rb
CHANGED
@@ -11,9 +11,9 @@ require 'arel_extensions/nodes/union_all'
|
|
11
11
|
|
12
12
|
module ArelExtensions
|
13
13
|
module Math
|
14
|
-
#function + between
|
15
|
-
#String and others (convert in string) allows you to concatenate 2 or more strings together.
|
16
|
-
#Date and integer adds or subtracts a specified time interval from a date.
|
14
|
+
# function + between
|
15
|
+
# String and others (convert in string) allows you to concatenate 2 or more strings together.
|
16
|
+
# Date and integer adds or subtracts a specified time interval from a date.
|
17
17
|
def +(other)
|
18
18
|
case self
|
19
19
|
when Arel::Nodes::Quoted
|
@@ -43,7 +43,7 @@ module ArelExtensions
|
|
43
43
|
rescue Exception
|
44
44
|
col = nil
|
45
45
|
end
|
46
|
-
if (!col) #if the column doesn't exist in the database
|
46
|
+
if (!col) # if the column doesn't exist in the database
|
47
47
|
Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new(self, other))
|
48
48
|
else
|
49
49
|
arg = col.type
|
@@ -62,8 +62,8 @@ module ArelExtensions
|
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
65
|
-
#function returns the time between two dates
|
66
|
-
#function returns the substraction between two ints
|
65
|
+
# function returns the time between two dates
|
66
|
+
# function returns the substraction between two ints
|
67
67
|
def -(other)
|
68
68
|
case self
|
69
69
|
when Arel::Nodes::Grouping
|
@@ -91,7 +91,7 @@ module ArelExtensions
|
|
91
91
|
rescue Exception
|
92
92
|
col = nil
|
93
93
|
end
|
94
|
-
if (!col) #if the column doesn't exist in the database
|
94
|
+
if (!col) # if the column doesn't exist in the database
|
95
95
|
Arel::Nodes::Grouping.new(Arel::Nodes::Subtraction.new(self, other))
|
96
96
|
else
|
97
97
|
arg = col.type
|
@@ -103,7 +103,7 @@ module ArelExtensions
|
|
103
103
|
rescue Exception
|
104
104
|
col2 = nil
|
105
105
|
end
|
106
|
-
if (!col2) #if the column doesn't exist in the database
|
106
|
+
if (!col2) # if the column doesn't exist in the database
|
107
107
|
ArelExtensions::Nodes::DateSub.new [self, other]
|
108
108
|
else
|
109
109
|
arg2 = col2.type
|
@@ -133,6 +133,5 @@ module ArelExtensions
|
|
133
133
|
end
|
134
134
|
end
|
135
135
|
end
|
136
|
-
|
137
136
|
end
|
138
137
|
end
|
@@ -11,7 +11,6 @@ require 'arel_extensions/nodes/sum'
|
|
11
11
|
|
12
12
|
module ArelExtensions
|
13
13
|
module MathFunctions
|
14
|
-
|
15
14
|
# Arel does not handle Decimal literal properly
|
16
15
|
def * other
|
17
16
|
case other
|
@@ -47,7 +46,7 @@ module ArelExtensions
|
|
47
46
|
ArelExtensions::Nodes::Floor.new [self]
|
48
47
|
end
|
49
48
|
|
50
|
-
|
49
|
+
# function gives the base 10 log
|
51
50
|
def log10
|
52
51
|
ArelExtensions::Nodes::Log10.new [self]
|
53
52
|
end
|
@@ -75,13 +74,13 @@ module ArelExtensions
|
|
75
74
|
ArelExtensions::Nodes::Sum.new self, opts
|
76
75
|
end
|
77
76
|
|
78
|
-
#function that can be invoked to produce random numbers between 0 and 1
|
79
|
-
# def rand seed = nil
|
80
|
-
# ArelExtensions::Nodes::Rand.new [seed]
|
81
|
-
# end
|
82
|
-
alias_method
|
77
|
+
# function that can be invoked to produce random numbers between 0 and 1
|
78
|
+
# def rand seed = nil
|
79
|
+
# ArelExtensions::Nodes::Rand.new [seed]
|
80
|
+
# end
|
81
|
+
alias_method(:random, :rand) rescue nil
|
83
82
|
|
84
|
-
#function is used to round a numeric field to the number of decimals specified
|
83
|
+
# function is used to round a numeric field to the number of decimals specified
|
85
84
|
def round precision = nil
|
86
85
|
if precision
|
87
86
|
ArelExtensions::Nodes::Round.new [self, precision]
|
@@ -96,14 +95,14 @@ module ArelExtensions
|
|
96
95
|
sprintf(format_string,0) # this line is to get the right error message if the format_string is not correct
|
97
96
|
m = /^(.*)%([ #+\-0]*)([1-9][0-9]+|[1-9]?)[.]?([0-9]*)([a-zA-Z])(.*)$/.match(format_string)
|
98
97
|
opts = {
|
99
|
-
:
|
100
|
-
:
|
101
|
-
:
|
102
|
-
:
|
103
|
-
:
|
104
|
-
:
|
105
|
-
:
|
106
|
-
:
|
98
|
+
prefix: m[1],
|
99
|
+
flags: m[2].split(//).uniq.join,
|
100
|
+
width: m[3].to_i,
|
101
|
+
precision: m[4] != '' ? m[4].to_i : 6,
|
102
|
+
type: m[5],
|
103
|
+
suffix: m[6],
|
104
|
+
locale: locale,
|
105
|
+
original_string: format_string
|
107
106
|
}
|
108
107
|
# opts = {:locale => 'fr_FR', :type => "e"/"f"/"d", :prefix => "$ ", :suffix => " %", :flags => " +-#0", :width => 5, :precision => 6}
|
109
108
|
ArelExtensions::Nodes::FormattedNumber.new [self,opts]
|
@@ -111,6 +110,5 @@ module ArelExtensions
|
|
111
110
|
Arel::Nodes.build_quoted('Wrong Format')
|
112
111
|
end
|
113
112
|
end
|
114
|
-
|
115
113
|
end
|
116
114
|
end
|
@@ -19,7 +19,6 @@ module ArelExtensions
|
|
19
19
|
|
20
20
|
class Else < Arel::Nodes::Unary # :nodoc:
|
21
21
|
end
|
22
|
-
|
23
22
|
end
|
24
23
|
else
|
25
24
|
class Case < Arel::Nodes::Case
|
@@ -96,9 +95,9 @@ module ArelExtensions
|
|
96
95
|
|
97
96
|
def eql? other
|
98
97
|
self.class == other.class &&
|
99
|
-
|
100
|
-
|
101
|
-
|
98
|
+
self.case == other.case &&
|
99
|
+
self.conditions == other.conditions &&
|
100
|
+
self.default == other.default
|
102
101
|
end
|
103
102
|
alias :== :eql?
|
104
103
|
|
@@ -14,7 +14,10 @@ module ArelExtensions
|
|
14
14
|
@return_type = :decimal
|
15
15
|
when :number
|
16
16
|
@return_type = :number
|
17
|
-
when 'char', 'varchar', '
|
17
|
+
when 'char', 'varchar', 'nchar', 'nvarchar'
|
18
|
+
@return_type = :string
|
19
|
+
when 'text', :text, 'ntext', :ntext
|
20
|
+
@as_attr = expr[1].to_sym
|
18
21
|
@return_type = :string
|
19
22
|
when :datetime, 'datetime','smalldatetime'
|
20
23
|
@return_type = :datetime
|
@@ -46,7 +49,6 @@ module ArelExtensions
|
|
46
49
|
def return_type
|
47
50
|
@return_type
|
48
51
|
end
|
49
|
-
|
50
52
|
end
|
51
53
|
end
|
52
54
|
end
|
File without changes
|
@@ -11,7 +11,7 @@ module ArelExtensions::Nodes
|
|
11
11
|
else
|
12
12
|
node
|
13
13
|
end
|
14
|
-
}.flatten.reduce([]) { |
|
14
|
+
}.flatten.reduce([]) { |res, b|
|
15
15
|
# concatenate successive literal strings.
|
16
16
|
if b.is_a?(Arel::Nodes::Quoted) && b.expr == ""
|
17
17
|
res
|
@@ -37,7 +37,6 @@ module ArelExtensions::Nodes
|
|
37
37
|
def concat(other)
|
38
38
|
Concat.new(self.expressions + [other])
|
39
39
|
end
|
40
|
-
|
41
40
|
end
|
42
41
|
|
43
42
|
class GroupConcat < AggregateFunction
|
@@ -49,6 +48,5 @@ module ArelExtensions::Nodes
|
|
49
48
|
@separator = convert_to_node(separator)
|
50
49
|
super node, opts
|
51
50
|
end
|
52
|
-
|
53
51
|
end
|
54
52
|
end
|
@@ -2,7 +2,7 @@ require 'date'
|
|
2
2
|
|
3
3
|
module ArelExtensions
|
4
4
|
module Nodes
|
5
|
-
class DateDiff < Function #difference entre colonne date et date string/date
|
5
|
+
class DateDiff < Function # difference entre colonne date et date string/date
|
6
6
|
attr_accessor :left_node_type
|
7
7
|
attr_accessor :right_node_type
|
8
8
|
|
@@ -97,7 +97,7 @@ module ArelExtensions
|
|
97
97
|
v ||= self.expressions.last
|
98
98
|
if defined?(ActiveSupport::Duration) && ActiveSupport::Duration === v
|
99
99
|
if @date_type == :ruby_date
|
100
|
-
Arel.sql("(INTERVAL '1' DAY) * %s" % v.inspect.to_i
|
100
|
+
Arel.sql("(INTERVAL '1' DAY) * %s" % v.inspect.to_i)
|
101
101
|
else
|
102
102
|
Arel.sql("(INTERVAL '1' SECOND) * %s" % v.to_i)
|
103
103
|
end
|
@@ -150,6 +150,7 @@ module ArelExtensions
|
|
150
150
|
end
|
151
151
|
|
152
152
|
private
|
153
|
+
|
153
154
|
def convert(object)
|
154
155
|
case object
|
155
156
|
when Arel::Attributes::Attribute, Arel::Nodes::Node, ActiveSupport::Duration
|
@@ -157,16 +158,16 @@ module ArelExtensions
|
|
157
158
|
when Integer
|
158
159
|
object.days
|
159
160
|
when DateTime, Time, Date
|
160
|
-
raise(ArgumentError, "#{object.class}
|
161
|
+
raise(ArgumentError, "#{object.class} cannot be converted to Integer")
|
161
162
|
when String
|
162
163
|
Arel::Nodes.build_quoted(object)
|
163
164
|
else
|
164
|
-
raise(ArgumentError, "#{object.class}
|
165
|
+
raise(ArgumentError, "#{object.class} cannot be converted to Integer")
|
165
166
|
end
|
166
167
|
end
|
167
168
|
end
|
168
169
|
|
169
|
-
class DateSub < Function #difference entre colonne date et date string/date
|
170
|
+
class DateSub < Function # difference entre colonne date et date string/date
|
170
171
|
RETURN_TYPE = :integer
|
171
172
|
|
172
173
|
def initialize(expr)
|
@@ -183,12 +184,10 @@ module ArelExtensions
|
|
183
184
|
if defined?(ActiveSupport::Duration) && ActiveSupport::Duration === object
|
184
185
|
object.to_i
|
185
186
|
else
|
186
|
-
raise(ArgumentError, "#{object.class}
|
187
|
+
raise(ArgumentError, "#{object.class} cannot be converted to Number")
|
187
188
|
end
|
188
189
|
end
|
189
190
|
end
|
190
|
-
|
191
191
|
end
|
192
|
-
|
193
192
|
end
|
194
193
|
end
|
@@ -1,15 +1,41 @@
|
|
1
|
+
require 'strscan'
|
2
|
+
|
1
3
|
module ArelExtensions
|
2
4
|
module Nodes
|
3
5
|
class Format < Function
|
4
6
|
RETURN_TYPE = :string
|
5
7
|
|
6
8
|
attr_accessor :col_type, :iso_format
|
9
|
+
|
7
10
|
def initialize expr
|
8
11
|
col = expr.first
|
9
|
-
@iso_format = expr[1]
|
12
|
+
@iso_format = convert_format(expr[1])
|
10
13
|
@col_type = type_of_attribute(col)
|
11
14
|
super [col, convert_to_string_node(@iso_format)]
|
12
15
|
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
# Address portability issues with some of the formats.
|
20
|
+
def convert_format(fmt)
|
21
|
+
s = StringScanner.new fmt
|
22
|
+
res = StringIO.new
|
23
|
+
while !s.eos?
|
24
|
+
res <<
|
25
|
+
case
|
26
|
+
when s.scan(/%D/) then '%m/%d/%y'
|
27
|
+
when s.scan(/%F/) then '%Y-%m-%d'
|
28
|
+
when s.scan(/%R/) then '%H:%M'
|
29
|
+
when s.scan(/%r/) then '%I:%M:%S %p'
|
30
|
+
when s.scan(/%T/) then '%H:%M:%S'
|
31
|
+
when s.scan(/%v/) then '%e-%b-%Y'
|
32
|
+
|
33
|
+
when s.scan(/[^%]+/) then s.matched
|
34
|
+
when s.scan(/./) then s.matched
|
35
|
+
end
|
36
|
+
end
|
37
|
+
res.string
|
38
|
+
end
|
13
39
|
end
|
14
40
|
end
|
15
41
|
end
|