arel_extensions 1.0.8 → 1.1.0

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: 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: []