arel_extensions 1.0.6 → 1.0.7

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 99e66779787e74a1e41f072a4515bc0aabcd4146
4
- data.tar.gz: 5918126e0d59efe520b893949f2f18d9a4c659b1
3
+ metadata.gz: 7e6925dda8ff2e84e0501da7f283326b69feb5ad
4
+ data.tar.gz: 8935f5b0b37b38c8bfa63f5858eea8fc00fbe389
5
5
  SHA512:
6
- metadata.gz: 26f6700d800e3a1426977d924233fc3f7db52482018792e3cd3f1c9338f543132d4fa656fb24b1af47e0c3532b31deab6d26b6b1ec54cc9e0e4e9c9e09febb12
7
- data.tar.gz: 15f28347171e501dd95ca8a3ac2a1897d21805f81b5125b0a9765509c01daba4c263babfc53a03226e57d8c8acebfe4f41fb5f9c65b010a2aa7dcd54d7e82bdb
6
+ metadata.gz: e14c35a07d01adce7aec5b79a5b0e063262cdb4ae35c6684d45ab334ea19fd988790eb158a539fe25d9f6801562295fbb80afc3e630fadf0cd3af58debd08e66
7
+ data.tar.gz: a81609fa1c9281814271fa5d3fcebf269c08818e60c67c89b550d9072e0196f5606e1cadd3cb8465ab82899b9bec6a4878713b66a01ab62c4015a74c7bfaa58d
data/README.md CHANGED
@@ -192,7 +192,7 @@ User.connection.execute(insert_manager.to_sql)
192
192
  </thead>
193
193
  <tbody>
194
194
  <tr>
195
- <th class="tg-82sq" rowspan="6"><div>Number functions</div></th>
195
+ <th class="tg-82sq" rowspan="7"><div>Number functions</div></th>
196
196
  <td class="tg-yw4l">ABS<br>column.abs<br></td>
197
197
  <td class="ok">✔</td>
198
198
  <td class="ok">✔</td>
@@ -246,6 +246,15 @@ User.connection.execute(insert_manager.to_sql)
246
246
  <td class="ok">✔</td>
247
247
  <td class="ok">✔</td>
248
248
  </tr>
249
+ <tr>
250
+ <td class="tg-yw4l">POSIX FORMATTING<br>column.format_number("$ %7.2f","en_US")</td>
251
+ <td class="ok">✔</td>
252
+ <td class="ok">✔</td>
253
+ <td class="ok">✔</td>
254
+ <td class="ok">✔</td>
255
+ <td class="ok">✔</td>
256
+ <td class="ko">not implemented</td>
257
+ </tr>
249
258
  <tr>
250
259
  <th class="tg-ffjm" rowspan="17"><div>String functions</div></th>
251
260
  <td class="tg-yw4l">CONCAT<br>column + "string"</td>
data/TODO CHANGED
@@ -14,7 +14,7 @@ TODO:
14
14
  New features:
15
15
  - POSIX format numbers (%.2f), dates (man 3 printf)
16
16
  - cast, to_char
17
- - auto-remove order by in sub queries
17
+ - auto-remove order by (when no limit) in sub queries
18
18
  - avoid incompatible queries in PgSQL/Oracle/SQLServer when columns are used outside of group by columns (in select or order by)
19
19
 
20
20
  Tests improvements:
@@ -68,7 +68,8 @@ module ArelExtensions
68
68
  :precision => m[4] != '' ? m[4].to_i : 6,
69
69
  :type => m[5],
70
70
  :suffix => m[6],
71
- :locale => locale
71
+ :locale => locale,
72
+ :original_string => format_string
72
73
  }
73
74
  # opts = {:locale => 'fr_FR', :type => "e"/"f"/"d", :prefix => "$ ", :suffix => " %", :flags => " +-#0", :width => 5, :precision => 6}
74
75
  ArelExtensions::Nodes::FormattedNumber.new [self,opts]
@@ -3,7 +3,7 @@ module ArelExtensions
3
3
  class FormattedNumber < Function
4
4
  RETURN_TYPE = :string
5
5
 
6
- attr_accessor :locale, :prefix, :suffix, :flags, :scientific_notation, :width,:precision, :type
6
+ attr_accessor :locale, :prefix, :suffix, :flags, :scientific_notation, :width,:precision, :type, :original_string
7
7
 
8
8
  def initialize expr
9
9
  # expr[1] = {:locale => 'fr_FR', :type => "e"/"f"/"d", :prefix => "$ ", :suffix => " %", :flags => " +-#0", :width => 5, :precision => 6}
@@ -16,6 +16,7 @@ module ArelExtensions
16
16
  @type = expr[1][:type]
17
17
  @flags = expr[1][:flags]
18
18
  @scientific_notation = /[eE]/.match(expr[1][:type]) || false
19
+ @original_string = expr[1][:original_string]
19
20
  super [col]
20
21
  end
21
22
 
@@ -4,5 +4,10 @@ module ArelExtensions
4
4
  RETURN_TYPE = :boolean
5
5
 
6
6
  end
7
+
8
+ class IsNotNull < Function
9
+ RETURN_TYPE = :boolean
10
+
11
+ end
7
12
  end
8
13
  end
@@ -8,6 +8,12 @@ module ArelExtensions
8
8
  def is_null
9
9
  ArelExtensions::Nodes::IsNull.new [self]
10
10
  end
11
+
12
+ #ISNOTNULL function lets you return an alternative value when an expression is NOT NULL.
13
+ def is_not_null
14
+ ArelExtensions::Nodes::IsNotNull.new [self]
15
+ end
16
+
11
17
  # returns the first non-null expr in the expression list. You must specify at least two expressions.
12
18
  #If all occurrences of expr evaluate to null, then the function returns null.
13
19
  def coalesce *args
@@ -18,6 +18,82 @@ module ArelExtensions
18
18
  ArelExtensions::Nodes::Cast.new([self,right])
19
19
  end
20
20
 
21
+ def in(other) #In should handle nil element in the Array
22
+ res = nil
23
+ case other
24
+ when Enumerable
25
+ if other.include?(nil)
26
+ other.delete(nil)
27
+ case other.length
28
+ when 0
29
+ res = self.is_null
30
+ when 1
31
+ res = self.is_null.or(self==other[0])
32
+ else
33
+ res = self.is_null.or(Arel::Nodes::In.new(self,other.map{|e| convert_to_node(e)}))
34
+ end
35
+ else
36
+ res = Arel::Nodes::In.new(self,other.map{|e| convert_to_node(e)})
37
+ end
38
+ when nil
39
+ res = self.is_null
40
+ when Arel::SelectManager
41
+ res = Arel::Nodes::In.new(self, other.ast)
42
+ when Range
43
+ res = self.between(other)
44
+ else
45
+ res = Arel::Nodes::In.new(self,convert_to_node(other))
46
+ end
47
+ res
48
+ end
49
+
50
+ def not_in(other) #In should handle nil element in the Array
51
+ res = nil
52
+ case other
53
+ when Enumerable
54
+ if other.include?(nil)
55
+ other.delete(nil)
56
+ case other.length
57
+ when 0
58
+ res = self.is_not_null
59
+ when 1
60
+ res = self.is_not_null.and(self!=other[0])
61
+ else
62
+ res = self.is_not_null.and(Arel::Nodes::NotIn.new(self,other.map{|e| convert_to_node(e)}))
63
+ end
64
+ else
65
+ res = Arel::Nodes::NotIn.new(self,other.map{|e| convert_to_node(e)})
66
+ end
67
+ when nil
68
+ res = self.is_not_null
69
+ when Arel::SelectManager
70
+ res = Arel::Nodes::NotIn.new(self, other.ast)
71
+ else
72
+ res = Arel::Nodes::NotIn.new(self,convert_to_node(other))
73
+ end
74
+ res
75
+ end
76
+
77
+ def convert_to_node(object)
78
+ case object
79
+ when Arel::Attributes::Attribute, Arel::Nodes::Node, Integer
80
+ object
81
+ when DateTime
82
+ Arel::Nodes.build_quoted(object, self)
83
+ when Time
84
+ Arel::Nodes.build_quoted(object.strftime('%H:%M:%S'), self)
85
+ when String
86
+ Arel::Nodes.build_quoted(object)
87
+ when Date
88
+ Arel::Nodes.build_quoted(object.to_s, self)
89
+ when NilClass
90
+ Arel.sql('NULL')
91
+ when ActiveSupport::Duration
92
+ object.to_i
93
+ else
94
+ raise(ArgumentError, "#{object.class} can not be converted to CONCAT arg")
95
+ end
96
+ end
21
97
 
22
98
  end
23
99
  end
@@ -1,3 +1,3 @@
1
1
  module ArelExtensions
2
- VERSION = "1.0.6".freeze
2
+ VERSION = "1.0.7".freeze
3
3
  end
@@ -7,6 +7,15 @@ require 'arel_extensions/visitors/mssql'
7
7
 
8
8
  Arel::Visitors::MSSQL.class_eval do
9
9
  include ArelExtensions::Visitors::MSSQL
10
+
11
+ alias_method :old_visit_Arel_Nodes_SelectStatement, :visit_Arel_Nodes_SelectStatement
12
+ def visit_Arel_Nodes_SelectStatement o, collector
13
+ if !collector.value.blank? && o.limit.blank? && o.offset.blank?
14
+ o = o.dup
15
+ o.orders = []
16
+ end
17
+ old_visit_Arel_Nodes_SelectStatement(o,collector)
18
+ end
10
19
  end
11
20
 
12
21
  begin
@@ -15,6 +24,15 @@ begin
15
24
  if Arel::Visitors::VISITORS['sqlserver'] && Arel::Visitors::VISITORS['sqlserver'] != Arel::Visitors::MSSQL
16
25
  Arel::Visitors::VISITORS['sqlserver'].class_eval do
17
26
  include ArelExtensions::Visitors::MSSQL
27
+
28
+ alias_method :old_visit_Arel_Nodes_SelectStatement, :visit_Arel_Nodes_SelectStatement
29
+ def visit_Arel_Nodes_SelectStatement o, collector
30
+ if !collector.value.blank? && o.limit.blank? && o.offset.blank?
31
+ o = o.dup
32
+ o.orders = []
33
+ end
34
+ old_visit_Arel_Nodes_SelectStatement(o,collector)
35
+ end
18
36
  end
19
37
  end
20
38
  end
@@ -56,6 +56,14 @@ module ArelExtensions
56
56
  collector << " IS NULL)"
57
57
  collector
58
58
  end
59
+
60
+ def visit_ArelExtensions_Nodes_IsNotNull o, collector
61
+ collector << "("
62
+ collector = visit o.left, collector
63
+ # collector << Arel::Visitors::MSSQL::COMMA
64
+ collector << " IS NOT NULL)"
65
+ collector
66
+ end
59
67
 
60
68
  # Deprecated
61
69
  def visit_ArelExtensions_Nodes_ConcatOld o, collector
@@ -231,11 +239,11 @@ module ArelExtensions
231
239
  end
232
240
 
233
241
  def visit_ArelExtensions_Nodes_Blank o, collector
234
- visit o.left.trim.length.eq(0), collector
242
+ visit o.left.coalesce('').trim.length.eq(0), collector
235
243
  end
236
244
 
237
245
  def visit_ArelExtensions_Nodes_NotBlank o, collector
238
- visit o.left.trim.length.gt(0), collector
246
+ visit o.left.coalesce('').trim.length.gt(0), collector
239
247
  end
240
248
 
241
249
  def visit_ArelExtensions_Nodes_Format o, collector
@@ -432,6 +440,62 @@ module ArelExtensions
432
440
  collector << ")"
433
441
  collector
434
442
  end
443
+
444
+ def visit_ArelExtensions_Nodes_FormattedNumber o, collector
445
+ col = o.left
446
+ locale = Arel::Nodes.build_quoted(o.locale.tr('_','-'))
447
+ param = Arel::Nodes.build_quoted("N#{o.precision}")
448
+ sign = ArelExtensions::Nodes::Case.new.when(col<0).
449
+ then('-').
450
+ else(o.flags.include?('+') ? '+' : (o.flags.include?(' ') ? ' ' : ''))
451
+ sign_length = o.flags.include?('+') || o.flags.include?(' ') ?
452
+ Arel::Nodes.build_quoted(1) :
453
+ ArelExtensions::Nodes::Case.new.when(col<0).then(1).else(0)
454
+
455
+ if o.scientific_notation
456
+ number = ArelExtensions::Nodes::Concat.new([
457
+ Arel::Nodes::NamedFunction.new('FORMAT',[
458
+ col.abs/Arel::Nodes.build_quoted(10).pow(col.abs.log10.floor),
459
+ param,
460
+ locale
461
+ ]),
462
+ o.type,
463
+ Arel::Nodes::NamedFunction.new('FORMAT',[
464
+ col.abs.log10.floor,
465
+ Arel::Nodes.build_quoted('N0'),
466
+ locale
467
+ ])
468
+ ])
469
+ else
470
+ number = Arel::Nodes::NamedFunction.new('FORMAT',[
471
+ Arel::Nodes.build_quoted(col.abs),
472
+ param,
473
+ locale
474
+ ])
475
+ end
476
+
477
+ repeated_char = (o.width == 0) ? Arel::Nodes.build_quoted('') : ArelExtensions::Nodes::Case.new().
478
+ when(Arel::Nodes.build_quoted(o.width).abs-(number.length+sign_length)>0).
479
+ then(Arel::Nodes.build_quoted(
480
+ o.flags.include?('-') ? ' ' : (o.flags.include?('0') ? '0' : ' ')
481
+ ).repeat(Arel::Nodes.build_quoted(o.width).abs-(number.length+sign_length))
482
+ ).
483
+ else('')
484
+ before = (!o.flags.include?('0'))&&(!o.flags.include?('-')) ? repeated_char : ''
485
+ middle = (o.flags.include?('0'))&&(!o.flags.include?('-')) ? repeated_char : ''
486
+ after = o.flags.include?('-') ? repeated_char : ''
487
+ full_number = col.when(0).then('0').else(
488
+ ArelExtensions::Nodes::Concat.new([
489
+ before,
490
+ sign,
491
+ middle,
492
+ number,
493
+ after
494
+ ])
495
+ )
496
+ collector = visit ArelExtensions::Nodes::Concat.new([Arel::Nodes.build_quoted(o.prefix),full_number,Arel::Nodes.build_quoted(o.suffix)]), collector
497
+ collector
498
+ end
435
499
 
436
500
  end
437
501
  end
@@ -255,6 +255,17 @@ module ArelExtensions
255
255
  collector << ")"
256
256
  collector
257
257
  end
258
+
259
+ def visit_ArelExtensions_Nodes_IsNotNull o, collector
260
+ collector << "NOT ISNULL("
261
+ collector = visit o.left, collector
262
+ if o.right
263
+ collector << Arel::Visitors::MySQL::COMMA
264
+ collector = visit o.right, collector
265
+ end
266
+ collector << ")"
267
+ collector
268
+ end
258
269
 
259
270
  def visit_ArelExtensions_Nodes_Wday o, collector
260
271
  collector << "(WEEKDAY("
@@ -285,7 +296,63 @@ module ArelExtensions
285
296
  collector << ")"
286
297
  collector
287
298
  end
288
-
299
+
300
+ alias_method :old_visit_Arel_Nodes_SelectStatement, :visit_Arel_Nodes_SelectStatement
301
+ def visit_Arel_Nodes_SelectStatement o, collector
302
+ if !collector.value.blank? && o.limit.blank? && o.offset.blank?
303
+ o = o.dup
304
+ o.orders = []
305
+ end
306
+ old_visit_Arel_Nodes_SelectStatement(o,collector)
307
+ end
308
+
309
+ def visit_ArelExtensions_Nodes_FormattedNumber o, collector
310
+ col = o.left
311
+ params = o.locale ? [o.precision,Arel::Nodes.build_quoted(o.locale)] : [o.precision]
312
+ sign = ArelExtensions::Nodes::Case.new.when(col<0).
313
+ then('-').
314
+ else(o.flags.include?('+') ? '+' : (o.flags.include?(' ') ? ' ' : ''))
315
+ sign_length = ArelExtensions::Nodes::Length.new([sign])
316
+
317
+ if o.scientific_notation
318
+ number = ArelExtensions::Nodes::Concat.new([
319
+ Arel::Nodes::NamedFunction.new('FORMAT',[
320
+ col.abs/Arel::Nodes.build_quoted(10).pow(col.abs.log10.floor)
321
+ ]+params),
322
+ o.type,
323
+ Arel::Nodes::NamedFunction.new('FORMAT',[
324
+ col.abs.log10.floor,
325
+ 0
326
+ ])
327
+ ])
328
+ else
329
+ number = Arel::Nodes::NamedFunction.new('FORMAT',[col.abs]+params)
330
+ end
331
+
332
+ repeated_char = (o.width == 0) ? Arel::Nodes.build_quoted('') : ArelExtensions::Nodes::Case.new().
333
+ when(Arel::Nodes.build_quoted(o.width).abs-(number.length+sign_length)>0).
334
+ then(Arel::Nodes.build_quoted(
335
+ o.flags.include?('-') ? ' ' : (o.flags.include?('0') ? '0' : ' ')
336
+ ).repeat(Arel::Nodes.build_quoted(o.width).abs-(number.length+sign_length))
337
+ ).
338
+ else('')
339
+ before = (!o.flags.include?('0'))&&(!o.flags.include?('-')) ? repeated_char : ''
340
+ middle = (o.flags.include?('0'))&&(!o.flags.include?('-')) ? repeated_char : ''
341
+ after = o.flags.include?('-') ? repeated_char : ''
342
+ full_number = col.when(0).then('0').else(
343
+ ArelExtensions::Nodes::Concat.new([
344
+ before,
345
+ sign,
346
+ middle,
347
+ number,
348
+ after
349
+ ])
350
+ )
351
+ collector = visit ArelExtensions::Nodes::Concat.new([Arel::Nodes.build_quoted(o.prefix),full_number,Arel::Nodes.build_quoted(o.suffix)]), collector
352
+ collector
353
+ end
354
+
355
+
289
356
  end
290
357
  end
291
358
  end
@@ -9,6 +9,7 @@ module ArelExtensions
9
9
  '%H' => 'HH24', '%k' => '', '%I' => 'HH', '%l' => '', '%P' => 'am', '%p' => 'AM', # hours
10
10
  '%M' => 'MI', '%S' => 'SS', '%L' => 'MS', '%N' => 'US', '%z' => 'tz' # seconds, subseconds
11
11
  }
12
+ Arel::Visitors::Oracle::NUMBER_COMMA_MAPPING = { 'en_US' => '.,', 'fr_FR' => ', ' }
12
13
 
13
14
  def visit_ArelExtensions_Nodes_Log10 o, collector
14
15
  collector << "LOG("
@@ -241,6 +242,12 @@ module ArelExtensions
241
242
  collector << ' IS NULL'
242
243
  collector
243
244
  end
245
+
246
+ def visit_ArelExtensions_Nodes_IsNotNull o, collector
247
+ collector = visit o.left, collector
248
+ collector << ' IS NOT NULL'
249
+ collector
250
+ end
244
251
 
245
252
  def visit_ArelExtensions_Nodes_Rand o, collector
246
253
  collector << "DBMS_RANDOM.VALUE("
@@ -374,7 +381,9 @@ module ArelExtensions
374
381
  end
375
382
 
376
383
  def visit_ArelExtensions_Nodes_Repeat o, collector
377
- collector << "LPAD('',"
384
+ collector << "LPAD("
385
+ collector = visit o.expressions[0], collector #can't put empty string, otherwise it wouldn't work
386
+ collector << Arel::Visitors::ToSql::COMMA
378
387
  collector = visit o.expressions[1], collector
379
388
  collector << Arel::Visitors::ToSql::COMMA
380
389
  collector = visit o.expressions[0], collector
@@ -493,6 +502,69 @@ module ArelExtensions
493
502
  collector
494
503
  end
495
504
 
505
+
506
+ alias_method :old_visit_Arel_Nodes_SelectStatement, :visit_Arel_Nodes_SelectStatement
507
+ def visit_Arel_Nodes_SelectStatement o, collector
508
+ if !collector.value.blank? && o.limit.blank? && o.offset.blank?
509
+ o = o.dup
510
+ o.orders = []
511
+ end
512
+ old_visit_Arel_Nodes_SelectStatement(o,collector)
513
+ end
514
+
515
+ def visit_ArelExtensions_Nodes_FormattedNumber o, collector
516
+ col = o.left
517
+ comma = Arel::Visitors::Oracle::NUMBER_COMMA_MAPPING[o.locale] || '.,'
518
+ options = Arel::Nodes.build_quoted("NLS_NUMERIC_CHARACTERS = '"+comma+"'")
519
+ nines_after = (1..o.precision).map{'9'}.join('')
520
+ nines_before = (1..16).map{'9'}.join('')
521
+ sign = ArelExtensions::Nodes::Case.new.when(col<0).
522
+ then('-').
523
+ else(o.flags.include?('+') ? '+' : (o.flags.include?(' ') ? ' ' : ''))
524
+ sign_length = o.flags.include?('+') || o.flags.include?(' ') ?
525
+ Arel::Nodes.build_quoted(1) :
526
+ ArelExtensions::Nodes::Case.new.when(col<0).then(1).else(0)
527
+
528
+ if o.scientific_notation
529
+ number = Arel::Nodes::NamedFunction.new('TO_CHAR',[
530
+ Arel::Nodes.build_quoted(col.abs),
531
+ Arel::Nodes.build_quoted('FM'+nines_before+'D'+nines_after+'EEEE'),
532
+ options
533
+ ])
534
+ if o.type == 'e'
535
+ number = number.replace('E','e')
536
+ end
537
+ else
538
+ number = Arel::Nodes::NamedFunction.new('TO_CHAR',[
539
+ Arel::Nodes.build_quoted(col.abs),
540
+ Arel::Nodes.build_quoted('FM'+nines_before+'D'+nines_after),
541
+ options
542
+ ])
543
+ end
544
+
545
+ repeated_char = (o.width == 0) ? Arel::Nodes.build_quoted('') : ArelExtensions::Nodes::Case.new().
546
+ when(Arel::Nodes.build_quoted(o.width).abs-(number.length+sign_length)>0).
547
+ then(Arel::Nodes.build_quoted(
548
+ o.flags.include?('-') ? ' ' : (o.flags.include?('0') ? '0' : ' ')
549
+ ).repeat(Arel::Nodes.build_quoted(o.width).abs-(number.length+sign_length))
550
+ ).
551
+ else('')
552
+ before = (!o.flags.include?('0'))&&(!o.flags.include?('-')) ? repeated_char : ''
553
+ middle = (o.flags.include?('0'))&&(!o.flags.include?('-')) ? repeated_char : ''
554
+ after = o.flags.include?('-') ? repeated_char : ''
555
+ full_number = col.when(0).then('0').else(
556
+ ArelExtensions::Nodes::Concat.new([
557
+ before,
558
+ sign,
559
+ middle,
560
+ number,
561
+ after
562
+ ])
563
+ )
564
+ collector = visit ArelExtensions::Nodes::Concat.new([Arel::Nodes.build_quoted(o.prefix),full_number,Arel::Nodes.build_quoted(o.suffix)]), collector
565
+ collector
566
+ end
567
+
496
568
 
497
569
  end
498
570
  end
@@ -8,6 +8,7 @@ module ArelExtensions
8
8
  '%H' => 'HH24', '%k' => '', '%I' => 'HH', '%l' => '', '%P' => 'am', '%p' => 'AM', # hours
9
9
  '%M' => 'MI', '%S' => 'SS', '%L' => 'MS', '%N' => 'US', '%z' => 'tz' # seconds, subseconds
10
10
  }
11
+ Arel::Visitors::PostgreSQL::NUMBER_COMMA_MAPPING = { 'en_US' => '.', 'fr_FR' => ',' }
11
12
 
12
13
  def visit_ArelExtensions_Nodes_Rand o, collector
13
14
  collector << "RANDOM("
@@ -234,6 +235,12 @@ module ArelExtensions
234
235
  collector << ' IS NULL'
235
236
  collector
236
237
  end
238
+
239
+ def visit_ArelExtensions_Nodes_IsNotNull o, collector
240
+ collector = visit o.left, collector
241
+ collector << ' IS NOT NULL'
242
+ collector
243
+ end
237
244
 
238
245
  def visit_ArelExtensions_Nodes_Sum o, collector
239
246
  collector << "sum("
@@ -272,6 +279,67 @@ module ArelExtensions
272
279
  collector
273
280
  end
274
281
 
282
+ def visit_ArelExtensions_Nodes_FormattedNumber o, collector
283
+ col = o.left
284
+ comma = Arel::Visitors::PostgreSQL::NUMBER_COMMA_MAPPING[o.locale] || '.'
285
+ nines_after = (1..o.precision).map{'9'}.join('')
286
+ nines_before = (1..16).map{'9'}.join('')
287
+ sign = ArelExtensions::Nodes::Case.new.when(col<0).
288
+ then('-').
289
+ else(o.flags.include?('+') ? '+' : (o.flags.include?(' ') ? ' ' : ''))
290
+ sign_length = ArelExtensions::Nodes::Length.new([sign])
291
+
292
+ if o.scientific_notation
293
+ number = ArelExtensions::Nodes::Concat.new([
294
+ Arel::Nodes::NamedFunction.new('TO_CHAR',[
295
+ col.abs/Arel::Nodes.build_quoted(10).pow(col.abs.log10.floor),
296
+ Arel::Nodes.build_quoted('FM'+nines_before+'"'+comma+'"V'+nines_after)
297
+ ]),
298
+ o.type,
299
+ Arel::Nodes::NamedFunction.new('TO_CHAR',[
300
+ col.abs.log10.floor,
301
+ Arel::Nodes.build_quoted('FM'+nines_before)
302
+ ])
303
+ ])
304
+ else
305
+ number = Arel::Nodes::NamedFunction.new('TO_CHAR',[
306
+ Arel::Nodes.build_quoted(col.abs),
307
+ Arel::Nodes.build_quoted('FM'+nines_before+'"'+comma+'"V'+nines_after)
308
+ ])
309
+ end
310
+
311
+ repeated_char = (o.width == 0) ? Arel::Nodes.build_quoted('') : ArelExtensions::Nodes::Case.new().
312
+ when(Arel::Nodes.build_quoted(o.width).abs-(number.length+sign_length)>0).
313
+ then(Arel::Nodes.build_quoted(
314
+ o.flags.include?('-') ? ' ' : (o.flags.include?('0') ? '0' : ' ')
315
+ ).repeat(Arel::Nodes.build_quoted(o.width).abs-(number.length+sign_length))
316
+ ).
317
+ else('')
318
+ before = (!o.flags.include?('0'))&&(!o.flags.include?('-')) ? repeated_char : ''
319
+ middle = (o.flags.include?('0'))&&(!o.flags.include?('-')) ? repeated_char : ''
320
+ after = o.flags.include?('-') ? repeated_char : ''
321
+ full_number = col.when(0).then('0').else(
322
+ ArelExtensions::Nodes::Concat.new([
323
+ before,
324
+ sign,
325
+ middle,
326
+ number,
327
+ after
328
+ ])
329
+ )
330
+ collector = visit ArelExtensions::Nodes::Concat.new([Arel::Nodes.build_quoted(o.prefix),full_number,Arel::Nodes.build_quoted(o.suffix)]), collector
331
+ collector
332
+ end
333
+
334
+
335
+ alias_method :old_visit_Arel_Nodes_SelectStatement, :visit_Arel_Nodes_SelectStatement
336
+ def visit_Arel_Nodes_SelectStatement o, collector
337
+ if !collector.value.blank? && o.limit.blank? && o.offset.blank?
338
+ o = o.dup
339
+ o.orders = []
340
+ end
341
+ old_visit_Arel_Nodes_SelectStatement(o,collector)
342
+ end
275
343
 
276
344
  end
277
345
  end
@@ -8,6 +8,7 @@ module ArelExtensions
8
8
  '%H' => '%H', '%k' => '%k', '%I' => '%I', '%l' => '%l', '%P' => '%p', '%p' => '%p', # hours
9
9
  '%M' => '%M', '%S' => '%S', '%L' => '', '%N' => '%f', '%z' => '' # seconds, subseconds
10
10
  }
11
+ Arel::Visitors::SQLite::NUMBER_COMMA_MAPPING = { 'fr_FR' => {',' => ' ','.' =>','} }
11
12
 
12
13
  #String functions
13
14
  def visit_ArelExtensions_Nodes_IMatches o, collector # insensitive on ASCII
@@ -153,6 +154,12 @@ module ArelExtensions
153
154
  collector << ' IS NULL'
154
155
  collector
155
156
  end
157
+
158
+ def visit_ArelExtensions_Nodes_IsNotNull o, collector
159
+ collector = visit o.left, collector
160
+ collector << ' IS NOT NULL'
161
+ collector
162
+ end
156
163
 
157
164
  def visit_ArelExtensions_Nodes_Rand o, collector
158
165
  collector << "RANDOM("
@@ -319,7 +326,7 @@ module ArelExtensions
319
326
 
320
327
  remove_method(:visit_Arel_Nodes_GreaterThan) rescue nil
321
328
  def visit_Arel_Nodes_GreaterThan o, collector
322
- collector = visit get_time_converted(o.left), collector
329
+ collector = visit get_time_converted(o.left), collector
323
330
  collector << " > "
324
331
  collector = visit get_time_converted(o.right), collector
325
332
  collector
@@ -327,7 +334,7 @@ module ArelExtensions
327
334
 
328
335
  remove_method(:visit_Arel_Nodes_LessThanOrEqual) rescue nil
329
336
  def visit_Arel_Nodes_LessThanOrEqual o, collector
330
- collector = visit get_time_converted(o.left), collector
337
+ collector = visit get_time_converted(o.left), collector
331
338
  collector << " <= "
332
339
  collector = visit get_time_converted(o.right), collector
333
340
  collector
@@ -335,12 +342,33 @@ module ArelExtensions
335
342
 
336
343
  remove_method(:visit_Arel_Nodes_LessThan) rescue nil
337
344
  def visit_Arel_Nodes_LessThan o, collector
338
- collector = visit get_time_converted(o.left), collector
345
+ collector = visit get_time_converted(o.left), collector
339
346
  collector << " < "
340
347
  collector = visit get_time_converted(o.right), collector
341
348
  collector
342
349
  end
350
+
351
+
352
+ alias_method :old_visit_Arel_Nodes_SelectStatement, :visit_Arel_Nodes_SelectStatement
353
+ def visit_Arel_Nodes_SelectStatement o, collector
354
+ if !collector.value.blank? && o.limit.blank?
355
+ o = o.dup
356
+ o.orders = []
357
+ end
358
+ old_visit_Arel_Nodes_SelectStatement(o,collector)
359
+ end
343
360
 
361
+ def visit_ArelExtensions_Nodes_FormattedNumber o, collector
362
+
363
+ format = Arel::Nodes::NamedFunction.new('printf',[Arel::Nodes.build_quoted(o.original_string),o.left])
364
+ locale_map = Arel::Visitors::SQLite::NUMBER_COMMA_MAPPING[o.locale]
365
+ if locale_map
366
+ format = format.replace(',',locale_map[',']).replace('.',locale_map['.'])
367
+ end
368
+ visit format, collector
369
+ collector
370
+ end
371
+
344
372
  end
345
373
  end
346
374
  end
@@ -366,6 +366,13 @@ module ArelExtensions
366
366
  collector << ")"
367
367
  collector
368
368
  end
369
+
370
+ def visit_ArelExtensions_Nodes_IsNotNull o, collector
371
+ collector << "NOT ISNULL("
372
+ collector = visit o.left, collector
373
+ collector << ")"
374
+ collector
375
+ end
369
376
 
370
377
  def visit_ArelExtensions_Nodes_Then o, collector
371
378
  collector << "CASE WHEN ("
@@ -434,109 +441,67 @@ module ArelExtensions
434
441
  end
435
442
  end
436
443
 
437
- def visit_ArelExtensions_Nodes_Union o, collector
438
- collector = visit o.left, collector
439
- collector << " UNION "
440
- collector = visit o.right, collector
441
- collector
442
- end
443
-
444
- def visit_ArelExtensions_Nodes_UnionAll o, collector
445
- collector = visit o.left, collector
446
- collector << " UNION ALL "
447
- collector = visit o.right, collector
448
- collector
449
- end
450
-
451
- def visit_ArelExtensions_Nodes_As o, collector
452
- if o.left.is_a?(ArelExtensions::Nodes::Union) || o.left.is_a?(ArelExtensions::Nodes::UnionAll)
453
- collector << "("
444
+ def visit_ArelExtensions_Nodes_Union o, collector
454
445
  collector = visit o.left, collector
455
- collector << ") "
456
- visit o.right, collector
457
- else
446
+ collector << " UNION "
447
+ collector = visit o.right, collector
448
+ collector
449
+ end
450
+
451
+ def visit_ArelExtensions_Nodes_UnionAll o, collector
458
452
  collector = visit o.left, collector
459
- collector << " AS "
453
+ collector << " UNION ALL "
454
+ collector = visit o.right, collector
455
+ collector
456
+ end
457
+
458
+ def visit_ArelExtensions_Nodes_As o, collector
459
+ if o.left.is_a?(ArelExtensions::Nodes::Union) || o.left.is_a?(ArelExtensions::Nodes::UnionAll)
460
+ collector << "("
461
+ collector = visit o.left, collector
462
+ collector << ") "
463
+ visit o.right, collector
464
+ else
465
+ collector = visit o.left, collector
466
+ collector << " AS "
467
+ visit o.right, collector
468
+ end
469
+ end
470
+
471
+ def visit_ArelExtensions_Nodes_Case o, collector
472
+ collector << "CASE "
473
+ if o.case
474
+ visit o.case, collector
475
+ collector << " "
476
+ end
477
+ o.conditions.each do |condition|
478
+ visit condition, collector
479
+ collector << " "
480
+ end
481
+ if o.default
482
+ visit o.default, collector
483
+ collector << " "
484
+ end
485
+ collector << "END"
486
+ end
487
+
488
+ def visit_ArelExtensions_Nodes_When o, collector
489
+ collector << "WHEN "
490
+ visit o.left, collector
491
+ collector << " THEN "
460
492
  visit o.right, collector
461
493
  end
462
- end
463
-
464
- def visit_ArelExtensions_Nodes_Case o, collector
465
- collector << "CASE "
466
- if o.case
467
- visit o.case, collector
468
- collector << " "
469
- end
470
- o.conditions.each do |condition|
471
- visit condition, collector
472
- collector << " "
473
- end
474
- if o.default
475
- visit o.default, collector
476
- collector << " "
477
- end
478
- collector << "END"
479
- end
480
-
481
- def visit_ArelExtensions_Nodes_When o, collector
482
- collector << "WHEN "
483
- visit o.left, collector
484
- collector << " THEN "
485
- visit o.right, collector
486
- end
487
494
 
488
- def visit_ArelExtensions_Nodes_Else o, collector
489
- collector << "ELSE "
490
- visit o.expr, collector
491
- end
492
-
493
-
494
-
495
- def visit_ArelExtensions_Nodes_FormattedNumber o, collector
496
- col = o.left
497
- params = o.locale ? [o.precision,Arel::Nodes.build_quoted(o.locale)] : [o.precision]
498
- sign = ArelExtensions::Nodes::Case.new.when(col<0).
499
- then('-').
500
- else(o.flags.include?('+') ? '+' : (o.flags.include?(' ') ? ' ' : ''))
501
- sign_length = ArelExtensions::Nodes::Length.new([sign])
502
-
503
- if o.scientific_notation
504
- number = ArelExtensions::Nodes::Concat.new([
505
- Arel::Nodes::NamedFunction.new('FORMAT',[
506
- col.abs/Arel::Nodes.build_quoted(10).pow(col.abs.log10.floor)
507
- ]+params),
508
- o.type,
509
- Arel::Nodes::NamedFunction.new('FORMAT',[
510
- col.abs.log10.floor,
511
- 0
512
- ])
513
- ])
514
- else
515
- number = Arel::Nodes::NamedFunction.new('FORMAT',[col.abs]+params)
495
+ def visit_ArelExtensions_Nodes_Else o, collector
496
+ collector << "ELSE "
497
+ visit o.expr, collector
516
498
  end
517
499
 
518
- repeated_char = (o.width == 0) ? Arel::Nodes.build_quoted('') : ArelExtensions::Nodes::Case.new().
519
- when(Arel::Nodes.build_quoted(o.width).abs-(number.length+sign_length)>0).
520
- then(Arel::Nodes.build_quoted(
521
- o.flags.include?('-') ? ' ' : (o.flags.include?('0') ? '0' : ' ')
522
- ).repeat(Arel::Nodes.build_quoted(o.width).abs-(number.length+sign_length))
523
- ).
524
- else('')
525
- before = (!o.flags.include?('0'))&&(!o.flags.include?('-')) ? repeated_char : ''
526
- middle = (o.flags.include?('0'))&&(!o.flags.include?('-')) ? repeated_char : ''
527
- after = o.flags.include?('-') ? repeated_char : ''
528
- full_number = col.when(0).then(0).else(
529
- ArelExtensions::Nodes::Concat.new([
530
- before,
531
- sign,
532
- middle,
533
- number,
534
- after
535
- ])
536
- )
537
- collector = visit ArelExtensions::Nodes::Concat.new([Arel::Nodes.build_quoted(o.prefix),full_number,Arel::Nodes.build_quoted(o.suffix)]), collector
538
- collector
539
- end
500
+
501
+
502
+ def visit_ArelExtensions_Nodes_FormattedNumber o, collector
503
+ visit o.left, collector
504
+ end
540
505
 
541
506
  remove_method(:visit_Arel_Nodes_LessThan) rescue nil
542
507
  def visit_Arel_Nodes_LessThan o, collector
@@ -545,6 +510,8 @@ module ArelExtensions
545
510
  visit o.right, collector
546
511
  end
547
512
 
513
+
514
+
548
515
  end
549
516
  end
550
517
  end
@@ -302,15 +302,24 @@ module ArelExtensions
302
302
  .must_be_like %{(CAST("users"."id" AS int) + 2)}
303
303
  end
304
304
 
305
+ it "should be possible to to have nil element in the function NIL" do
306
+ compile(@table[:id].in(nil))
307
+ .must_be_like %{ISNULL("users"."id")}
308
+ compile(@table[:id].in([nil]))
309
+ .must_be_like %{ISNULL("users"."id")}
310
+ compile(@table[:id].in([nil,1]))
311
+ .must_be_like %{(ISNULL("users"."id") OR "users"."id" = 1)}
312
+ compile(@table[:id].in([nil,1,2]))
313
+ .must_be_like %{(ISNULL("users"."id") OR "users"."id" IN (1, 2))}
314
+ compile(@table[:id].in(1))
315
+ .must_be_like %{"users"."id" IN (1)}
316
+ compile(@table[:id].in([1]))
317
+ .must_be_like %{"users"."id" IN (1)}
318
+ compile(@table[:id].in([1,2]))
319
+ .must_be_like %{"users"."id" IN (1, 2)}
305
320
 
306
- it "should be possible to specify a cool format on number" do
307
- #puts @price.format_number("$$ %+030.2e €€","fr_FR").to_sql
308
- compile(@price.format_number("$$ %+030.2e €€","fr_FR"))
309
- .must_be_like %{CONCAT('$$ ', CASE \"products\".\"price\" WHEN 0 THEN 0 ELSE CONCAT('', CASE WHEN \"products\".\"price\" < 0 THEN '-' ELSE '+' END, CASE WHEN (ABS(30) - (LENGTH(CONCAT(FORMAT(ABS(\"products\".\"price\") / POW(10, FLOOR(LOG10(ABS(\"products\".\"price\")))), 2, 'fr_FR'), 'e', FORMAT(FLOOR(LOG10(ABS(\"products\".\"price\"))), 0))) + LENGTH(CASE WHEN \"products\".\"price\" < 0 THEN '-' ELSE '+' END))) > 0 THEN REPEAT('0', (ABS(30) - (LENGTH(CONCAT(FORMAT(ABS(\"products\".\"price\") / POW(10, FLOOR(LOG10(ABS(\"products\".\"price\")))), 2, 'fr_FR'), 'e', FORMAT(FLOOR(LOG10(ABS(\"products\".\"price\"))), 0))) + LENGTH(CASE WHEN \"products\".\"price\" < 0 THEN '-' ELSE '+' END)))) ELSE '' END, CONCAT(FORMAT(ABS(\"products\".\"price\") / POW(10, FLOOR(LOG10(ABS(\"products\".\"price\")))), 2, 'fr_FR'), 'e', FORMAT(FLOOR(LOG10(ABS(\"products\".\"price\"))), 0)), '') END, ' €€')}
310
321
  end
311
-
312
-
313
-
322
+
314
323
  puts "AREL VERSION : " + Arel::VERSION.to_s
315
324
  end
316
325
  end
@@ -55,7 +55,7 @@ module ArelExtensions
55
55
  @lucas = User.where(:id => u.id)
56
56
  u = User.create :age => 15, :name => "Sophie", :created_at => d, :score => 20.16
57
57
  @sophie = User.where(:id => u.id)
58
- u = User.create :age => 20, :name => "Camille", :created_at => d, :score => -20.16
58
+ u = User.create :age => 20, :name => "Camille", :created_at => d, :score => -20.16, :comments => ''
59
59
  @camille = User.where(:id => u.id)
60
60
  u = User.create :age => 21, :name => "Arthur", :created_at => d, :score => 65.62, :comments => 'arrêté'
61
61
  @arthur = User.where(:id => u.id)
@@ -310,9 +310,14 @@ module ArelExtensions
310
310
  assert_equal 0, @myung.where(@name.blank).count
311
311
  assert_equal 1, @myung.where(@name.not_blank).count
312
312
  assert_equal 1, @myung.where(@comments.blank).count
313
+ assert_equal 0, @myung.where(@comments.not_blank).count
314
+ assert_equal 1, @sophie.where(@comments.blank).count
315
+ assert_equal 0, @sophie.where(@comments.not_blank).count
316
+ assert_equal 1, @camille.where(@comments.blank).count
317
+ assert_equal 0, @camille.where(@comments.not_blank).count
318
+
313
319
  assert_equal 0, @neg.where(@comments.blank).count
314
320
  assert_equal 1, @neg.where(@comments.not_blank).count
315
- assert_equal 0, @myung.where(@comments.not_blank).count
316
321
  assert_equal 'false', t(@myung, @name.blank.then('true', 'false'))
317
322
  assert_equal 'true', t(@myung, @name.not_blank.then('true', 'false'))
318
323
  assert_equal 'true', t(@myung, @comments.blank.then('true', 'false'))
@@ -437,9 +442,12 @@ module ArelExtensions
437
442
  assert_equal "Sophie2", t(@sophie, @name + 2)
438
443
  assert_equal "Sophie1997-06-15", t(@sophie, @name + d)
439
444
  assert_equal "Sophie15", t(@sophie, @name + @age)
440
- assert_equal "SophieSophie", t(@sophie, @name + @name)
445
+ assert_equal "SophieSophie", t(@sophie, @name + @name)
446
+ assert_equal "SophieSophieSophie", t(@sophie, @name + @name + @name)
447
+ assert_equal "SophieSophieSophie", t(@sophie, @name.concat(@name.concat(@name)))
448
+ assert_equal "SophieSophieSophie", t(@sophie, @name.concat(@name).concat(@name))
441
449
  #FIXME: should work as expected in Oracle
442
- assert_equal "Sophie2016-05-23", t(@sophie, @name + @created_at) unless @env_db == 'oracle'
450
+ assert_equal "Sophie2016-05-23", t(@sophie, @name + @created_at) unless @env_db == 'oracle'
443
451
  #concat Integer
444
452
  assert_equal 1, User.where((@age + 10).eq(33)).count
445
453
  assert_equal 1, User.where((@age + "1").eq(6)).count
@@ -496,20 +504,22 @@ module ArelExtensions
496
504
  assert_equal 4, User.find_by_sql(@ut.project(@score.when(20.16).then(1).else(0).as('score_bin')).to_sql).sum(&:score_bin)
497
505
  end
498
506
 
499
- def test_format_numbers
500
- skip "Not yet implemented" if @env_db != 'mysql'
507
+ def test_format_numbers
501
508
  #score of Arthur = 65.62
509
+ skip " Works with SQLite if the version used knows printf" if @env_db = $sqlite
502
510
  assert_equal "AZERTY65,62" , t(@arthur, @score.format_number("AZERTY%.2f","fr_FR"))
503
511
  assert_equal "65,62AZERTY" , t(@arthur, @score.format_number("%.2fAZERTY","fr_FR"))
504
- assert_equal "$ 65.62 €" , t(@arthur, @score.format_number("$ %.2f €","en_EN"))
512
+ assert_equal "$ 65.62 €" , t(@arthur, @score.format_number("$ %.2f €","en_US"))
505
513
  assert_equal "$ 0065,62 €" , t(@arthur, @score.format_number("$ %07.2f €","fr_FR"))
506
514
  assert_equal "$ 65,62 €" , t(@arthur, @score.format_number("$ %-07.2f €","fr_FR"))
507
515
  assert_equal "$ 65,62 €" , t(@arthur, @score.format_number("$ %-7.2f €","fr_FR"))
508
516
  assert_equal "$ 65,62 €" , t(@arthur, @score.format_number("$ % 7.2f €","fr_FR"))
517
+ assert_equal "$ 65,6 €" , t(@arthur, @score.format_number("$ % 7.1f €","fr_FR"))
509
518
  assert_equal "$ +65,62 €" , t(@arthur, @score.format_number("$ % +7.2f €","fr_FR"))
510
- assert_equal "$ +065,62 €" , t(@arthur, @score.format_number("$ %0+7.2f €","fr_FR"))
511
- assert_equal "$ 6,56e1 €" , t(@arthur, @score.format_number("$ %.2e €","fr_FR"))
512
- assert_equal "$ 6,56E1 €" , t(@arthur, @score.format_number("$ %.2E €","fr_FR"))
519
+ assert_equal "$ +065,62 €" , t(@arthur, @score.format_number("$ %0+7.2f €","fr_FR"))
520
+ assert_includes ["$ 6,56e1 €","$ 6,56e+01 €"], t(@arthur, @score.format_number("$ %.2e €","fr_FR"))
521
+ assert_includes ["$ 6,56E1 €","$ 6,56E+01 €"], t(@arthur, @score.format_number("$ %.2E €","fr_FR"))
522
+ assert_includes ["$ 6,562E1 €","$ 6,562E+01 €"], t(@arthur, @score.format_number("$ %.3E €","fr_FR"))
513
523
  assert_equal "Wrong Format" , t(@arthur, @score.format_number("$ %...234.6F €","fr_FR"))
514
524
  end
515
525
 
@@ -554,6 +564,65 @@ module ArelExtensions
554
564
  assert_equal "0", t(@arthur,ArelExtensions::Nodes::Case.new.when(@comments.smatches("Arrete")).then("1").else("0"))
555
565
  assert_equal "0", t(@arthur,ArelExtensions::Nodes::Case.new.when(@comments.smatches("Arrêté")).then("1").else("0"))
556
566
  end
567
+
568
+ def test_subquery_with_order
569
+ assert_equal 8, User.where(:name => User.select(:name).order(:name)).count
570
+ assert_equal 8, User.where(@ut[:name].in(@ut.project(@ut[:name]).order(@ut[:name]))).count
571
+ if !['mysql'].include?(@env_db) # MySql can't have limit in IN subquery
572
+ assert_equal 2, User.where(:name => User.select(:name).order(:name).limit(2)).count
573
+ #assert_equal 6, User.where(:name => User.select(:name).order(:name).offset(2)).count
574
+ end
575
+ end
576
+
577
+ def test_in_with_nil
578
+ assert_equal true , @myung.where(@age.in(1)).blank?
579
+ assert_equal false , @myung.where(@age.in(23)).blank?
580
+ assert_equal true , @myung.where(@age.in([1])).blank?
581
+ assert_equal true , @myung.where(@age.in([1,2])).blank?
582
+ assert_equal false , @myung.where(@age.in([1,23])).blank?
583
+ assert_equal true , @myung.where(@age.in(nil)).blank?
584
+ assert_equal true , @myung.where(@age.in([nil])).blank?
585
+ assert_equal true , @myung.where(@age.in([nil,1])).blank?
586
+ assert_equal false , @myung.where(@age.in([nil,23])).blank?
587
+ assert_equal true , @myung.where(@age.in([nil,1,2])).blank?
588
+ assert_equal false , @myung.where(@age.in([nil,1,23])).blank?
589
+ assert_equal true , @test.where(@age.in(1)).blank?
590
+ assert_equal true , @test.where(@age.in([1])).blank?
591
+ assert_equal true , @test.where(@age.in([1,2])).blank?
592
+ assert_equal false , @test.where(@age.in(nil)).blank?
593
+ assert_equal false , @test.where(@age.in([nil])).blank?
594
+ assert_equal false , @test.where(@age.in([nil,1])).blank?
595
+ assert_equal false , @test.where(@age.in([nil,1,2])).blank?
596
+ end
597
+
598
+ def test_is_not_null
599
+ assert_equal false , @myung.where(@age.is_not_null).blank?
600
+ assert_equal true , @test.where(@age.is_not_null).blank?
601
+ end
602
+
603
+ def test_not_in_with_nil
604
+ assert_equal false , @myung.where(@age.not_in(1)).blank?
605
+ assert_equal true , @myung.where(@age.not_in(23)).blank?
606
+ assert_equal false , @myung.where(@age.not_in([1])).blank?
607
+ assert_equal false , @myung.where(@age.not_in([1,2])).blank?
608
+ assert_equal true , @myung.where(@age.not_in([1,23])).blank?
609
+ assert_equal false , @myung.where(@age.not_in(nil)).blank?
610
+ assert_equal false , @myung.where(@age.not_in([nil])).blank?
611
+ assert_equal false , @myung.where(@age.not_in([nil,1])).blank?
612
+ assert_equal true , @myung.where(@age.not_in([nil,23])).blank?
613
+ assert_equal false , @myung.where(@age.not_in([nil,1,2])).blank?
614
+ assert_equal true , @myung.where(@age.not_in([nil,1,23])).blank?
615
+
616
+ #if the column is null, the entry will never be selected with not in (like every DBMS does)
617
+ #assert_equal false , @test.where(@age.not_in(1)).blank?
618
+ #assert_equal false , @test.where(@age.not_in([1])).blank?
619
+ #assert_equal false , @test.where(@age.not_in([1,2])).blank?
620
+ #assert_equal true , @test.where(@age.not_in(nil)).blank?
621
+ #assert_equal true , @test.where(@age.not_in([nil])).blank?
622
+ #assert_equal true , @test.where(@age.not_in([nil,1])).blank?
623
+ #assert_equal true , @test.where(@age.not_in([nil,1,2])).blank?
624
+ end
625
+
557
626
  end
558
627
  end
559
628
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: arel_extensions
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.6
4
+ version: 1.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yann Azoury
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2018-04-17 00:00:00.000000000 Z
13
+ date: 2018-06-08 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: arel