arel_extensions 2.0.0 → 2.0.10
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/.rubocop.yml +7 -4
- data/.travis.yml +59 -91
- data/Gemfile +14 -19
- data/README.md +17 -12
- data/Rakefile +38 -27
- data/appveyor.yml +1 -1
- data/arel_extensions.gemspec +2 -2
- data/functions.html +3 -3
- data/gemfiles/rails4.gemfile +1 -1
- data/gemfiles/rails6.gemfile +30 -0
- data/gemspec_v2/arel_extensions-v2.gemspec +28 -0
- data/generate_gems.sh +14 -0
- data/init/mssql.sql +4 -4
- data/init/mysql.sql +38 -38
- data/init/postgresql.sql +21 -21
- data/lib/arel_extensions.rb +63 -19
- data/lib/arel_extensions/attributes.rb +0 -1
- data/lib/arel_extensions/boolean_functions.rb +38 -13
- data/lib/arel_extensions/common_sql_functions.rb +5 -4
- data/lib/arel_extensions/comparators.rb +4 -2
- data/lib/arel_extensions/insert_manager.rb +15 -13
- data/lib/arel_extensions/math.rb +3 -3
- data/lib/arel_extensions/math_functions.rb +10 -5
- data/lib/arel_extensions/nodes.rb +1 -1
- data/lib/arel_extensions/nodes/abs.rb +0 -0
- data/lib/arel_extensions/nodes/aggregate_function.rb +14 -0
- data/lib/arel_extensions/nodes/case.rb +8 -4
- data/lib/arel_extensions/nodes/ceil.rb +0 -0
- data/lib/arel_extensions/nodes/coalesce.rb +2 -2
- data/lib/arel_extensions/nodes/collate.rb +1 -1
- data/lib/arel_extensions/nodes/concat.rb +6 -13
- data/lib/arel_extensions/nodes/date_diff.rb +3 -5
- data/lib/arel_extensions/nodes/duration.rb +0 -2
- data/lib/arel_extensions/nodes/find_in_set.rb +0 -0
- data/lib/arel_extensions/nodes/floor.rb +0 -0
- data/lib/arel_extensions/nodes/format.rb +8 -8
- data/lib/arel_extensions/nodes/formatted_number.rb +23 -23
- data/lib/arel_extensions/nodes/function.rb +2 -0
- data/lib/arel_extensions/nodes/is_null.rb +0 -0
- data/lib/arel_extensions/nodes/json.rb +28 -30
- data/lib/arel_extensions/nodes/length.rb +0 -0
- data/lib/arel_extensions/nodes/locate.rb +0 -0
- data/lib/arel_extensions/nodes/matches.rb +4 -4
- data/lib/arel_extensions/nodes/power.rb +6 -5
- data/lib/arel_extensions/nodes/rand.rb +0 -0
- data/lib/arel_extensions/nodes/repeat.rb +2 -2
- data/lib/arel_extensions/nodes/replace.rb +24 -6
- data/lib/arel_extensions/nodes/round.rb +5 -5
- data/lib/arel_extensions/nodes/soundex.rb +16 -15
- data/lib/arel_extensions/nodes/std.rb +19 -21
- data/lib/arel_extensions/nodes/substring.rb +8 -15
- data/lib/arel_extensions/nodes/sum.rb +7 -0
- data/lib/arel_extensions/nodes/trim.rb +3 -3
- data/lib/arel_extensions/nodes/union.rb +2 -3
- data/lib/arel_extensions/nodes/union_all.rb +0 -1
- data/lib/arel_extensions/nodes/wday.rb +0 -0
- data/lib/arel_extensions/null_functions.rb +2 -2
- data/lib/arel_extensions/predications.rb +35 -33
- data/lib/arel_extensions/set_functions.rb +2 -2
- data/lib/arel_extensions/string_functions.rb +34 -12
- data/lib/arel_extensions/tasks.rb +5 -5
- data/lib/arel_extensions/version.rb +1 -1
- data/lib/arel_extensions/visitors.rb +1 -1
- data/lib/arel_extensions/visitors/ibm_db.rb +1 -1
- data/lib/arel_extensions/visitors/mssql.rb +14 -13
- data/lib/arel_extensions/visitors/mysql.rb +90 -37
- data/lib/arel_extensions/visitors/oracle.rb +15 -15
- data/lib/arel_extensions/visitors/oracle12.rb +1 -1
- data/lib/arel_extensions/visitors/postgresql.rb +78 -32
- data/lib/arel_extensions/visitors/sqlite.rb +61 -53
- data/lib/arel_extensions/visitors/to_sql.rb +70 -58
- data/test/arelx_test_helper.rb +28 -0
- data/test/real_db_test.rb +1 -1
- data/test/support/fake_record.rb +1 -1
- data/test/test_comparators.rb +9 -8
- data/test/visitors/test_bulk_insert_oracle.rb +8 -7
- data/test/visitors/test_bulk_insert_sqlite.rb +9 -8
- data/test/visitors/test_bulk_insert_to_sql.rb +8 -10
- data/test/visitors/test_oracle.rb +41 -40
- data/test/visitors/test_to_sql.rb +367 -193
- data/test/with_ar/all_agnostic_test.rb +68 -35
- data/test/with_ar/insert_agnostic_test.rb +3 -2
- data/test/with_ar/test_bulk_sqlite.rb +6 -5
- data/test/with_ar/test_math_sqlite.rb +4 -4
- data/test/with_ar/test_string_mysql.rb +4 -6
- data/test/with_ar/test_string_sqlite.rb +3 -7
- data/version_v1.rb +3 -0
- data/version_v2.rb +3 -0
- metadata +14 -7
- data/test/helper.rb +0 -18
@@ -71,6 +71,8 @@ module ArelExtensions
|
|
71
71
|
Arel.sql('NULL')
|
72
72
|
when ActiveSupport::Duration
|
73
73
|
Arel.sql(object.to_i)
|
74
|
+
when Array
|
75
|
+
Arel::Nodes::Grouping.new(object.map{|r| convert_to_node(e)})
|
74
76
|
else
|
75
77
|
raise(ArgumentError, "#{object.class} can not be converted to CONCAT arg")
|
76
78
|
end
|
File without changes
|
@@ -18,7 +18,7 @@ module ArelExtensions
|
|
18
18
|
JsonSet.new(self,key,value)
|
19
19
|
end
|
20
20
|
|
21
|
-
def group as_array = true, orders= nil
|
21
|
+
def group as_array = true, orders = nil
|
22
22
|
JsonGroup.new(self,as_array, orders)
|
23
23
|
end
|
24
24
|
|
@@ -31,33 +31,35 @@ module ArelExtensions
|
|
31
31
|
class Json < JsonNode
|
32
32
|
|
33
33
|
def initialize *expr
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
if expr.first.is_a?(String) || (expr.first.is_a?(Arel::Attributes::Attribute) && type_of_attribute(expr.first) == :string) || (expr.first.return_type == :string)
|
53
|
-
@dict = convert_to_node(expr.first)
|
34
|
+
@dict =
|
35
|
+
if expr.length == 1
|
36
|
+
case exp = expr.first
|
37
|
+
when JsonNode
|
38
|
+
exp.dict
|
39
|
+
when Array
|
40
|
+
exp.map{|e|
|
41
|
+
(e.is_a?(Array) || e.is_a?(Hash)) ? Json.new(e) : convert_to_node(e)
|
42
|
+
}
|
43
|
+
when Hash
|
44
|
+
exp.reduce({}){|acc,v|
|
45
|
+
acc[convert_to_node(v[0])] = (v[1].is_a?(Array) || v[1].is_a?(Hash)) ? Json.new(v[1]) : convert_to_node(v[1])
|
46
|
+
acc
|
47
|
+
}
|
48
|
+
when String, Numeric, TrueClass, FalseClass
|
49
|
+
convert_to_node(exp)
|
50
|
+
when NilClass
|
51
|
+
Arel.sql('null')
|
54
52
|
else
|
55
|
-
|
53
|
+
if (exp.is_a?(Arel::Attributes::Attribute) && type_of_attribute(exp) == :string) \
|
54
|
+
|| (exp.return_type == :string)
|
55
|
+
convert_to_node(exp)
|
56
|
+
else
|
57
|
+
[convert_to_node(exp)]
|
58
|
+
end
|
56
59
|
end
|
60
|
+
else
|
61
|
+
expr.map{|e| (e.is_a?(Array) || e.is_a?(Hash)) ? Json.new(e) : convert_to_node(e) }
|
57
62
|
end
|
58
|
-
else
|
59
|
-
@dict = expr.map{|e| (e.is_a?(Array) || e.is_a?(Hash)) ? Json.new(e) : convert_to_node(e) }
|
60
|
-
end
|
61
63
|
super
|
62
64
|
end
|
63
65
|
|
@@ -73,11 +75,7 @@ module ArelExtensions
|
|
73
75
|
@dict = as_array ? json : json.dict
|
74
76
|
@as_array = as_array
|
75
77
|
if orders
|
76
|
-
|
77
|
-
@orders = orders
|
78
|
-
else
|
79
|
-
@orders = [orders]
|
80
|
-
end
|
78
|
+
@orders = Array(orders)
|
81
79
|
end
|
82
80
|
end
|
83
81
|
end
|
File without changes
|
File without changes
|
@@ -3,7 +3,7 @@ module ArelExtensions
|
|
3
3
|
class IMatches < Arel::Nodes::Matches
|
4
4
|
|
5
5
|
attr_accessor :case_sensitive if Arel::VERSION.to_i < 7
|
6
|
-
|
6
|
+
|
7
7
|
def initialize(left, right, escape = nil)
|
8
8
|
r = Arel::Nodes.build_quoted(right)
|
9
9
|
if Arel::VERSION.to_i < 7 # managed by default in version 7+ (rails 5), so useful for rails 3 & 4
|
@@ -17,13 +17,13 @@ module ArelExtensions
|
|
17
17
|
|
18
18
|
class IDoesNotMatch < IMatches
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
class AiMatches < IMatches
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
class AiIMatches < IMatches
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
class SMatches < IMatches
|
28
28
|
end
|
29
29
|
|
@@ -1,11 +1,12 @@
|
|
1
1
|
module ArelExtensions
|
2
2
|
module Nodes
|
3
3
|
class Power < Function
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
RETURN_TYPE = :number
|
5
|
+
|
6
|
+
def initialize expr
|
7
|
+
super [convert_to_node(expr.first), convert_to_number(expr[1])]
|
8
|
+
end
|
9
|
+
|
9
10
|
end
|
10
11
|
end
|
11
12
|
end
|
File without changes
|
@@ -2,7 +2,7 @@ module ArelExtensions
|
|
2
2
|
module Nodes
|
3
3
|
class Repeat < Function
|
4
4
|
RETURN_TYPE = :string
|
5
|
-
|
5
|
+
|
6
6
|
def initialize expr
|
7
7
|
tab = expr.map { |arg|
|
8
8
|
convert_to_node(arg)
|
@@ -11,7 +11,7 @@ module ArelExtensions
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def +(other)
|
14
|
-
return ArelExtensions::Nodes::Concat.new(self.expressions + [other])
|
14
|
+
return ArelExtensions::Nodes::Concat.new(self.expressions + [other])
|
15
15
|
end
|
16
16
|
|
17
17
|
end
|
@@ -2,18 +2,36 @@ module ArelExtensions
|
|
2
2
|
module Nodes
|
3
3
|
class Replace < Function
|
4
4
|
RETURN_TYPE = :string
|
5
|
+
attr_accessor :left, :pattern, :substitute
|
5
6
|
|
6
|
-
def initialize
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
def initialize left, pattern, substitute
|
8
|
+
@left = convert_to_node(left)
|
9
|
+
@pattern = convert_to_node(pattern)
|
10
|
+
@substitute = convert_to_node(substitute)
|
11
|
+
super([@left,@pattern,@substitute])
|
11
12
|
end
|
12
13
|
|
13
14
|
def +(other)
|
14
|
-
return ArelExtensions::Nodes::Concat.new(self.expressions + [other])
|
15
|
+
return ArelExtensions::Nodes::Concat.new(self.expressions + [other])
|
15
16
|
end
|
16
17
|
|
17
18
|
end
|
19
|
+
|
20
|
+
class RegexpReplace < Function
|
21
|
+
RETURN_TYPE = :string
|
22
|
+
attr_accessor :left, :pattern, :substitute
|
23
|
+
|
24
|
+
def initialize left, pattern, substitute
|
25
|
+
@left = convert_to_node(left)
|
26
|
+
@pattern = (pattern.is_a?(Regexp) ? pattern : %r[#{pattern}])
|
27
|
+
@substitute = convert_to_node(substitute)
|
28
|
+
super([@left,@pattern,@substitute])
|
29
|
+
end
|
30
|
+
|
31
|
+
def +(other)
|
32
|
+
return ArelExtensions::Nodes::Concat.new(self.expressions + [other])
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
18
36
|
end
|
19
37
|
end
|
@@ -4,11 +4,11 @@ module ArelExtensions
|
|
4
4
|
RETURN_TYPE = :number
|
5
5
|
|
6
6
|
def initialize expr
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
7
|
+
if expr && expr.length == 1
|
8
|
+
super [convert_to_node(expr.first)]
|
9
|
+
else
|
10
|
+
super [convert_to_node(expr.first), convert_to_number(expr[1])]
|
11
|
+
end
|
12
12
|
end
|
13
13
|
|
14
14
|
end
|
@@ -1,18 +1,19 @@
|
|
1
1
|
module ArelExtensions
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
RETURN_TYPE = :string
|
8
|
-
|
9
|
-
def ==(other)
|
10
|
-
Arel::Nodes::Equality.new self, Arel::Nodes.build_quoted(other, self)
|
11
|
-
end
|
2
|
+
module Nodes
|
3
|
+
class Soundex < Function
|
4
|
+
include Arel::Expressions
|
5
|
+
include ArelExtensions::Comparators
|
12
6
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
7
|
+
RETURN_TYPE = :string
|
8
|
+
|
9
|
+
def ==(other)
|
10
|
+
Arel::Nodes::Equality.new self, Arel::Nodes.build_quoted(other, self)
|
11
|
+
end
|
12
|
+
|
13
|
+
def !=(other)
|
14
|
+
Arel::Nodes::NotEqual.new self, Arel::Nodes.build_quoted(other, self)
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
18
19
|
end
|
@@ -1,26 +1,24 @@
|
|
1
1
|
module ArelExtensions
|
2
2
|
module Nodes
|
3
|
-
class Std <
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
end
|
3
|
+
class Std < AggregateFunction
|
4
|
+
RETURN_TYPE = :number
|
5
|
+
attr_accessor :unbiased_estimator
|
6
|
+
|
7
|
+
def initialize node, opts = {}
|
8
|
+
@unbiased_estimator = opts[:unbiased] ? true : false
|
9
|
+
super node, opts
|
10
|
+
end
|
12
11
|
end
|
13
|
-
|
14
|
-
class Variance <
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
12
|
+
|
13
|
+
class Variance < AggregateFunction
|
14
|
+
RETURN_TYPE = :number
|
15
|
+
attr_accessor :unbiased_estimator
|
16
|
+
|
17
|
+
def initialize node, opts = {}
|
18
|
+
@unbiased_estimator = opts[:unbiased] ? true : false
|
19
|
+
super node, opts
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
25
23
|
end
|
26
24
|
end
|
@@ -1,22 +1,15 @@
|
|
1
1
|
module ArelExtensions
|
2
2
|
module Nodes
|
3
3
|
class Substring < Function
|
4
|
-
|
4
|
+
RETURN_TYPE = :string
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
return super(tab)
|
14
|
-
end
|
15
|
-
|
16
|
-
# def +(other)
|
17
|
-
# puts "[Substring] : #{other.inspect} (#{self.expressions.inspect})"
|
18
|
-
# return ArelExtensions::Nodes::Concat.new(self.expressions + [other])
|
19
|
-
# end
|
6
|
+
def initialize expr
|
7
|
+
tab = [convert_to_node(expr[0]), convert_to_node(expr[1])]
|
8
|
+
if expr[2]
|
9
|
+
tab << convert_to_node(expr[2])
|
10
|
+
end
|
11
|
+
return super(tab)
|
12
|
+
end
|
20
13
|
|
21
14
|
end
|
22
15
|
end
|
@@ -2,7 +2,7 @@ module ArelExtensions
|
|
2
2
|
module Nodes
|
3
3
|
class Trim < Function
|
4
4
|
RETURN_TYPE = :string
|
5
|
-
|
5
|
+
|
6
6
|
def initialize expr
|
7
7
|
tab = expr.map { |arg|
|
8
8
|
convert_to_node(arg)
|
@@ -11,13 +11,13 @@ module ArelExtensions
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def +(other)
|
14
|
-
return ArelExtensions::Nodes::Concat.new(self.expressions + [other])
|
14
|
+
return ArelExtensions::Nodes::Concat.new(self.expressions + [other])
|
15
15
|
end
|
16
16
|
|
17
17
|
end
|
18
18
|
|
19
19
|
class Ltrim < Trim
|
20
|
-
|
20
|
+
RETURN_TYPE = :string
|
21
21
|
end
|
22
22
|
|
23
23
|
class Rtrim < Trim
|
@@ -7,11 +7,11 @@ module ArelExtensions
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def +(other)
|
10
|
-
return ArelExtensions::Nodes::Union.new(self,other)
|
10
|
+
return ArelExtensions::Nodes::Union.new(self,other)
|
11
11
|
end
|
12
12
|
|
13
13
|
def union(other)
|
14
|
-
return ArelExtensions::Nodes::UnionAll.new(self,other)
|
14
|
+
return ArelExtensions::Nodes::UnionAll.new(self,other)
|
15
15
|
end
|
16
16
|
|
17
17
|
def as other
|
@@ -21,4 +21,3 @@ module ArelExtensions
|
|
21
21
|
|
22
22
|
end
|
23
23
|
end
|
24
|
-
|
File without changes
|
@@ -8,12 +8,12 @@ module ArelExtensions
|
|
8
8
|
def is_null
|
9
9
|
ArelExtensions::Nodes::IsNull.new [self]
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
#ISNOTNULL function lets you return an alternative value when an expression is NOT NULL.
|
13
13
|
def is_not_null
|
14
14
|
ArelExtensions::Nodes::IsNotNull.new [self]
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
17
|
# returns the first non-null expr in the expression list. You must specify at least two expressions.
|
18
18
|
#If all occurrences of expr evaluate to null, then the function returns null.
|
19
19
|
def coalesce *args
|
@@ -1,10 +1,11 @@
|
|
1
1
|
module ArelExtensions
|
2
2
|
module Predications
|
3
|
-
|
3
|
+
|
4
|
+
def when right, expression = nil
|
4
5
|
ArelExtensions::Nodes::Case.new(self).when(right,expression)
|
5
6
|
end
|
6
7
|
|
7
|
-
def matches(other, escape=nil,case_sensitive= nil)
|
8
|
+
def matches(other, escape = nil,case_sensitive = nil)
|
8
9
|
if Arel::VERSION.to_i < 7
|
9
10
|
Arel::Nodes::Matches.new(self, Arel::Nodes.build_quoted(other), escape)
|
10
11
|
else
|
@@ -12,7 +13,7 @@ module ArelExtensions
|
|
12
13
|
end
|
13
14
|
end
|
14
15
|
|
15
|
-
def imatches(other, escape=nil)
|
16
|
+
def imatches(other, escape = nil)
|
16
17
|
ArelExtensions::Nodes::IMatches.new(self, other, escape)
|
17
18
|
end
|
18
19
|
|
@@ -20,51 +21,53 @@ module ArelExtensions
|
|
20
21
|
ArelExtensions::Nodes::Cast.new([self,right])
|
21
22
|
end
|
22
23
|
|
23
|
-
def in(other) #In should handle nil element in the Array
|
24
|
+
def in(*other) #In should handle nil element in the Array
|
25
|
+
other = other.first if other.length <= 1
|
24
26
|
case other
|
25
27
|
when Range
|
26
28
|
self.between(other)
|
29
|
+
when Arel::Nodes::Grouping
|
30
|
+
Arel::Nodes::In.new(self, quoted_node(other))
|
27
31
|
when Enumerable
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
Arel::Nodes::In.new(self,quoted_array(other))
|
40
|
-
end
|
32
|
+
nils, values = other.partition{ |v| v.nil? }
|
33
|
+
ranges, values = values.partition{ |v| v.is_a?(Range) || v.is_a?(Arel::SelectManager)}
|
34
|
+
# In order of (imagined) decreasing efficiency: nil, values, and then more complex.
|
35
|
+
clauses =
|
36
|
+
nils.uniq.map { |r| self.in(r) } \
|
37
|
+
+ (case values.uniq.size
|
38
|
+
when 0 then []
|
39
|
+
when 1 then [values[0].is_a?(Arel::Nodes::Grouping) ? self.in(values[0]) : self.eq(values[0])]
|
40
|
+
else [Arel::Nodes::In.new(self, quoted_array(values))] end) \
|
41
|
+
+ ranges.uniq.map { |r| self.in(r) }
|
42
|
+
clauses.empty? ? Arel.false : clauses.reduce(&:or)
|
41
43
|
when nil
|
42
44
|
self.is_null
|
43
45
|
when Arel::SelectManager
|
44
46
|
Arel::Nodes::In.new(self, other.ast)
|
45
47
|
else
|
46
|
-
Arel::Nodes::In.new(self,quoted_node(other))
|
48
|
+
Arel::Nodes::In.new(self, quoted_node(other))
|
47
49
|
end
|
48
50
|
end
|
49
51
|
|
50
|
-
def not_in(other) #In should handle nil element in the Array
|
52
|
+
def not_in(*other) #In should handle nil element in the Array
|
53
|
+
other = other.first if other.length <= 1
|
51
54
|
case other
|
52
55
|
when Range
|
53
56
|
Arel::Nodes::Not.new(self.between(other))
|
57
|
+
when Arel::Nodes::Grouping
|
58
|
+
Arel::Nodes::NotIn.new(self, quoted_node(other))
|
54
59
|
when Enumerable
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
Arel::Nodes::NotIn.new(self,quoted_array(other))
|
67
|
-
end
|
60
|
+
nils, values = other.partition{ |v| v.nil? }
|
61
|
+
ranges, values = values.partition{ |v| v.is_a?(Range) || v.is_a?(Arel::SelectManager)}
|
62
|
+
# In order of (imagined) decreasing efficiency: nil, values, and then more complex.
|
63
|
+
clauses =
|
64
|
+
nils.uniq.map { |r| self.not_in(r) } \
|
65
|
+
+ (case values.uniq.size
|
66
|
+
when 0 then []
|
67
|
+
when 1 then [values[0].is_a?(Arel::Nodes::Grouping) ? self.not_in(values[0]) : self.not_eq(values[0])]
|
68
|
+
else [Arel::Nodes::NotIn.new(self, quoted_array(values))] end) \
|
69
|
+
+ ranges.uniq.map { |r| self.not_in(r) }
|
70
|
+
Arel::Nodes::And.new clauses
|
68
71
|
when nil
|
69
72
|
self.is_not_null
|
70
73
|
when Arel::SelectManager
|
@@ -94,6 +97,5 @@ module ArelExtensions
|
|
94
97
|
raise(ArgumentError, "#{object.class} can not be converted to CONCAT arg")
|
95
98
|
end
|
96
99
|
end
|
97
|
-
|
98
100
|
end
|
99
101
|
end
|