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
@@ -2,8 +2,9 @@ require 'date'
2
2
 
3
3
  module ArelExtensions
4
4
  module Nodes
5
- class DateDiff < Function # difference entre colonne date et date string/date
6
- attr_accessor :left_node_type, :right_node_type
5
+ class DateDiff < Function #difference entre colonne date et date string/date
6
+ attr_accessor :left_node_type
7
+ attr_accessor :right_node_type
7
8
 
8
9
  RETURN_TYPE = :integer # by default...
9
10
 
@@ -11,24 +12,24 @@ module ArelExtensions
11
12
  res = []
12
13
  col = expr.first
13
14
  case col
14
- when Arel::Nodes::Node, Arel::Attributes::Attribute
15
+ when Arel::Nodes::Node, Arel::Attributes::Attribute
15
16
  @left_node_type = type_of_attribute(col)
16
17
  when Date
17
18
  @left_node_type = :ruby_date
18
19
  when DateTime, Time
19
20
  @left_node_type = :ruby_time
20
21
  end
21
- res << (%i[date ruby_date].include?(@left_node_type) ? convert_to_date_node(col) : convert_to_datetime_node(col))
22
+ res << ([:date, :ruby_date].include?(@left_node_type) ? convert_to_date_node(col) : convert_to_datetime_node(col))
22
23
  case expr[1]
23
- when Arel::Nodes::Node, Arel::Attributes::Attribute
24
+ when Arel::Nodes::Node, Arel::Attributes::Attribute
24
25
  @right_node_type = type_of_attribute(expr[1])
25
26
  when Date
26
27
  @right_node_type = :ruby_date
27
28
  when DateTime, Time
28
29
  @right_node_type = :ruby_time
29
30
  end
30
- res << (%i[date ruby_date].include?(@left_node_type) ? convert_to_date_node(expr[1]) : convert_to_datetime_node(expr[1]))
31
- super(res)
31
+ res << ([:date, :ruby_date].include?(@left_node_type) ? convert_to_date_node(expr[1]) : convert_to_datetime_node(expr[1]))
32
+ super res
32
33
  end
33
34
  end
34
35
 
@@ -36,90 +37,87 @@ module ArelExtensions
36
37
  RETURN_TYPE = :date
37
38
  attr_accessor :date_type
38
39
 
39
- def initialize(expr)
40
+ def initialize expr
40
41
  col = expr.first
41
42
  @date_type = type_of_attribute(col)
42
43
  tab = expr.map do |arg|
43
44
  convert(arg)
44
45
  end
45
- super(tab)
46
+ return super(tab)
46
47
  end
47
48
 
48
49
  def sqlite_value
49
- v = expressions.last
50
- if defined?(ActiveSupport::Duration) && v.is_a?(ActiveSupport::Duration)
50
+ v = self.expressions.last
51
+ if defined?(ActiveSupport::Duration) && ActiveSupport::Duration === v
51
52
  if @date_type == :date
52
- Arel.quoted((v.value >= 0 ? '+' : '-') + v.inspect)
53
+ return Arel::Nodes.build_quoted((v.value >= 0 ? '+' : '-') + v.inspect)
53
54
  elsif @date_type == :datetime
54
- Arel.quoted((v.value >= 0 ? '+' : '-') + v.inspect)
55
+ return Arel::Nodes.build_quoted((v.value >= 0 ? '+' : '-') + v.inspect)
55
56
  end
56
57
  else
57
- v
58
+ return v
58
59
  end
59
60
  end
60
61
 
61
62
  def mysql_value(v = nil)
62
- v ||= expressions.last
63
- if defined?(ActiveSupport::Duration) && v.is_a?(ActiveSupport::Duration)
63
+ v ||= self.expressions.last
64
+ if defined?(ActiveSupport::Duration) && ActiveSupport::Duration === v
64
65
  if @date_type == :date || @date_type == :datetime
65
66
  Arel.sql('INTERVAL %s' % v.inspect.sub(/s\Z/, ''))
66
67
  end
67
- elsif v.is_a?(ArelExtensions::Nodes::Duration)
68
- v.with_interval = true
69
- v
70
68
  else
71
- v
69
+ if ArelExtensions::Nodes::Duration === v
70
+ v.with_interval = true
71
+ v
72
+ else
73
+ v
74
+ end
72
75
  end
73
76
  end
74
77
 
75
78
  def postgresql_value(v = nil)
76
- v ||= expressions.last
77
- if defined?(ActiveSupport::Duration) && v.is_a?(ActiveSupport::Duration)
79
+ v ||= self.expressions.last
80
+ if defined?(ActiveSupport::Duration) && ActiveSupport::Duration === v
78
81
  if @date_type == :date
79
82
  Arel.sql("INTERVAL '%s'" % v.inspect.sub(/s\Z/, '').upcase)
80
83
  elsif @date_type == :datetime
81
84
  Arel.sql("INTERVAL '%s'" % v.inspect.sub(/s\Z/, '').upcase)
82
85
  end
83
- elsif v.is_a?(ArelExtensions::Nodes::Duration)
84
- v.with_interval = true
85
- v
86
86
  else
87
- v
87
+ if ArelExtensions::Nodes::Duration === v
88
+ v.with_interval = true
89
+ v
90
+ else
91
+ v
92
+ end
88
93
  end
89
94
  end
90
95
 
91
96
  def oracle_value(v = nil)
92
- v ||= expressions.last
93
- if defined?(ActiveSupport::Duration) && v.is_a?(ActiveSupport::Duration)
97
+ v ||= self.expressions.last
98
+ if defined?(ActiveSupport::Duration) && ActiveSupport::Duration === v
94
99
  if @date_type == :ruby_date
95
- Arel.sql("(INTERVAL '1' DAY) * %s" % v.inspect.to_i)
100
+ Arel.sql("(INTERVAL '1' DAY) * %s" % v.inspect.to_i )
96
101
  else
97
102
  Arel.sql("(INTERVAL '1' SECOND) * %s" % v.to_i)
98
103
  end
99
- elsif v.is_a?(ArelExtensions::Nodes::Duration)
100
- v.with_interval = true
101
- v
102
104
  else
103
- v
105
+ if ArelExtensions::Nodes::Duration === v
106
+ v.with_interval = true
107
+ v
108
+ else
109
+ v
110
+ end
104
111
  end
105
112
  end
106
113
 
107
114
  def mssql_value(v = nil)
108
- v ||= expressions.last
109
- if defined?(ActiveSupport::Duration) && v.is_a?(ActiveSupport::Duration)
115
+ v ||= self.expressions.last
116
+ if defined?(ActiveSupport::Duration) && ActiveSupport::Duration === v
110
117
  if @date_type == :date
111
- v.to_i / (24 * 3600)
118
+ v.to_i / (24*3600)
112
119
  elsif @date_type == :datetime
113
- if v.parts.size == 1
114
- # first entry in the dict v.parts; one of [:years, :months, :weeks, :days, :hours, :minutes, :seconds]
115
- # | the value
116
- # | |
117
- # | |
118
- # v v
119
- v.parts.first.second
120
- else
121
- v.to_i
122
- end
120
+ v.to_i
123
121
  end
124
122
  else
125
123
  v
@@ -127,40 +125,33 @@ module ArelExtensions
127
125
  end
128
126
 
129
127
  def mssql_datepart(v = nil)
130
- v ||= expressions.last
131
- if defined?(ActiveSupport::Duration) && v.is_a?(ActiveSupport::Duration)
128
+ v ||= self.expressions.last
129
+ if defined?(ActiveSupport::Duration) && ActiveSupport::Duration === v
132
130
  if @date_type == :date
133
131
  Arel.sql('day')
134
132
  elsif @date_type == :datetime
135
- res = if v.parts.size == 1
136
- # first entry in the dict v.parts; one of [:years, :months, :weeks, :days, :hours, :minutes, :seconds]
137
- # | the key
138
- # | | convert symbol to string
139
- # | | | remove the plural suffix `s`
140
- # v v v v
141
- v.parts.first.first.to_s[0..-2]
142
- else
143
- 'second'
144
- end
145
- Arel.sql(res)
146
- end
147
- elsif v.is_a?(ArelExtensions::Nodes::Duration)
148
- v.with_interval = true
149
- case v.left
150
- when 'd', 'm', 'y'
151
- Arel.sql('day')
152
- when 'h', 'mn', 's'
153
133
  Arel.sql('second')
154
- when /i\z/
155
- Arel.sql(ArelExtensions::Visitors::MSSQL::LOADED_VISITOR::DATE_MAPPING[v.left[0..-2]])
134
+ end
135
+ else
136
+ if ArelExtensions::Nodes::Duration === v
137
+ v.with_interval = true
138
+ case v.left
139
+ when 'd','m','y'
140
+ Arel.sql('day')
141
+ when 'h','mn','s'
142
+ Arel.sql('second')
143
+ when /i\z/
144
+ Arel.sql(Arel::Visitors::MSSQL::DATE_MAPPING[v.left[0..-2]])
145
+ else
146
+ Arel.sql(Arel::Visitors::MSSQL::DATE_MAPPING[v.left])
147
+ end
156
148
  else
157
- Arel.sql(ArelExtensions::Visitors::MSSQL::LOADED_VISITOR::DATE_MAPPING[v.left])
149
+ nil
158
150
  end
159
151
  end
160
152
  end
161
153
 
162
154
  private
163
-
164
155
  def convert(object)
165
156
  case object
166
157
  when Arel::Attributes::Attribute, Arel::Nodes::Node, ActiveSupport::Duration
@@ -168,20 +159,20 @@ module ArelExtensions
168
159
  when Integer
169
160
  object.days
170
161
  when DateTime, Time, Date
171
- raise(ArgumentError, "#{object.class} cannot be converted to Integer")
162
+ raise(ArgumentError, "#{object.class} can not be converted to Integer")
172
163
  when String
173
- Arel.quoted(object)
164
+ Arel::Nodes.build_quoted(object)
174
165
  else
175
- raise(ArgumentError, "#{object.class} cannot be converted to Integer")
166
+ raise(ArgumentError, "#{object.class} can not be converted to Integer")
176
167
  end
177
168
  end
178
169
  end
179
170
 
180
- class DateSub < Function # difference entre colonne date et date string/date
171
+ class DateSub < Function #difference entre colonne date et date string/date
181
172
  RETURN_TYPE = :integer
182
173
 
183
174
  def initialize(expr)
184
- super([expr.first, convert_number(expr[1])])
175
+ super [expr.first, convert_number(expr[1])]
185
176
  end
186
177
 
187
178
  def convert_number(object)
@@ -191,13 +182,15 @@ module ArelExtensions
191
182
  when String
192
183
  object.to_i
193
184
  else
194
- if defined?(ActiveSupport::Duration) && object.is_a?(ActiveSupport::Duration)
185
+ if defined?(ActiveSupport::Duration) && ActiveSupport::Duration === object
195
186
  object.to_i
196
187
  else
197
- raise(ArgumentError, "#{object.class} cannot be converted to Number")
188
+ raise(ArgumentError, "#{object.class} can not be converted to Number")
198
189
  end
199
190
  end
200
191
  end
192
+
201
193
  end
194
+
202
195
  end
203
196
  end
@@ -5,21 +5,24 @@ module ArelExtensions
5
5
 
6
6
  attr_accessor :with_interval
7
7
 
8
- def initialize(left, right, aliaz = nil)
9
- tab = []
8
+ def initialize left, right, aliaz = nil
9
+ tab = Array.new
10
10
  tab << left
11
11
  tab << right
12
12
  @with_interval = left.end_with?('i')
13
13
  super(tab, aliaz)
14
14
  end
15
15
 
16
+
16
17
  def left
17
18
  @expressions.first
18
19
  end
19
20
 
21
+
20
22
  def right
21
23
  @expressions[1]
22
24
  end
25
+
23
26
  end
24
27
  end
25
28
  end
@@ -2,6 +2,7 @@ module ArelExtensions
2
2
  module Nodes
3
3
  class FindInSet < Function
4
4
  RETURN_TYPE = :integer
5
+
5
6
  end
6
7
  end
7
8
  end
@@ -1,7 +1,7 @@
1
1
  module ArelExtensions
2
2
  module Nodes
3
3
  class Floor < Function
4
- RETURN_TYPE = :number
4
+ RETURN_TYPE = :number
5
5
  end
6
6
  end
7
7
  end
@@ -1,42 +1,15 @@
1
- require 'strscan'
2
-
3
1
  module ArelExtensions
4
2
  module Nodes
5
- class Format < Function
3
+ class Format < Function
6
4
  RETURN_TYPE = :string
7
5
 
8
- attr_accessor :col_type, :iso_format, :time_zone
9
-
10
- def initialize(expr)
11
- col = expr[0]
12
- @iso_format = convert_format(expr[1])
13
- @time_zone = expr[2]
14
- @col_type = type_of_attribute(col)
15
- super([col, convert_to_string_node(@iso_format)])
16
- end
17
-
18
- private
19
-
20
- # Address portability issues with some of the formats.
21
- def convert_format(fmt)
22
- s = StringScanner.new fmt
23
- res = StringIO.new
24
- while !s.eos?
25
- res <<
26
- case
27
- when s.scan(/%D/) then '%m/%d/%y'
28
- when s.scan(/%F/) then '%Y-%m-%d'
29
- when s.scan(/%R/) then '%H:%M'
30
- when s.scan(/%r/) then '%I:%M:%S %p'
31
- when s.scan(/%T/) then '%H:%M:%S'
32
- when s.scan(/%v/) then '%e-%b-%Y'
33
-
34
- when s.scan(/[^%]+/) then s.matched
35
- when s.scan(/./) then s.matched
36
- end
37
- end
38
- res.string
39
- end
6
+ attr_accessor :col_type, :iso_format
7
+ def initialize expr
8
+ col = expr.first
9
+ @iso_format = expr[1]
10
+ @col_type = type_of_attribute(col)
11
+ super [col, convert_to_string_node(@iso_format)]
12
+ end
40
13
  end
41
14
  end
42
15
  end
@@ -1,24 +1,25 @@
1
1
  module ArelExtensions
2
- module Nodes
3
- class FormattedNumber < Function
4
- RETURN_TYPE = :string
5
-
6
- attr_accessor :locale, :prefix, :suffix, :flags, :scientific_notation, :width, :precision, :type, :original_string
7
-
8
- def initialize(expr)
9
- # expr[1] = {locale: 'fr_FR', type: "e"/"f"/"d", prefix: "$ ", suffix: " %", flags: " +-#0", width: 5, precision: 6}
10
- col = expr.first
11
- @locale = expr[1][:locale]
12
- @prefix = expr[1][:prefix]
13
- @suffix = expr[1][:suffix]
14
- @width = expr[1][:width]
15
- @precision = expr[1][:precision]
16
- @type = expr[1][:type]
17
- @flags = expr[1][:flags]
18
- @scientific_notation = /[eE]/.match(expr[1][:type]) || false
19
- @original_string = expr[1][:original_string]
20
- super([col])
21
- end
22
- end
23
- end
2
+ module Nodes
3
+ class FormattedNumber < Function
4
+ RETURN_TYPE = :string
5
+
6
+ attr_accessor :locale, :prefix, :suffix, :flags, :scientific_notation, :width,:precision, :type, :original_string
7
+
8
+ def initialize expr
9
+ # expr[1] = {:locale => 'fr_FR', :type => "e"/"f"/"d", :prefix => "$ ", :suffix => " %", :flags => " +-#0", :width => 5, :precision => 6}
10
+ col = expr.first
11
+ @locale = expr[1][:locale]
12
+ @prefix = expr[1][:prefix]
13
+ @suffix = expr[1][:suffix]
14
+ @width = expr[1][:width]
15
+ @precision = expr[1][:precision]
16
+ @type = expr[1][:type]
17
+ @flags = expr[1][:flags]
18
+ @scientific_notation = /[eE]/.match(expr[1][:type]) || false
19
+ @original_string = expr[1][:original_string]
20
+ super [col]
21
+ end
22
+
23
+ end
24
+ end
24
25
  end
@@ -1,11 +1,5 @@
1
1
  require 'arel_extensions/predications'
2
2
 
3
- # This is required for rails 6.1
4
- # See https://github.com/thoughtbot/shoulda-matchers/issues/335
5
- if !Array.respond_to?(:wrap)
6
- require 'active_support/core_ext/array/wrap'
7
- end
8
-
9
3
  module ArelExtensions
10
4
  module Nodes
11
5
  class Function < Arel::Nodes::Function
@@ -16,24 +10,18 @@ module ArelExtensions
16
10
 
17
11
  RETURN_TYPE = :string # by default...
18
12
 
19
- # Support multibyte string if they are available.
20
- MBSTRING =
21
- defined?(ActiveSupport::Multibyte::Chars) ? ActiveSupport::Multibyte::Chars : String
22
-
23
13
  # overrides as to make new Node like AliasPredication
24
14
 
25
15
  def return_type
26
16
  self.class.const_get(:RETURN_TYPE)
27
17
  end
28
18
 
29
- def as(other)
30
- res = Arel::Nodes::As.new(clone, Arel.sql(other))
31
- self.alias = Arel.sql(other)
32
- res
19
+ def as other
20
+ Arel::Nodes::As.new(self, Arel.sql(other))
33
21
  end
34
22
 
35
23
  def expr
36
- @expressions.first
24
+ @expressions.first
37
25
  end
38
26
 
39
27
  def left
@@ -45,21 +33,25 @@ module ArelExtensions
45
33
  end
46
34
 
47
35
  def ==(other)
48
- Arel::Nodes::Equality.new self, Arel.quoted(other, self)
36
+ Arel::Nodes::Equality.new self, Arel::Nodes.build_quoted(other, self)
49
37
  end
50
38
 
51
39
  def !=(other)
52
- Arel::Nodes::NotEqual.new self, Arel.quoted(other, self)
40
+ Arel::Nodes::NotEqual.new self, Arel::Nodes.build_quoted(other, self)
53
41
  end
54
42
 
55
43
  def type_of_attribute(att)
56
44
  case att
57
45
  when Arel::Attributes::Attribute
58
- Arel.column_of(att.relation.table_name, att.name.to_s)&.type || att
46
+ begin
47
+ Arel::Table.engine.connection.schema_cache.columns_hash(att.relation.table_name)[att.name.to_s].type
48
+ rescue
49
+ att
50
+ end
59
51
  when ArelExtensions::Nodes::Function
60
52
  att.return_type
61
- # else
62
- # nil
53
+ # else
54
+ # nil
63
55
  end
64
56
  end
65
57
 
@@ -68,23 +60,19 @@ module ArelExtensions
68
60
  when Arel::Attributes::Attribute, Arel::Nodes::Node, Integer
69
61
  object
70
62
  when DateTime
71
- Arel.quoted(object, self)
63
+ Arel::Nodes.build_quoted(object, self)
72
64
  when Time
73
- Arel.quoted(object.strftime('%H:%M:%S'), self)
74
- when MBSTRING, String, Symbol
75
- Arel.quoted(object.to_s)
76
- when TrueClass, FalseClass
77
- Arel.quoted(object)
65
+ Arel::Nodes.build_quoted(object.strftime('%H:%M:%S'), self)
66
+ when String, Symbol
67
+ Arel::Nodes.build_quoted(object.to_s)
78
68
  when Date
79
- Arel.quoted(object.to_s, self)
69
+ Arel::Nodes.build_quoted(object.to_s, self)
80
70
  when NilClass
81
71
  Arel.sql('NULL')
82
72
  when ActiveSupport::Duration
83
73
  Arel.sql(object.to_i)
84
- when Array
85
- Arel.grouping(object.map { |e| convert_to_node(e) })
86
74
  else
87
- raise(ArgumentError, "#{object.class} cannot be converted to CONCAT arg")
75
+ raise(ArgumentError, "#{object.class} can not be converted to CONCAT arg")
88
76
  end
89
77
  end
90
78
 
@@ -93,9 +81,9 @@ module ArelExtensions
93
81
  when Arel::Nodes::Node
94
82
  object
95
83
  when Integer
96
- Arel.quoted(object.to_s)
84
+ Arel::Nodes.build_quoted(object.to_s)
97
85
  when Arel::Attributes::Attribute
98
- case type_of_attribute(object)
86
+ case self.type_of_attribute(object)
99
87
  when :date
100
88
  ArelExtensions::Nodes::Format.new [object, 'yyyy-mm-dd']
101
89
  when :time
@@ -104,19 +92,19 @@ module ArelExtensions
104
92
  object
105
93
  end
106
94
  when DateTime
107
- Arel.quoted(object, self)
95
+ Arel::Nodes.build_quoted(object, self)
108
96
  when Time
109
- Arel.quoted(object.strftime('%H:%M:%S'), self)
110
- when MBSTRING, String
111
- Arel.quoted(object.to_s)
97
+ Arel::Nodes.build_quoted(object.strftime('%H:%M:%S'), self)
98
+ when String
99
+ Arel::Nodes.build_quoted(object)
112
100
  when Date
113
- Arel.quoted(object, self)
101
+ Arel::Nodes.build_quoted(object, self)
114
102
  when NilClass
115
103
  Arel.sql(nil)
116
104
  when ActiveSupport::Duration
117
- Arel.quoted(object.to_i.to_s)
105
+ Arel::Nodes.build_quoted(object.to_i.to_s)
118
106
  else
119
- raise(ArgumentError, "#{object.class} cannot be converted to CONCAT arg")
107
+ raise(ArgumentError, "#{object.class} can not be converted to CONCAT arg")
120
108
  end
121
109
  end
122
110
 
@@ -125,13 +113,13 @@ module ArelExtensions
125
113
  when Arel::Attributes::Attribute, Arel::Nodes::Node
126
114
  object
127
115
  when DateTime, Time
128
- Arel.quoted(Date.new(object.year, object.month, object.day), self)
129
- when MBSTRING, String
130
- Arel.quoted(Date.parse(object.to_s), self)
116
+ Arel::Nodes.build_quoted(Date.new(object.year, object.month, object.day), self)
117
+ when String
118
+ Arel::Nodes.build_quoted(Date.parse(object), self)
131
119
  when Date
132
- Arel.quoted(object, self)
120
+ Arel::Nodes.build_quoted(object, self)
133
121
  else
134
- raise(ArgumentError, "#{object.class} cannot be converted to Date")
122
+ raise(ArgumentError, "#{object.class} can not be converted to Date")
135
123
  end
136
124
  end
137
125
 
@@ -140,13 +128,13 @@ module ArelExtensions
140
128
  when Arel::Attributes::Attribute, Arel::Nodes::Node
141
129
  object
142
130
  when DateTime, Time
143
- Arel.quoted(object, self)
144
- when MBSTRING, String
145
- Arel.quoted(Time.parse(object.to_s), self)
131
+ Arel::Nodes.build_quoted(object, self)
132
+ when String
133
+ Arel::Nodes.build_quoted(Time.parse(object), self)
146
134
  when Date
147
- Arel.quoted(Time.utc(object.year, object.month, object.day, 0, 0, 0), self)
135
+ Arel::Nodes.build_quoted(Time.utc(object.year, object.month, object.day, 0, 0, 0), self)
148
136
  else
149
- raise(ArgumentError, "#{object.class} cannot be converted to Datetime")
137
+ raise(ArgumentError, "#{object.class} can not be converted to Datetime")
150
138
  end
151
139
  end
152
140
 
@@ -164,9 +152,10 @@ module ArelExtensions
164
152
  when NilClass
165
153
  0
166
154
  else
167
- raise(ArgumentError, "#{object.class} cannot be converted to NUMBER arg")
155
+ raise(ArgumentError, "#{object.class} can not be converted to NUMBER arg")
168
156
  end
169
157
  end
158
+
170
159
  end
171
160
  end
172
161
  end
@@ -4,13 +4,11 @@ module ArelExtensions
4
4
  module Nodes
5
5
  class IsNull < Arel::Nodes::Unary
6
6
  include ArelExtensions::BooleanFunctions
7
-
8
7
  RETURN_TYPE = :boolean
9
8
  end
10
9
 
11
10
  class IsNotNull < Arel::Nodes::Unary
12
11
  include ArelExtensions::BooleanFunctions
13
-
14
12
  RETURN_TYPE = :boolean
15
13
  end
16
14
  end