arel_extensions 1.6.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 -7
  4. data/.rubocop.yml +3 -67
  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 +91 -258
  14. data/Rakefile +30 -48
  15. data/TODO +1 -0
  16. data/appveyor.yml +22 -60
  17. data/arel_extensions.gemspec +14 -13
  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 +14 -14
  23. data/gemfiles/rails5_2.gemfile +14 -16
  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 -7
  30. data/lib/arel_extensions/boolean_functions.rb +14 -53
  31. data/lib/arel_extensions/common_sql_functions.rb +17 -16
  32. data/lib/arel_extensions/comparators.rb +28 -29
  33. data/lib/arel_extensions/date_duration.rb +13 -17
  34. data/lib/arel_extensions/insert_manager.rb +15 -18
  35. data/lib/arel_extensions/math.rb +53 -55
  36. data/lib/arel_extensions/math_functions.rb +39 -46
  37. data/lib/arel_extensions/nodes/abs.rb +1 -0
  38. data/lib/arel_extensions/nodes/blank.rb +2 -1
  39. data/lib/arel_extensions/nodes/case.rb +19 -20
  40. data/lib/arel_extensions/nodes/cast.rb +8 -10
  41. data/lib/arel_extensions/nodes/ceil.rb +1 -1
  42. data/lib/arel_extensions/nodes/coalesce.rb +4 -3
  43. data/lib/arel_extensions/nodes/collate.rb +10 -9
  44. data/lib/arel_extensions/nodes/concat.rb +18 -9
  45. data/lib/arel_extensions/nodes/date_diff.rb +26 -42
  46. data/lib/arel_extensions/nodes/duration.rb +3 -0
  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 +37 -46
  52. data/lib/arel_extensions/nodes/is_null.rb +0 -0
  53. data/lib/arel_extensions/nodes/json.rb +39 -52
  54. data/lib/arel_extensions/nodes/length.rb +0 -5
  55. data/lib/arel_extensions/nodes/levenshtein_distance.rb +1 -1
  56. data/lib/arel_extensions/nodes/locate.rb +2 -1
  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 +1 -0
  62. data/lib/arel_extensions/nodes/repeat.rb +5 -3
  63. data/lib/arel_extensions/nodes/replace.rb +8 -16
  64. data/lib/arel_extensions/nodes/round.rb +6 -5
  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 -8
  68. data/lib/arel_extensions/nodes/then.rb +1 -1
  69. data/lib/arel_extensions/nodes/trim.rb +6 -4
  70. data/lib/arel_extensions/nodes/union.rb +8 -5
  71. data/lib/arel_extensions/nodes/union_all.rb +7 -4
  72. data/lib/arel_extensions/nodes/wday.rb +4 -0
  73. data/lib/arel_extensions/nodes.rb +1 -1
  74. data/lib/arel_extensions/null_functions.rb +5 -19
  75. data/lib/arel_extensions/predications.rb +44 -45
  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 +35 -91
  79. data/lib/arel_extensions/tasks.rb +6 -6
  80. data/lib/arel_extensions/version.rb +1 -1
  81. data/lib/arel_extensions/visitors/ibm_db.rb +31 -24
  82. data/lib/arel_extensions/visitors/mssql.rb +194 -440
  83. data/lib/arel_extensions/visitors/mysql.rb +212 -368
  84. data/lib/arel_extensions/visitors/oracle.rb +179 -236
  85. data/lib/arel_extensions/visitors/oracle12.rb +31 -18
  86. data/lib/arel_extensions/visitors/postgresql.rb +173 -271
  87. data/lib/arel_extensions/visitors/sqlite.rb +127 -157
  88. data/lib/arel_extensions/visitors/to_sql.rb +238 -300
  89. data/lib/arel_extensions/visitors.rb +62 -83
  90. data/lib/arel_extensions.rb +31 -235
  91. data/test/database.yml +10 -20
  92. data/test/helper.rb +18 -0
  93. data/test/real_db_test.rb +118 -121
  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 +370 -773
  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 +38 -52
  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 -18
  113. data/NEWS.md +0 -116
  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 -29
  121. data/gemfiles/rails6.gemfile +0 -34
  122. data/gemfiles/rails6_1.gemfile +0 -42
  123. data/gemfiles/rails7.gemfile +0 -42
  124. data/gemfiles/rails7_1.gemfile +0 -41
  125. data/gemfiles/rails7_2.gemfile +0 -41
  126. data/gemfiles/rails8.gemfile +0 -40
  127. data/gemfiles/rails8_1.gemfile +0 -41
  128. data/gemspecs/arel_extensions-v1.gemspec +0 -27
  129. data/gemspecs/arel_extensions-v2.gemspec +0 -27
  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 -3
  146. data/version_v2.rb +0 -3
@@ -1,67 +1,43 @@
1
1
  module ArelExtensions
2
2
  module Visitors
3
- class Arel::Visitors::PostgreSQL
4
- DATE_MAPPING = {
5
- 'd' => 'DAY', 'm' => 'MONTH', 'w' => 'WEEK', 'y' => 'YEAR', 'wd' => 'DOW',
6
- 'h' => 'HOUR', 'mn' => 'MINUTE', 's' => 'SECOND'
7
- }.freeze
8
-
9
- DATE_FORMAT_DIRECTIVES = {
10
- '%Y' => 'YYYY', '%C' => 'CC', '%y' => 'YY',
11
- '%m' => 'MM', '%B' => 'TMMonth', '%^B' => 'TMMONTH', '%b' => 'TMMon', '%^b' => 'TMMON',
12
- '%V' => 'IW', '%G' => 'IYYY', # ISO week number and year of week
13
- '%d' => 'DD', '%e' => 'FMDD', '%j' => 'DDD', '%w' => '', '%a' => 'TMDy', '%A' => 'TMDay', # day, weekday
14
- '%H' => 'HH24', '%k' => '', '%I' => 'HH', '%l' => '', '%P' => 'am', '%p' => 'AM', # hours
15
- '%M' => 'MI', '%S' => 'SS', '%L' => 'MS', '%N' => 'US', '%z' => 'tz', # seconds, subseconds
16
- '%%' => '%',
17
- }.freeze
18
-
19
- NUMBER_COMMA_MAPPING = {
20
- 'en_US' => '.,', 'fr_FR' => ',', 'sv_SE' => ', '
21
- }.freeze
22
-
23
- def visit_ArelExtensions_Nodes_ByteSize o, collector
24
- collector << 'octet_length('
25
- collector = visit o.expr.coalesce(''), collector
26
- collector << ')'
27
- collector
28
- end
29
-
30
- def visit_ArelExtensions_Nodes_CharLength o, collector
31
- collector << 'length('
32
- collector = visit o.expr.coalesce(''), collector
33
- collector << ')'
34
- collector
35
- end
3
+ Arel::Visitors::PostgreSQL.class_eval do
4
+ Arel::Visitors::PostgreSQL::DATE_MAPPING = {'d' => 'DAY', 'm' => 'MONTH', 'w' => 'WEEK', 'y' => 'YEAR', 'wd' => 'DOW', 'h' => 'HOUR', 'mn' => 'MINUTE', 's' => 'SECOND'}
5
+ Arel::Visitors::PostgreSQL::DATE_FORMAT_DIRECTIVES = {
6
+ '%Y' => 'IYYY', '%C' => 'CC', '%y' => 'YY', '%m' => 'MM', '%B' => 'Month', '%^B' => 'MONTH', '%b' => 'Mon', '%^b' => 'MON',
7
+ '%d' => 'DD', '%e' => 'FMDD', '%j' => 'DDD', '%w' => '', '%A' => 'Day', # day, weekday
8
+ '%H' => 'HH24', '%k' => '', '%I' => 'HH', '%l' => '', '%P' => 'am', '%p' => 'AM', # hours
9
+ '%M' => 'MI', '%S' => 'SS', '%L' => 'MS', '%N' => 'US', '%z' => 'tz' # seconds, subseconds
10
+ }
11
+ Arel::Visitors::PostgreSQL::NUMBER_COMMA_MAPPING = { 'en_US' => '.,', 'fr_FR' => ',', 'sv_SE' => ', ' }
36
12
 
37
13
  def visit_ArelExtensions_Nodes_Rand o, collector
38
- collector << 'RANDOM('
39
- if (o.left != nil && o.right != nil)
14
+ collector << "RANDOM("
15
+ if(o.left != nil && o.right != nil)
40
16
  collector = visit o.left, collector
41
- collector << COMMA
17
+ collector << Arel::Visitors::PostgreSQL::COMMA
42
18
  collector = isit o.right, collector
43
19
  end
44
- collector << ')'
20
+ collector << ")"
45
21
  collector
46
22
  end
47
23
 
48
24
  def visit_ArelExtensions_Nodes_Power o, collector
49
- collector << 'POWER('
25
+ collector << "POWER("
50
26
  o.expressions.each_with_index { |arg, i|
51
- collector << Arel::Visitors::ToSql::COMMA if i != 0
27
+ collector << Arel::Visitors::ToSql::COMMA unless i == 0
52
28
  collector = visit arg, collector
53
29
  }
54
- collector << ')'
30
+ collector << ")"
55
31
  collector
56
32
  end
57
33
 
58
34
  def visit_ArelExtensions_Nodes_Log10 o, collector
59
- collector << 'LOG('
35
+ collector << "LOG("
60
36
  o.expressions.each_with_index { |arg, i|
61
- collector << Arel::Visitors::ToSql::COMMA if i != 0
37
+ collector << Arel::Visitors::ToSql::COMMA unless i == 0
62
38
  collector = visit arg, collector
63
39
  }
64
- collector << ')'
40
+ collector << ")"
65
41
  collector
66
42
  end
67
43
 
@@ -69,7 +45,7 @@ module ArelExtensions
69
45
  remove_method(:visit_Arel_Nodes_Regexp) rescue nil
70
46
  def visit_Arel_Nodes_Regexp o, collector
71
47
  collector = visit o.left, collector
72
- collector << ' ~ '
48
+ collector << " ~ "
73
49
  collector = visit o.right, collector
74
50
  collector
75
51
  end
@@ -77,7 +53,7 @@ module ArelExtensions
77
53
  remove_method(:visit_Arel_Nodes_NotRegexp) rescue nil
78
54
  def visit_Arel_Nodes_NotRegexp o, collector
79
55
  collector = visit o.left, collector
80
- collector << ' !~ '
56
+ collector << " !~ "
81
57
  collector = visit o.right, collector
82
58
  collector
83
59
  end
@@ -88,11 +64,11 @@ module ArelExtensions
88
64
  collector = visit arg, collector
89
65
  collector << ' || ' unless i == o.expressions.length - 1
90
66
  }
91
- collector << ')'
67
+ collector << ")"
92
68
  collector
93
69
  end
94
70
 
95
- alias_method(:old_visit_Arel_Nodes_As, :visit_Arel_Nodes_As) rescue nil
71
+ alias_method :old_visit_Arel_Nodes_As, :visit_Arel_Nodes_As
96
72
  def visit_Arel_Nodes_As o, collector
97
73
  if o.left.is_a?(Arel::Nodes::Binary)
98
74
  collector << '('
@@ -101,126 +77,80 @@ module ArelExtensions
101
77
  else
102
78
  collector = visit o.left, collector
103
79
  end
104
- collector << ' AS '
105
-
106
- # sometimes these values are already quoted, if they are, don't double quote it
107
- quote = o.right.is_a?(Arel::Nodes::SqlLiteral) && o.right[0] != '"' && o.right[-1] != '"'
108
-
109
- collector << '"' if quote
80
+ collector << " AS \""
110
81
  collector = visit o.right, collector
111
- collector << '"' if quote
112
-
113
- collector
114
- end
115
-
116
- def visit_Aggregate_For_AggregateFunction o, collector
117
- if !o.order.blank? || !o.group.blank?
118
- collector << ' OVER ('
119
- if !o.group.blank?
120
- collector << ' PARTITION BY '
121
- o.group.each_with_index do |group, i|
122
- collector << COMMA if i != 0
123
- visit group, collector
124
- end
125
- end
126
- if !o.order.blank?
127
- collector << ' ORDER BY '
128
- o.order.each_with_index do |order, i|
129
- collector << COMMA if i != 0
130
- visit order, collector
131
- end
132
- end
133
- collector << ')'
134
- end
82
+ collector << "\""
135
83
  collector
136
84
  end
137
85
 
138
86
  def visit_ArelExtensions_Nodes_GroupConcat o, collector
139
- collector << 'array_to_string(array_agg('
87
+ collector << "array_to_string(array_agg("
140
88
  collector = visit o.left, collector
141
- if o.order && !o.order.blank?
142
- collector << ' ORDER BY'
143
- o.order.each_with_index do |order, i|
144
- collector << COMMA if i != 0
145
- collector << ' '
146
- visit order, collector
89
+ if !o.orders.blank?
90
+ collector << ' ORDER BY '
91
+ o.orders.each_with_index do |order,i|
92
+ collector << Arel::Visitors::PostgreSQL::COMMA unless i == 0
93
+ collector = visit order, collector
147
94
  end
148
95
  end
149
- collector << ')'
150
- o.order = nil
151
- visit_Aggregate_For_AggregateFunction o, collector
152
- collector << COMMA
153
- sep = o.separator.is_a?(Arel::Nodes::Quoted) ? o.separator.expr : o.separator
154
- collector =
155
- if 'NULL' != sep
156
- visit o.separator, collector
157
- else
158
- visit Arel.quoted(','), collector
159
- end
160
- collector << ')'
96
+ collector << ")"
97
+ collector << Arel::Visitors::PostgreSQL::COMMA
98
+ if o.right && o.right != 'NULL'
99
+ collector = visit o.right, collector
100
+ else
101
+ collector = visit Arel::Nodes.build_quoted(','), collector
102
+ end
103
+ collector << ")"
161
104
  collector
162
105
  end
163
106
 
164
107
  def visit_ArelExtensions_Nodes_Trim o, collector
165
- collector << 'TRIM(BOTH '
166
- collector = visit o.right, collector
167
- collector << ' FROM '
168
- collector = visit o.left, collector
169
- collector << ')'
170
- collector
108
+ collector << 'TRIM(BOTH '
109
+ collector = visit o.right, collector
110
+ collector << " FROM "
111
+ collector = visit o.left, collector
112
+ collector << ")"
113
+ collector
171
114
  end
172
115
 
173
116
  def visit_ArelExtensions_Nodes_Ltrim o, collector
174
- collector << 'TRIM(LEADING '
175
- collector = visit o.right, collector
176
- collector << ' FROM '
177
- collector = visit o.left, collector
178
- collector << ')'
179
- collector
117
+ collector << 'TRIM(LEADING '
118
+ collector = visit o.right, collector
119
+ collector << " FROM "
120
+ collector = visit o.left, collector
121
+ collector << ")"
122
+ collector
180
123
  end
181
124
 
182
125
  def visit_ArelExtensions_Nodes_Rtrim o, collector
183
126
  collector << 'TRIM(TRAILING '
184
127
  collector = visit o.right, collector
185
- collector << ' FROM '
128
+ collector << " FROM "
186
129
  collector = visit o.left, collector
187
- collector << ')'
130
+ collector << ")"
188
131
  collector
189
132
  end
190
133
 
191
134
  def visit_ArelExtensions_Nodes_Format o, collector
192
- visit_ArelExtensions_Nodes_FormattedDate o, collector
193
- end
194
-
195
- def visit_ArelExtensions_Nodes_FormattedDate o, collector
196
- fmt = ArelExtensions::Visitors::strftime_to_format(o.iso_format, DATE_FORMAT_DIRECTIVES)
197
- collector << 'TO_CHAR('
198
- collector << '(' if o.time_zone
135
+ collector << "TO_CHAR("
199
136
  collector = visit o.left, collector
200
- case o.time_zone
201
- when Hash
202
- src_tz, dst_tz = o.time_zone.first
203
- collector << ') AT TIME ZONE '
204
- collector = visit Arel.quoted(src_tz), collector
205
- collector << ' AT TIME ZONE '
206
- collector = visit Arel.quoted(dst_tz), collector
207
- when String
208
- collector << ") AT TIME ZONE 'UTC' AT TIME ZONE "
209
- collector = visit Arel.quoted(o.time_zone), collector
210
- end
211
- collector << COMMA
212
- collector = visit Arel.quoted(fmt), collector
213
- collector << ')'
137
+ collector << Arel::Visitors::PostgreSQL::COMMA
138
+
139
+ f = o.iso_format.dup
140
+ Arel::Visitors::PostgreSQL::DATE_FORMAT_DIRECTIVES.each { |d, r| f.gsub!(d, r) }
141
+ collector = visit Arel::Nodes.build_quoted(f), collector
142
+
143
+ collector << ")"
214
144
  collector
215
145
  end
216
146
 
217
147
  def visit_ArelExtensions_Nodes_Repeat o, collector
218
- collector << 'REPEAT('
148
+ collector << "REPEAT("
219
149
  o.expressions.each_with_index { |arg, i|
220
- collector << Arel::Visitors::ToSql::COMMA if i != 0
150
+ collector << Arel::Visitors::ToSql::COMMA unless i == 0
221
151
  collector = visit arg, collector
222
152
  }
223
- collector << ')'
153
+ collector << ")"
224
154
  collector
225
155
  end
226
156
 
@@ -262,9 +192,9 @@ module ArelExtensions
262
192
 
263
193
  def visit_ArelExtensions_Nodes_Collate o, collector
264
194
  if o.ai
265
- collector << 'unaccent('
195
+ collector << "unaccent("
266
196
  collector = visit o.expressions.first, collector
267
- collector << ')'
197
+ collector << ")"
268
198
  elsif o.ci
269
199
  collector = visit o.expressions.first, collector
270
200
  else
@@ -275,7 +205,7 @@ module ArelExtensions
275
205
 
276
206
  def visit_ArelExtensions_Nodes_DateAdd o, collector
277
207
  collector = visit o.left, collector
278
- collector << ' + ' # (o.right.value >= 0 ? ' + ' : ' - ')
208
+ collector << ' + ' #(o.right.value >= 0 ? ' + ' : ' - ')
279
209
  collector = visit o.postgresql_value(o.right), collector
280
210
  collector
281
211
  end
@@ -283,16 +213,16 @@ module ArelExtensions
283
213
  def visit_ArelExtensions_Nodes_DateDiff o, collector
284
214
  if o.right_node_type == :ruby_date || o.right_node_type == :ruby_time || o.right_node_type == :date || o.right_node_type == :datetime || o.right_node_type == :time
285
215
  collector << if o.left_node_type == :ruby_time || o.left_node_type == :datetime || o.left_node_type == :time
286
- "DATEDIFF('second', "
216
+ "DATEDIFF('second', "
287
217
  else
288
- "DATEDIFF('day', "
218
+ "DATEDIFF('day', "
289
219
  end
290
220
  collector = visit o.right, collector
291
221
  collector << (o.right_node_type == :date ? '::date' : '::timestamp')
292
- collector << COMMA
222
+ collector << Arel::Visitors::PostgreSQL::COMMA
293
223
  collector = visit o.left, collector
294
224
  collector << (o.left_node_type == :date ? '::date' : '::timestamp')
295
- collector << ')'
225
+ collector << ")"
296
226
  else
297
227
  collector << '('
298
228
  collector = visit o.left, collector
@@ -309,57 +239,41 @@ module ArelExtensions
309
239
  def visit_ArelExtensions_Nodes_Duration o, collector
310
240
  if o.with_interval
311
241
  interval = case o.left
312
- when 'd', 'm', 'y'
242
+ when 'd','m','y'
313
243
  'DAY'
314
- when 'h', 'mn', 's'
244
+ when 'h','mn','s'
315
245
  'SECOND'
316
246
  when /i\z/
317
- collector << '('
247
+ collector << "("
318
248
  collector = visit o.right, collector
319
- collector << ')'
320
- collector << " * (INTERVAL '1' #{DATE_MAPPING[o.left[0..-2]]})"
249
+ collector << ")"
250
+ collector << " * (INTERVAL '1' #{Arel::Visitors::PostgreSQL::DATE_MAPPING[o.left[0..-2]]})"
321
251
  return collector
322
252
  end
323
253
  end
324
- collector << "EXTRACT(#{DATE_MAPPING[o.left]} FROM CAST("
254
+ collector << "EXTRACT(#{Arel::Visitors::PostgreSQL::DATE_MAPPING[o.left]} FROM "
325
255
  collector = visit o.right, collector
326
- collector << ' AS TIMESTAMP WITH TIME ZONE))'
256
+ collector << ")"
327
257
  collector << " * (INTERVAL '1' #{interval})" if interval && o.with_interval
328
258
  collector
329
259
  end
330
260
 
331
261
  def visit_ArelExtensions_Nodes_Locate o, collector
332
- collector << 'POSITION('
262
+ collector << "POSITION("
333
263
  collector = visit o.right, collector
334
- collector << ' IN '
264
+ collector << " IN "
335
265
  collector = visit o.left, collector
336
- collector << ')'
266
+ collector << ")"
337
267
  collector
338
268
  end
339
269
 
340
270
  def visit_ArelExtensions_Nodes_Substring o, collector
341
- collector << 'SUBSTR('
271
+ collector << "SUBSTR("
342
272
  o.expressions.each_with_index { |arg, i|
343
- collector << COMMA if i != 0
273
+ collector << Arel::Visitors::PostgreSQL::COMMA unless i == 0
344
274
  collector = visit arg, collector
345
275
  }
346
- collector << ')'
347
- collector
348
- end
349
-
350
- def visit_ArelExtensions_Nodes_RegexpReplace o, collector
351
- collector << 'REGEXP_REPLACE('
352
- visit o.left, collector
353
- collector << Arel::Visitors::ToSql::COMMA
354
- tab = o.pattern.inspect + 'g' # Make it always global
355
- pattern = tab.split('/')[1..-2].join('/')
356
- flags = tab.split('/')[-1]
357
- visit Arel.quoted(pattern), collector
358
- collector << Arel::Visitors::ToSql::COMMA
359
- visit o.substitute, collector
360
- collector << Arel::Visitors::ToSql::COMMA
361
- visit Arel.quoted(flags + 'g'), collector
362
- collector << ')'
276
+ collector << ")"
363
277
  collector
364
278
  end
365
279
 
@@ -370,111 +284,98 @@ module ArelExtensions
370
284
  end
371
285
 
372
286
  def visit_ArelExtensions_Nodes_IsNotNull o, collector
373
- collector = visit o.expr, collector
287
+ collector = visit o.expr, collector
374
288
  collector << ' IS NOT NULL'
375
289
  collector
376
290
  end
377
291
 
378
292
  def visit_ArelExtensions_Nodes_Sum o, collector
379
- collector << 'sum('
293
+ collector << "sum("
380
294
  collector = visit o.expr, collector
381
- collector << ')'
382
- visit_Aggregate_For_AggregateFunction o, collector
295
+ collector << ")"
383
296
  collector
384
297
  end
385
298
 
386
299
  def visit_ArelExtensions_Nodes_Wday o, collector
387
- collector << 'EXRTACT(DOW, '
300
+ collector << "EXRTACT(DOW, "
388
301
  collector = visit o.date, collector
389
302
  collector << ')'
390
303
  collector
391
304
  end
392
305
 
393
306
  def visit_ArelExtensions_Nodes_Cast o, collector
394
- as_attr =
395
- case o.as_attr
396
- when :string
397
- 'varchar'
398
- when :text, :ntext
399
- 'text'
400
- when :time
401
- 'time'
402
- when :int
403
- collector << 'CAST(CAST('
404
- collector = visit o.left, collector
405
- collector << ' AS numeric) AS int)'
406
- return collector
407
- when :number, :decimal, :float
408
- 'numeric'
409
- when :datetime
410
- 'timestamp without time zone'
411
- when :date
412
- 'date'
413
- when :binary
414
- 'binary'
415
- when :jsonb
416
- 'jsonb'
417
- else
418
- o.as_attr.to_s
419
- end
420
-
421
- collector << 'CAST('
307
+ as_attr = case o.as_attr
308
+ when :string
309
+ Arel::Nodes::SqlLiteral.new('varchar')
310
+ when :time
311
+ Arel::Nodes::SqlLiteral.new('time')
312
+ when :int
313
+ collector << "CAST(CAST("
314
+ collector = visit o.left, collector
315
+ collector << " AS numeric) AS int)"
316
+ return collector
317
+ when :number, :decimal, :float
318
+ Arel::Nodes::SqlLiteral.new('numeric')
319
+ when :datetime
320
+ Arel::Nodes::SqlLiteral.new('timestamp')
321
+ when :date
322
+ Arel::Nodes::SqlLiteral.new('date')
323
+ when :binary
324
+ Arel::Nodes::SqlLiteral.new('binary')
325
+ else
326
+ Arel::Nodes::SqlLiteral.new(o.as_attr.to_s)
327
+ end
328
+ collector << "CAST("
422
329
  collector = visit o.left, collector
423
- collector << ' AS '
424
- collector = visit Arel::Nodes::SqlLiteral.new(as_attr), collector
425
- collector << ')'
330
+ collector << " AS "
331
+ collector = visit as_attr, collector
332
+ collector << ")"
426
333
  collector
427
334
  end
428
335
 
429
336
  def visit_ArelExtensions_Nodes_FormattedNumber o, collector
430
337
  col = o.left.coalesce(0)
431
- comma = o.precision == 0 ? '' : (NUMBER_COMMA_MAPPING[o.locale][0] || '.')
432
- thousand_separator = NUMBER_COMMA_MAPPING[o.locale][1] || (NUMBER_COMMA_MAPPING[o.locale] ? '' : 'G')
338
+ comma = o.precision == 0 ? '' : (Arel::Visitors::PostgreSQL::NUMBER_COMMA_MAPPING[o.locale][0] || '.')
339
+ thousand_separator = Arel::Visitors::PostgreSQL::NUMBER_COMMA_MAPPING[o.locale][1] || (Arel::Visitors::PostgreSQL::NUMBER_COMMA_MAPPING[o.locale] ? '' : 'G')
433
340
  nines_after = (1..o.precision).map{'9'}.join('')
434
- nines_before = ("999#{thousand_separator}" * 4 + '990')
341
+ nines_before = ("999#{thousand_separator}"*4+"990")
435
342
 
436
- sign = Arel.when(col < 0).
343
+ sign = ArelExtensions::Nodes::Case.new.when(col<0).
437
344
  then('-').
438
345
  else(o.flags.include?('+') ? '+' : (o.flags.include?(' ') ? ' ' : ''))
439
346
  sign_length = ArelExtensions::Nodes::Length.new([sign])
440
347
 
441
- number =
442
- if o.scientific_notation
443
- ArelExtensions::Nodes::Concat.new([
444
- Arel::Nodes::NamedFunction.new('TRIM', [
445
- Arel::Nodes::NamedFunction.new('TO_CHAR', [
446
- Arel.when(col.not_eq 0).then(col.abs / Arel.quoted(10).pow(col.abs.log10.floor)).else(1),
447
- Arel.quoted("FM#{nines_before}\"#{comma}\"V#{nines_after}")
448
- ])]),
449
- o.type,
450
- Arel::Nodes::NamedFunction.new('TRIM', [
451
- Arel::Nodes::NamedFunction.new('TO_CHAR', [
452
- Arel.when(col.not_eq 0).then(col.abs.log10.floor).else(0),
453
- Arel.quoted("FM#{nines_before}")
454
- ])])
455
- ])
456
- else
457
- Arel::Nodes::NamedFunction.new('TRIM', [
458
- Arel::Nodes::NamedFunction.new('TO_CHAR', [
459
- Arel.quoted(col.abs),
460
- Arel.quoted("FM#{nines_before}\"#{comma}\"V#{nines_after}")
461
- ])])
462
- end
348
+ if o.scientific_notation
349
+ number = ArelExtensions::Nodes::Concat.new([
350
+ Arel::Nodes::NamedFunction.new('TRIM',[
351
+ Arel::Nodes::NamedFunction.new('TO_CHAR',[
352
+ col.abs/Arel::Nodes.build_quoted(10).pow(col.abs.log10.floor),
353
+ Arel::Nodes.build_quoted('FM'+nines_before+'"'+comma+'"V'+nines_after)
354
+ ])]),
355
+ o.type,
356
+ Arel::Nodes::NamedFunction.new('TRIM',[
357
+ Arel::Nodes::NamedFunction.new('TO_CHAR',[
358
+ col.abs.log10.floor,
359
+ Arel::Nodes.build_quoted('FM'+nines_before)
360
+ ])])
361
+ ])
362
+ else
363
+ number = Arel::Nodes::NamedFunction.new('TRIM',[
364
+ Arel::Nodes::NamedFunction.new('TO_CHAR',[
365
+ Arel::Nodes.build_quoted(col.abs),
366
+ Arel::Nodes.build_quoted('FM'+nines_before+'"'+comma+'"V'+nines_after)
367
+ ])])
368
+ end
463
369
 
464
- repeated_char =
465
- if o.width == 0
466
- Arel.quoted('')
467
- else
468
- Arel
469
- .when(Arel.quoted(o.width).abs - (number.length + sign_length) > 0)
470
- .then(Arel.quoted(
471
- o.flags.include?('-') ? ' ' : (o.flags.include?('0') ? '0' : ' ')
472
- ).repeat(Arel.quoted(o.width).abs - (number.length + sign_length))
473
- )
474
- .else('')
475
- end
476
- before = !o.flags.include?('0') && !o.flags.include?('-') ? repeated_char : ''
477
- middle = o.flags.include?('0') && !o.flags.include?('-') ? repeated_char : ''
370
+ repeated_char = (o.width == 0) ? Arel::Nodes.build_quoted('') : ArelExtensions::Nodes::Case.new().
371
+ when(Arel::Nodes.build_quoted(o.width).abs-(number.length+sign_length)>0).
372
+ then(Arel::Nodes.build_quoted(
373
+ o.flags.include?('-') ? ' ' : (o.flags.include?('0') ? '0' : ' ')
374
+ ).repeat(Arel::Nodes.build_quoted(o.width).abs-(number.length+sign_length))
375
+ ).
376
+ else('')
377
+ before = (!o.flags.include?('0'))&&(!o.flags.include?('-')) ? repeated_char : ''
378
+ middle = (o.flags.include?('0'))&&(!o.flags.include?('-')) ? repeated_char : ''
478
379
  after = o.flags.include?('-') ? repeated_char : ''
479
380
  full_number = ArelExtensions::Nodes::Concat.new([
480
381
  before,
@@ -483,30 +384,30 @@ module ArelExtensions
483
384
  number,
484
385
  after
485
386
  ])
486
- collector = visit ArelExtensions::Nodes::Concat.new([Arel.quoted(o.prefix), full_number, Arel.quoted(o.suffix)]), collector
387
+ collector = visit ArelExtensions::Nodes::Concat.new([Arel::Nodes.build_quoted(o.prefix),full_number,Arel::Nodes.build_quoted(o.suffix)]), collector
487
388
  collector
488
389
  end
489
390
 
490
391
 
491
- alias_method(:old_visit_Arel_Nodes_SelectStatement, :visit_Arel_Nodes_SelectStatement) rescue nil
392
+ alias_method :old_visit_Arel_Nodes_SelectStatement, :visit_Arel_Nodes_SelectStatement
492
393
  def visit_Arel_Nodes_SelectStatement o, collector
493
394
 
494
395
  if !(collector.value.blank? || (collector.value.is_a?(Array) && collector.value[0].blank?)) && o.limit.blank? && o.offset.blank?
495
396
  o = o.dup
496
397
  o.orders = []
497
398
  end
498
- old_visit_Arel_Nodes_SelectStatement(o, collector)
399
+ old_visit_Arel_Nodes_SelectStatement(o,collector)
499
400
  end
500
401
 
501
- alias_method(:old_visit_Arel_Nodes_TableAlias, :visit_Arel_Nodes_TableAlias) rescue nil
402
+ alias_method :old_visit_Arel_Nodes_TableAlias, :visit_Arel_Nodes_TableAlias
502
403
  def visit_Arel_Nodes_TableAlias o, collector
503
404
  if o.name.length > 63
504
405
  o = Arel::Table.new(o.table_name).alias(Arel.shorten(o.name))
505
406
  end
506
- old_visit_Arel_Nodes_TableAlias(o, collector)
407
+ old_visit_Arel_Nodes_TableAlias(o,collector)
507
408
  end
508
409
 
509
- alias_method(:old_visit_Arel_Attributes_Attribute, :visit_Arel_Attributes_Attribute) rescue nil
410
+ alias_method :old_visit_Arel_Attributes_Attribute, :visit_Arel_Attributes_Attribute
510
411
  def visit_Arel_Attributes_Attribute o, collector
511
412
  join_name = o.relation.table_alias || o.relation.name
512
413
  if join_name.length > 63
@@ -516,35 +417,33 @@ module ArelExtensions
516
417
  end
517
418
 
518
419
  def visit_ArelExtensions_Nodes_Std o, collector
519
- collector << (o.unbiased_estimator ? 'STDDEV_SAMP(' : 'STDDEV_POP(')
420
+ collector << (o.unbiased_estimator ? "STDDEV_SAMP(" : "STDDEV_POP(")
520
421
  visit o.left, collector
521
- collector << ')'
522
- visit_Aggregate_For_AggregateFunction o, collector
422
+ collector << ")"
523
423
  collector
524
424
  end
525
425
 
526
426
  def visit_ArelExtensions_Nodes_Variance o, collector
527
- collector << (o.unbiased_estimator ? 'VAR_SAMP(' : 'VAR_POP(')
427
+ collector << (o.unbiased_estimator ? "VAR_SAMP(" : "VAR_POP(")
528
428
  visit o.left, collector
529
- collector << ')'
530
- visit_Aggregate_For_AggregateFunction o, collector
429
+ collector << ")"
531
430
  collector
532
431
  end
533
432
 
534
- def visit_ArelExtensions_Nodes_Json o, collector
433
+ def visit_ArelExtensions_Nodes_Json o,collector
535
434
  case o.dict
536
435
  when Array
537
436
  collector << 'to_jsonb(array['
538
- o.dict.each.with_index do |v, i|
437
+ o.dict.each.with_index do |v,i|
539
438
  if i != 0
540
439
  collector << Arel::Visitors::MySQL::COMMA
541
440
  end
542
- collector = visit v, collector
441
+ collector = visit v, collector
543
442
  end
544
443
  collector << '])'
545
444
  when Hash
546
445
  collector << 'jsonb_build_object('
547
- o.dict.each.with_index do |(k, v), i|
446
+ o.dict.each.with_index do |(k,v),i|
548
447
  if i != 0
549
448
  collector << Arel::Visitors::MySQL::COMMA
550
449
  end
@@ -553,11 +452,13 @@ module ArelExtensions
553
452
  collector = visit v, collector
554
453
  end
555
454
  collector << ')'
556
- when String, Numeric, TrueClass, FalseClass
557
- collector = visit Arel.quoted("#{o.dict}"), collector
455
+ when String,Numeric,TrueClass,FalseClass
456
+ collector = visit Arel::Nodes.build_quoted("#{o.dict}"), collector
558
457
  collector << '::jsonb'
559
458
  when NilClass
560
- collector << %Q['null'::jsonb]
459
+ collector << %Q['null'::jsonb]
460
+ when Arel::Attributes::Attribute
461
+ collector = visit o.dict.cast(:jsonb), collector
561
462
  else
562
463
  collector = visit o.dict, collector
563
464
  collector << '::jsonb'
@@ -565,8 +466,8 @@ module ArelExtensions
565
466
  collector
566
467
  end
567
468
 
568
- def visit_ArelExtensions_Nodes_JsonMerge o, collector
569
- o.expressions.each.with_index do |v, i|
469
+ def visit_ArelExtensions_Nodes_JsonMerge o,collector
470
+ o.expressions.each.with_index do |v,i|
570
471
  if i != 0
571
472
  collector << ' || '
572
473
  end
@@ -575,14 +476,14 @@ module ArelExtensions
575
476
  collector
576
477
  end
577
478
 
578
- def visit_ArelExtensions_Nodes_JsonGet o, collector
479
+ def visit_ArelExtensions_Nodes_JsonGet o,collector
579
480
  collector = visit o.dict, collector
580
- collector << ' ->> '
481
+ collector << ' -> '
581
482
  collector = visit o.key, collector
582
483
  collector
583
484
  end
584
485
 
585
- def visit_ArelExtensions_Nodes_JsonSet o, collector
486
+ def visit_ArelExtensions_Nodes_JsonSet o,collector
586
487
  collector << 'jsonb_set('
587
488
  collector = visit o.dict, collector
588
489
  collector << Arel::Visitors::MySQL::COMMA
@@ -604,7 +505,7 @@ module ArelExtensions
604
505
  else
605
506
  case o.dict
606
507
  when Hash
607
- o.dict.each.with_index do |(k, v), i|
508
+ o.dict.each.with_index do |(k,v),i|
608
509
  if i != 0
609
510
  collector << ' || '
610
511
  end
@@ -622,6 +523,7 @@ module ArelExtensions
622
523
  end
623
524
  collector
624
525
  end
526
+
625
527
  end
626
528
  end
627
529
  end