arel_extensions 1.5.3 → 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 (141) 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 +90 -239
  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 +10 -10
  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 -48
  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 +7 -5
  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 +43 -44
  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 +36 -82
  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 +192 -423
  83. data/lib/arel_extensions/visitors/mysql.rb +212 -354
  84. data/lib/arel_extensions/visitors/oracle.rb +178 -221
  85. data/lib/arel_extensions/visitors/oracle12.rb +31 -18
  86. data/lib/arel_extensions/visitors/postgresql.rb +173 -257
  87. data/lib/arel_extensions/visitors/sqlite.rb +126 -140
  88. data/lib/arel_extensions/visitors/to_sql.rb +237 -299
  89. data/lib/arel_extensions/visitors.rb +62 -83
  90. data/lib/arel_extensions.rb +31 -226
  91. data/test/database.yml +7 -15
  92. data/test/helper.rb +18 -0
  93. data/test/real_db_test.rb +117 -120
  94. data/test/support/fake_record.rb +3 -9
  95. data/test/test_comparators.rb +17 -14
  96. data/test/visitors/test_bulk_insert_oracle.rb +11 -11
  97. data/test/visitors/test_bulk_insert_sqlite.rb +13 -12
  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 +366 -721
  102. data/test/with_ar/insert_agnostic_test.rb +21 -27
  103. data/test/with_ar/test_bulk_sqlite.rb +16 -17
  104. data/test/with_ar/test_math_sqlite.rb +26 -26
  105. data/test/with_ar/test_string_mysql.rb +33 -31
  106. data/test/with_ar/test_string_sqlite.rb +34 -30
  107. metadata +37 -47
  108. data/.github/workflows/publish.yml +0 -30
  109. data/.github/workflows/release.yml +0 -30
  110. data/.github/workflows/ruby.yml +0 -403
  111. data/CONTRIBUTING.md +0 -102
  112. data/NEWS.md +0 -109
  113. data/bin/build +0 -15
  114. data/bin/compose +0 -6
  115. data/bin/publish +0 -8
  116. data/dev/arelx.dockerfile +0 -44
  117. data/dev/compose.yaml +0 -71
  118. data/dev/postgres.dockerfile +0 -5
  119. data/dev/rbenv +0 -189
  120. data/gemfiles/rails4_2.gemfile +0 -38
  121. data/gemfiles/rails5.gemfile +0 -29
  122. data/gemfiles/rails6.gemfile +0 -34
  123. data/gemfiles/rails6_1.gemfile +0 -42
  124. data/gemfiles/rails7.gemfile +0 -42
  125. data/gemfiles/rails7_1.gemfile +0 -41
  126. data/gemfiles/rails7_2.gemfile +0 -41
  127. data/gemspecs/arel_extensions-v1.gemspec +0 -27
  128. data/gemspecs/arel_extensions-v2.gemspec +0 -27
  129. data/generate_gems.sh +0 -15
  130. data/lib/arel_extensions/aliases.rb +0 -14
  131. data/lib/arel_extensions/helpers.rb +0 -62
  132. data/lib/arel_extensions/nodes/aggregate_function.rb +0 -13
  133. data/lib/arel_extensions/nodes/formatted_date.rb +0 -42
  134. data/lib/arel_extensions/nodes/rollup.rb +0 -36
  135. data/lib/arel_extensions/nodes/select.rb +0 -10
  136. data/lib/arel_extensions/nodes/sum.rb +0 -7
  137. data/lib/arel_extensions/visitors/convert_format.rb +0 -37
  138. data/lib/arel_extensions/warning.rb +0 -42
  139. data/test/arelx_test_helper.rb +0 -92
  140. data/version_v1.rb +0 -3
  141. data/version_v2.rb +0 -3
@@ -1,53 +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
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' => ', ' }
22
12
 
23
13
  def visit_ArelExtensions_Nodes_Rand o, collector
24
- collector << 'RANDOM('
25
- if (o.left != nil && o.right != nil)
14
+ collector << "RANDOM("
15
+ if(o.left != nil && o.right != nil)
26
16
  collector = visit o.left, collector
27
- collector << COMMA
17
+ collector << Arel::Visitors::PostgreSQL::COMMA
28
18
  collector = isit o.right, collector
29
19
  end
30
- collector << ')'
20
+ collector << ")"
31
21
  collector
32
22
  end
33
23
 
34
24
  def visit_ArelExtensions_Nodes_Power o, collector
35
- collector << 'POWER('
25
+ collector << "POWER("
36
26
  o.expressions.each_with_index { |arg, i|
37
- collector << Arel::Visitors::ToSql::COMMA if i != 0
27
+ collector << Arel::Visitors::ToSql::COMMA unless i == 0
38
28
  collector = visit arg, collector
39
29
  }
40
- collector << ')'
30
+ collector << ")"
41
31
  collector
42
32
  end
43
33
 
44
34
  def visit_ArelExtensions_Nodes_Log10 o, collector
45
- collector << 'LOG('
35
+ collector << "LOG("
46
36
  o.expressions.each_with_index { |arg, i|
47
- collector << Arel::Visitors::ToSql::COMMA if i != 0
37
+ collector << Arel::Visitors::ToSql::COMMA unless i == 0
48
38
  collector = visit arg, collector
49
39
  }
50
- collector << ')'
40
+ collector << ")"
51
41
  collector
52
42
  end
53
43
 
@@ -55,7 +45,7 @@ module ArelExtensions
55
45
  remove_method(:visit_Arel_Nodes_Regexp) rescue nil
56
46
  def visit_Arel_Nodes_Regexp o, collector
57
47
  collector = visit o.left, collector
58
- collector << ' ~ '
48
+ collector << " ~ "
59
49
  collector = visit o.right, collector
60
50
  collector
61
51
  end
@@ -63,7 +53,7 @@ module ArelExtensions
63
53
  remove_method(:visit_Arel_Nodes_NotRegexp) rescue nil
64
54
  def visit_Arel_Nodes_NotRegexp o, collector
65
55
  collector = visit o.left, collector
66
- collector << ' !~ '
56
+ collector << " !~ "
67
57
  collector = visit o.right, collector
68
58
  collector
69
59
  end
@@ -74,11 +64,11 @@ module ArelExtensions
74
64
  collector = visit arg, collector
75
65
  collector << ' || ' unless i == o.expressions.length - 1
76
66
  }
77
- collector << ')'
67
+ collector << ")"
78
68
  collector
79
69
  end
80
70
 
81
- 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
82
72
  def visit_Arel_Nodes_As o, collector
83
73
  if o.left.is_a?(Arel::Nodes::Binary)
84
74
  collector << '('
@@ -87,126 +77,80 @@ module ArelExtensions
87
77
  else
88
78
  collector = visit o.left, collector
89
79
  end
90
- collector << ' AS '
91
-
92
- # sometimes these values are already quoted, if they are, don't double quote it
93
- quote = o.right.is_a?(Arel::Nodes::SqlLiteral) && o.right[0] != '"' && o.right[-1] != '"'
94
-
95
- collector << '"' if quote
80
+ collector << " AS \""
96
81
  collector = visit o.right, collector
97
- collector << '"' if quote
98
-
99
- collector
100
- end
101
-
102
- def visit_Aggregate_For_AggregateFunction o, collector
103
- if !o.order.blank? || !o.group.blank?
104
- collector << ' OVER ('
105
- if !o.group.blank?
106
- collector << ' PARTITION BY '
107
- o.group.each_with_index do |group, i|
108
- collector << COMMA if i != 0
109
- visit group, collector
110
- end
111
- end
112
- if !o.order.blank?
113
- collector << ' ORDER BY '
114
- o.order.each_with_index do |order, i|
115
- collector << COMMA if i != 0
116
- visit order, collector
117
- end
118
- end
119
- collector << ')'
120
- end
82
+ collector << "\""
121
83
  collector
122
84
  end
123
85
 
124
86
  def visit_ArelExtensions_Nodes_GroupConcat o, collector
125
- collector << 'array_to_string(array_agg('
87
+ collector << "array_to_string(array_agg("
126
88
  collector = visit o.left, collector
127
- if o.order && !o.order.blank?
128
- collector << ' ORDER BY'
129
- o.order.each_with_index do |order, i|
130
- collector << COMMA if i != 0
131
- collector << ' '
132
- 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
133
94
  end
134
95
  end
135
- collector << ')'
136
- o.order = nil
137
- visit_Aggregate_For_AggregateFunction o, collector
138
- collector << COMMA
139
- sep = o.separator.is_a?(Arel::Nodes::Quoted) ? o.separator.expr : o.separator
140
- collector =
141
- if 'NULL' != sep
142
- visit o.separator, collector
143
- else
144
- visit Arel.quoted(','), collector
145
- end
146
- 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 << ")"
147
104
  collector
148
105
  end
149
106
 
150
107
  def visit_ArelExtensions_Nodes_Trim o, collector
151
- collector << 'TRIM(BOTH '
152
- collector = visit o.right, collector
153
- collector << ' FROM '
154
- collector = visit o.left, collector
155
- collector << ')'
156
- collector
108
+ collector << 'TRIM(BOTH '
109
+ collector = visit o.right, collector
110
+ collector << " FROM "
111
+ collector = visit o.left, collector
112
+ collector << ")"
113
+ collector
157
114
  end
158
115
 
159
116
  def visit_ArelExtensions_Nodes_Ltrim o, collector
160
- collector << 'TRIM(LEADING '
161
- collector = visit o.right, collector
162
- collector << ' FROM '
163
- collector = visit o.left, collector
164
- collector << ')'
165
- collector
117
+ collector << 'TRIM(LEADING '
118
+ collector = visit o.right, collector
119
+ collector << " FROM "
120
+ collector = visit o.left, collector
121
+ collector << ")"
122
+ collector
166
123
  end
167
124
 
168
125
  def visit_ArelExtensions_Nodes_Rtrim o, collector
169
126
  collector << 'TRIM(TRAILING '
170
127
  collector = visit o.right, collector
171
- collector << ' FROM '
128
+ collector << " FROM "
172
129
  collector = visit o.left, collector
173
- collector << ')'
130
+ collector << ")"
174
131
  collector
175
132
  end
176
133
 
177
134
  def visit_ArelExtensions_Nodes_Format o, collector
178
- visit_ArelExtensions_Nodes_FormattedDate o, collector
179
- end
180
-
181
- def visit_ArelExtensions_Nodes_FormattedDate o, collector
182
- fmt = ArelExtensions::Visitors::strftime_to_format(o.iso_format, DATE_FORMAT_DIRECTIVES)
183
- collector << 'TO_CHAR('
184
- collector << '(' if o.time_zone
135
+ collector << "TO_CHAR("
185
136
  collector = visit o.left, collector
186
- case o.time_zone
187
- when Hash
188
- src_tz, dst_tz = o.time_zone.first
189
- collector << ') AT TIME ZONE '
190
- collector = visit Arel.quoted(src_tz), collector
191
- collector << ' AT TIME ZONE '
192
- collector = visit Arel.quoted(dst_tz), collector
193
- when String
194
- collector << ") AT TIME ZONE 'UTC' AT TIME ZONE "
195
- collector = visit Arel.quoted(o.time_zone), collector
196
- end
197
- collector << COMMA
198
- collector = visit Arel.quoted(fmt), collector
199
- 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 << ")"
200
144
  collector
201
145
  end
202
146
 
203
147
  def visit_ArelExtensions_Nodes_Repeat o, collector
204
- collector << 'REPEAT('
148
+ collector << "REPEAT("
205
149
  o.expressions.each_with_index { |arg, i|
206
- collector << Arel::Visitors::ToSql::COMMA if i != 0
150
+ collector << Arel::Visitors::ToSql::COMMA unless i == 0
207
151
  collector = visit arg, collector
208
152
  }
209
- collector << ')'
153
+ collector << ")"
210
154
  collector
211
155
  end
212
156
 
@@ -248,9 +192,9 @@ module ArelExtensions
248
192
 
249
193
  def visit_ArelExtensions_Nodes_Collate o, collector
250
194
  if o.ai
251
- collector << 'unaccent('
195
+ collector << "unaccent("
252
196
  collector = visit o.expressions.first, collector
253
- collector << ')'
197
+ collector << ")"
254
198
  elsif o.ci
255
199
  collector = visit o.expressions.first, collector
256
200
  else
@@ -261,7 +205,7 @@ module ArelExtensions
261
205
 
262
206
  def visit_ArelExtensions_Nodes_DateAdd o, collector
263
207
  collector = visit o.left, collector
264
- collector << ' + ' # (o.right.value >= 0 ? ' + ' : ' - ')
208
+ collector << ' + ' #(o.right.value >= 0 ? ' + ' : ' - ')
265
209
  collector = visit o.postgresql_value(o.right), collector
266
210
  collector
267
211
  end
@@ -269,16 +213,16 @@ module ArelExtensions
269
213
  def visit_ArelExtensions_Nodes_DateDiff o, collector
270
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
271
215
  collector << if o.left_node_type == :ruby_time || o.left_node_type == :datetime || o.left_node_type == :time
272
- "DATEDIFF('second', "
216
+ "DATEDIFF('second', "
273
217
  else
274
- "DATEDIFF('day', "
218
+ "DATEDIFF('day', "
275
219
  end
276
220
  collector = visit o.right, collector
277
221
  collector << (o.right_node_type == :date ? '::date' : '::timestamp')
278
- collector << COMMA
222
+ collector << Arel::Visitors::PostgreSQL::COMMA
279
223
  collector = visit o.left, collector
280
224
  collector << (o.left_node_type == :date ? '::date' : '::timestamp')
281
- collector << ')'
225
+ collector << ")"
282
226
  else
283
227
  collector << '('
284
228
  collector = visit o.left, collector
@@ -295,57 +239,41 @@ module ArelExtensions
295
239
  def visit_ArelExtensions_Nodes_Duration o, collector
296
240
  if o.with_interval
297
241
  interval = case o.left
298
- when 'd', 'm', 'y'
242
+ when 'd','m','y'
299
243
  'DAY'
300
- when 'h', 'mn', 's'
244
+ when 'h','mn','s'
301
245
  'SECOND'
302
246
  when /i\z/
303
- collector << '('
247
+ collector << "("
304
248
  collector = visit o.right, collector
305
- collector << ')'
306
- collector << " * (INTERVAL '1' #{DATE_MAPPING[o.left[0..-2]]})"
249
+ collector << ")"
250
+ collector << " * (INTERVAL '1' #{Arel::Visitors::PostgreSQL::DATE_MAPPING[o.left[0..-2]]})"
307
251
  return collector
308
252
  end
309
253
  end
310
- collector << "EXTRACT(#{DATE_MAPPING[o.left]} FROM CAST("
254
+ collector << "EXTRACT(#{Arel::Visitors::PostgreSQL::DATE_MAPPING[o.left]} FROM "
311
255
  collector = visit o.right, collector
312
- collector << ' AS TIMESTAMP WITH TIME ZONE))'
256
+ collector << ")"
313
257
  collector << " * (INTERVAL '1' #{interval})" if interval && o.with_interval
314
258
  collector
315
259
  end
316
260
 
317
261
  def visit_ArelExtensions_Nodes_Locate o, collector
318
- collector << 'POSITION('
262
+ collector << "POSITION("
319
263
  collector = visit o.right, collector
320
- collector << ' IN '
264
+ collector << " IN "
321
265
  collector = visit o.left, collector
322
- collector << ')'
266
+ collector << ")"
323
267
  collector
324
268
  end
325
269
 
326
270
  def visit_ArelExtensions_Nodes_Substring o, collector
327
- collector << 'SUBSTR('
271
+ collector << "SUBSTR("
328
272
  o.expressions.each_with_index { |arg, i|
329
- collector << COMMA if i != 0
273
+ collector << Arel::Visitors::PostgreSQL::COMMA unless i == 0
330
274
  collector = visit arg, collector
331
275
  }
332
- collector << ')'
333
- collector
334
- end
335
-
336
- def visit_ArelExtensions_Nodes_RegexpReplace o, collector
337
- collector << 'REGEXP_REPLACE('
338
- visit o.left, collector
339
- collector << Arel::Visitors::ToSql::COMMA
340
- tab = o.pattern.inspect + 'g' # Make it always global
341
- pattern = tab.split('/')[1..-2].join('/')
342
- flags = tab.split('/')[-1]
343
- visit Arel.quoted(pattern), collector
344
- collector << Arel::Visitors::ToSql::COMMA
345
- visit o.substitute, collector
346
- collector << Arel::Visitors::ToSql::COMMA
347
- visit Arel.quoted(flags + 'g'), collector
348
- collector << ')'
276
+ collector << ")"
349
277
  collector
350
278
  end
351
279
 
@@ -356,111 +284,98 @@ module ArelExtensions
356
284
  end
357
285
 
358
286
  def visit_ArelExtensions_Nodes_IsNotNull o, collector
359
- collector = visit o.expr, collector
287
+ collector = visit o.expr, collector
360
288
  collector << ' IS NOT NULL'
361
289
  collector
362
290
  end
363
291
 
364
292
  def visit_ArelExtensions_Nodes_Sum o, collector
365
- collector << 'sum('
293
+ collector << "sum("
366
294
  collector = visit o.expr, collector
367
- collector << ')'
368
- visit_Aggregate_For_AggregateFunction o, collector
295
+ collector << ")"
369
296
  collector
370
297
  end
371
298
 
372
299
  def visit_ArelExtensions_Nodes_Wday o, collector
373
- collector << 'EXRTACT(DOW, '
300
+ collector << "EXRTACT(DOW, "
374
301
  collector = visit o.date, collector
375
302
  collector << ')'
376
303
  collector
377
304
  end
378
305
 
379
306
  def visit_ArelExtensions_Nodes_Cast o, collector
380
- as_attr =
381
- case o.as_attr
382
- when :string
383
- 'varchar'
384
- when :text, :ntext
385
- 'text'
386
- when :time
387
- 'time'
388
- when :int
389
- collector << 'CAST(CAST('
390
- collector = visit o.left, collector
391
- collector << ' AS numeric) AS int)'
392
- return collector
393
- when :number, :decimal, :float
394
- 'numeric'
395
- when :datetime
396
- 'timestamp without time zone'
397
- when :date
398
- 'date'
399
- when :binary
400
- 'binary'
401
- when :jsonb
402
- 'jsonb'
403
- else
404
- o.as_attr.to_s
405
- end
406
-
407
- 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("
408
329
  collector = visit o.left, collector
409
- collector << ' AS '
410
- collector = visit Arel::Nodes::SqlLiteral.new(as_attr), collector
411
- collector << ')'
330
+ collector << " AS "
331
+ collector = visit as_attr, collector
332
+ collector << ")"
412
333
  collector
413
334
  end
414
335
 
415
336
  def visit_ArelExtensions_Nodes_FormattedNumber o, collector
416
337
  col = o.left.coalesce(0)
417
- comma = o.precision == 0 ? '' : (NUMBER_COMMA_MAPPING[o.locale][0] || '.')
418
- 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')
419
340
  nines_after = (1..o.precision).map{'9'}.join('')
420
- nines_before = ("999#{thousand_separator}" * 4 + '990')
341
+ nines_before = ("999#{thousand_separator}"*4+"990")
421
342
 
422
- sign = Arel.when(col < 0).
343
+ sign = ArelExtensions::Nodes::Case.new.when(col<0).
423
344
  then('-').
424
345
  else(o.flags.include?('+') ? '+' : (o.flags.include?(' ') ? ' ' : ''))
425
346
  sign_length = ArelExtensions::Nodes::Length.new([sign])
426
347
 
427
- number =
428
- if o.scientific_notation
429
- ArelExtensions::Nodes::Concat.new([
430
- Arel::Nodes::NamedFunction.new('TRIM', [
431
- Arel::Nodes::NamedFunction.new('TO_CHAR', [
432
- Arel.when(col.not_eq 0).then(col.abs / Arel.quoted(10).pow(col.abs.log10.floor)).else(1),
433
- Arel.quoted("FM#{nines_before}\"#{comma}\"V#{nines_after}")
434
- ])]),
435
- o.type,
436
- Arel::Nodes::NamedFunction.new('TRIM', [
437
- Arel::Nodes::NamedFunction.new('TO_CHAR', [
438
- Arel.when(col.not_eq 0).then(col.abs.log10.floor).else(0),
439
- Arel.quoted("FM#{nines_before}")
440
- ])])
441
- ])
442
- else
443
- Arel::Nodes::NamedFunction.new('TRIM', [
444
- Arel::Nodes::NamedFunction.new('TO_CHAR', [
445
- Arel.quoted(col.abs),
446
- Arel.quoted("FM#{nines_before}\"#{comma}\"V#{nines_after}")
447
- ])])
448
- 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
449
369
 
450
- repeated_char =
451
- if o.width == 0
452
- Arel.quoted('')
453
- else
454
- Arel
455
- .when(Arel.quoted(o.width).abs - (number.length + sign_length) > 0)
456
- .then(Arel.quoted(
457
- o.flags.include?('-') ? ' ' : (o.flags.include?('0') ? '0' : ' ')
458
- ).repeat(Arel.quoted(o.width).abs - (number.length + sign_length))
459
- )
460
- .else('')
461
- end
462
- before = !o.flags.include?('0') && !o.flags.include?('-') ? repeated_char : ''
463
- 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 : ''
464
379
  after = o.flags.include?('-') ? repeated_char : ''
465
380
  full_number = ArelExtensions::Nodes::Concat.new([
466
381
  before,
@@ -469,30 +384,30 @@ module ArelExtensions
469
384
  number,
470
385
  after
471
386
  ])
472
- 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
473
388
  collector
474
389
  end
475
390
 
476
391
 
477
- 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
478
393
  def visit_Arel_Nodes_SelectStatement o, collector
479
394
 
480
395
  if !(collector.value.blank? || (collector.value.is_a?(Array) && collector.value[0].blank?)) && o.limit.blank? && o.offset.blank?
481
396
  o = o.dup
482
397
  o.orders = []
483
398
  end
484
- old_visit_Arel_Nodes_SelectStatement(o, collector)
399
+ old_visit_Arel_Nodes_SelectStatement(o,collector)
485
400
  end
486
401
 
487
- 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
488
403
  def visit_Arel_Nodes_TableAlias o, collector
489
404
  if o.name.length > 63
490
405
  o = Arel::Table.new(o.table_name).alias(Arel.shorten(o.name))
491
406
  end
492
- old_visit_Arel_Nodes_TableAlias(o, collector)
407
+ old_visit_Arel_Nodes_TableAlias(o,collector)
493
408
  end
494
409
 
495
- 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
496
411
  def visit_Arel_Attributes_Attribute o, collector
497
412
  join_name = o.relation.table_alias || o.relation.name
498
413
  if join_name.length > 63
@@ -502,35 +417,33 @@ module ArelExtensions
502
417
  end
503
418
 
504
419
  def visit_ArelExtensions_Nodes_Std o, collector
505
- collector << (o.unbiased_estimator ? 'STDDEV_SAMP(' : 'STDDEV_POP(')
420
+ collector << (o.unbiased_estimator ? "STDDEV_SAMP(" : "STDDEV_POP(")
506
421
  visit o.left, collector
507
- collector << ')'
508
- visit_Aggregate_For_AggregateFunction o, collector
422
+ collector << ")"
509
423
  collector
510
424
  end
511
425
 
512
426
  def visit_ArelExtensions_Nodes_Variance o, collector
513
- collector << (o.unbiased_estimator ? 'VAR_SAMP(' : 'VAR_POP(')
427
+ collector << (o.unbiased_estimator ? "VAR_SAMP(" : "VAR_POP(")
514
428
  visit o.left, collector
515
- collector << ')'
516
- visit_Aggregate_For_AggregateFunction o, collector
429
+ collector << ")"
517
430
  collector
518
431
  end
519
432
 
520
- def visit_ArelExtensions_Nodes_Json o, collector
433
+ def visit_ArelExtensions_Nodes_Json o,collector
521
434
  case o.dict
522
435
  when Array
523
436
  collector << 'to_jsonb(array['
524
- o.dict.each.with_index do |v, i|
437
+ o.dict.each.with_index do |v,i|
525
438
  if i != 0
526
439
  collector << Arel::Visitors::MySQL::COMMA
527
440
  end
528
- collector = visit v, collector
441
+ collector = visit v, collector
529
442
  end
530
443
  collector << '])'
531
444
  when Hash
532
445
  collector << 'jsonb_build_object('
533
- o.dict.each.with_index do |(k, v), i|
446
+ o.dict.each.with_index do |(k,v),i|
534
447
  if i != 0
535
448
  collector << Arel::Visitors::MySQL::COMMA
536
449
  end
@@ -539,11 +452,13 @@ module ArelExtensions
539
452
  collector = visit v, collector
540
453
  end
541
454
  collector << ')'
542
- when String, Numeric, TrueClass, FalseClass
543
- collector = visit Arel.quoted("#{o.dict}"), collector
455
+ when String,Numeric,TrueClass,FalseClass
456
+ collector = visit Arel::Nodes.build_quoted("#{o.dict}"), collector
544
457
  collector << '::jsonb'
545
458
  when NilClass
546
- collector << %Q['null'::jsonb]
459
+ collector << %Q['null'::jsonb]
460
+ when Arel::Attributes::Attribute
461
+ collector = visit o.dict.cast(:jsonb), collector
547
462
  else
548
463
  collector = visit o.dict, collector
549
464
  collector << '::jsonb'
@@ -551,8 +466,8 @@ module ArelExtensions
551
466
  collector
552
467
  end
553
468
 
554
- def visit_ArelExtensions_Nodes_JsonMerge o, collector
555
- 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|
556
471
  if i != 0
557
472
  collector << ' || '
558
473
  end
@@ -561,14 +476,14 @@ module ArelExtensions
561
476
  collector
562
477
  end
563
478
 
564
- def visit_ArelExtensions_Nodes_JsonGet o, collector
479
+ def visit_ArelExtensions_Nodes_JsonGet o,collector
565
480
  collector = visit o.dict, collector
566
- collector << ' ->> '
481
+ collector << ' -> '
567
482
  collector = visit o.key, collector
568
483
  collector
569
484
  end
570
485
 
571
- def visit_ArelExtensions_Nodes_JsonSet o, collector
486
+ def visit_ArelExtensions_Nodes_JsonSet o,collector
572
487
  collector << 'jsonb_set('
573
488
  collector = visit o.dict, collector
574
489
  collector << Arel::Visitors::MySQL::COMMA
@@ -590,7 +505,7 @@ module ArelExtensions
590
505
  else
591
506
  case o.dict
592
507
  when Hash
593
- o.dict.each.with_index do |(k, v), i|
508
+ o.dict.each.with_index do |(k,v),i|
594
509
  if i != 0
595
510
  collector << ' || '
596
511
  end
@@ -608,6 +523,7 @@ module ArelExtensions
608
523
  end
609
524
  collector
610
525
  end
526
+
611
527
  end
612
528
  end
613
529
  end