arel_extensions 1.3.9 → 2.0.0.rc3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (134) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +2 -1
  3. data/.gitignore +6 -7
  4. data/.rubocop.yml +3 -67
  5. data/.travis/oracle/download.js +152 -0
  6. data/.travis/oracle/download.sh +30 -0
  7. data/.travis/oracle/download_ojdbc.js +116 -0
  8. data/.travis/oracle/install.sh +34 -0
  9. data/.travis/setup_accounts.sh +9 -0
  10. data/.travis/sqlite3/extension-functions.sh +6 -0
  11. data/.travis.yml +223 -0
  12. data/Gemfile +21 -16
  13. data/README.md +90 -282
  14. data/Rakefile +30 -48
  15. data/TODO +1 -0
  16. data/appveyor.yml +22 -60
  17. data/arel_extensions.gemspec +14 -13
  18. data/functions.html +3 -3
  19. data/gemfiles/rails3.gemfile +10 -10
  20. data/gemfiles/rails4.gemfile +29 -0
  21. data/gemfiles/rails5_0.gemfile +29 -0
  22. data/gemfiles/rails5_1_4.gemfile +14 -14
  23. data/gemfiles/rails5_2.gemfile +14 -16
  24. data/init/mssql.sql +4 -4
  25. data/init/mysql.sql +38 -38
  26. data/init/oracle.sql +0 -0
  27. data/init/postgresql.sql +21 -21
  28. data/init/sqlite.sql +0 -0
  29. data/lib/arel_extensions/attributes.rb +3 -4
  30. data/lib/arel_extensions/boolean_functions.rb +14 -53
  31. data/lib/arel_extensions/common_sql_functions.rb +17 -16
  32. data/lib/arel_extensions/comparators.rb +28 -27
  33. data/lib/arel_extensions/date_duration.rb +13 -17
  34. data/lib/arel_extensions/insert_manager.rb +15 -18
  35. data/lib/arel_extensions/math.rb +53 -55
  36. data/lib/arel_extensions/math_functions.rb +39 -46
  37. data/lib/arel_extensions/nodes/abs.rb +1 -0
  38. data/lib/arel_extensions/nodes/blank.rb +2 -1
  39. data/lib/arel_extensions/nodes/case.rb +19 -20
  40. data/lib/arel_extensions/nodes/cast.rb +8 -10
  41. data/lib/arel_extensions/nodes/ceil.rb +1 -1
  42. data/lib/arel_extensions/nodes/coalesce.rb +4 -3
  43. data/lib/arel_extensions/nodes/collate.rb +10 -9
  44. data/lib/arel_extensions/nodes/concat.rb +18 -9
  45. data/lib/arel_extensions/nodes/date_diff.rb +26 -42
  46. data/lib/arel_extensions/nodes/duration.rb +3 -0
  47. data/lib/arel_extensions/nodes/find_in_set.rb +1 -0
  48. data/lib/arel_extensions/nodes/floor.rb +1 -1
  49. data/lib/arel_extensions/nodes/format.rb +8 -35
  50. data/lib/arel_extensions/nodes/formatted_number.rb +23 -22
  51. data/lib/arel_extensions/nodes/function.rb +37 -42
  52. data/lib/arel_extensions/nodes/is_null.rb +0 -0
  53. data/lib/arel_extensions/nodes/json.rb +39 -52
  54. data/lib/arel_extensions/nodes/length.rb +0 -5
  55. data/lib/arel_extensions/nodes/levenshtein_distance.rb +1 -1
  56. data/lib/arel_extensions/nodes/locate.rb +2 -1
  57. data/lib/arel_extensions/nodes/log10.rb +2 -1
  58. data/lib/arel_extensions/nodes/matches.rb +7 -5
  59. data/lib/arel_extensions/nodes/md5.rb +1 -0
  60. data/lib/arel_extensions/nodes/power.rb +5 -5
  61. data/lib/arel_extensions/nodes/rand.rb +1 -0
  62. data/lib/arel_extensions/nodes/repeat.rb +5 -3
  63. data/lib/arel_extensions/nodes/replace.rb +8 -16
  64. data/lib/arel_extensions/nodes/round.rb +6 -5
  65. data/lib/arel_extensions/nodes/soundex.rb +15 -15
  66. data/lib/arel_extensions/nodes/std.rb +21 -18
  67. data/lib/arel_extensions/nodes/substring.rb +16 -8
  68. data/lib/arel_extensions/nodes/then.rb +1 -1
  69. data/lib/arel_extensions/nodes/trim.rb +6 -4
  70. data/lib/arel_extensions/nodes/union.rb +8 -5
  71. data/lib/arel_extensions/nodes/union_all.rb +7 -4
  72. data/lib/arel_extensions/nodes/wday.rb +4 -0
  73. data/lib/arel_extensions/nodes.rb +1 -1
  74. data/lib/arel_extensions/null_functions.rb +5 -19
  75. data/lib/arel_extensions/predications.rb +43 -44
  76. data/lib/arel_extensions/railtie.rb +5 -5
  77. data/lib/arel_extensions/set_functions.rb +7 -5
  78. data/lib/arel_extensions/string_functions.rb +29 -59
  79. data/lib/arel_extensions/tasks.rb +6 -6
  80. data/lib/arel_extensions/version.rb +1 -1
  81. data/lib/arel_extensions/visitors/ibm_db.rb +31 -24
  82. data/lib/arel_extensions/visitors/mssql.rb +180 -375
  83. data/lib/arel_extensions/visitors/mysql.rb +212 -350
  84. data/lib/arel_extensions/visitors/oracle.rb +178 -220
  85. data/lib/arel_extensions/visitors/oracle12.rb +31 -18
  86. data/lib/arel_extensions/visitors/postgresql.rb +173 -256
  87. data/lib/arel_extensions/visitors/sqlite.rb +126 -140
  88. data/lib/arel_extensions/visitors/to_sql.rb +237 -298
  89. data/lib/arel_extensions/visitors.rb +58 -82
  90. data/lib/arel_extensions.rb +31 -202
  91. data/test/database.yml +7 -15
  92. data/test/helper.rb +18 -0
  93. data/test/real_db_test.rb +116 -105
  94. data/test/support/fake_record.rb +3 -3
  95. data/test/test_comparators.rb +17 -14
  96. data/test/visitors/test_bulk_insert_oracle.rb +11 -11
  97. data/test/visitors/test_bulk_insert_sqlite.rb +13 -12
  98. data/test/visitors/test_bulk_insert_to_sql.rb +13 -11
  99. data/test/visitors/test_oracle.rb +55 -55
  100. data/test/visitors/test_to_sql.rb +226 -419
  101. data/test/with_ar/all_agnostic_test.rb +365 -709
  102. data/test/with_ar/insert_agnostic_test.rb +21 -27
  103. data/test/with_ar/test_bulk_sqlite.rb +16 -17
  104. data/test/with_ar/test_math_sqlite.rb +26 -26
  105. data/test/with_ar/test_string_mysql.rb +33 -31
  106. data/test/with_ar/test_string_sqlite.rb +34 -30
  107. metadata +34 -37
  108. data/.github/workflows/publish.yml +0 -29
  109. data/.github/workflows/release.yml +0 -30
  110. data/.github/workflows/ruby.yml +0 -345
  111. data/NEWS.md +0 -62
  112. data/bin/build +0 -15
  113. data/bin/publish +0 -8
  114. data/dev/compose.yaml +0 -29
  115. data/gemfiles/rails4_2.gemfile +0 -38
  116. data/gemfiles/rails5.gemfile +0 -29
  117. data/gemfiles/rails6.gemfile +0 -30
  118. data/gemfiles/rails6_1.gemfile +0 -30
  119. data/gemfiles/rails7.gemfile +0 -23
  120. data/gemfiles/rails7_1.gemfile +0 -22
  121. data/gemspecs/arel_extensions-v1.gemspec +0 -27
  122. data/gemspecs/arel_extensions-v2.gemspec +0 -27
  123. data/generate_gems.sh +0 -15
  124. data/lib/arel_extensions/aliases.rb +0 -14
  125. data/lib/arel_extensions/helpers.rb +0 -57
  126. data/lib/arel_extensions/nodes/aggregate_function.rb +0 -13
  127. data/lib/arel_extensions/nodes/formatted_date.rb +0 -42
  128. data/lib/arel_extensions/nodes/rollup.rb +0 -36
  129. data/lib/arel_extensions/nodes/select.rb +0 -10
  130. data/lib/arel_extensions/nodes/sum.rb +0 -7
  131. data/lib/arel_extensions/visitors/convert_format.rb +0 -37
  132. data/test/arelx_test_helper.rb +0 -67
  133. data/version_v1.rb +0 -3
  134. data/version_v2.rb +0 -3
@@ -7,15 +7,15 @@ require 'arel_extensions/nodes/formatted_number'
7
7
  require 'arel_extensions/nodes/log10'
8
8
  require 'arel_extensions/nodes/power'
9
9
  require 'arel_extensions/nodes/std'
10
- require 'arel_extensions/nodes/sum'
11
10
 
12
11
  module ArelExtensions
13
12
  module MathFunctions
13
+
14
14
  # Arel does not handle Decimal literal properly
15
15
  def * other
16
16
  case other
17
17
  when Float, BigDecimal
18
- super(Arel.quoted(other))
18
+ super(Arel::Nodes.build_quoted(other))
19
19
  else
20
20
  super(other)
21
21
  end
@@ -25,7 +25,7 @@ module ArelExtensions
25
25
  def / other
26
26
  case other
27
27
  when Float, BigDecimal
28
- super(Arel.quoted(other))
28
+ super(Arel::Nodes.build_quoted(other))
29
29
  else
30
30
  super(other)
31
31
  end
@@ -33,86 +33,79 @@ module ArelExtensions
33
33
 
34
34
  # Abs function returns the absolute value of a number passed as argument #
35
35
  def abs
36
- ArelExtensions::Nodes::Abs.new [self]
36
+ ArelExtensions::Nodes::Abs.new [self]
37
37
  end
38
38
 
39
39
  # will rounded up any positive or negative decimal value within the function upwards #
40
40
  def ceil
41
- ArelExtensions::Nodes::Ceil.new [self]
41
+ ArelExtensions::Nodes::Ceil.new [self]
42
42
  end
43
43
 
44
44
  # function rounded up any positive or negative decimal value down to the next least integer
45
45
  def floor
46
- ArelExtensions::Nodes::Floor.new [self]
46
+ ArelExtensions::Nodes::Floor.new [self]
47
47
  end
48
48
 
49
- # function gives the base 10 log
49
+ # function gives the base 10 log
50
50
  def log10
51
- ArelExtensions::Nodes::Log10.new [self]
51
+ ArelExtensions::Nodes::Log10.new [self]
52
52
  end
53
53
 
54
54
  # function gives the power of a number
55
55
  def pow exposant = 0
56
- ArelExtensions::Nodes::Power.new [self, exposant]
56
+ ArelExtensions::Nodes::Power.new [self,exposant]
57
57
  end
58
58
 
59
59
  # function gives the power of a number
60
60
  def power exposant = 0
61
- ArelExtensions::Nodes::Power.new [self, exposant]
61
+ ArelExtensions::Nodes::Power.new [self,exposant]
62
62
  end
63
63
 
64
64
  # Aggregate Functions
65
- def std opts = {unbiased: true}
66
- ArelExtensions::Nodes::Std.new self, **opts
67
- end
68
-
69
- def variance opts = {unbiased: true}
70
- ArelExtensions::Nodes::Variance.new self, **opts
65
+ def std unbiased = true
66
+ ArelExtensions::Nodes::Std.new [self,unbiased]
71
67
  end
72
68
 
73
- def sum opts = {unbiased: true}
74
- if Gem::Version.new(Arel::VERSION) >= Gem::Version.new('9.0.0')
75
- Arel::Nodes::Sum.new [self]
76
- else
77
- ArelExtensions::Nodes::Sum.new self, **opts
78
- end
69
+ def variance unbiased = true
70
+ ArelExtensions::Nodes::Variance.new [self,unbiased]
79
71
  end
80
72
 
81
- # function that can be invoked to produce random numbers between 0 and 1
82
- # def rand seed = nil
83
- # ArelExtensions::Nodes::Rand.new [seed]
84
- # end
85
- alias_method(:random, :rand) rescue nil
73
+ #function that can be invoked to produce random numbers between 0 and 1
74
+ # def rand seed = nil
75
+ # ArelExtensions::Nodes::Rand.new [seed]
76
+ # end
77
+ alias_method :random, :rand
86
78
 
87
- # function is used to round a numeric field to the number of decimals specified
79
+ #function is used to round a numeric field to the number of decimals specified
88
80
  def round precision = nil
89
- if precision
90
- ArelExtensions::Nodes::Round.new [self, precision]
91
- else
92
- ArelExtensions::Nodes::Round.new [self]
93
- end
81
+ if precision
82
+ ArelExtensions::Nodes::Round.new [self, precision]
83
+ else
84
+ ArelExtensions::Nodes::Round.new [self]
85
+ end
94
86
  end
95
87
 
96
88
  # function returning a number at a specific format
97
- def format_number format_string, locale = nil
89
+ def format_number format_string, locale=nil
98
90
  begin
99
- sprintf(format_string, 0) # this line is to get the right error message if the format_string is not correct
91
+ sprintf(format_string,0) # this line is to get the right error message if the format_string is not correct
100
92
  m = /^(.*)%([ #+\-0]*)([1-9][0-9]+|[1-9]?)[.]?([0-9]*)([a-zA-Z])(.*)$/.match(format_string)
101
93
  opts = {
102
- prefix: m[1],
103
- flags: m[2].split(//).uniq.join,
104
- width: m[3].to_i,
105
- precision: m[4] != '' ? m[4].to_i : 6,
106
- type: m[5],
107
- suffix: m[6],
108
- locale: locale,
109
- original_string: format_string
94
+ :prefix => m[1],
95
+ :flags => m[2].split(//).uniq.join,
96
+ :width => m[3].to_i,
97
+ :precision => m[4] != '' ? m[4].to_i : 6,
98
+ :type => m[5],
99
+ :suffix => m[6],
100
+ :locale => locale,
101
+ :original_string => format_string
110
102
  }
111
- # opts = {locale: 'fr_FR', type: "e"/"f"/"d", prefix: "$ ", suffix: " %", flags: " +-#0", width: 5, precision: 6}
112
- ArelExtensions::Nodes::FormattedNumber.new [self, opts]
103
+ # opts = {:locale => 'fr_FR', :type => "e"/"f"/"d", :prefix => "$ ", :suffix => " %", :flags => " +-#0", :width => 5, :precision => 6}
104
+ ArelExtensions::Nodes::FormattedNumber.new [self,opts]
113
105
  rescue Exception
114
- Arel.quoted('Wrong Format')
106
+ Arel::Nodes.build_quoted('Wrong Format')
115
107
  end
116
108
  end
109
+
117
110
  end
118
111
  end
@@ -2,6 +2,7 @@ module ArelExtensions
2
2
  module Nodes
3
3
  class Abs < Function
4
4
  RETURN_TYPE = :number
5
+
5
6
  end
6
7
  end
7
8
  end
@@ -16,8 +16,9 @@ module ArelExtensions
16
16
  RETURN_TYPE = :boolean
17
17
 
18
18
  def initialize expr
19
- super expr.first
19
+ super expr.first
20
20
  end
21
21
  end
22
+
22
23
  end
23
24
  end
@@ -1,11 +1,7 @@
1
1
  module ArelExtensions
2
2
  module Nodes
3
- if Gem::Version.new(Arel::VERSION) < Gem::Version.new('7.1.0')
3
+ if Arel::VERSION < "7.1.0"
4
4
  class Case < Arel::Nodes::Node
5
- include Arel::Expressions
6
- include Arel::Math
7
- include Arel::Predications
8
- include Arel::OrderPredications
9
5
  attr_accessor :case, :conditions, :default
10
6
 
11
7
  def initialize expression = nil, default = nil
@@ -19,6 +15,7 @@ module ArelExtensions
19
15
 
20
16
  class Else < Arel::Nodes::Unary # :nodoc:
21
17
  end
18
+
22
19
  end
23
20
  else
24
21
  class Case < Arel::Nodes::Case
@@ -29,25 +26,23 @@ module ArelExtensions
29
26
  end
30
27
  end
31
28
 
32
- class ArelExtensions::Nodes::Case
29
+ ArelExtensions::Nodes::Case.class_eval do
33
30
  include Arel::Expressions
34
- include Arel::Math
35
- include Arel::Predications
36
31
  include Arel::OrderPredications
37
- include ArelExtensions::Aliases
38
- include ArelExtensions::Comparators
39
- include ArelExtensions::DateDuration
40
32
  include ArelExtensions::Math
41
- include ArelExtensions::MathFunctions
42
- include ArelExtensions::NullFunctions
33
+ include ArelExtensions::Comparators
43
34
  include ArelExtensions::Predications
35
+ include ArelExtensions::MathFunctions
44
36
  include ArelExtensions::StringFunctions
37
+ include ArelExtensions::NullFunctions
45
38
 
46
39
  def return_type
47
40
  obj = if @conditions.length > 0
48
- @conditions.last.right
41
+ @conditions.last.right
49
42
  elsif @default
50
43
  @default.expr
44
+ else
45
+ nil
51
46
  end
52
47
  if obj.respond_to?(:return_type)
53
48
  obj.return_type
@@ -55,10 +50,14 @@ module ArelExtensions
55
50
  case obj
56
51
  when Integer, Float
57
52
  :number
58
- when Date, DateTime, Time
53
+ when Date, DateTime,Time
59
54
  :datetime
60
55
  when Arel::Attributes::Attribute
61
- Arel.column_of(obj.relation.table_name, obj.name.to_s)&.type || :string
56
+ begin
57
+ Arel::Table.engine.connection.schema_cache.columns_hash(obj.relation.table_name)[obj.name.to_s].type
58
+ rescue Exception
59
+ :string
60
+ end
62
61
  else
63
62
  :string
64
63
  end
@@ -93,14 +92,14 @@ module ArelExtensions
93
92
 
94
93
  def eql? other
95
94
  self.class == other.class &&
96
- self.case == other.case &&
97
- self.conditions == other.conditions &&
98
- self.default == other.default
95
+ self.case == other.case &&
96
+ self.conditions == other.conditions &&
97
+ self.default == other.default
99
98
  end
100
99
  alias :== :eql?
101
100
 
102
101
  def as other
103
- Arel::Nodes::As.new self, Arel.sql(other)
102
+ Arel::Nodes::As.new self, Arel::Nodes::SqlLiteral.new(other)
104
103
  end
105
104
  end
106
105
  end
@@ -14,16 +14,13 @@ module ArelExtensions
14
14
  @return_type = :decimal
15
15
  when :number
16
16
  @return_type = :number
17
- when 'char', 'varchar', 'nchar', 'nvarchar'
17
+ when 'char', 'varchar', 'text', 'nchar', 'nvarchar', 'ntext'
18
18
  @return_type = :string
19
- when 'text', :text, 'ntext', :ntext
20
- @as_attr = expr[1].to_sym
21
- @return_type = :string
22
- when :datetime, 'datetime', 'smalldatetime'
19
+ when :datetime, 'datetime','smalldatetime'
23
20
  @return_type = :datetime
24
- when :time, 'time'
21
+ when :time,'time'
25
22
  @return_type = :time
26
- when :date, 'date'
23
+ when :date,'date'
27
24
  @return_type = :date
28
25
  when :binary, 'binary', 'varbinary', 'image'
29
26
  @return_type = :binary
@@ -32,23 +29,24 @@ module ArelExtensions
32
29
  @as_attr = :string
33
30
  end
34
31
  tab = [convert_to_node(expr.first)]
35
- super(tab)
32
+ return super(tab)
36
33
  end
37
34
 
38
35
  def +(other)
39
36
  case @return_type
40
37
  when :string
41
- ArelExtensions::Nodes::Concat.new [self, other]
38
+ return ArelExtensions::Nodes::Concat.new [self, other]
42
39
  when :ruby_time
43
40
  ArelExtensions::Nodes::DateAdd.new [self, other]
44
41
  else
45
- Arel.grouping(Arel::Nodes::Addition.new self, other)
42
+ Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new self, other)
46
43
  end
47
44
  end
48
45
 
49
46
  def return_type
50
47
  @return_type
51
48
  end
49
+
52
50
  end
53
51
  end
54
52
  end
@@ -1,7 +1,7 @@
1
1
  module ArelExtensions
2
2
  module Nodes
3
3
  class Ceil < Function
4
- RETURN_TYPE = :number
4
+ RETURN_TYPE = :number
5
5
  end
6
6
  end
7
7
  end
@@ -2,7 +2,7 @@ module ArelExtensions
2
2
  module Nodes
3
3
  class Coalesce < Function
4
4
  RETURN_TYPE = :string
5
-
5
+
6
6
  attr_accessor :left_node_type
7
7
 
8
8
  def return_type
@@ -20,15 +20,16 @@ module ArelExtensions
20
20
  @left_node_type = :number
21
21
  when ArelExtensions::Nodes::Coalesce, ArelExtensions::Nodes::Function
22
22
  @left_node_type = expr.first.respond_to?(:left_node_type) ? expr.first.left_node_type : nil
23
- when Arel::Nodes::Node, Arel::Attributes::Attribute
23
+ when Arel::Nodes::Node, Arel::Attributes::Attribute
24
24
  @left_node_type = type_of_attribute(expr.first)
25
25
  when Date
26
26
  @left_node_type = :ruby_date
27
27
  when DateTime, Time
28
28
  @left_node_type = :ruby_time
29
29
  end
30
- super(tab)
30
+ return super(tab)
31
31
  end
32
+
32
33
  end
33
34
  end
34
35
  end
@@ -1,17 +1,18 @@
1
1
  module ArelExtensions
2
2
  module Nodes
3
3
  class Collate < Function
4
- RETURN_TYPE = :string
4
+ RETURN_TYPE = :string
5
5
 
6
- attr_accessor :ai, :ci, :option
6
+ attr_accessor :ai, :ci, :option
7
+
8
+ def initialize left, option=nil, ai=false, ci=false
9
+ @ai = ai
10
+ @ci = ci
11
+ @option = option
12
+ tab = [convert_to_node(left)]
13
+ return super(tab)
14
+ end
7
15
 
8
- def initialize left, option = nil, ai = false, ci = false
9
- @ai = ai
10
- @ci = ci
11
- @option = option
12
- tab = [convert_to_node(left)]
13
- super(tab)
14
- end
15
16
  end
16
17
  end
17
18
  end
@@ -11,12 +11,12 @@ module ArelExtensions::Nodes
11
11
  else
12
12
  node
13
13
  end
14
- }.flatten.reduce([]) { |res, b|
14
+ }.flatten.reduce([]) { | res, b |
15
15
  # concatenate successive literal strings.
16
- if b.is_a?(Arel::Nodes::Quoted) && b.expr == ''
16
+ if b.is_a?(Arel::Nodes::Quoted) && b.expr == ""
17
17
  res
18
18
  elsif res.last && res.last.is_a?(Arel::Nodes::Quoted) && b.is_a?(Arel::Nodes::Quoted)
19
- res[-1] = Arel.quoted(res.last.expr.to_s + b.expr.to_s)
19
+ res[-1] = Arel::Nodes.build_quoted(res.last.expr + b.expr)
20
20
  else
21
21
  res << b
22
22
  end
@@ -37,16 +37,25 @@ module ArelExtensions::Nodes
37
37
  def concat(other)
38
38
  Concat.new(self.expressions + [other])
39
39
  end
40
+
40
41
  end
41
42
 
42
- class GroupConcat < AggregateFunction
43
+ class GroupConcat < Function
43
44
  RETURN_TYPE = :string
44
45
 
45
- attr_accessor :separator
46
-
47
- def initialize node, separator = ', ', **opts
48
- @separator = convert_to_node(separator)
49
- super node, **opts
46
+ attr_accessor :orders
47
+
48
+ def initialize expr
49
+ tab = expr.map { |arg|
50
+ if arg.is_a?(Array)
51
+ @orders = arg
52
+ nil
53
+ else
54
+ convert_to_node(arg)
55
+ end
56
+ }.compact
57
+ super(tab)
50
58
  end
59
+
51
60
  end
52
61
  end
@@ -2,7 +2,7 @@ require 'date'
2
2
 
3
3
  module ArelExtensions
4
4
  module Nodes
5
- class DateDiff < Function # difference entre colonne date et date string/date
5
+ class DateDiff < Function #difference entre colonne date et date string/date
6
6
  attr_accessor :left_node_type
7
7
  attr_accessor :right_node_type
8
8
 
@@ -12,23 +12,23 @@ module ArelExtensions
12
12
  res = []
13
13
  col = expr.first
14
14
  case col
15
- when Arel::Nodes::Node, Arel::Attributes::Attribute
15
+ when Arel::Nodes::Node, Arel::Attributes::Attribute
16
16
  @left_node_type = type_of_attribute(col)
17
17
  when Date
18
18
  @left_node_type = :ruby_date
19
19
  when DateTime, Time
20
20
  @left_node_type = :ruby_time
21
21
  end
22
- res << (%i[date ruby_date].include?(@left_node_type) ? convert_to_date_node(col) : convert_to_datetime_node(col))
22
+ res << ([:date, :ruby_date].include?(@left_node_type) ? convert_to_date_node(col) : convert_to_datetime_node(col))
23
23
  case expr[1]
24
- when Arel::Nodes::Node, Arel::Attributes::Attribute
24
+ when Arel::Nodes::Node, Arel::Attributes::Attribute
25
25
  @right_node_type = type_of_attribute(expr[1])
26
26
  when Date
27
27
  @right_node_type = :ruby_date
28
28
  when DateTime, Time
29
29
  @right_node_type = :ruby_time
30
30
  end
31
- res << (%i[date ruby_date].include?(@left_node_type) ? convert_to_date_node(expr[1]) : convert_to_datetime_node(expr[1]))
31
+ res << ([:date, :ruby_date].include?(@left_node_type) ? convert_to_date_node(expr[1]) : convert_to_datetime_node(expr[1]))
32
32
  super res
33
33
  end
34
34
  end
@@ -43,19 +43,19 @@ module ArelExtensions
43
43
  tab = expr.map do |arg|
44
44
  convert(arg)
45
45
  end
46
- super(tab)
46
+ return super(tab)
47
47
  end
48
48
 
49
49
  def sqlite_value
50
50
  v = self.expressions.last
51
51
  if defined?(ActiveSupport::Duration) && ActiveSupport::Duration === v
52
52
  if @date_type == :date
53
- Arel.quoted((v.value >= 0 ? '+' : '-') + v.inspect)
53
+ return Arel::Nodes.build_quoted((v.value >= 0 ? '+' : '-') + v.inspect)
54
54
  elsif @date_type == :datetime
55
- Arel.quoted((v.value >= 0 ? '+' : '-') + v.inspect)
55
+ return Arel::Nodes.build_quoted((v.value >= 0 ? '+' : '-') + v.inspect)
56
56
  end
57
57
  else
58
- v
58
+ return v
59
59
  end
60
60
  end
61
61
 
@@ -97,7 +97,7 @@ module ArelExtensions
97
97
  v ||= self.expressions.last
98
98
  if defined?(ActiveSupport::Duration) && ActiveSupport::Duration === v
99
99
  if @date_type == :ruby_date
100
- Arel.sql("(INTERVAL '1' DAY) * %s" % v.inspect.to_i)
100
+ Arel.sql("(INTERVAL '1' DAY) * %s" % v.inspect.to_i )
101
101
  else
102
102
  Arel.sql("(INTERVAL '1' SECOND) * %s" % v.to_i)
103
103
  end
@@ -115,18 +115,9 @@ module ArelExtensions
115
115
  v ||= self.expressions.last
116
116
  if defined?(ActiveSupport::Duration) && ActiveSupport::Duration === v
117
117
  if @date_type == :date
118
- v.to_i / (24 * 3600)
118
+ v.to_i / (24*3600)
119
119
  elsif @date_type == :datetime
120
- if v.parts.size == 1
121
- # first entry in the dict v.parts; one of [:years, :months, :weeks, :days, :hours, :minutes, :seconds]
122
- # | the value
123
- # | |
124
- # | |
125
- # v v
126
- v.parts.first.second
127
- else
128
- v.to_i
129
- end
120
+ v.to_i
130
121
  end
131
122
  else
132
123
  v
@@ -139,37 +130,28 @@ module ArelExtensions
139
130
  if @date_type == :date
140
131
  Arel.sql('day')
141
132
  elsif @date_type == :datetime
142
- res = if v.parts.size == 1
143
- # first entry in the dict v.parts; one of [:years, :months, :weeks, :days, :hours, :minutes, :seconds]
144
- # | the key
145
- # | | convert symbol to string
146
- # | | | remove the plural suffix `s`
147
- # v v v v
148
- v.parts.first.first.to_s[0..-2]
149
- else
150
- 'second'
151
- end
152
- Arel.sql(res)
133
+ Arel.sql('second')
153
134
  end
154
135
  else
155
136
  if ArelExtensions::Nodes::Duration === v
156
137
  v.with_interval = true
157
138
  case v.left
158
- when 'd', 'm', 'y'
139
+ when 'd','m','y'
159
140
  Arel.sql('day')
160
- when 'h', 'mn', 's'
141
+ when 'h','mn','s'
161
142
  Arel.sql('second')
162
143
  when /i\z/
163
- Arel.sql(ArelExtensions::Visitors::MSSQL::LOADED_VISITOR::DATE_MAPPING[v.left[0..-2]])
144
+ Arel.sql(Arel::Visitors::MSSQL::DATE_MAPPING[v.left[0..-2]])
164
145
  else
165
- Arel.sql(ArelExtensions::Visitors::MSSQL::LOADED_VISITOR::DATE_MAPPING[v.left])
146
+ Arel.sql(Arel::Visitors::MSSQL::DATE_MAPPING[v.left])
166
147
  end
148
+ else
149
+ nil
167
150
  end
168
151
  end
169
152
  end
170
153
 
171
154
  private
172
-
173
155
  def convert(object)
174
156
  case object
175
157
  when Arel::Attributes::Attribute, Arel::Nodes::Node, ActiveSupport::Duration
@@ -177,16 +159,16 @@ module ArelExtensions
177
159
  when Integer
178
160
  object.days
179
161
  when DateTime, Time, Date
180
- raise(ArgumentError, "#{object.class} cannot be converted to Integer")
162
+ raise(ArgumentError, "#{object.class} can not be converted to Integer")
181
163
  when String
182
- Arel.quoted(object)
164
+ Arel::Nodes.build_quoted(object)
183
165
  else
184
- raise(ArgumentError, "#{object.class} cannot be converted to Integer")
166
+ raise(ArgumentError, "#{object.class} can not be converted to Integer")
185
167
  end
186
168
  end
187
169
  end
188
170
 
189
- class DateSub < Function # difference entre colonne date et date string/date
171
+ class DateSub < Function #difference entre colonne date et date string/date
190
172
  RETURN_TYPE = :integer
191
173
 
192
174
  def initialize(expr)
@@ -203,10 +185,12 @@ module ArelExtensions
203
185
  if defined?(ActiveSupport::Duration) && ActiveSupport::Duration === object
204
186
  object.to_i
205
187
  else
206
- raise(ArgumentError, "#{object.class} cannot be converted to Number")
188
+ raise(ArgumentError, "#{object.class} can not be converted to Number")
207
189
  end
208
190
  end
209
191
  end
192
+
210
193
  end
194
+
211
195
  end
212
196
  end
@@ -13,13 +13,16 @@ module ArelExtensions
13
13
  super(tab, aliaz)
14
14
  end
15
15
 
16
+
16
17
  def left
17
18
  @expressions.first
18
19
  end
19
20
 
21
+
20
22
  def right
21
23
  @expressions[1]
22
24
  end
25
+
23
26
  end
24
27
  end
25
28
  end
@@ -2,6 +2,7 @@ module ArelExtensions
2
2
  module Nodes
3
3
  class FindInSet < Function
4
4
  RETURN_TYPE = :integer
5
+
5
6
  end
6
7
  end
7
8
  end
@@ -1,7 +1,7 @@
1
1
  module ArelExtensions
2
2
  module Nodes
3
3
  class Floor < Function
4
- RETURN_TYPE = :number
4
+ RETURN_TYPE = :number
5
5
  end
6
6
  end
7
7
  end
@@ -1,42 +1,15 @@
1
- require 'strscan'
2
-
3
1
  module ArelExtensions
4
2
  module Nodes
5
- class Format < Function
3
+ class Format < Function
6
4
  RETURN_TYPE = :string
7
5
 
8
- attr_accessor :col_type, :iso_format, :time_zone
9
-
10
- def initialize expr
11
- col = expr[0]
12
- @iso_format = convert_format(expr[1])
13
- @time_zone = expr[2]
14
- @col_type = type_of_attribute(col)
15
- super [col, convert_to_string_node(@iso_format)]
16
- end
17
-
18
- private
19
-
20
- # Address portability issues with some of the formats.
21
- def convert_format(fmt)
22
- s = StringScanner.new fmt
23
- res = StringIO.new
24
- while !s.eos?
25
- res <<
26
- case
27
- when s.scan(/%D/) then '%m/%d/%y'
28
- when s.scan(/%F/) then '%Y-%m-%d'
29
- when s.scan(/%R/) then '%H:%M'
30
- when s.scan(/%r/) then '%I:%M:%S %p'
31
- when s.scan(/%T/) then '%H:%M:%S'
32
- when s.scan(/%v/) then '%e-%b-%Y'
33
-
34
- when s.scan(/[^%]+/) then s.matched
35
- when s.scan(/./) then s.matched
36
- end
37
- end
38
- res.string
39
- end
6
+ attr_accessor :col_type, :iso_format
7
+ def initialize expr
8
+ col = expr.first
9
+ @iso_format = expr[1]
10
+ @col_type = type_of_attribute(col)
11
+ super [col, convert_to_string_node(@iso_format)]
12
+ end
40
13
  end
41
14
  end
42
15
  end