arel_extensions 1.0.6 → 1.0.7

Sign up to get free protection for your applications and to get access to all the features.
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