arel_extensions 1.1.3 → 1.1.4

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: 68ee590a18210a1a5692c9ba7c4caf3c47a11f4e
4
- data.tar.gz: a78126c03105531c7e0c25cee082c34c18eb7fdd
3
+ metadata.gz: c605fff28ecad52dbb7519c17ea982844ecad5fc
4
+ data.tar.gz: ad640c79367460a9b06ce89bffd6ef587ec1f30d
5
5
  SHA512:
6
- metadata.gz: fd66f0377b2c25fe6e18c3ee250e1fc55e699d6a423e43c65fee38749752955e1e3f33ca58f31200d9ed26fcc818da44c2d1f02c7ee11e05c9a7756f5a560f1f
7
- data.tar.gz: d7b6f047370c4cc2af72b632adb10678ed70ba9ef2e58e6a1630d1672ed8a3dc562f093a2787cd15611454a92c2be1f94f98b74f877e48bdf49420107129f7a1
6
+ metadata.gz: f113a241aec0ab76d42be635e1db174f82c02e2f8bdb0f5320a02b92b84b9d237f8ac1c2da27411a8ced881bdd752cf61f7d60224eca2e62683befde0f90ec74
7
+ data.tar.gz: a60110f2acf2d1b46b2a576d2800fe1718b923c307e1691e960153c6cf72db8cce65e932fc5bac397af413b0dd1a8499a067522ad00080e76a34094837ec2a43
data/.travis.yml CHANGED
@@ -15,7 +15,7 @@ before_install:
15
15
  # - sh -ex .travis/oracle/install.sh
16
16
  # - .travis/setup_accounts.sh
17
17
  install:
18
- - gem install bundler
18
+ - gem install bundler -v 1.17.3
19
19
  - bundle install
20
20
  gemfile:
21
21
  - gemfiles/rails4.gemfile
data/Gemfile CHANGED
@@ -5,15 +5,15 @@ gemspec
5
5
  group :development, :test do
6
6
  gem "sqlite3", :platforms => [:mri, :mswin, :x64_mingw, :mingw]
7
7
  gem "mysql2", '0.4.10', :platforms => [:mri, :mswin, :x64_mingw, :mingw]
8
- gem "pg", :platforms => [:mri, :mingw, :x64_mingw, :mswin]
8
+ gem "pg", '< 1', :platforms => [:mri, :mingw, :x64_mingw, :mswin]
9
9
 
10
10
  gem "jdbc-sqlite3", :platforms => :jruby
11
11
  gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
12
12
  gem "activerecord-jdbcmysql-adapter", :platforms => :jruby
13
13
  gem "activerecord-jdbcpostgresql-adapter", :platforms => :jruby
14
14
 
15
- gem "tiny_tds", '~> 1.3.0' ,:require => false, :platforms => [:mingw, :x64_mingw, :mswin]
16
- gem "activerecord-sqlserver-adapter", '~> 4.2.0', :platforms => [:mingw, :x64_mingw, :mswin]
15
+ gem "tiny_tds", '~> 1.3.0' ,:require => false, :platforms => [:mri,:mingw, :x64_mingw, :mswin]
16
+ gem "activerecord-sqlserver-adapter", '~> 4.2.0', :platforms => [:mri, :mingw, :x64_mingw, :mswin]
17
17
 
18
18
  gem 'ruby-oci8', :platforms => [:mri, :mswin, :x64_mingw, :mingw]
19
19
  gem 'activerecord-oracle_enhanced-adapter', '~> 1.6.0'
@@ -24,7 +24,7 @@ module ArelExtensions
24
24
  else
25
25
  return Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new self, other)
26
26
  end
27
- when ArelExtensions::Nodes::Function
27
+ when ArelExtensions::Nodes::Function,ArelExtensions::Nodes::Case
28
28
  return case self.return_type
29
29
  when :string, :text
30
30
  self.concat(other)
@@ -72,7 +72,7 @@ module ArelExtensions
72
72
  else
73
73
  Arel::Nodes::Grouping.new(Arel::Nodes::Subtraction.new(self, other))
74
74
  end
75
- when ArelExtensions::Nodes::Function
75
+ when ArelExtensions::Nodes::Function, ArelExtensions::Nodes::Case
76
76
  case self.return_type
77
77
  when :string, :text # ???
78
78
  Arel::Nodes::Grouping.new(Arel::Nodes::Subtraction.new(self, other)) # ??
@@ -4,6 +4,7 @@ module ArelExtensions
4
4
  class Case < Arel::Nodes::Node
5
5
  include Arel::Expressions
6
6
  include Arel::OrderPredications
7
+ include ArelExtensions::Math
7
8
  include ArelExtensions::Comparators
8
9
  include ArelExtensions::Predications
9
10
  include ArelExtensions::MathFunctions
@@ -17,19 +18,47 @@ module ArelExtensions
17
18
  @conditions = []
18
19
  @default = default
19
20
  end
21
+
22
+ def return_type
23
+ obj = if @conditions.length > 0
24
+ @conditions.last.right
25
+ elsif @default
26
+ @default.expr
27
+ else
28
+ nil
29
+ end
30
+ if obj.respond_to?(:return_type)
31
+ obj.return_type
32
+ else
33
+ case obj
34
+ when Integer, Float
35
+ :number
36
+ when Date, DateTime,Time
37
+ :datetime
38
+ when Arel::Attributes::Attribute
39
+ begin
40
+ Arel::Table.engine.connection.schema_cache.columns_hash(obj.relation.table_name)[obj.name.to_s].cast_type.type
41
+ rescue Exception
42
+ :string
43
+ end
44
+ else
45
+ :string
46
+ end
47
+ end
48
+ end
20
49
 
21
50
  def when condition, expression = nil
22
- @conditions << When.new(Arel::Nodes.build_quoted(condition), expression)
51
+ @conditions << When.new(condition, expression)
23
52
  self
24
53
  end
25
54
 
26
55
  def then expression
27
- @conditions.last.right = Arel::Nodes.build_quoted(expression)
56
+ @conditions.last.right = expression
28
57
  self
29
58
  end
30
59
 
31
60
  def else expression
32
- @default = Else.new Arel::Nodes.build_quoted(expression)
61
+ @default = Else.new expression
33
62
  self
34
63
  end
35
64
 
@@ -67,8 +96,13 @@ module ArelExtensions
67
96
 
68
97
  class Case < Arel::Nodes::Case
69
98
  include Arel::Expressions
99
+ include Arel::OrderPredications
100
+ include ArelExtensions::Math
70
101
  include ArelExtensions::Comparators
71
102
  include ArelExtensions::Predications
103
+ include ArelExtensions::MathFunctions
104
+ include ArelExtensions::StringFunctions
105
+ include ArelExtensions::NullFunctions
72
106
 
73
107
  end
74
108
 
@@ -0,0 +1,11 @@
1
+ module ArelExtensions
2
+ module Nodes
3
+ class LevenshteinDistance < Function
4
+ RETURN_TYPE = :number
5
+
6
+ def initialize expr
7
+ super [convert_to_node(expr.first), Arel::Nodes.build_quoted(expr[1])]
8
+ end
9
+ end
10
+ end
11
+ end
@@ -1,8 +1,8 @@
1
1
  module ArelExtensions
2
2
  module Predications
3
3
  if Arel::VERSION.to_i < 7
4
- def when right
5
- ArelExtensions::Nodes::Case.new(self).when(right)
4
+ def when right, expression=nil
5
+ ArelExtensions::Nodes::Case.new(self).when(right,expression)
6
6
  end
7
7
  end
8
8
 
@@ -147,6 +147,10 @@ module ArelExtensions
147
147
  def repeat other = 1
148
148
  ArelExtensions::Nodes::Repeat.new [self, other]
149
149
  end
150
+
151
+ def levenshtein_distance other
152
+ ArelExtensions::Nodes::LevenshteinDistance.new [self, other]
153
+ end
150
154
 
151
155
  end
152
156
  end
@@ -1,3 +1,3 @@
1
1
  module ArelExtensions
2
- VERSION = "1.1.3".freeze
2
+ VERSION = "1.1.4".freeze
3
3
  end
@@ -1,6 +1,7 @@
1
1
  require 'arel_extensions/visitors/to_sql'
2
2
  require 'arel_extensions/visitors/mysql'
3
3
  require 'arel_extensions/visitors/oracle'
4
+ require 'arel_extensions/visitors/oracle12'
4
5
  require 'arel_extensions/visitors/postgresql'
5
6
  require 'arel_extensions/visitors/sqlite'
6
7
  require 'arel_extensions/visitors/mssql'
@@ -461,15 +461,14 @@ module ArelExtensions
461
461
  before = (!o.flags.include?('0'))&&(!o.flags.include?('-')) ? repeated_char : ''
462
462
  middle = (o.flags.include?('0'))&&(!o.flags.include?('-')) ? repeated_char : ''
463
463
  after = o.flags.include?('-') ? repeated_char : ''
464
- full_number = col.when(0).then('0').else(
464
+ full_number =
465
465
  ArelExtensions::Nodes::Concat.new([
466
466
  before,
467
467
  sign,
468
468
  middle,
469
469
  number,
470
470
  after
471
- ])
472
- )
471
+ ])
473
472
  collector = visit ArelExtensions::Nodes::Concat.new([Arel::Nodes.build_quoted(o.prefix),full_number,Arel::Nodes.build_quoted(o.suffix)]), collector
474
473
  collector
475
474
  end
@@ -1,6 +1,8 @@
1
+ #require 'oracle_visitor'
1
2
  module ArelExtensions
2
3
  module Visitors
3
- Arel::Visitors::Oracle.class_eval do
4
+ Arel::Visitors::Oracle.class_eval do
5
+
4
6
  SPECIAL_CHARS = {"\t" => 'CHR(9)', "\n" => 'CHR(10)', "\r" => 'CHR(13)'}
5
7
  Arel::Visitors::Oracle::DATE_MAPPING = {'d' => 'DAY', 'm' => 'MONTH', 'w' => 'IW', 'y' => 'YEAR', 'wd' => 'D', 'h' => 'HOUR', 'mn' => 'MINUTE', 's' => 'SECOND'}
6
8
  Arel::Visitors::Oracle::DATE_FORMAT_DIRECTIVES = {
@@ -589,7 +591,6 @@ module ArelExtensions
589
591
  end
590
592
 
591
593
 
592
-
593
594
  end
594
595
  end
595
596
  end
@@ -0,0 +1,68 @@
1
+ module ArelExtensions
2
+ module Visitors
3
+ if Arel::VERSION.to_i < 7
4
+ class Arel::Visitors::Oracle12 < Arel::Visitors::Oracle
5
+
6
+
7
+ def visit_Arel_Nodes_SelectStatement(o, collector)
8
+ # Oracle does not allow LIMIT clause with select for update
9
+ if o.limit && o.lock
10
+ raise ArgumentError, <<-MSG
11
+ 'Combination of limit and lock is not supported.
12
+ because generated SQL statements
13
+ `SELECT FOR UPDATE and FETCH FIRST n ROWS` generates ORA-02014.`
14
+ MSG
15
+ end
16
+ super
17
+ end
18
+
19
+ def visit_Arel_Nodes_SelectOptions(o, collector)
20
+ collector = maybe_visit o.offset, collector
21
+ collector = maybe_visit o.limit, collector
22
+ maybe_visit o.lock, collector
23
+ end
24
+
25
+ def visit_Arel_Nodes_Limit(o, collector)
26
+ collector << "FETCH FIRST "
27
+ collector = visit o.expr, collector
28
+ collector << " ROWS ONLY"
29
+ end
30
+
31
+ def visit_Arel_Nodes_Offset(o, collector)
32
+ collector << "OFFSET "
33
+ visit o.expr, collector
34
+ collector << " ROWS"
35
+ end
36
+
37
+ def visit_Arel_Nodes_Except(o, collector)
38
+ collector << "( "
39
+ collector = infix_value o, collector, " MINUS "
40
+ collector << " )"
41
+ end
42
+
43
+ def visit_Arel_Nodes_UpdateStatement(o, collector)
44
+ # Oracle does not allow ORDER BY/LIMIT in UPDATEs.
45
+ if o.orders.any? && o.limit.nil?
46
+ # However, there is no harm in silently eating the ORDER BY clause if no LIMIT has been provided,
47
+ # otherwise let the user deal with the error
48
+ o = o.dup
49
+ o.orders = []
50
+ end
51
+
52
+ super
53
+ end
54
+
55
+ def visit_Arel_Nodes_BindParam(o, collector)
56
+ collector.add_bind(o.value) { |i| ":a#{i}" }
57
+ end
58
+
59
+ def is_distinct_from(o, collector)
60
+ collector << "DECODE("
61
+ collector = visit [o.left, o.right, 0, 1], collector
62
+ collector << ")"
63
+ end
64
+
65
+ end
66
+ end
67
+ end
68
+ end
@@ -481,20 +481,20 @@ module ArelExtensions
481
481
  if o.default
482
482
  visit o.default, collector
483
483
  collector << " "
484
- end
484
+ end
485
485
  collector << "END"
486
486
  end
487
487
 
488
488
  def visit_ArelExtensions_Nodes_When o, collector
489
489
  collector << "WHEN "
490
- visit o.left, collector
490
+ visit Arel::Nodes.build_quoted(o.left), collector
491
491
  collector << " THEN "
492
- visit o.right, collector
492
+ visit Arel::Nodes.build_quoted(o.right), collector
493
493
  end
494
494
 
495
495
  def visit_ArelExtensions_Nodes_Else o, collector
496
496
  collector << "ELSE "
497
- visit o.expr, collector
497
+ visit Arel::Nodes.build_quoted(o.expr), collector
498
498
  end
499
499
 
500
500
 
@@ -524,6 +524,14 @@ module ArelExtensions
524
524
  collector
525
525
  end
526
526
 
527
+ def visit_ArelExtensions_Nodes_LevenshteinDistance o, collector
528
+ collector << "LEVENSHTEIN_DISTANCE("
529
+ collector = visit o.left, collector
530
+ collector << Arel::Visitors::ToSql::COMMA
531
+ collector = visit o.right, collector
532
+ collector << ')'
533
+ collector
534
+ end
527
535
 
528
536
  end
529
537
  end
@@ -69,7 +69,7 @@ module ArelExtensions
69
69
  fake_table = Arel::Table.new('fake_tables')
70
70
 
71
71
  compile(fake_table[:fake_att] - 42).must_be_like %{("fake_tables"."fake_att" - 42)}
72
- compile(fake_table[:fake_att].coalesce(0) - 42).must_be_like %{(COALESCE("fake_tables"."fake_att", 0) - 42)}
72
+ compile(fake_table[:fake_att].coalesce(0) - 42).must_be_like %{(COALESCE("fake_tables"."fake_att", 0) - 42)}
73
73
  end
74
74
 
75
75
  # String Functions
@@ -351,6 +351,13 @@ module ArelExtensions
351
351
  .must_be_like %{((((LOCATE('test', "users"."name") + 1) + LOCATE('test', "users"."name")) - 1) + 1)}
352
352
  end
353
353
 
354
+ it "should be possible to add and substract on some nodes" do
355
+ c = @table[:name]
356
+ compile(c.when(0,0).else(42) + 42).must_be_like %{(CASE "users"."name" WHEN 0 THEN 0 ELSE 42 END + 42)}
357
+ compile(c.when(0,0).else(42) - 42).must_be_like %{(CASE "users"."name" WHEN 0 THEN 0 ELSE 42 END - 42)}
358
+ compile(c.when(0,"0").else("42") + "42").must_be_like %{CONCAT(CASE "users"."name" WHEN 0 THEN '0' ELSE '42' END, '42')}
359
+ end
360
+
354
361
  it "should be possible to desc and asc on functions" do
355
362
  c = @table[:name]
356
363
  compile(c.asc)
@@ -501,7 +501,12 @@ module ArelExtensions
501
501
 
502
502
  # Case clause
503
503
  def test_case
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)
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)
505
+ assert_equal 2, t(@arthur, @score.when(65.62,1).else(0)+1)
506
+ assert_equal 0, t(@arthur, @score.when(65.62,1).else(0)-1)
507
+ assert_equal "11", t(@arthur, @score.when(65.62).then("1").else("0")+"1")
508
+ assert_equal 66.62, t(@arthur, @score.when(65.62,@score).else(@score)+1)
509
+ assert_equal "65.621", t(@arthur, @score.when(65.62,@score.cast(:string)).else(@score.cast(:string))+1).tr('0','') #tr is here because of precision on cast for some DBMS
505
510
  end
506
511
 
507
512
  def test_format_numbers
@@ -523,8 +528,8 @@ module ArelExtensions
523
528
  assert_includes ["$ 6,56e1 €","$ 6,56e+01 €"], t(@arthur, @score.format_number("$ %.2e €","fr_FR"))
524
529
  assert_includes ["$ 6,56E1 €","$ 6,56E+01 €"], t(@arthur, @score.format_number("$ %.2E €","fr_FR"))
525
530
  assert_includes ["$ 6,562E1 €","$ 6,562E+01 €"], t(@arthur, @score.format_number("$ %.3E €","fr_FR"))
526
- assert_equal "123 456 765,6" , t(@arthur, (@score+123456700).format_number("%.1f","sv_SE"))
527
- assert_equal "123456765,6" , t(@arthur, (@score+123456700).format_number("%.1f","fr_FR"))
531
+ assert_equal "123 456 765,6" , t(@arthur, (@score+123456700).format_number("%.1f","sv_SE")).gsub("\u00A0"," ") #some DBMS put no-break space here (it makes sense thus)
532
+ assert_equal "123456765,6" , t(@arthur, (@score+123456700).format_number("%.1f","fr_FR")).gsub("\u00A0","") #because SqlServer does it like no one else
528
533
  assert_equal "123,456,765.6" , t(@arthur, (@score+123456700).format_number("%.1f","en_US"))
529
534
  assert_equal " 123,456,765.6" , t(@arthur, (@score+123456700).format_number("%16.1f","en_US"))
530
535
  assert_equal "$ 0,00 €" , t(@arthur, @score.when(65.62).then(Arel.sql("null")).else(1).format_number("$ %.2f €","fr_FR"))
@@ -666,7 +671,13 @@ module ArelExtensions
666
671
  assert ( 537.0355 - t(User.where(nil), @score.variance(false))).abs < 0.01
667
672
  assert ( 24.77408 - t(User.where(nil), @score.std)).abs < 0.01
668
673
  assert ( 23.17403 - t(User.where(nil), @score.std(false))).abs < 0.01
674
+
669
675
  end
676
+
677
+ #def test_levenshtein_distance
678
+ #assert 2, t(@arthur,@name.levenshtein_distance("Artour"))
679
+ #end
680
+
670
681
  end
671
682
  end
672
683
  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.1.3
4
+ version: 1.1.4
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: 2019-01-08 00:00:00.000000000 Z
13
+ date: 2019-01-15 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: arel
@@ -138,6 +138,7 @@ files:
138
138
  - lib/arel_extensions/nodes/function.rb
139
139
  - lib/arel_extensions/nodes/is_null.rb
140
140
  - lib/arel_extensions/nodes/length.rb
141
+ - lib/arel_extensions/nodes/levenshtein_distance.rb
141
142
  - lib/arel_extensions/nodes/locate.rb
142
143
  - lib/arel_extensions/nodes/log10.rb
143
144
  - lib/arel_extensions/nodes/matches.rb
@@ -166,6 +167,7 @@ files:
166
167
  - lib/arel_extensions/visitors/mssql.rb
167
168
  - lib/arel_extensions/visitors/mysql.rb
168
169
  - lib/arel_extensions/visitors/oracle.rb
170
+ - lib/arel_extensions/visitors/oracle12.rb
169
171
  - lib/arel_extensions/visitors/postgresql.rb
170
172
  - lib/arel_extensions/visitors/sqlite.rb
171
173
  - lib/arel_extensions/visitors/to_sql.rb
@@ -209,7 +211,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
209
211
  version: '0'
210
212
  requirements: []
211
213
  rubyforge_project:
212
- rubygems_version: 2.5.2.1
214
+ rubygems_version: 2.5.2.3
213
215
  signing_key:
214
216
  specification_version: 4
215
217
  summary: Extending Arel