arel_extensions 1.3.4 → 2.0.0.rc3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +2 -1
  3. data/.rubocop.yml +4 -31
  4. data/.travis/oracle/download.js +152 -0
  5. data/.travis/oracle/download.sh +30 -0
  6. data/.travis/oracle/download_ojdbc.js +116 -0
  7. data/.travis/oracle/install.sh +34 -0
  8. data/.travis/setup_accounts.sh +9 -0
  9. data/.travis/sqlite3/extension-functions.sh +6 -0
  10. data/.travis.yml +223 -0
  11. data/Gemfile +21 -16
  12. data/README.md +14 -125
  13. data/Rakefile +30 -41
  14. data/TODO +1 -0
  15. data/appveyor.yml +44 -0
  16. data/arel_extensions.gemspec +14 -14
  17. data/functions.html +3 -3
  18. data/gemfiles/rails3.gemfile +10 -10
  19. data/gemfiles/rails4.gemfile +14 -14
  20. data/gemfiles/rails5_0.gemfile +14 -14
  21. data/gemfiles/rails5_1_4.gemfile +14 -14
  22. data/gemfiles/rails5_2.gemfile +14 -15
  23. data/init/mssql.sql +4 -4
  24. data/init/mysql.sql +38 -38
  25. data/init/oracle.sql +0 -0
  26. data/init/postgresql.sql +21 -21
  27. data/init/sqlite.sql +0 -0
  28. data/lib/arel_extensions/attributes.rb +3 -4
  29. data/lib/arel_extensions/boolean_functions.rb +14 -53
  30. data/lib/arel_extensions/common_sql_functions.rb +16 -15
  31. data/lib/arel_extensions/comparators.rb +28 -27
  32. data/lib/arel_extensions/date_duration.rb +14 -13
  33. data/lib/arel_extensions/insert_manager.rb +15 -18
  34. data/lib/arel_extensions/math.rb +44 -31
  35. data/lib/arel_extensions/math_functions.rb +39 -46
  36. data/lib/arel_extensions/nodes/abs.rb +1 -0
  37. data/lib/arel_extensions/nodes/blank.rb +2 -1
  38. data/lib/arel_extensions/nodes/case.rb +16 -16
  39. data/lib/arel_extensions/nodes/cast.rb +6 -8
  40. data/lib/arel_extensions/nodes/ceil.rb +1 -1
  41. data/lib/arel_extensions/nodes/coalesce.rb +3 -2
  42. data/lib/arel_extensions/nodes/collate.rb +10 -9
  43. data/lib/arel_extensions/nodes/concat.rb +18 -9
  44. data/lib/arel_extensions/nodes/date_diff.rb +22 -38
  45. data/lib/arel_extensions/nodes/duration.rb +3 -0
  46. data/lib/arel_extensions/nodes/find_in_set.rb +1 -0
  47. data/lib/arel_extensions/nodes/floor.rb +1 -1
  48. data/lib/arel_extensions/nodes/format.rb +8 -35
  49. data/lib/arel_extensions/nodes/formatted_number.rb +23 -22
  50. data/lib/arel_extensions/nodes/function.rb +37 -42
  51. data/lib/arel_extensions/nodes/is_null.rb +0 -0
  52. data/lib/arel_extensions/nodes/json.rb +39 -48
  53. data/lib/arel_extensions/nodes/length.rb +0 -5
  54. data/lib/arel_extensions/nodes/levenshtein_distance.rb +1 -1
  55. data/lib/arel_extensions/nodes/locate.rb +1 -0
  56. data/lib/arel_extensions/nodes/log10.rb +2 -1
  57. data/lib/arel_extensions/nodes/matches.rb +7 -5
  58. data/lib/arel_extensions/nodes/md5.rb +1 -0
  59. data/lib/arel_extensions/nodes/power.rb +5 -5
  60. data/lib/arel_extensions/nodes/rand.rb +1 -0
  61. data/lib/arel_extensions/nodes/repeat.rb +4 -2
  62. data/lib/arel_extensions/nodes/replace.rb +8 -16
  63. data/lib/arel_extensions/nodes/round.rb +6 -5
  64. data/lib/arel_extensions/nodes/soundex.rb +15 -15
  65. data/lib/arel_extensions/nodes/std.rb +21 -18
  66. data/lib/arel_extensions/nodes/substring.rb +16 -8
  67. data/lib/arel_extensions/nodes/trim.rb +5 -3
  68. data/lib/arel_extensions/nodes/union.rb +8 -5
  69. data/lib/arel_extensions/nodes/union_all.rb +7 -4
  70. data/lib/arel_extensions/nodes/wday.rb +4 -0
  71. data/lib/arel_extensions/nodes.rb +1 -1
  72. data/lib/arel_extensions/null_functions.rb +7 -5
  73. data/lib/arel_extensions/predications.rb +43 -44
  74. data/lib/arel_extensions/railtie.rb +5 -5
  75. data/lib/arel_extensions/set_functions.rb +7 -5
  76. data/lib/arel_extensions/string_functions.rb +29 -58
  77. data/lib/arel_extensions/tasks.rb +6 -6
  78. data/lib/arel_extensions/version.rb +1 -1
  79. data/lib/arel_extensions/visitors/ibm_db.rb +31 -24
  80. data/lib/arel_extensions/visitors/mssql.rb +184 -269
  81. data/lib/arel_extensions/visitors/mysql.rb +206 -271
  82. data/lib/arel_extensions/visitors/oracle.rb +175 -191
  83. data/lib/arel_extensions/visitors/oracle12.rb +31 -18
  84. data/lib/arel_extensions/visitors/postgresql.rb +170 -244
  85. data/lib/arel_extensions/visitors/sqlite.rb +124 -138
  86. data/lib/arel_extensions/visitors/to_sql.rb +237 -269
  87. data/lib/arel_extensions/visitors.rb +59 -75
  88. data/lib/arel_extensions.rb +31 -149
  89. data/test/database.yml +7 -15
  90. data/test/helper.rb +18 -0
  91. data/test/real_db_test.rb +113 -102
  92. data/test/support/fake_record.rb +3 -3
  93. data/test/test_comparators.rb +17 -14
  94. data/test/visitors/test_bulk_insert_oracle.rb +10 -10
  95. data/test/visitors/test_bulk_insert_sqlite.rb +12 -11
  96. data/test/visitors/test_bulk_insert_to_sql.rb +12 -10
  97. data/test/visitors/test_oracle.rb +55 -55
  98. data/test/visitors/test_to_sql.rb +226 -419
  99. data/test/with_ar/all_agnostic_test.rb +357 -567
  100. data/test/with_ar/insert_agnostic_test.rb +19 -25
  101. data/test/with_ar/test_bulk_sqlite.rb +15 -16
  102. data/test/with_ar/test_math_sqlite.rb +26 -26
  103. data/test/with_ar/test_string_mysql.rb +33 -31
  104. data/test/with_ar/test_string_sqlite.rb +34 -30
  105. metadata +23 -29
  106. data/.github/workflows/ruby.yml +0 -389
  107. data/gemfiles/rails6.gemfile +0 -29
  108. data/gemfiles/rails6_1.gemfile +0 -29
  109. data/gemfiles/rails7.gemfile +0 -22
  110. data/gemspecs/arel_extensions-v1.gemspec +0 -28
  111. data/gemspecs/arel_extensions-v2.gemspec +0 -28
  112. data/generate_gems.sh +0 -15
  113. data/lib/arel_extensions/aliases.rb +0 -14
  114. data/lib/arel_extensions/helpers.rb +0 -51
  115. data/lib/arel_extensions/nodes/aggregate_function.rb +0 -13
  116. data/lib/arel_extensions/nodes/sum.rb +0 -7
  117. data/lib/arel_extensions/visitors/convert_format.rb +0 -37
  118. data/test/arelx_test_helper.rb +0 -71
  119. data/version_v1.rb +0 -3
  120. data/version_v2.rb +0 -3
@@ -1,45 +1,17 @@
1
1
  module ArelExtensions
2
2
  module Visitors
3
3
  module MSSQL
4
-
5
- mssql_class = Arel::Visitors.constants.select { |c|
6
- Arel::Visitors.const_get(c).is_a?(Class) && %i[MSSQL SQLServer].include?(c)
7
- }.first
8
-
9
- LOADED_VISITOR = Arel::Visitors.const_get(mssql_class) || Arel::Visitors.const_get('MSSQL')
10
-
11
- LOADED_VISITOR::DATE_MAPPING = {
12
- 'd' => 'day', 'm' => 'month', 'y' => 'year', 'wd' => 'weekday', 'w' => 'week', 'h' => 'hour', 'mn' => 'minute', 's' => 'second'
13
- }.freeze
14
-
15
- LOADED_VISITOR::DATE_FORMAT_DIRECTIVES = {
16
- '%Y' => 'YYYY', '%C' => '', '%y' => 'YY', '%m' => 'MM', '%B' => 'month', '%^B' => '', '%b' => '', '%^b' => '', # year, month
17
- '%V' => 'iso_week', '%G' => '', # ISO week number and year of week
18
- '%d' => 'DD', '%e' => '' , '%j' => '' , '%w' => 'dw', %'a' => '', '%A' => 'weekday', # day, weekday
19
- '%H' => 'hh', '%k' => '' , '%I' => '' , '%l' => '' , '%P' => '', '%p' => '', # hours
4
+ Arel::Visitors::MSSQL::DATE_MAPPING = {'d' => 'day', 'm' => 'month', 'y' => 'year', 'wd' => 'weekday', 'w' => 'week', 'h' => 'hour', 'mn' => 'minute', 's' => 'second'}
5
+ Arel::Visitors::MSSQL::DATE_FORMAT_DIRECTIVES = {
6
+ '%Y' => 'YYYY', '%C' => '', '%y' => 'YY', '%m' => 'MM', '%B' => '', '%b' => '', '%^b' => '', # year, month
7
+ '%d' => 'DD', '%e' => '', '%j' => '', '%w' => 'dw', '%A' => '', # day, weekday
8
+ '%H' => 'hh', '%k' => '', '%I' => '', '%l' => '', '%P' => '', '%p' => '', # hours
20
9
  '%M' => 'mi', '%S' => 'ss', '%L' => 'ms', '%N' => 'ns', '%z' => 'tz'
21
- }.freeze
22
-
23
- LOADED_VISITOR::DATE_FORMAT_FORMAT = {
24
- 'YY' => '0#', 'MM' => '0#', 'DD' => '0#', 'hh' => '0#', 'mi' => '0#', 'ss' => '0#', 'iso_week' => '0#'
25
10
  }
26
-
27
- LOADED_VISITOR::DATE_NAME = [
28
- '%B', '%A'
29
- ]
30
-
31
- LOADED_VISITOR::DATE_FORMAT_REGEX =
32
- Regexp.new(
33
- LOADED_VISITOR::DATE_FORMAT_DIRECTIVES
34
- .keys
35
- .map{|k| Regexp.escape(k)}
36
- .join('|')
37
- ).freeze
38
-
39
11
  # TODO; all others... http://www.sql-server-helper.com/tips/date-formats.aspx
40
- LOADED_VISITOR::DATE_CONVERT_FORMATS = {
12
+ Arel::Visitors::MSSQL::DATE_CONVERT_FORMATS = {
41
13
  'YYYY-MM-DD' => 120,
42
- 'YY-MM-DD' => 120,
14
+ 'YY-MM-DD' => 120,
43
15
  'MM/DD/YYYY' => 101,
44
16
  'MM-DD-YYYY' => 110,
45
17
  'YYYY/MM/DD' => 111,
@@ -47,108 +19,108 @@ module ArelExtensions
47
19
  'DD-MM-YY' => 5,
48
20
  'DD.MM.YYYY' => 104,
49
21
  'YYYY-MM-DDTHH:MM:SS:MMM' => 126
50
- }.freeze
22
+ }
51
23
 
52
24
  # Math Functions
53
25
  def visit_ArelExtensions_Nodes_Ceil o, collector
54
- collector << 'CEILING('
26
+ collector << "CEILING("
55
27
  collector = visit o.expr, collector
56
- collector << ')'
28
+ collector << ")"
57
29
  collector
58
30
  end
59
31
 
60
32
  def visit_ArelExtensions_Nodes_Log10 o, collector
61
- collector << 'LOG10('
33
+ collector << "LOG10("
62
34
  o.expressions.each_with_index { |arg, i|
63
- collector << Arel::Visitors::ToSql::COMMA if i != 0
35
+ collector << Arel::Visitors::ToSql::COMMA unless i == 0
64
36
  collector = visit arg, collector
65
37
  }
66
- collector << ')'
38
+ collector << ")"
67
39
  collector
68
40
  end
69
41
 
70
42
  def visit_ArelExtensions_Nodes_Power o, collector
71
- collector << 'POWER('
43
+ collector << "POWER("
72
44
  o.expressions.each_with_index { |arg, i|
73
- collector << Arel::Visitors::ToSql::COMMA if i != 0
45
+ collector << Arel::Visitors::ToSql::COMMA unless i == 0
74
46
  collector = visit arg, collector
75
47
  }
76
- collector << ')'
48
+ collector << ")"
77
49
  collector
78
50
  end
79
51
 
80
52
  def visit_ArelExtensions_Nodes_IsNull o, collector
81
- collector << '('
53
+ collector << "("
82
54
  collector = visit o.expr, collector
83
- collector << ' IS NULL)'
55
+ collector << " IS NULL)"
84
56
  collector
85
57
  end
86
58
 
87
59
  def visit_ArelExtensions_Nodes_IsNotNull o, collector
88
- collector << '('
60
+ collector << "("
89
61
  collector = visit o.expr, collector
90
- collector << ' IS NOT NULL)'
62
+ collector << " IS NOT NULL)"
91
63
  collector
92
64
  end
93
65
 
94
66
  def visit_ArelExtensions_Nodes_Concat o, collector
95
- collector << 'CONCAT('
67
+ collector << "CONCAT("
96
68
  o.expressions.each_with_index { |arg, i|
97
- collector << LOADED_VISITOR::COMMA if i != 0
69
+ collector << Arel::Visitors::MSSQL::COMMA unless i == 0
98
70
  collector = visit arg, collector
99
71
  }
100
- collector << ')'
72
+ collector << ")"
101
73
  collector
102
74
  end
103
75
 
104
76
  def visit_ArelExtensions_Nodes_Repeat o, collector
105
- collector << 'REPLICATE('
77
+ collector << "REPLICATE("
106
78
  o.expressions.each_with_index { |arg, i|
107
- collector << Arel::Visitors::ToSql::COMMA if i != 0
79
+ collector << Arel::Visitors::ToSql::COMMA unless i == 0
108
80
  collector = visit arg, collector
109
81
  }
110
- collector << ')'
82
+ collector << ")"
111
83
  collector
112
84
  end
113
85
 
114
86
 
115
87
 
116
88
  def visit_ArelExtensions_Nodes_DateDiff o, collector
117
- case o.right_node_type
118
- when :ruby_date, :ruby_time, :date, :datetime, :time
119
- collector << case o.left_node_type
120
- when :ruby_time, :datetime, :time then 'DATEDIFF(second'
121
- else 'DATEDIFF(day'
89
+ 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
90
+ collector << if o.left_node_type == :ruby_time || o.left_node_type == :datetime || o.left_node_type == :time
91
+ 'DATEDIFF(second'
92
+ else
93
+ 'DATEDIFF(day'
122
94
  end
123
- collector << LOADED_VISITOR::COMMA
95
+ collector << Arel::Visitors::MSSQL::COMMA
124
96
  collector = visit o.right, collector
125
- collector << LOADED_VISITOR::COMMA
97
+ collector << Arel::Visitors::MSSQL::COMMA
126
98
  collector = visit o.left, collector
127
99
  collector << ')'
128
100
  else
129
101
  da = ArelExtensions::Nodes::DateAdd.new([])
130
- collector << 'DATEADD('
102
+ collector << "DATEADD("
131
103
  collector = visit da.mssql_datepart(o.right), collector
132
- collector << LOADED_VISITOR::COMMA
133
- collector << '-('
104
+ collector << Arel::Visitors::MSSQL::COMMA
105
+ collector << "-("
134
106
  collector = visit da.mssql_value(o.right), collector
135
- collector << ')'
136
- collector << LOADED_VISITOR::COMMA
107
+ collector << ")"
108
+ collector << Arel::Visitors::MSSQL::COMMA
137
109
  collector = visit o.left, collector
138
- collector << ')'
110
+ collector << ")"
139
111
  collector
140
112
  end
141
113
  collector
142
114
  end
143
115
 
144
116
  def visit_ArelExtensions_Nodes_DateAdd o, collector
145
- collector << 'DATEADD('
117
+ collector << "DATEADD("
146
118
  collector = visit o.mssql_datepart(o.right), collector
147
- collector << LOADED_VISITOR::COMMA
119
+ collector << Arel::Visitors::MSSQL::COMMA
148
120
  collector = visit o.mssql_value(o.right), collector
149
- collector << LOADED_VISITOR::COMMA
121
+ collector << Arel::Visitors::MSSQL::COMMA
150
122
  collector = visit o.left, collector
151
- collector << ')'
123
+ collector << ")"
152
124
  collector
153
125
  end
154
126
 
@@ -159,78 +131,77 @@ module ArelExtensions
159
131
  left = o.left.end_with?('i') ? o.left[0..-2] : o.left
160
132
  conv = ['h', 'mn', 's'].include?(o.left)
161
133
  collector << 'DATEPART('
162
- collector << LOADED_VISITOR::DATE_MAPPING[left]
163
- collector << LOADED_VISITOR::COMMA
134
+ collector << Arel::Visitors::MSSQL::DATE_MAPPING[left]
135
+ collector << Arel::Visitors::MSSQL::COMMA
164
136
  collector << 'CONVERT(datetime,' if conv
165
137
  collector = visit o.right, collector
166
138
  collector << ')' if conv
167
- collector << ')'
139
+ collector << ")"
168
140
  end
169
141
  collector
170
142
  end
171
143
 
172
144
  def visit_ArelExtensions_Nodes_Length o, collector
173
- if o.bytewise
174
- collector << '(DATALENGTH('
175
- collector = visit o.expr, collector
176
- collector << ') / ISNULL(NULLIF(DATALENGTH(LEFT(COALESCE('
177
- collector = visit o.expr, collector
178
- collector << ", '#' ), 1 )), 0), 1))"
179
- collector
180
- else
181
- collector << 'LEN('
182
- collector = visit o.expr, collector
183
- collector << ')'
184
- collector
185
- end
145
+ collector << "LEN("
146
+ collector = visit o.expr, collector
147
+ collector << ")"
148
+ collector
186
149
  end
187
150
 
188
151
  def visit_ArelExtensions_Nodes_Round o, collector
189
- collector << 'ROUND('
152
+ collector << "ROUND("
190
153
  o.expressions.each_with_index { |arg, i|
191
- collector << LOADED_VISITOR::COMMA if i != 0
154
+ collector << Arel::Visitors::MSSQL::COMMA unless i == 0
192
155
  collector = visit arg, collector
193
156
  }
194
157
  if o.expressions.length == 1
195
- collector << LOADED_VISITOR::COMMA
196
- collector << '0'
158
+ collector << Arel::Visitors::MSSQL::COMMA
159
+ collector << "0"
197
160
  end
198
- collector << ')'
161
+ collector << ")"
199
162
  collector
200
163
  end
201
164
 
202
165
  def visit_ArelExtensions_Nodes_Locate o, collector
203
- collector << 'CHARINDEX('
166
+ collector << "CHARINDEX("
204
167
  collector = visit o.right, collector
205
- collector << LOADED_VISITOR::COMMA
168
+ collector << Arel::Visitors::MSSQL::COMMA
206
169
  collector = visit o.left, collector
207
- collector << ')'
170
+ collector << ")"
208
171
  collector
209
172
  end
210
173
 
211
174
  def visit_ArelExtensions_Nodes_Substring o, collector
212
175
  collector << 'SUBSTRING('
213
176
  collector = visit o.expressions[0], collector
214
- collector << LOADED_VISITOR::COMMA
177
+ collector << Arel::Visitors::MSSQL::COMMA
215
178
  collector = visit o.expressions[1], collector
216
- collector << LOADED_VISITOR::COMMA
179
+ collector << Arel::Visitors::MSSQL::COMMA
217
180
  collector = o.expressions[2] ? visit(o.expressions[2], collector) : visit(o.expressions[0].length, collector)
218
181
  collector << ')'
219
182
  collector
220
183
  end
221
184
 
222
185
  def visit_ArelExtensions_Nodes_Trim o, collector
223
- collector << 'TRIM( '
224
- collector = visit o.right, collector
225
- collector << ' FROM '
226
- collector = visit o.left, collector
227
- collector << ')'
186
+ if o.right
187
+ collector << "REPLACE(REPLACE(LTRIM(RTRIM(REPLACE(REPLACE("
188
+ collector = visit o.left, collector
189
+ collector << ", ' ', '~'), "
190
+ collector = visit o.right, collector
191
+ collector << ", ' '))), ' ', "
192
+ collector = visit o.right, collector
193
+ collector << "), '~', ' ')"
194
+ else
195
+ collector << "LTRIM(RTRIM("
196
+ collector = visit o.left, collector
197
+ collector << "))"
198
+ end
228
199
  collector
229
200
  end
230
201
 
231
202
  def visit_ArelExtensions_Nodes_Ltrim o, collector
232
203
  if o.right
233
- collector << 'REPLACE(REPLACE(LTRIM(REPLACE(REPLACE('
204
+ collector << "REPLACE(REPLACE(LTRIM(REPLACE(REPLACE("
234
205
  collector = visit o.left, collector
235
206
  collector << ", ' ', '~'), "
236
207
  collector = visit o.right, collector
@@ -238,16 +209,16 @@ module ArelExtensions
238
209
  collector = visit o.right, collector
239
210
  collector << "), '~', ' ')"
240
211
  else
241
- collector << 'LTRIM('
212
+ collector << "LTRIM("
242
213
  collector = visit o.left, collector
243
- collector << ')'
214
+ collector << ")"
244
215
  end
245
216
  collector
246
217
  end
247
218
 
248
219
  def visit_ArelExtensions_Nodes_Rtrim o, collector
249
220
  if o.right
250
- collector << 'REPLACE(REPLACE(RTRIM(REPLACE(REPLACE('
221
+ collector << "REPLACE(REPLACE(RTRIM(REPLACE(REPLACE("
251
222
  collector = visit o.left, collector
252
223
  collector << ", ' ', '~'), "
253
224
  collector = visit o.right, collector
@@ -255,9 +226,9 @@ module ArelExtensions
255
226
  collector = visit o.right, collector
256
227
  collector << "), '~', ' ')"
257
228
  else
258
- collector << 'RTRIM('
229
+ collector << "RTRIM("
259
230
  collector = visit o.left, collector
260
- collector << ')'
231
+ collector << ")"
261
232
  end
262
233
  collector
263
234
  end
@@ -271,98 +242,64 @@ module ArelExtensions
271
242
  end
272
243
 
273
244
  def visit_ArelExtensions_Nodes_Format o, collector
274
- f = ArelExtensions::Visitors::strftime_to_format(o.iso_format, LOADED_VISITOR::DATE_FORMAT_DIRECTIVES)
275
- if fmt = LOADED_VISITOR::DATE_CONVERT_FORMATS[f]
245
+ f = o.iso_format.dup
246
+ Arel::Visitors::MSSQL::DATE_FORMAT_DIRECTIVES.each { |d, r| f.gsub!(d, r) }
247
+ if Arel::Visitors::MSSQL::DATE_CONVERT_FORMATS[f]
276
248
  collector << "CONVERT(VARCHAR(#{f.length})"
277
- collector << LOADED_VISITOR::COMMA
278
- if o.time_zone
279
- collector << 'CONVERT(datetime'
280
- collector << LOADED_VISITOR::COMMA
281
- collector << ' '
282
- end
249
+ collector << Arel::Visitors::MSSQL::COMMA
283
250
  collector = visit o.left, collector
284
- case o.time_zone
285
- when Hash
286
- src_tz, dst_tz = o.time_zone.first
287
- collector << ') AT TIME ZONE '
288
- collector = visit Arel.quoted(src_tz), collector
289
- collector << ' AT TIME ZONE '
290
- collector = visit Arel.quoted(dst_tz), collector
291
- when String
292
- collector << ') AT TIME ZONE '
293
- collector = visit Arel.quoted(o.time_zone), collector
294
- end
295
- collector << LOADED_VISITOR::COMMA
296
- collector << fmt.to_s
251
+ collector << Arel::Visitors::MSSQL::COMMA
252
+ collector << Arel::Visitors::MSSQL::DATE_CONVERT_FORMATS[f].to_s
297
253
  collector << ')'
298
254
  collector
299
255
  else
300
- s = StringScanner.new o.iso_format
301
- collector << '('
302
- sep = ''
303
- while !s.eos?
304
- collector << sep
305
- sep = ' + '
306
- case
307
- when s.scan(LOADED_VISITOR::DATE_FORMAT_REGEX)
308
- dir = LOADED_VISITOR::DATE_FORMAT_DIRECTIVES[s.matched]
309
- fmt = LOADED_VISITOR::DATE_FORMAT_FORMAT[dir]
310
- date_name = LOADED_VISITOR::DATE_NAME.include?(s.matched)
311
- collector << 'TRIM('
312
- collector << 'FORMAT(' if fmt
313
- collector << 'STR(' if !fmt && !date_name
314
- collector << (date_name ? 'DATENAME(' : 'DATEPART(')
315
- collector << dir
316
- collector << LOADED_VISITOR::COMMA
317
- if o.time_zone
318
- collector << 'CONVERT(datetime'
319
- collector << LOADED_VISITOR::COMMA
320
- collector << ' '
256
+ collector << "("
257
+ t = o.iso_format.split('%')
258
+ t.each_with_index {|str, i|
259
+ if i == 0 && t[0] != '%'
260
+ collector = visit Arel::Nodes.build_quoted(str), collector
261
+ if str.length > 1
262
+ collector << Arel::Visitors::MSSQL::COMMA
263
+ collector = visit Arel::Nodes.build_quoted(str.sub(/\A./, '')), collector
321
264
  end
322
- collector = visit o.left, collector
323
- case o.time_zone
324
- when Hash
325
- src_tz, dst_tz = o.time_zone.first.first, o.time_zone.first.second
326
- collector << ') AT TIME ZONE '
327
- collector = visit Arel.quoted(src_tz), collector
328
- collector << ' AT TIME ZONE '
329
- collector = visit Arel.quoted(dst_tz), collector
330
- when String
331
- collector << ') AT TIME ZONE '
332
- collector = visit Arel.quoted(o.time_zone), collector
265
+ elsif str.length > 0
266
+ if !Arel::Visitors::MSSQL::DATE_FORMAT_DIRECTIVES['%' + str[0]].blank?
267
+ collector << 'LTRIM(STR(DATEPART('
268
+ collector << Arel::Visitors::MSSQL::DATE_FORMAT_DIRECTIVES['%' + str[0]]
269
+ collector << Arel::Visitors::MSSQL::COMMA
270
+ collector = visit o.left, collector
271
+ collector << ')))'
272
+ if str.length > 1
273
+ collector << ' + '
274
+ collector = visit Arel::Nodes.build_quoted(str.sub(/\A./, '')), collector
275
+ end
333
276
  end
334
- collector << ')'
335
- collector << ')' if !fmt && !date_name
336
- collector << LOADED_VISITOR::COMMA << "'#{fmt}')" if fmt
337
- collector << ')'
338
- when s.scan(/^%%/)
339
- collector = visit Arel.quoted('%'), collector
340
- when s.scan(/[^%]+|./)
341
- collector = visit Arel.quoted(s.matched), collector
342
277
  end
343
- end
278
+ collector << ' + ' if t[i + 1]
279
+ }
280
+
344
281
  collector << ')'
345
282
  collector
346
283
  end
347
284
  end
348
285
 
349
286
  def visit_ArelExtensions_Nodes_Replace o, collector
350
- collector << 'REPLACE('
287
+ collector << "REPLACE("
351
288
  o.expressions.each_with_index { |arg, i|
352
- collector << LOADED_VISITOR::COMMA if i != 0
289
+ collector << Arel::Visitors::MSSQL::COMMA unless i == 0
353
290
  collector = visit arg, collector
354
291
  }
355
- collector << ')'
292
+ collector << ")"
356
293
  collector
357
294
  end
358
295
 
359
296
  def visit_ArelExtensions_Nodes_FindInSet o, collector
360
- collector << 'dbo.FIND_IN_SET('
297
+ collector << "dbo.FIND_IN_SET("
361
298
  o.expressions.each_with_index { |arg, i|
362
- collector << LOADED_VISITOR::COMMA if i != 0
299
+ collector << Arel::Visitors::MSSQL::COMMA unless i == 0
363
300
  collector = visit arg, collector
364
301
  }
365
- collector << ')'
302
+ collector << ")"
366
303
  collector
367
304
  end
368
305
 
@@ -405,9 +342,9 @@ module ArelExtensions
405
342
  end
406
343
 
407
344
  def visit_ArelExtensions_Nodes_AiIMatches o, collector
408
- collector = visit o.left.collate(true, true), collector
345
+ collector = visit o.left.collate(true,true), collector
409
346
  collector << ' LIKE '
410
- collector = visit o.right.collate(true, true), collector
347
+ collector = visit o.right.collate(true,true), collector
411
348
  if o.escape
412
349
  collector << ' ESCAPE '
413
350
  visit o.escape, collector
@@ -445,27 +382,6 @@ module ArelExtensions
445
382
  collector
446
383
  end
447
384
 
448
- alias_method(:old_visit_Arel_Nodes_As, :visit_Arel_Nodes_As) rescue nil
449
- def visit_Arel_Nodes_As o, collector
450
- if o.left.is_a?(Arel::Nodes::Binary)
451
- collector << '('
452
- collector = visit o.left, collector
453
- collector << ')'
454
- else
455
- collector = visit o.left, collector
456
- end
457
- collector << ' AS '
458
-
459
- # sometimes these values are already quoted, if they are, don't double quote it
460
- quote = o.right.is_a?(Arel::Nodes::SqlLiteral) && o.right[0] != '"' && o.right[-1] != '"'
461
-
462
- collector << '"' if quote
463
- collector = visit o.right, collector
464
- collector << '"' if quote
465
-
466
- collector
467
- end
468
-
469
385
  # SQL Server does not know about REGEXP
470
386
  def visit_Arel_Nodes_Regexp o, collector
471
387
  collector = visit o.left, collector
@@ -481,109 +397,106 @@ module ArelExtensions
481
397
 
482
398
  # TODO;
483
399
  def visit_ArelExtensions_Nodes_GroupConcat o, collector
484
- collector << '(STRING_AGG('
400
+ collector << "(STRING_AGG("
485
401
  collector = visit o.left, collector
486
402
  collector << Arel::Visitors::Oracle::COMMA
487
- collector =
488
- if o.separator && o.separator != 'NULL'
489
- visit o.separator, collector
490
- else
491
- visit Arel.quoted(','), collector
492
- end
493
- collector << ') WITHIN GROUP (ORDER BY '
494
- if o.order.present?
495
- o.order.each_with_index do |order, i|
496
- collector << Arel::Visitors::Oracle::COMMA if i != 0
403
+ if o.right && o.right != 'NULL'
404
+ collector = visit o.right, collector
405
+ else
406
+ collector = visit Arel::Nodes.build_quoted(','), collector
407
+ end
408
+ collector << ") WITHIN GROUP (ORDER BY "
409
+ if !o.orders.blank?
410
+ o.orders.each_with_index do |order,i|
411
+ collector << Arel::Visitors::Oracle::COMMA unless i == 0
497
412
  collector = visit order, collector
498
413
  end
499
414
  else
500
415
  collector = visit o.left, collector
501
416
  end
502
- collector << '))'
417
+ collector << "))"
503
418
  collector
504
419
  end
505
420
 
506
421
  def visit_ArelExtensions_Nodes_MD5 o, collector
507
422
  collector << "LOWER(CONVERT(NVARCHAR(32),HashBytes('MD5',CONVERT(VARCHAR,"
508
423
  collector = visit o.left, collector
509
- collector << ')),2))'
424
+ collector << ")),2))"
510
425
  collector
511
426
  end
512
427
 
513
428
  def visit_ArelExtensions_Nodes_Cast o, collector
514
- as_attr =
515
- case o.as_attr
516
- when :string
517
- 'varchar'
518
- when :time
519
- 'time'
520
- when :date
521
- 'date'
522
- when :datetime
523
- 'datetime'
524
- when :number, :decimal, :float
525
- 'decimal(10,6)'
526
- when :int
527
- collector << 'CAST(CAST('
528
- collector = visit o.left, collector
529
- collector << ' AS decimal(10,0)) AS int)'
530
- return collector
531
- when :binary
532
- 'binary'
533
- else
534
- o.as_attr.to_s
535
- end
536
- collector << 'CAST('
429
+ case o.as_attr
430
+ when :string
431
+ as_attr = Arel::Nodes::SqlLiteral.new('varchar')
432
+ when :time
433
+ as_attr = Arel::Nodes::SqlLiteral.new('time')
434
+ when :date
435
+ as_attr = Arel::Nodes::SqlLiteral.new('date')
436
+ when :datetime
437
+ as_attr = Arel::Nodes::SqlLiteral.new('datetime')
438
+ when :number,:decimal, :float
439
+ as_attr = Arel::Nodes::SqlLiteral.new('decimal(10,6)')
440
+ when :int
441
+ collector << "CAST(CAST("
442
+ collector = visit o.left, collector
443
+ collector << " AS decimal(10,0)) AS int)"
444
+ return collector
445
+ when :binary
446
+ as_attr = Arel::Nodes::SqlLiteral.new('binary')
447
+ else
448
+ as_attr = Arel::Nodes::SqlLiteral.new(o.as_attr.to_s)
449
+ end
450
+ collector << "CAST("
537
451
  collector = visit o.left, collector
538
- collector << ' AS '
539
- collector = visit Arel::Nodes::SqlLiteral.new(as_attr), collector
540
- collector << ')'
452
+ collector << " AS "
453
+ collector = visit as_attr, collector
454
+ collector << ")"
541
455
  collector
542
456
  end
543
457
 
544
458
  def visit_ArelExtensions_Nodes_FormattedNumber o, collector
545
459
  col = o.left.coalesce(0)
546
- locale = Arel.quoted(o.locale.tr('_', '-'))
547
- param = Arel.quoted("N#{o.precision}")
548
- sign = Arel.when(col < 0).
460
+ locale = Arel::Nodes.build_quoted(o.locale.tr('_','-'))
461
+ param = Arel::Nodes.build_quoted("N#{o.precision}")
462
+ sign = ArelExtensions::Nodes::Case.new.when(col<0).
549
463
  then('-').
550
464
  else(o.flags.include?('+') ? '+' : (o.flags.include?(' ') ? ' ' : ''))
551
465
  sign_length = o.flags.include?('+') || o.flags.include?(' ') ?
552
- Arel.quoted(1) :
553
- Arel.when(col < 0).then(1).else(0)
554
-
555
- number =
556
- if o.scientific_notation
557
- ArelExtensions::Nodes::Concat.new([
558
- Arel::Nodes::NamedFunction.new('FORMAT', [
559
- col.abs / Arel.quoted(10).pow(col.abs.log10.floor),
466
+ Arel::Nodes.build_quoted(1) :
467
+ ArelExtensions::Nodes::Case.new.when(col<0).then(1).else(0)
468
+
469
+ if o.scientific_notation
470
+ number = ArelExtensions::Nodes::Concat.new([
471
+ Arel::Nodes::NamedFunction.new('FORMAT',[
472
+ col.abs/Arel::Nodes.build_quoted(10).pow(col.abs.log10.floor),
560
473
  param,
561
474
  locale
562
475
  ]),
563
476
  o.type,
564
- Arel::Nodes::NamedFunction.new('FORMAT', [
477
+ Arel::Nodes::NamedFunction.new('FORMAT',[
565
478
  col.abs.log10.floor,
566
- Arel.quoted('N0'),
479
+ Arel::Nodes.build_quoted('N0'),
567
480
  locale
568
481
  ])
569
482
  ])
570
- else
571
- Arel::Nodes::NamedFunction.new('FORMAT', [
572
- Arel.quoted(col.abs),
483
+ else
484
+ number = Arel::Nodes::NamedFunction.new('FORMAT',[
485
+ Arel::Nodes.build_quoted(col.abs),
573
486
  param,
574
487
  locale
575
488
  ])
576
- end
489
+ end
577
490
 
578
- repeated_char = (o.width == 0) ? Arel.quoted('') : ArelExtensions::Nodes::Case.new.
579
- when(Arel.quoted(o.width).abs - (number.length + sign_length) > 0).
580
- then(Arel.quoted(
491
+ repeated_char = (o.width == 0) ? Arel::Nodes.build_quoted('') : ArelExtensions::Nodes::Case.new().
492
+ when(Arel::Nodes.build_quoted(o.width).abs-(number.length+sign_length)>0).
493
+ then(Arel::Nodes.build_quoted(
581
494
  o.flags.include?('-') ? ' ' : (o.flags.include?('0') ? '0' : ' ')
582
- ).repeat(Arel.quoted(o.width).abs - (number.length + sign_length))
495
+ ).repeat(Arel::Nodes.build_quoted(o.width).abs-(number.length+sign_length))
583
496
  ).
584
497
  else('')
585
- before = (!o.flags.include?('0')) && (!o.flags.include?('-')) ? repeated_char : ''
586
- middle = (o.flags.include?('0')) && (!o.flags.include?('-')) ? repeated_char : ''
498
+ before = (!o.flags.include?('0'))&&(!o.flags.include?('-')) ? repeated_char : ''
499
+ middle = (o.flags.include?('0'))&&(!o.flags.include?('-')) ? repeated_char : ''
587
500
  after = o.flags.include?('-') ? repeated_char : ''
588
501
  full_number =
589
502
  ArelExtensions::Nodes::Concat.new([
@@ -593,27 +506,27 @@ module ArelExtensions
593
506
  number,
594
507
  after
595
508
  ])
596
- collector = visit ArelExtensions::Nodes::Concat.new([Arel.quoted(o.prefix), full_number, Arel.quoted(o.suffix)]), collector
509
+ collector = visit ArelExtensions::Nodes::Concat.new([Arel::Nodes.build_quoted(o.prefix),full_number,Arel::Nodes.build_quoted(o.suffix)]), collector
597
510
  collector
598
511
  end
599
512
 
600
513
  def visit_ArelExtensions_Nodes_Std o, collector
601
- collector << (o.unbiased_estimator ? 'STDEV(' : 'STDEVP(')
514
+ collector << (o.unbiased_estimator ? "STDEV(" : "STDEVP(")
602
515
  visit o.left, collector
603
- collector << ')'
516
+ collector << ")"
604
517
  collector
605
518
  end
606
519
 
607
520
  def visit_ArelExtensions_Nodes_Variance o, collector
608
- collector << (o.unbiased_estimator ? 'VAR(' : 'VARP(')
521
+ collector << (o.unbiased_estimator ? "VAR(" : "VARP(")
609
522
  visit o.left, collector
610
- collector << ')'
523
+ collector << ")"
611
524
  collector
612
525
  end
613
526
 
614
527
 
615
528
  def visit_ArelExtensions_Nodes_LevenshteinDistance o, collector
616
- collector << 'dbo.LEVENSHTEIN_DISTANCE('
529
+ collector << "dbo.LEVENSHTEIN_DISTANCE("
617
530
  collector = visit o.left, collector
618
531
  collector << Arel::Visitors::ToSql::COMMA
619
532
  collector = visit o.right, collector
@@ -622,18 +535,20 @@ module ArelExtensions
622
535
  end
623
536
 
624
537
 
625
- def visit_ArelExtensions_Nodes_JsonGet o, collector
538
+ def visit_ArelExtensions_Nodes_JsonGet o,collector
626
539
  collector << 'JSON_VALUE('
627
540
  collector = visit o.dict, collector
628
541
  collector << Arel::Visitors::MySQL::COMMA
629
542
  if o.key.is_a?(Integer)
630
543
  collector << "\"$[#{o.key}]\""
631
544
  else
632
- collector = visit Arel.quoted('$.') + o.key, collector
545
+ collector = visit Arel::Nodes.build_quoted('$.')+o.key, collector
633
546
  end
634
547
  collector << ')'
635
548
  collector
636
549
  end
550
+
551
+
637
552
  end
638
553
  end
639
554
  end