arel_extensions 1.2.23 → 2.0.0.rc3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -7
  3. data/.travis.yml +91 -61
  4. data/Gemfile +20 -15
  5. data/README.md +12 -17
  6. data/Rakefile +29 -40
  7. data/appveyor.yml +1 -1
  8. data/arel_extensions.gemspec +3 -3
  9. data/functions.html +3 -3
  10. data/gemfiles/rails3.gemfile +9 -9
  11. data/gemfiles/rails4.gemfile +13 -13
  12. data/gemfiles/rails5_0.gemfile +13 -13
  13. data/gemfiles/rails5_1_4.gemfile +13 -13
  14. data/gemfiles/rails5_2.gemfile +13 -13
  15. data/init/mssql.sql +4 -4
  16. data/init/mysql.sql +38 -38
  17. data/init/postgresql.sql +21 -21
  18. data/lib/arel_extensions.rb +19 -69
  19. data/lib/arel_extensions/attributes.rb +1 -0
  20. data/lib/arel_extensions/boolean_functions.rb +14 -55
  21. data/lib/arel_extensions/common_sql_functions.rb +8 -7
  22. data/lib/arel_extensions/comparators.rb +15 -14
  23. data/lib/arel_extensions/date_duration.rb +5 -4
  24. data/lib/arel_extensions/insert_manager.rb +16 -17
  25. data/lib/arel_extensions/math.rb +12 -11
  26. data/lib/arel_extensions/math_functions.rb +22 -29
  27. data/lib/arel_extensions/nodes.rb +1 -1
  28. data/lib/arel_extensions/nodes/abs.rb +1 -0
  29. data/lib/arel_extensions/nodes/blank.rb +1 -0
  30. data/lib/arel_extensions/nodes/case.rb +8 -11
  31. data/lib/arel_extensions/nodes/cast.rb +2 -4
  32. data/lib/arel_extensions/nodes/ceil.rb +1 -1
  33. data/lib/arel_extensions/nodes/change_case.rb +0 -0
  34. data/lib/arel_extensions/nodes/coalesce.rb +3 -2
  35. data/lib/arel_extensions/nodes/collate.rb +2 -1
  36. data/lib/arel_extensions/nodes/concat.rb +16 -7
  37. data/lib/arel_extensions/nodes/date_diff.rb +13 -10
  38. data/lib/arel_extensions/nodes/duration.rb +3 -0
  39. data/lib/arel_extensions/nodes/find_in_set.rb +1 -0
  40. data/lib/arel_extensions/nodes/floor.rb +1 -1
  41. data/lib/arel_extensions/nodes/format.rb +8 -34
  42. data/lib/arel_extensions/nodes/formatted_number.rb +23 -22
  43. data/lib/arel_extensions/nodes/function.rb +16 -25
  44. data/lib/arel_extensions/nodes/json.rb +36 -43
  45. data/lib/arel_extensions/nodes/length.rb +1 -0
  46. data/lib/arel_extensions/nodes/levenshtein_distance.rb +0 -0
  47. data/lib/arel_extensions/nodes/locate.rb +1 -0
  48. data/lib/arel_extensions/nodes/log10.rb +2 -1
  49. data/lib/arel_extensions/nodes/matches.rb +6 -4
  50. data/lib/arel_extensions/nodes/md5.rb +1 -0
  51. data/lib/arel_extensions/nodes/power.rb +5 -5
  52. data/lib/arel_extensions/nodes/rand.rb +1 -0
  53. data/lib/arel_extensions/nodes/repeat.rb +4 -2
  54. data/lib/arel_extensions/nodes/replace.rb +6 -22
  55. data/lib/arel_extensions/nodes/round.rb +6 -5
  56. data/lib/arel_extensions/nodes/soundex.rb +15 -15
  57. data/lib/arel_extensions/nodes/std.rb +21 -18
  58. data/lib/arel_extensions/nodes/substring.rb +16 -8
  59. data/lib/arel_extensions/nodes/then.rb +0 -0
  60. data/lib/arel_extensions/nodes/trim.rb +5 -3
  61. data/lib/arel_extensions/nodes/union.rb +5 -2
  62. data/lib/arel_extensions/nodes/union_all.rb +3 -0
  63. data/lib/arel_extensions/nodes/wday.rb +4 -0
  64. data/lib/arel_extensions/null_functions.rb +7 -5
  65. data/lib/arel_extensions/predications.rb +34 -35
  66. data/lib/arel_extensions/railtie.rb +5 -5
  67. data/lib/arel_extensions/set_functions.rb +4 -2
  68. data/lib/arel_extensions/string_functions.rb +22 -43
  69. data/lib/arel_extensions/tasks.rb +5 -5
  70. data/lib/arel_extensions/version.rb +1 -1
  71. data/lib/arel_extensions/visitors.rb +60 -68
  72. data/lib/arel_extensions/visitors/ibm_db.rb +12 -5
  73. data/lib/arel_extensions/visitors/mssql.rb +57 -63
  74. data/lib/arel_extensions/visitors/mysql.rb +98 -149
  75. data/lib/arel_extensions/visitors/oracle.rb +68 -71
  76. data/lib/arel_extensions/visitors/oracle12.rb +15 -2
  77. data/lib/arel_extensions/visitors/postgresql.rb +63 -116
  78. data/lib/arel_extensions/visitors/sqlite.rb +70 -83
  79. data/lib/arel_extensions/visitors/to_sql.rb +109 -141
  80. data/test/database.yml +0 -2
  81. data/test/helper.rb +18 -0
  82. data/test/real_db_test.rb +43 -28
  83. data/test/support/fake_record.rb +2 -2
  84. data/test/test_comparators.rb +12 -9
  85. data/test/visitors/test_bulk_insert_oracle.rb +8 -8
  86. data/test/visitors/test_bulk_insert_sqlite.rb +10 -9
  87. data/test/visitors/test_bulk_insert_to_sql.rb +10 -8
  88. data/test/visitors/test_oracle.rb +42 -42
  89. data/test/visitors/test_to_sql.rb +196 -361
  90. data/test/with_ar/all_agnostic_test.rb +160 -195
  91. data/test/with_ar/insert_agnostic_test.rb +4 -3
  92. data/test/with_ar/test_bulk_sqlite.rb +9 -6
  93. data/test/with_ar/test_math_sqlite.rb +12 -8
  94. data/test/with_ar/test_string_mysql.rb +11 -5
  95. data/test/with_ar/test_string_sqlite.rb +12 -4
  96. metadata +11 -22
  97. data/.github/workflows/ruby.yml +0 -102
  98. data/gemfiles/rails6.gemfile +0 -30
  99. data/gemfiles/rails6_1.gemfile +0 -30
  100. data/gemspecs/arel_extensions-v1.gemspec +0 -28
  101. data/gemspecs/arel_extensions-v2.gemspec +0 -28
  102. data/generate_gems.sh +0 -15
  103. data/lib/arel_extensions/nodes/aggregate_function.rb +0 -13
  104. data/lib/arel_extensions/nodes/sum.rb +0 -7
  105. data/lib/arel_extensions/visitors/convert_format.rb +0 -37
  106. data/test/arelx_test_helper.rb +0 -26
  107. data/version_v1.rb +0 -3
  108. data/version_v2.rb +0 -3
@@ -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
 
@@ -26,55 +26,41 @@ module ArelExtensions
26
26
  [@dict].hash
27
27
  end
28
28
 
29
- def convert_to_json_node(n)
30
- case n
31
- when JsonNode
32
- n.dict
33
- when Array
34
- n.map{|e|
35
- (e.is_a?(Array) || e.is_a?(Hash)) ? Json.new(e) : convert_to_json_node(e)
36
- }
37
- when Hash
38
- n.reduce({}){|acc,v|
39
- acc[convert_to_json_node(v[0])] = (v[1].is_a?(Array) || v[1].is_a?(Hash)) ? Json.new(v[1]) : convert_to_json_node(v[1])
40
- acc
41
- }
42
- when String, Numeric, TrueClass, FalseClass
43
- convert_to_node(n)
44
- when Date
45
- convert_to_node(n.strftime("%Y-%m-%d"))
46
- when DateTime, Time
47
- convert_to_node(n.strftime("%Y-%m-%dT%H:%M:%S.%L%:z"))
48
- when NilClass
49
- Arel.sql('null')
50
- else
51
- convert_to_node(n)
52
- end
53
- end
54
-
55
- def type_of_node(v)
56
- if v.is_a?(Arel::Attributes::Attribute)
57
- self.type_of_attribute(v)
58
- elsif v.respond_to?(:return_type)
59
- v.return_type
60
- elsif v.nil?
61
- :nil
62
- else
63
- :string
64
- end
65
- end
66
29
  end
67
30
 
68
31
  class Json < JsonNode
32
+
69
33
  def initialize *expr
70
- @dict =
71
- if expr.length == 1
72
- convert_to_json_node(expr.first)
34
+ if expr.length == 1
35
+ case expr.first
36
+ when JsonNode
37
+ @dict = expr.first.dict
38
+ when Array
39
+ @dict = expr.first.map{|e|
40
+ (e.is_a?(Array) || e.is_a?(Hash)) ? Json.new(e) : convert_to_node(e)
41
+ }
42
+ when Hash
43
+ @dict = expr.first.inject({}){|acc,v|
44
+ 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])
45
+ acc
46
+ }
47
+ when String, Numeric, TrueClass, FalseClass
48
+ @dict = convert_to_node(expr.first)
49
+ when NilClass
50
+ @dict = Arel.sql('null')
73
51
  else
74
- expr.map{|e| convert_to_json_node(e) }
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)
54
+ else
55
+ @dict = [convert_to_node(expr.first)]
56
+ end
75
57
  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
76
61
  super
77
62
  end
63
+
78
64
  end
79
65
 
80
66
  class JsonMerge < JsonNode
@@ -87,7 +73,11 @@ module ArelExtensions
87
73
  @dict = as_array ? json : json.dict
88
74
  @as_array = as_array
89
75
  if orders
90
- @orders = Array(orders)
76
+ if orders.is_a?(Array)
77
+ @orders = orders
78
+ else
79
+ @orders = [orders]
80
+ end
91
81
  end
92
82
  end
93
83
  end
@@ -99,6 +89,7 @@ module ArelExtensions
99
89
  @dict = json
100
90
  @key = convert_to_node(key)
101
91
  end
92
+
102
93
  end
103
94
 
104
95
  class JsonSet < JsonNode
@@ -109,6 +100,8 @@ module ArelExtensions
109
100
  @key = convert_to_node(key)
110
101
  @value = Json.new(value)
111
102
  end
103
+
112
104
  end
105
+
113
106
  end
114
107
  end
@@ -2,6 +2,7 @@ module ArelExtensions
2
2
  module Nodes
3
3
  class Length < Function
4
4
  RETURN_TYPE = :integer
5
+
5
6
  end
6
7
  end
7
8
  end
File without changes
@@ -9,6 +9,7 @@ module ArelExtensions
9
9
  end
10
10
  return super(tab)
11
11
  end
12
+
12
13
  end
13
14
  end
14
15
  end
@@ -1,7 +1,8 @@
1
1
  module ArelExtensions
2
2
  module Nodes
3
3
  class Log10 < Function
4
- RETURN_TYPE = :number
4
+ RETURN_TYPE = :number
5
+
5
6
  end
6
7
  end
7
8
  end
@@ -1,8 +1,9 @@
1
1
  module ArelExtensions
2
2
  module Nodes
3
3
  class IMatches < Arel::Nodes::Matches
4
- attr_accessor :case_sensitive if Arel::VERSION.to_i < 7
5
4
 
5
+ attr_accessor :case_sensitive if Arel::VERSION.to_i < 7
6
+
6
7
  def initialize(left, right, escape = nil)
7
8
  r = Arel::Nodes.build_quoted(right)
8
9
  if Arel::VERSION.to_i < 7 # managed by default in version 7+ (rails 5), so useful for rails 3 & 4
@@ -16,14 +17,15 @@ module ArelExtensions
16
17
 
17
18
  class IDoesNotMatch < IMatches
18
19
  end
19
-
20
+
20
21
  class AiMatches < IMatches
21
22
  end
22
-
23
+
23
24
  class AiIMatches < IMatches
24
25
  end
25
-
26
+
26
27
  class SMatches < IMatches
27
28
  end
29
+
28
30
  end
29
31
  end
@@ -2,6 +2,7 @@ module ArelExtensions
2
2
  module Nodes
3
3
  class MD5 < Function
4
4
  RETURN_TYPE = :string
5
+
5
6
  end
6
7
  end
7
8
  end
@@ -1,11 +1,11 @@
1
1
  module ArelExtensions
2
2
  module Nodes
3
3
  class Power < Function
4
- RETURN_TYPE = :number
5
-
6
- def initialize expr
7
- super [convert_to_node(expr.first), convert_to_number(expr[1])]
8
- end
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
  end
10
10
  end
11
11
  end
@@ -10,6 +10,7 @@ module ArelExtensions
10
10
  super []
11
11
  end
12
12
  end
13
+
13
14
  end
14
15
  end
15
16
  end
@@ -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,8 +11,10 @@ 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
  end
18
+
17
19
  end
18
20
  end
@@ -2,34 +2,18 @@ module ArelExtensions
2
2
  module Nodes
3
3
  class Replace < Function
4
4
  RETURN_TYPE = :string
5
- attr_accessor :left, :pattern, :substitute
6
5
 
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])
6
+ def initialize expr
7
+ tab = expr.map { |arg|
8
+ convert_to_node(arg)
9
+ }
10
+ return super(tab)
12
11
  end
13
12
 
14
13
  def +(other)
15
- return ArelExtensions::Nodes::Concat.new(self.expressions + [other])
14
+ return ArelExtensions::Nodes::Concat.new(self.expressions + [other])
16
15
  end
17
- end
18
-
19
- class RegexpReplace < Function
20
- RETURN_TYPE = :string
21
- attr_accessor :left, :pattern, :substitute
22
16
 
23
- def initialize left, pattern, substitute
24
- @left = convert_to_node(left)
25
- @pattern = (pattern.is_a?(Regexp) ? pattern : %r[#{pattern}])
26
- @substitute = convert_to_node(substitute)
27
- super([@left,@pattern,@substitute])
28
- end
29
-
30
- def +(other)
31
- return ArelExtensions::Nodes::Concat.new(self.expressions + [other])
32
- end
33
17
  end
34
18
  end
35
19
  end
@@ -4,12 +4,13 @@ module ArelExtensions
4
4
  RETURN_TYPE = :number
5
5
 
6
6
  def initialize expr
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
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
  end
14
15
  end
15
16
  end
@@ -1,18 +1,18 @@
1
1
  module ArelExtensions
2
- module Nodes
3
- class Soundex < Function
4
- include Arel::Expressions
5
- include ArelExtensions::Comparators
2
+ module Nodes
3
+ class Soundex < Function
4
+ include Arel::Expressions
5
+ include ArelExtensions::Comparators
6
+
7
+ RETURN_TYPE = :string
8
+
9
+ def ==(other)
10
+ Arel::Nodes::Equality.new self, Arel::Nodes.build_quoted(other, self)
11
+ end
6
12
 
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
- end
17
- end
13
+ def !=(other)
14
+ Arel::Nodes::NotEqual.new self, Arel::Nodes.build_quoted(other, self)
15
+ end
16
+ end
17
+ end
18
18
  end
@@ -1,23 +1,26 @@
1
1
  module ArelExtensions
2
2
  module Nodes
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
11
- end
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
3
+ class Std < Function
4
+ RETURN_TYPE = :number
5
+
6
+ attr_accessor :unbiased_estimator
7
+ def initialize expr
8
+ col = expr.first
9
+ @unbiased_estimator = expr[1]
10
+ super [col]
11
+ end
21
12
  end
13
+
14
+ class Variance < Function
15
+ RETURN_TYPE = :number
16
+
17
+ attr_accessor :unbiased_estimator
18
+ def initialize expr
19
+ col = expr.first
20
+ @unbiased_estimator = expr[1]
21
+ super [col]
22
+ end
23
+ end
24
+
22
25
  end
23
26
  end
@@ -1,15 +1,23 @@
1
1
  module ArelExtensions
2
2
  module Nodes
3
3
  class Substring < Function
4
- RETURN_TYPE = :string
4
+ RETURN_TYPE = :string
5
+
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
+ # else
11
+ # tab << expr[0].length
12
+ end
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
5
20
 
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
13
21
  end
14
22
  end
15
23
  end
File without changes
@@ -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,16 +11,18 @@ 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
  end
17
18
 
18
19
  class Ltrim < Trim
19
- RETURN_TYPE = :string
20
+ RETURN_TYPE = :string
20
21
  end
21
22
 
22
23
  class Rtrim < Trim
23
24
  RETURN_TYPE = :string
24
25
  end
26
+
25
27
  end
26
28
  end