arel_extensions 1.0.8 → 1.1.0

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: 609562660b01b52ccd184d516350279bd561e0a6
4
- data.tar.gz: 8d27e16f757f07669329be3c7cf517fd97c3d29b
3
+ metadata.gz: b42393f60593054c04105afad4f4500dc826cd93
4
+ data.tar.gz: 383b4bc32619fe292c7f7ba31f867f1f49c8da80
5
5
  SHA512:
6
- metadata.gz: 321e17886db0f209b2d0fe76d9d46c5999285a1f751738457c4ce10a63c3a040dc069d02166f8d6355cba2113832a9545b5a0384c9d62a55194a5307e3d3ce9f
7
- data.tar.gz: e856b02e9d6ba606ad727780fc8d50cdc6af8fb33655647379ab9595d1f2997ef52aff6c5cd5c3c567f51015ea6753cfca2818344938532bb4ca8275947ec64f
6
+ metadata.gz: 7a724f2bd5c6d6ecedf567d44cc5d9be29f4270043b9d816b0090e19fce6380af13af3e5d4930f5252add2b4542d58ff7f6a21c202e1a5001665c7aa10b9aee3
7
+ data.tar.gz: 29f68d3d37bee531b23098ccace43491c42d781f719c451d1a7bbbaa4c0067b54abbf356940be7f955ad72984a07132e59e1bc4b8cea0f061e0abeb7099c416b
data/.travis.yml CHANGED
@@ -12,7 +12,7 @@ before_install:
12
12
  - sudo apt-get install -y sqlite3-pcre curl
13
13
  - .travis/sqlite3/extension-functions.sh
14
14
  - .travis/oracle/download.sh
15
- - .travis/oracle/install.sh
15
+ - sh -ex .travis/oracle/install.sh
16
16
  - .travis/setup_accounts.sh
17
17
  install:
18
18
  - gem install bundler
data/README.md CHANGED
@@ -72,6 +72,11 @@ With Arel Extensions:
72
72
  ```
73
73
 
74
74
  Other functions : ABS, RAND, ROUND, FLOOR, CEIL, FORMAT
75
+ Exemples :
76
+ ```ruby
77
+ t[:price].format_number("%07.2f €","fr_FR")
78
+ # equivalent to 'sprintf("%07.2f €",price)' plus locale management
79
+ ```
75
80
 
76
81
  ## String operations
77
82
 
@@ -12,6 +12,10 @@ Arel::Nodes::Binary.class_eval do
12
12
  include Arel::Expressions
13
13
  end
14
14
 
15
+ Arel::Nodes::Casted.class_eval do
16
+ include Arel::AliasPredication
17
+ end
18
+
15
19
  Arel::Nodes::Unary.class_eval do
16
20
  include Arel::Math
17
21
  include Arel::AliasPredication
@@ -21,6 +25,7 @@ end
21
25
  Arel::Nodes::Grouping.class_eval do
22
26
  include Arel::Math
23
27
  include Arel::AliasPredication
28
+ include Arel::OrderPredications
24
29
  include Arel::Expressions
25
30
  end
26
31
 
@@ -67,6 +72,10 @@ module Arel
67
72
  def self.rand
68
73
  ArelExtensions::Nodes::Rand.new
69
74
  end
75
+
76
+ def self.shorten s
77
+ Base64.urlsafe_encode64(Digest::MD5.new.digest(s)).tr('=', '').tr('-', '_')
78
+ end
70
79
  end
71
80
 
72
81
  Arel::Attributes::Attribute.class_eval do
@@ -15,51 +15,59 @@ module ArelExtensions
15
15
  #String and others (convert in string) allows you to concatenate 2 or more strings together.
16
16
  #Date and integer adds or subtracts a specified time interval from a date.
17
17
  def +(other)
18
- return ArelExtensions::Nodes::Concat.new [self, other] if self.is_a?(Arel::Nodes::Quoted)
19
- if self.is_a?(Arel::Nodes::Grouping)
18
+ case self
19
+ when Arel::Nodes::Quoted
20
+ return self.concat(other)
21
+ when Arel::Nodes::Grouping
20
22
  if self.expr.left.is_a?(String) || self.expr.right.is_a?(String)
21
- return ArelExtensions::Nodes::Concat.new [self, other]
23
+ return self.concat(other)
22
24
  else
23
25
  return Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new self, other)
24
26
  end
25
- end
26
- if self.is_a?(ArelExtensions::Nodes::Function)
27
+ when ArelExtensions::Nodes::Function
27
28
  return case self.return_type
28
29
  when :string, :text
29
- ArelExtensions::Nodes::Concat.new [self, other]
30
+ self.concat(other)
30
31
  when :integer, :decimal, :float, :number, :int
31
32
  Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new self, other)
32
33
  when :date, :datetime
33
34
  ArelExtensions::Nodes::DateAdd.new [self, other]
34
35
  else
35
- ArelExtensions::Nodes::Concat.new [self, other]
36
+ self.concat(other)
36
37
  end
37
- end
38
- if self.is_a?(Arel::Nodes::Function)
38
+ when Arel::Nodes::Function
39
39
  return Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new self, other)
40
- end
41
- col = Arel::Table.engine.connection.schema_cache.columns_hash(self.relation.table_name)[self.name.to_s]
42
- if (!col) #if the column doesn't exist in the database
43
- Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new(self, other))
44
40
  else
45
- arg = col.type
46
- if arg == :integer || (!arg)
47
- other = other.to_i if other.is_a?(String)
48
- Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new self, other)
49
- elsif arg == :decimal || arg == :float
50
- other = Arel.sql(other) if other.is_a?(String) # Arel should accept Float & BigDecimal!
51
- Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new self, other)
52
- elsif arg == :datetime || arg == :date
53
- ArelExtensions::Nodes::DateAdd.new [self, other]
54
- elsif arg == :string || arg == :text
55
- ArelExtensions::Nodes::Concat.new [self, other]
56
- end
41
+ col = Arel::Table.engine.connection.schema_cache.columns_hash(self.relation.table_name)[self.name.to_s]
42
+ if (!col) #if the column doesn't exist in the database
43
+ Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new(self, other))
44
+ else
45
+ arg = col.type
46
+ if arg == :integer || (!arg)
47
+ other = other.to_i if other.is_a?(String)
48
+ Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new self, other)
49
+ elsif arg == :decimal || arg == :float
50
+ other = Arel.sql(other) if other.is_a?(String) # Arel should accept Float & BigDecimal!
51
+ Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new self, other)
52
+ elsif arg == :datetime || arg == :date
53
+ ArelExtensions::Nodes::DateAdd.new [self, other]
54
+ elsif arg == :string || arg == :text
55
+ self.concat(other)
56
+ end
57
+ end
57
58
  end
58
59
  end
59
60
 
60
61
  #function returns the time between two dates
61
62
  #function returns the substraction between two ints
62
63
  def -(other)
64
+ if self.is_a?(Arel::Nodes::Grouping)
65
+ if self.expr.left.is_a?(Date) || self.expr.left.is_a?(DateTime)
66
+ return Arel::Nodes::Grouping.new(ArelExtensions::Nodes::DateSub.new [self, other])
67
+ else
68
+ return Arel::Nodes::Grouping.new(Arel::Nodes::Subtraction.new(self, other))
69
+ end
70
+ end
63
71
  return case self.return_type
64
72
  when :string, :text # ???
65
73
  Arel::Nodes::Grouping.new(Arel::Nodes::Subtraction.new(self, other)) # ??
@@ -59,7 +59,7 @@ module ArelExtensions
59
59
  # function returning a number at a specific format
60
60
  def format_number format_string, locale=nil
61
61
  begin
62
- sprintf(format_string,0) # this line is to get the right error message if the format_string is not correct
62
+ sprintf(format_string,0) # this line is to get the right error message if the format_string is not correct
63
63
  m = /^(.*)%([ #+\-0]*)([1-9][0-9]+|[1-9]?)[.]?([0-9]*)([a-zA-Z])(.*)$/.match(format_string)
64
64
  opts = {
65
65
  :prefix => m[1],
@@ -73,7 +73,7 @@ module ArelExtensions
73
73
  }
74
74
  # opts = {:locale => 'fr_FR', :type => "e"/"f"/"d", :prefix => "$ ", :suffix => " %", :flags => " +-#0", :width => 5, :precision => 6}
75
75
  ArelExtensions::Nodes::FormattedNumber.new [self,opts]
76
- rescue
76
+ rescue Exception => e
77
77
  Arel::Nodes.build_quoted('Wrong Format')
78
78
  end
79
79
  end
@@ -3,6 +3,7 @@ module ArelExtensions
3
3
  if Arel::VERSION.to_i < 7
4
4
  class Case < Arel::Nodes::Node
5
5
  include Arel::Expressions
6
+ include Arel::OrderPredications
6
7
  include ArelExtensions::Comparators
7
8
  include ArelExtensions::Predications
8
9
 
@@ -1,40 +1,53 @@
1
- module ArelExtensions
2
- module Nodes
3
- class Concat < Function
4
- RETURN_TYPE = :string
5
-
6
- def initialize expr
7
- tab = expr.map { |arg|
8
- convert_to_node(arg)
9
- }
10
- return super(tab)
11
- end
12
-
13
- #def +(other)
14
- # return ArelExtensions::Nodes::Concat.new(self.expressions + [other])
15
- #end
16
-
17
- def concat(other)
18
- return ArelExtensions::Nodes::Concat.new(self.expressions + [other])
19
- end
1
+ module ArelExtensions::Nodes
2
+ class Concat < Function
3
+ RETURN_TYPE = :string
20
4
 
5
+ def initialize expr
6
+ tab = expr.map { |arg|
7
+ # flatten nested concats.
8
+ node = convert_to_node(arg)
9
+ if node.is_a?(Concat)
10
+ node.expressions
11
+ else
12
+ node
13
+ end
14
+ }.flatten.reduce([]) { | res, b |
15
+ # concatenate successive literal strings.
16
+ if b.is_a?(Arel::Nodes::Quoted) && b.expr == ""
17
+ res
18
+ elsif res.last && res.last.is_a?(Arel::Nodes::Quoted) && b.is_a?(Arel::Nodes::Quoted)
19
+ res[-1] = Arel::Nodes.build_quoted(res.last.expr + b.expr)
20
+ else
21
+ res << b
22
+ end
23
+ res
24
+ }
25
+ super(tab)
21
26
  end
22
27
 
23
- class GroupConcat < Function
24
- RETURN_TYPE = :string
28
+ #def +(other)
29
+ # Concat.new(self.expressions + [other])
30
+ #end
25
31
 
26
- def initialize expr
27
- tab = expr.map { |arg|
28
- convert_to_node(arg)
29
- }
30
- return super(tab)
31
- end
32
+ def concat(other)
33
+ Concat.new(self.expressions + [other])
34
+ end
35
+
36
+ end
32
37
 
33
- #def +(other)
34
- # return ArelExtensions::Nodes::Concat.new([self, other])
35
- #end
38
+ class GroupConcat < Function
39
+ RETURN_TYPE = :string
36
40
 
41
+ def initialize expr
42
+ tab = expr.map { |arg|
43
+ convert_to_node(arg)
44
+ }
45
+ super(tab)
37
46
  end
38
47
 
48
+ #def +(other)
49
+ # return Concat.new([self, other])
50
+ #end
51
+
39
52
  end
40
53
  end
@@ -4,7 +4,8 @@ module ArelExtensions
4
4
  module Nodes
5
5
  class Function < Arel::Nodes::Function
6
6
  include Arel::Math
7
- include Arel::Expressions
7
+ include Arel::Expressions
8
+ include Arel::OrderPredications
8
9
  include ArelExtensions::Predications
9
10
 
10
11
  RETURN_TYPE = :string # by default...
@@ -108,7 +108,12 @@ module ArelExtensions
108
108
  end
109
109
 
110
110
  def concat other
111
- ArelExtensions::Nodes::Concat.new [self, other]
111
+ res = ArelExtensions::Nodes::Concat.new [self, other]
112
+ if res.expressions.length == 1
113
+ res.expressions.first
114
+ else
115
+ res
116
+ end
112
117
  end
113
118
 
114
119
  def group_concat sep = nil
@@ -1,3 +1,3 @@
1
1
  module ArelExtensions
2
- VERSION = "1.0.8".freeze
2
+ VERSION = "1.1.0".freeze
3
3
  end
@@ -65,29 +65,6 @@ module ArelExtensions
65
65
  collector
66
66
  end
67
67
 
68
- # Deprecated
69
- def visit_ArelExtensions_Nodes_ConcatOld o, collector
70
- arg = o.left.relation.engine.columns.find{|c| c.name == o.left.name.to_s}.type
71
- if(o.right.is_a?(Arel::Attributes::Attribute))
72
- collector = visit o.left, collector
73
- collector << ' + '
74
- collector = visit o.right, collector
75
- collector
76
- elsif ( arg == :date || arg == :datetime)
77
- collector << "DATEADD(day"
78
- collector << Arel::Visitors::MSSQL::COMMA
79
- collector = visit o.right, collector
80
- collector << Arel::Visitors::MSSQL::COMMA
81
- collector = visit o.left, collector
82
- collector
83
- else
84
- collector = visit o.left, collector
85
- collector << " + '"
86
- collector = visit o.right, collector
87
- collector
88
- end
89
- end
90
-
91
68
  def visit_ArelExtensions_Nodes_Concat o, collector
92
69
  collector << "CONCAT("
93
70
  o.expressions.each_with_index { |arg, i|
@@ -394,21 +394,10 @@ module ArelExtensions
394
394
  # add primary_key if not present, avoid zip
395
395
  if Arel::VERSION.to_i < 7
396
396
  def visit_ArelExtensions_InsertManager_BulkValues o, collector
397
- raise ArgumentError, "missing columns" if o.cols.empty?
398
- table = collector.value.sub(/\AINSERT INTO/, '')
399
- into = " INTO#{table}"
400
- collector = Arel::Collectors::SQLString.new
401
- collector << "INSERT ALL\n"
402
- pk_name = @connection.primary_key(o.cols.first.relation.name)
403
- if pk_name
404
- pk_missing = !o.cols.detect{|c| c.name == pk_name }
405
- into.sub!(/\(/, %Q[("#{pk_name.upcase}", ]) if pk_missing
406
- else
407
- pk_missing = false
408
- end
397
+ collector << "("
409
398
  o.left.each_with_index do |row, idx| # values
410
- collector << "#{into} VALUES ("
411
- collector << "NULL, " if pk_missing # expects to have a trigger to set the value before insert
399
+ collector << " UNION ALL " if idx != 0
400
+ collector << "(SELECT "
412
401
  v = Arel::Nodes::Values.new(row, o.cols)
413
402
  len = v.expressions.length - 1
414
403
  v.expressions.each_with_index { |value, i|
@@ -421,19 +410,17 @@ module ArelExtensions
421
410
  end
422
411
  collector << Arel::Visitors::Oracle::COMMA unless i == len
423
412
  }
424
- collector << ')'
413
+ collector << ' FROM DUAL)'
425
414
  end
426
- collector << ' SELECT 1 FROM dual'
415
+ collector << ")"
427
416
  collector
428
417
  end
429
418
  else
430
419
  def visit_ArelExtensions_InsertManager_BulkValues o, collector
431
- table = collector.value.sub(/\AINSERT INTO/, '')
432
- into = " INTO#{table}"
433
- collector = Arel::Collectors::SQLString.new
434
- collector << "INSERT ALL\n"
420
+ collector << "("
435
421
  o.left.each_with_index do |row, idx|
436
- collector << "#{into} VALUES ("
422
+ collector << " UNION ALL " if idx != 0
423
+ collector << "(SELECT "
437
424
  v = Arel::Nodes::Values.new(row, o.cols)
438
425
  len = v.expressions.length - 1
439
426
  v.expressions.zip(v.columns).each_with_index { |(value, attr), i|
@@ -445,9 +432,9 @@ module ArelExtensions
445
432
  end
446
433
  collector << Arel::Visitors::Oracle::COMMA unless i == len
447
434
  }
448
- collector << ')'
435
+ collector << ' FROM DUAL)'
449
436
  end
450
- collector << ' SELECT 1 FROM dual'
437
+ collector << ")"
451
438
  collector
452
439
  end
453
440
  end
@@ -455,18 +442,17 @@ module ArelExtensions
455
442
 
456
443
  def get_time_converted element
457
444
  if element.is_a?(Time)
458
- res = ArelExtensions::Nodes::Format.new [element, '%H:%M:%S']
445
+ ArelExtensions::Nodes::Format.new [element, '%H:%M:%S']
459
446
  elsif element.is_a?(Arel::Attributes::Attribute)
460
447
  col = Arel::Table.engine.connection.schema_cache.columns_hash(element.relation.table_name)[element.name.to_s]
461
448
  if col && (col.type == :time)
462
- res = ArelExtensions::Nodes::Format.new [element, '%H:%M:%S']
449
+ ArelExtensions::Nodes::Format.new [element, '%H:%M:%S']
463
450
  else
464
- res = element
451
+ element
465
452
  end
466
453
  else
467
- res = element
454
+ element
468
455
  end
469
- return res
470
456
  end
471
457
 
472
458
 
@@ -511,10 +497,30 @@ module ArelExtensions
511
497
  end
512
498
  old_visit_Arel_Nodes_SelectStatement(o,collector)
513
499
  end
500
+
501
+ alias_method :old_visit_Arel_Nodes_TableAlias, :visit_Arel_Nodes_TableAlias
502
+ def visit_Arel_Nodes_TableAlias o, collector
503
+ if o.name.length > 30
504
+ o = Arel::Table.new(o.table_name).alias(Base64.urlsafe_encode64(Digest::MD5.new.digest(o.name)).tr('=', '').tr('-', '_'))
505
+ end
506
+ old_visit_Arel_Nodes_TableAlias(o,collector)
507
+ end
508
+
509
+
510
+ alias_method :old_visit_Arel_Attributes_Attribute, :visit_Arel_Attributes_Attribute
511
+ def visit_Arel_Attributes_Attribute o, collector
512
+ join_name = o.relation.table_alias || o.relation.name
513
+ if join_name.length > 30
514
+ join_name = Arel.shorten(join_name)
515
+ end
516
+ collector << "#{quote_table_name join_name}.#{quote_column_name o.name}"
517
+ end
518
+
514
519
 
515
520
  def visit_ArelExtensions_Nodes_FormattedNumber o, collector
516
521
  col = o.left
517
- comma = Arel::Visitors::Oracle::NUMBER_COMMA_MAPPING[o.locale] || '.,'
522
+ comma = Arel::Visitors::Oracle::NUMBER_COMMA_MAPPING[o.locale] || '.,'
523
+ comma_in_format = o.precision == 0 ? '' : 'D'
518
524
  options = Arel::Nodes.build_quoted("NLS_NUMERIC_CHARACTERS = '"+comma+"'")
519
525
  nines_after = (1..o.precision).map{'9'}.join('')
520
526
  nines_before = (1..16).map{'9'}.join('')
@@ -528,7 +534,7 @@ module ArelExtensions
528
534
  if o.scientific_notation
529
535
  number = Arel::Nodes::NamedFunction.new('TO_CHAR',[
530
536
  Arel::Nodes.build_quoted(col.abs),
531
- Arel::Nodes.build_quoted('FM'+nines_before+'D'+nines_after+'EEEE'),
537
+ Arel::Nodes.build_quoted('FM'+nines_before+comma_in_format+nines_after+'EEEE'),
532
538
  options
533
539
  ])
534
540
  if o.type == 'e'
@@ -537,7 +543,7 @@ module ArelExtensions
537
543
  else
538
544
  number = Arel::Nodes::NamedFunction.new('TO_CHAR',[
539
545
  Arel::Nodes.build_quoted(col.abs),
540
- Arel::Nodes.build_quoted('FM'+nines_before+'D'+nines_after),
546
+ Arel::Nodes.build_quoted('FM'+nines_before+comma_in_format+nines_after),
541
547
  options
542
548
  ])
543
549
  end
@@ -566,6 +572,8 @@ module ArelExtensions
566
572
  end
567
573
 
568
574
 
575
+
576
+
569
577
  end
570
578
  end
571
579
  end
@@ -279,9 +279,9 @@ module ArelExtensions
279
279
  collector
280
280
  end
281
281
 
282
- def visit_ArelExtensions_Nodes_FormattedNumber o, collector
282
+ def visit_ArelExtensions_Nodes_FormattedNumber o, collector
283
283
  col = o.left
284
- comma = Arel::Visitors::PostgreSQL::NUMBER_COMMA_MAPPING[o.locale] || '.'
284
+ comma = o.precision == 0 ? '' : (Arel::Visitors::PostgreSQL::NUMBER_COMMA_MAPPING[o.locale] || '.')
285
285
  nines_after = (1..o.precision).map{'9'}.join('')
286
286
  nines_before = (1..16).map{'9'}.join('')
287
287
  sign = ArelExtensions::Nodes::Case.new.when(col<0).
@@ -327,8 +327,8 @@ module ArelExtensions
327
327
  after
328
328
  ])
329
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
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
332
  end
333
333
 
334
334
 
@@ -341,6 +341,24 @@ module ArelExtensions
341
341
  old_visit_Arel_Nodes_SelectStatement(o,collector)
342
342
  end
343
343
 
344
+ alias_method :old_visit_Arel_Nodes_TableAlias, :visit_Arel_Nodes_TableAlias
345
+ def visit_Arel_Nodes_TableAlias o, collector
346
+ if o.name.length > 63
347
+ o = Arel::Table.new(o.table_name).alias(Arel.shorten(o.name))
348
+ end
349
+ old_visit_Arel_Nodes_TableAlias(o,collector)
350
+ end
351
+
352
+ alias_method :old_visit_Arel_Attributes_Attribute, :visit_Arel_Attributes_Attribute
353
+ def visit_Arel_Attributes_Attribute o, collector
354
+ join_name = o.relation.table_alias || o.relation.name
355
+ if join_name.length > 63
356
+ join_name = Arel.shorten(join_name)
357
+ end
358
+ collector << "#{quote_table_name join_name}.#{quote_column_name o.name}"
359
+ end
360
+
361
+
344
362
  end
345
363
  end
346
364
  end
@@ -7,10 +7,10 @@ module ArelExtensions
7
7
  @conn = FakeRecord::Base.new
8
8
  @visitor = Arel::Visitors::Oracle.new @conn.connection
9
9
  @table = Arel::Table.new(:users)
10
- @cols = ['id', 'name', 'comments', 'created_at']
10
+ @cols = ['name', 'comments', 'created_at']
11
11
  @data = [
12
- [23, 'nom1', "sdfdsfdsfsdf", '2016-01-01'],
13
- [25, 'nom2', "sdfdsfdsfsdf", '2016-01-01']
12
+ ['nom1', "sdfdsfdsfsdf", '2016-01-01'],
13
+ ['nom2', "sdfdsfdsfsdf", '2016-01-01']
14
14
  ]
15
15
  end
16
16
 
@@ -26,9 +26,9 @@ module ArelExtensions
26
26
  insert_manager = Arel::VERSION.to_i > 6 ? Arel::InsertManager.new().into(@table) : Arel::InsertManager.new(@conn).into(@table)
27
27
  insert_manager.bulk_insert(@cols, @data)
28
28
  sql = compile(insert_manager.ast)
29
- sql.must_be_like %Q[INSERT ALL INTO "users" ("id", "name", "comments", "created_at") VALUES (23, 'nom1', 'sdfdsfdsfsdf', '2016-01-01') INTO "users" ("id", "name", "comments", "created_at") VALUES (25, 'nom2', 'sdfdsfdsfsdf', '2016-01-01') SELECT 1 FROM dual]
29
+ sql.must_be_like %Q[INSERT INTO "users" ("name", "comments", "created_at") ((SELECT 'nom1', 'sdfdsfdsfsdf', '2016-01-01' FROM DUAL) UNION ALL (SELECT 'nom2', 'sdfdsfdsfsdf', '2016-01-01' FROM DUAL))]
30
30
  end
31
31
 
32
32
  end
33
33
  end
34
- end
34
+ end
@@ -63,7 +63,6 @@ module ArelExtensions
63
63
  it "should accept functions on strings" do
64
64
  c = @table[:name]
65
65
  compile(c + 'test').must_be_like %{CONCAT(\"users\".\"name\", 'test')}
66
- compile(c + 'test' + ' chain').must_be_like %{CONCAT(CONCAT(\"users\".\"name\", 'test'), ' chain')}
67
66
  compile(c.length).must_be_like %{LENGTH("users"."name")}
68
67
  #puts (c.length.round + 42).inspect
69
68
  compile(c.length.round + 42).must_be_like %{(ROUND(LENGTH("users"."name")) + 42)}
@@ -82,6 +81,13 @@ module ArelExtensions
82
81
  compile(c + '0').must_be_like %{CONCAT("users"."name", '0')}
83
82
  compile(c.substring(1) + '0').must_be_like %{CONCAT(SUBSTRING("users"."name", 1), '0')}
84
83
  compile(c.substring(1) + c.substring(2)).must_be_like %{CONCAT(SUBSTRING("users"."name", 1), SUBSTRING("users"."name", 2))}
84
+ compile(c.concat(c).concat(c)).must_be_like %{CONCAT("users"."name", "users"."name", "users"."name")}
85
+ compile(c + c + c).must_be_like %{CONCAT("users"."name", "users"."name", "users"."name")}
86
+
87
+ # some optimization on concat
88
+ compile(c + 'test' + ' chain').must_be_like %{CONCAT(\"users\".\"name\", 'test chain')}
89
+ compile(Arel::Nodes.build_quoted('test') + ' chain').must_be_like %{'test chain'}
90
+ compile(c + '' + c).must_be_like %{CONCAT(\"users\".\"name\", \"users\".\"name\")}
85
91
  end
86
92
 
87
93
  # Comparators
@@ -302,7 +308,7 @@ module ArelExtensions
302
308
  .must_be_like %{(CAST("users"."id" AS int) + 2)}
303
309
  end
304
310
 
305
- it "should be possible to to have nil element in the function NIL" do
311
+ it "should be possible to have nil element in the function NIL" do
306
312
  compile(@table[:id].in(nil))
307
313
  .must_be_like %{ISNULL("users"."id")}
308
314
  compile(@table[:id].in([nil]))
@@ -319,6 +325,30 @@ module ArelExtensions
319
325
  .must_be_like %{"users"."id" IN (1, 2)}
320
326
 
321
327
  end
328
+
329
+ it "should be possible to add and substract as much as we want" do
330
+ c = @table[:name]
331
+ compile(c.locate('test')+1)
332
+ .must_be_like %{(LOCATE('test', "users"."name") + 1)}
333
+ compile(c.locate('test')-1)
334
+ .must_be_like %{(LOCATE('test', "users"."name") - 1)}
335
+ compile(c.locate('test')+c.locate('test'))
336
+ .must_be_like %{(LOCATE('test', "users"."name") + LOCATE('test', "users"."name"))}
337
+ compile(c.locate('test')+1+c.locate('test')-1 + 1)
338
+ .must_be_like %{((((LOCATE('test', "users"."name") + 1) + LOCATE('test', "users"."name")) - 1) + 1)}
339
+ end
340
+
341
+ it "should be possible to desc and asc on functions" do
342
+ c = @table[:name]
343
+ compile(c.asc)
344
+ .must_be_like %{"users"."name" ASC}
345
+ compile(c.substring(2).asc)
346
+ .must_be_like %{SUBSTRING("users"."name", 2) ASC}
347
+ compile(c.substring(2).desc)
348
+ .must_be_like %{SUBSTRING("users"."name", 2) DESC}
349
+ compile((c.locate('test')+1).asc)
350
+ .must_be_like %{(LOCATE('test', "users"."name") + 1) ASC}
351
+ end
322
352
 
323
353
  puts "AREL VERSION : " + Arel::VERSION.to_s
324
354
  end
@@ -507,9 +507,12 @@ module ArelExtensions
507
507
  def test_format_numbers
508
508
  #score of Arthur = 65.62
509
509
  skip " Works with SQLite if the version used knows printf" if @env_db = $sqlite
510
+
511
+ assert_equal "Wrong Format" , t(@arthur, @score.format_number("$ %...234.6F €","fr_FR"))
510
512
  assert_equal "AZERTY65,62" , t(@arthur, @score.format_number("AZERTY%.2f","fr_FR"))
511
513
  assert_equal "65,62AZERTY" , t(@arthur, @score.format_number("%.2fAZERTY","fr_FR"))
512
514
  assert_equal "$ 65.62 €" , t(@arthur, @score.format_number("$ %.2f €","en_US"))
515
+ assert_equal "$ 66 €" , t(@arthur, @score.format_number("$ %.0f €","en_US"))
513
516
  assert_equal "$ 0065,62 €" , t(@arthur, @score.format_number("$ %07.2f €","fr_FR"))
514
517
  assert_equal "$ 65,62 €" , t(@arthur, @score.format_number("$ %-07.2f €","fr_FR"))
515
518
  assert_equal "$ 65,62 €" , t(@arthur, @score.format_number("$ %-7.2f €","fr_FR"))
@@ -519,8 +522,7 @@ module ArelExtensions
519
522
  assert_equal "$ +065,62 €" , t(@arthur, @score.format_number("$ %0+7.2f €","fr_FR"))
520
523
  assert_includes ["$ 6,56e1 €","$ 6,56e+01 €"], t(@arthur, @score.format_number("$ %.2e €","fr_FR"))
521
524
  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"))
523
- assert_equal "Wrong Format" , t(@arthur, @score.format_number("$ %...234.6F €","fr_FR"))
525
+ assert_includes ["$ 6,562E1 €","$ 6,562E+01 €"], t(@arthur, @score.format_number("$ %.3E €","fr_FR"))
524
526
  end
525
527
 
526
528
  def test_accent_insensitive
@@ -563,6 +565,7 @@ module ArelExtensions
563
565
  assert_equal "0", t(@arthur,ArelExtensions::Nodes::Case.new.when(@comments.smatches("arretez")).then("1").else("0"))
564
566
  assert_equal "0", t(@arthur,ArelExtensions::Nodes::Case.new.when(@comments.smatches("Arrete")).then("1").else("0"))
565
567
  assert_equal "0", t(@arthur,ArelExtensions::Nodes::Case.new.when(@comments.smatches("Arrêté")).then("1").else("0"))
568
+
566
569
  end
567
570
 
568
571
  def test_subquery_with_order
@@ -633,6 +636,17 @@ module ArelExtensions
633
636
  #assert_equal true , @test.where(@age.not_in([nil,1,2])).blank?
634
637
  end
635
638
 
639
+ def test_alias_shortened
640
+ if ['postgresql','oracle'].include?(@env_db)
641
+ new_alias = Arel.shorten('azerty' * 15)
642
+ at = User.arel_table.alias('azerty' * 15)
643
+ assert_equal "\"user_tests\" \"#{new_alias}\"".downcase, User.arel_table.alias('azerty' * 15).to_sql.downcase
644
+ assert_equal '"user_tests" "u"'.downcase, User.arel_table.alias('u').to_sql.downcase
645
+ assert_equal %Q[SELECT "#{new_alias}"."id" FROM "user_tests" "#{new_alias}"].downcase,
646
+ User.select(at[:id]).from(at).to_sql.downcase
647
+ end
648
+ end
649
+
636
650
  end
637
651
  end
638
652
  end
@@ -81,4 +81,4 @@ END;])
81
81
 
82
82
  end
83
83
  end
84
- end
84
+ 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.8
4
+ version: 1.1.0
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-06-21 00:00:00.000000000 Z
13
+ date: 2018-08-08 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: arel
@@ -208,26 +208,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
208
208
  version: '0'
209
209
  requirements: []
210
210
  rubyforge_project:
211
- rubygems_version: 2.0.14
211
+ rubygems_version: 2.5.2.1
212
212
  signing_key:
213
213
  specification_version: 4
214
214
  summary: Extending Arel
215
- test_files:
216
- - test/database.yml
217
- - test/helper.rb
218
- - test/real_db_test.rb
219
- - test/support/alter_system_user_password.sql
220
- - test/support/create_oracle_enhanced_users.sql
221
- - test/support/fake_record.rb
222
- - test/test_comparators.rb
223
- - test/visitors/test_bulk_insert_oracle.rb
224
- - test/visitors/test_bulk_insert_sqlite.rb
225
- - test/visitors/test_bulk_insert_to_sql.rb
226
- - test/visitors/test_oracle.rb
227
- - test/visitors/test_to_sql.rb
228
- - test/with_ar/all_agnostic_test.rb
229
- - test/with_ar/insert_agnostic_test.rb
230
- - test/with_ar/test_bulk_sqlite.rb
231
- - test/with_ar/test_math_sqlite.rb
232
- - test/with_ar/test_string_mysql.rb
233
- - test/with_ar/test_string_sqlite.rb
215
+ test_files: []