arel_extensions 1.7.0 → 2.0.0.rc3

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.
Files changed (146) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +2 -1
  3. data/.gitignore +6 -8
  4. data/.rubocop.yml +4 -194
  5. data/.travis/oracle/download.js +152 -0
  6. data/.travis/oracle/download.sh +30 -0
  7. data/.travis/oracle/download_ojdbc.js +116 -0
  8. data/.travis/oracle/install.sh +34 -0
  9. data/.travis/setup_accounts.sh +9 -0
  10. data/.travis/sqlite3/extension-functions.sh +6 -0
  11. data/.travis.yml +223 -0
  12. data/Gemfile +28 -2
  13. data/README.md +89 -265
  14. data/Rakefile +30 -50
  15. data/TODO +1 -0
  16. data/appveyor.yml +22 -60
  17. data/arel_extensions.gemspec +17 -14
  18. data/functions.html +3 -3
  19. data/gemfiles/rails3.gemfile +20 -0
  20. data/gemfiles/rails4.gemfile +29 -0
  21. data/gemfiles/rails5_0.gemfile +29 -0
  22. data/gemfiles/rails5_1_4.gemfile +17 -19
  23. data/gemfiles/rails5_2.gemfile +17 -26
  24. data/init/mssql.sql +4 -4
  25. data/init/mysql.sql +38 -38
  26. data/init/oracle.sql +0 -0
  27. data/init/postgresql.sql +25 -24
  28. data/init/sqlite.sql +0 -0
  29. data/lib/arel_extensions/attributes.rb +3 -9
  30. data/lib/arel_extensions/boolean_functions.rb +16 -57
  31. data/lib/arel_extensions/common_sql_functions.rb +20 -21
  32. data/lib/arel_extensions/comparators.rb +28 -31
  33. data/lib/arel_extensions/date_duration.rb +13 -19
  34. data/lib/arel_extensions/insert_manager.rb +15 -22
  35. data/lib/arel_extensions/math.rb +70 -68
  36. data/lib/arel_extensions/math_functions.rb +52 -57
  37. data/lib/arel_extensions/nodes/abs.rb +1 -0
  38. data/lib/arel_extensions/nodes/blank.rb +5 -6
  39. data/lib/arel_extensions/nodes/case.rb +27 -31
  40. data/lib/arel_extensions/nodes/cast.rb +12 -12
  41. data/lib/arel_extensions/nodes/ceil.rb +1 -1
  42. data/lib/arel_extensions/nodes/coalesce.rb +5 -4
  43. data/lib/arel_extensions/nodes/collate.rb +10 -9
  44. data/lib/arel_extensions/nodes/concat.rb +22 -13
  45. data/lib/arel_extensions/nodes/date_diff.rb +70 -77
  46. data/lib/arel_extensions/nodes/duration.rb +5 -2
  47. data/lib/arel_extensions/nodes/find_in_set.rb +1 -0
  48. data/lib/arel_extensions/nodes/floor.rb +1 -1
  49. data/lib/arel_extensions/nodes/format.rb +8 -35
  50. data/lib/arel_extensions/nodes/formatted_number.rb +23 -22
  51. data/lib/arel_extensions/nodes/function.rb +39 -50
  52. data/lib/arel_extensions/nodes/is_null.rb +0 -2
  53. data/lib/arel_extensions/nodes/json.rb +47 -72
  54. data/lib/arel_extensions/nodes/length.rb +0 -5
  55. data/lib/arel_extensions/nodes/levenshtein_distance.rb +2 -2
  56. data/lib/arel_extensions/nodes/locate.rb +3 -2
  57. data/lib/arel_extensions/nodes/log10.rb +2 -1
  58. data/lib/arel_extensions/nodes/matches.rb +8 -6
  59. data/lib/arel_extensions/nodes/md5.rb +1 -0
  60. data/lib/arel_extensions/nodes/power.rb +5 -5
  61. data/lib/arel_extensions/nodes/rand.rb +3 -2
  62. data/lib/arel_extensions/nodes/repeat.rb +6 -4
  63. data/lib/arel_extensions/nodes/replace.rb +8 -16
  64. data/lib/arel_extensions/nodes/round.rb +7 -6
  65. data/lib/arel_extensions/nodes/soundex.rb +15 -15
  66. data/lib/arel_extensions/nodes/std.rb +21 -18
  67. data/lib/arel_extensions/nodes/substring.rb +16 -58
  68. data/lib/arel_extensions/nodes/then.rb +2 -2
  69. data/lib/arel_extensions/nodes/trim.rb +7 -5
  70. data/lib/arel_extensions/nodes/union.rb +9 -6
  71. data/lib/arel_extensions/nodes/union_all.rb +8 -5
  72. data/lib/arel_extensions/nodes/wday.rb +6 -2
  73. data/lib/arel_extensions/nodes.rb +1 -1
  74. data/lib/arel_extensions/null_functions.rb +6 -18
  75. data/lib/arel_extensions/predications.rb +49 -54
  76. data/lib/arel_extensions/railtie.rb +5 -5
  77. data/lib/arel_extensions/set_functions.rb +7 -5
  78. data/lib/arel_extensions/string_functions.rb +55 -110
  79. data/lib/arel_extensions/tasks.rb +6 -6
  80. data/lib/arel_extensions/version.rb +1 -3
  81. data/lib/arel_extensions/visitors/ibm_db.rb +36 -29
  82. data/lib/arel_extensions/visitors/mssql.rb +248 -493
  83. data/lib/arel_extensions/visitors/mysql.rb +244 -420
  84. data/lib/arel_extensions/visitors/oracle.rb +258 -311
  85. data/lib/arel_extensions/visitors/oracle12.rb +34 -20
  86. data/lib/arel_extensions/visitors/postgresql.rb +239 -350
  87. data/lib/arel_extensions/visitors/sqlite.rb +169 -191
  88. data/lib/arel_extensions/visitors/to_sql.rb +299 -371
  89. data/lib/arel_extensions/visitors.rb +62 -83
  90. data/lib/arel_extensions.rb +32 -243
  91. data/test/database.yml +10 -20
  92. data/test/helper.rb +18 -0
  93. data/test/real_db_test.rb +120 -123
  94. data/test/support/fake_record.rb +3 -11
  95. data/test/test_comparators.rb +17 -14
  96. data/test/visitors/test_bulk_insert_oracle.rb +12 -12
  97. data/test/visitors/test_bulk_insert_sqlite.rb +14 -13
  98. data/test/visitors/test_bulk_insert_to_sql.rb +13 -11
  99. data/test/visitors/test_oracle.rb +55 -55
  100. data/test/visitors/test_to_sql.rb +226 -419
  101. data/test/with_ar/all_agnostic_test.rb +375 -912
  102. data/test/with_ar/insert_agnostic_test.rb +22 -28
  103. data/test/with_ar/test_bulk_sqlite.rb +17 -18
  104. data/test/with_ar/test_math_sqlite.rb +27 -27
  105. data/test/with_ar/test_string_mysql.rb +34 -32
  106. data/test/with_ar/test_string_sqlite.rb +35 -31
  107. metadata +64 -50
  108. data/.github/workflows/publish.yml +0 -30
  109. data/.github/workflows/release.yml +0 -30
  110. data/.github/workflows/ruby.yml +0 -452
  111. data/CONTRIBUTING.md +0 -102
  112. data/Makefile +0 -48
  113. data/NEWS.md +0 -131
  114. data/bin/build +0 -15
  115. data/bin/publish +0 -8
  116. data/dev/arelx.dockerfile +0 -41
  117. data/dev/compose.yaml +0 -69
  118. data/dev/postgres.dockerfile +0 -5
  119. data/dev/rbenv +0 -189
  120. data/gemfiles/rails5.gemfile +0 -36
  121. data/gemfiles/rails6.gemfile +0 -40
  122. data/gemfiles/rails6_1.gemfile +0 -48
  123. data/gemfiles/rails7.gemfile +0 -48
  124. data/gemfiles/rails7_1.gemfile +0 -48
  125. data/gemfiles/rails7_2.gemfile +0 -47
  126. data/gemfiles/rails8.gemfile +0 -40
  127. data/gemfiles/rails8_1.gemfile +0 -41
  128. data/gemspecs/arel_extensions-v1.gemspec +0 -25
  129. data/gemspecs/arel_extensions-v2.gemspec +0 -25
  130. data/generate_gems.sh +0 -15
  131. data/lib/arel_extensions/aliases.rb +0 -14
  132. data/lib/arel_extensions/constants.rb +0 -13
  133. data/lib/arel_extensions/helpers.rb +0 -61
  134. data/lib/arel_extensions/nodes/aggregate_function.rb +0 -13
  135. data/lib/arel_extensions/nodes/byte_size.rb +0 -11
  136. data/lib/arel_extensions/nodes/char_length.rb +0 -11
  137. data/lib/arel_extensions/nodes/formatted_date.rb +0 -42
  138. data/lib/arel_extensions/nodes/rollup.rb +0 -36
  139. data/lib/arel_extensions/nodes/select.rb +0 -10
  140. data/lib/arel_extensions/nodes/sum.rb +0 -7
  141. data/lib/arel_extensions/visitors/convert_format.rb +0 -37
  142. data/lib/arel_extensions/warning.rb +0 -42
  143. data/test/arelx_test_helper.rb +0 -94
  144. data/test/config_loader.rb +0 -9
  145. data/version_v1.rb +0 -5
  146. data/version_v2.rb +0 -5
@@ -5,94 +5,62 @@ module ArelExtensions
5
5
 
6
6
  attr_accessor :dict
7
7
 
8
- def merge(*expr)
9
- args = [self] + expr.map { |e| Json.new(e) }
8
+ def merge *expr
9
+ args = [self] + expr.map{|e| Json.new(e)}
10
10
  JsonMerge.new(args)
11
11
  end
12
12
 
13
- def get(key)
14
- JsonGet.new(self, key)
13
+ def get key
14
+ JsonGet.new(self,key)
15
15
  end
16
16
 
17
- def set(key, value)
18
- JsonSet.new(self, key, value)
17
+ def set key, value
18
+ JsonSet.new(self,key,value)
19
19
  end
20
20
 
21
- def group(as_array = true, orders = nil, distinct: false)
22
- if distinct
23
- JsonGroup.new(Arel::Nodes::NamedFunction.new('DISTINCT', [self]), as_array, orders)
24
- else
25
- JsonGroup.new(self, as_array, orders)
26
- end
21
+ def group as_array = true, orders= nil
22
+ JsonGroup.new(self,as_array, orders)
27
23
  end
28
24
 
29
25
  def hash
30
26
  [@dict].hash
31
27
  end
32
28
 
33
- def convert_to_json_node(n)
34
- case n
35
- when JsonNode
36
- n.dict
37
- when Array
38
- n.map { |e|
39
- e.is_a?(Array) || e.is_a?(Hash) ? Json.new(e) : convert_to_json_node(e)
40
- }
41
- when Hash
42
- n.reduce({}) { |acc, v|
43
- 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])
44
- acc
45
- }
46
- when String, Numeric, TrueClass, FalseClass
47
- convert_to_node(n)
48
- when Date
49
- convert_to_node(n.strftime('%Y-%m-%d'))
50
- when DateTime, Time
51
- convert_to_node(n.strftime('%Y-%m-%dT%H:%M:%S.%L%:z'))
52
- when NilClass
53
- Arel.null
54
- when Arel::SelectManager
55
- Arel.grouping(n)
56
- else
57
- convert_to_node(n)
58
- end
59
- end
60
-
61
- # A boolean literal, either bare (TrueClass/FalseClass) or wrapped in a Quoted node
62
- # (which is how `convert_to_node` represents one after construction).
63
- def boolean_literal?(v)
64
- v.is_a?(TrueClass) \
65
- || v.is_a?(FalseClass) \
66
- || (v.is_a?(Arel::Nodes::Quoted) && [true, false].include?(v.expr))
67
- end
68
-
69
- def type_of_node(v)
70
- if v.is_a?(Arel::Attributes::Attribute)
71
- type_of_attribute(v)
72
- elsif v.is_a?(Numeric)
73
- :numeric
74
- elsif boolean_literal?(v)
75
- :boolean
76
- elsif v.respond_to?(:return_type)
77
- v.return_type
78
- elsif v.nil?
79
- :nil
80
- else
81
- :string
82
- end
83
- end
84
29
  end
85
30
 
86
31
  class Json < JsonNode
87
- def initialize(*expr)
88
- @dict =
89
- if expr.length == 1
90
- convert_to_json_node(expr.first)
32
+
33
+ def initialize *expr
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')
91
51
  else
92
- 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
93
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
94
61
  super
95
62
  end
63
+
96
64
  end
97
65
 
98
66
  class JsonMerge < JsonNode
@@ -101,11 +69,15 @@ module ArelExtensions
101
69
  class JsonGroup < JsonNode
102
70
  attr_accessor :as_array, :orders
103
71
 
104
- def initialize(json, as_array = true, orders = nil)
72
+ def initialize json, as_array = true, orders = nil
105
73
  @dict = as_array ? json : json.dict
106
74
  @as_array = as_array
107
75
  if orders
108
- @orders = Array(orders)
76
+ if orders.is_a?(Array)
77
+ @orders = orders
78
+ else
79
+ @orders = [orders]
80
+ end
109
81
  end
110
82
  end
111
83
  end
@@ -113,20 +85,23 @@ module ArelExtensions
113
85
  class JsonGet < JsonNode
114
86
  attr_accessor :key
115
87
 
116
- def initialize(json, key)
88
+ def initialize json, key
117
89
  @dict = json
118
90
  @key = convert_to_node(key)
119
91
  end
92
+
120
93
  end
121
94
 
122
95
  class JsonSet < JsonNode
123
96
  attr_accessor :key, :value
124
97
 
125
- def initialize(json, key, value)
98
+ def initialize json, key, value
126
99
  @dict = json
127
100
  @key = convert_to_node(key)
128
101
  @value = Json.new(value)
129
102
  end
103
+
130
104
  end
105
+
131
106
  end
132
107
  end
@@ -2,12 +2,7 @@ module ArelExtensions
2
2
  module Nodes
3
3
  class Length < Function
4
4
  RETURN_TYPE = :integer
5
- attr_accessor :bytewise
6
5
 
7
- def initialize(node, bytewise = true)
8
- @bytewise = bytewise
9
- super([node])
10
- end
11
6
  end
12
7
  end
13
8
  end
@@ -3,8 +3,8 @@ module ArelExtensions
3
3
  class LevenshteinDistance < Function
4
4
  RETURN_TYPE = :number
5
5
 
6
- def initialize(expr)
7
- super([convert_to_node(expr.first), Arel.quoted(expr[1])])
6
+ def initialize expr
7
+ super [convert_to_node(expr.first), Arel::Nodes.build_quoted(expr[1])]
8
8
  end
9
9
  end
10
10
  end
@@ -3,12 +3,13 @@ module ArelExtensions
3
3
  class Locate < Function
4
4
  RETURN_TYPE = :integer
5
5
 
6
- def initialize(expr)
6
+ def initialize expr
7
7
  tab = expr.map do |arg|
8
8
  convert_to_node(arg)
9
9
  end
10
- super(tab)
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,11 +1,12 @@
1
1
  module ArelExtensions
2
2
  module Nodes
3
3
  class IMatches < Arel::Nodes::Matches
4
- attr_accessor :case_sensitive if AREL_VERSION < V7
5
4
 
5
+ attr_accessor :case_sensitive if Arel::VERSION.to_i < 7
6
+
6
7
  def initialize(left, right, escape = nil)
7
- r = Arel.quoted(right)
8
- if AREL_VERSION < V7 # managed by default in version 7+ (rails 5), so useful for rails 3 & 4
8
+ r = Arel::Nodes.build_quoted(right)
9
+ if Arel::VERSION.to_i < 7 # managed by default in version 7+ (rails 5), so useful for rails 3 & 4
9
10
  super(left, r, escape)
10
11
  @case_sensitive = false
11
12
  else
@@ -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
@@ -5,11 +5,12 @@ module ArelExtensions
5
5
 
6
6
  def initialize(seed = nil)
7
7
  if seed && seed.length == 1
8
- super
8
+ super seed
9
9
  else
10
- super([])
10
+ super []
11
11
  end
12
12
  end
13
+
13
14
  end
14
15
  end
15
16
  end
@@ -2,17 +2,19 @@ module ArelExtensions
2
2
  module Nodes
3
3
  class Repeat < Function
4
4
  RETURN_TYPE = :string
5
-
6
- def initialize(expr)
5
+
6
+ def initialize expr
7
7
  tab = expr.map { |arg|
8
8
  convert_to_node(arg)
9
9
  }
10
- super(tab)
10
+ return super(tab)
11
11
  end
12
12
 
13
13
  def +(other)
14
- ArelExtensions::Nodes::Concat.new(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,26 +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
- end
14
-
15
- class RegexpReplace < Function
16
- RETURN_TYPE = :string
17
- attr_accessor :left, :pattern, :substitute
18
12
 
19
- def initialize(left, pattern, substitute)
20
- @left = convert_to_node(left)
21
- @pattern = (pattern.is_a?(Regexp) ? pattern : /#{pattern}/)
22
- @substitute = convert_to_node(substitute)
23
- super([@left, @pattern, @substitute])
13
+ def +(other)
14
+ return ArelExtensions::Nodes::Concat.new(self.expressions + [other])
24
15
  end
16
+
25
17
  end
26
18
  end
27
19
  end
@@ -3,13 +3,14 @@ module ArelExtensions
3
3
  class Round < Function
4
4
  RETURN_TYPE = :number
5
5
 
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
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
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.quoted(other, self)
11
- end
12
-
13
- def !=(other)
14
- Arel::Nodes::NotEqual.new self, Arel.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
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
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,65 +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
- start = expr[1]
8
- if start.is_a?(Range) && expr[2]
9
- raise ArgumentError, 'cannot pass a length together with a Range start; the Range already determines the extracted length'
10
- end
11
-
12
- tab = [convert_to_node(expr[0]), start.is_a?(Range) ? start : convert_to_node(start)]
13
- if expr[2]
14
- tab << convert_to_node(expr[2])
15
- end
16
- super(tab)
17
- end
18
-
19
- def range?
20
- expressions[1].is_a?(Range)
21
- end
22
-
23
- # Builds the vendor-agnostic Arel node tree reproducing Ruby's
24
- # `String#[Range]` semantics: endless/beginless ranges, negative
25
- # "from the end" indices, `exclude_end?`, and Ruby's `nil`-vs-`""`
26
- # distinction (out of range vs valid-but-empty).
27
- #
28
- # Only meaningful when `#range?` is true; visitors need to check
29
- # that first, then `visit` the node this returns.
30
- def range_substring_node
31
- col = expressions[0]
32
- range = expressions[1]
33
- b = range.begin
34
- e = range.end
35
- n = col.char_length
36
-
37
- b_idx =
38
- if b.nil?
39
- 0
40
- elsif b.negative?
41
- n + b
42
- else
43
- b
44
- end
45
-
46
- e_idx =
47
- if e.nil?
48
- n
49
- else
50
- raw = e.negative? ? n + e : e
51
- range.exclude_end? ? raw : raw + 1
52
- end
53
-
54
- e_idx_clamped = Arel.when(n < e_idx).then(n).else(e_idx)
55
-
56
- cases = Arel.when(col.is_null).then(Arel.quoted(nil))
57
- cases = cases.when(n < b_idx).then(Arel.quoted(nil))
58
- cases = cases.when(b_idx < 0).then(Arel.quoted(nil)) if b.is_a?(Integer) && b.negative?
59
- cases
60
- .when(e_idx_clamped <= b_idx).then(Arel.quoted(''))
61
- .else(Substring.new([col, b_idx + 1, e_idx_clamped - b_idx]))
62
- end
63
21
  end
64
22
  end
65
23
  end
@@ -1,11 +1,11 @@
1
1
  module ArelExtensions
2
2
  module Nodes
3
3
  class Then < Function
4
- def initialize(expr)
4
+ def initialize expr
5
5
  tab = expr.map { |arg|
6
6
  convert_to_node(arg)
7
7
  }
8
- super(tab)
8
+ return super(tab)
9
9
  end
10
10
  end
11
11
  end
@@ -2,25 +2,27 @@ module ArelExtensions
2
2
  module Nodes
3
3
  class Trim < Function
4
4
  RETURN_TYPE = :string
5
-
6
- def initialize(expr)
5
+
6
+ def initialize expr
7
7
  tab = expr.map { |arg|
8
8
  convert_to_node(arg)
9
9
  }
10
- super(tab)
10
+ return super(tab)
11
11
  end
12
12
 
13
13
  def +(other)
14
- ArelExtensions::Nodes::Concat.new(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
@@ -1,21 +1,24 @@
1
1
  module ArelExtensions
2
2
  module Nodes
3
3
  class Union < Arel::Nodes::Union
4
- def initialize(left, right)
5
- super
4
+
5
+ def initialize left,right
6
+ return super(left,right)
6
7
  end
7
8
 
8
9
  def +(other)
9
- ArelExtensions::Nodes::Union.new(self, other)
10
+ return ArelExtensions::Nodes::Union.new(self,other)
10
11
  end
11
12
 
12
13
  def union(other)
13
- ArelExtensions::Nodes::UnionAll.new(self, other)
14
+ return ArelExtensions::Nodes::UnionAll.new(self,other)
14
15
  end
15
16
 
16
- def as(other)
17
- Arel::Nodes::TableAlias.new Arel.grouping(self), Arel::Nodes::SqlLiteral.new(other.to_s)
17
+ def as other
18
+ Arel::Nodes::TableAlias.new Arel::Nodes::Grouping.new(self), Arel::Nodes::SqlLiteral.new(other.to_s)
18
19
  end
19
20
  end
21
+
20
22
  end
21
23
  end
24
+
@@ -1,17 +1,20 @@
1
1
  module ArelExtensions
2
2
  module Nodes
3
3
  class UnionAll < Arel::Nodes::UnionAll
4
- def initialize(left, right)
5
- super
4
+
5
+ def initialize left,right
6
+ return super(left,right)
6
7
  end
7
8
 
8
9
  def union_all(other)
9
- ArelExtensions::Nodes::UnionAll.new(self, other)
10
+ return ArelExtensions::Nodes::UnionAll.new(self,other)
10
11
  end
11
12
 
12
- def as(other)
13
- Arel::Nodes::TableAlias.new Arel.grouping(self), Arel::Nodes::SqlLiteral.new(other.to_s)
13
+ def as other
14
+ Arel::Nodes::TableAlias.new Arel::Nodes::Grouping.new(self), Arel::Nodes::SqlLiteral.new(other.to_s)
14
15
  end
15
16
  end
17
+
16
18
  end
17
19
  end
20
+
@@ -1,15 +1,19 @@
1
1
  module ArelExtensions
2
2
  module Nodes
3
3
  class Wday < Function
4
- def initialize(other, aliaz = nil)
5
- tab = []
4
+
5
+
6
+ def initialize other, aliaz = nil
7
+ tab = Array.new
6
8
  tab << other
7
9
  super(tab, aliaz)
8
10
  end
9
11
 
12
+
10
13
  def date
11
14
  @expressions.first
12
15
  end
16
+
13
17
  end
14
18
  end
15
19
  end
@@ -1,2 +1,2 @@
1
1
  require 'arel_extensions/nodes/function'
2
- require 'arel_extensions/nodes/aggregate_function'
2
+