arel_extensions 1.2.25 → 2.0.0.rc3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -7
  3. data/.travis.yml +91 -61
  4. data/Gemfile +20 -15
  5. data/README.md +12 -17
  6. data/Rakefile +29 -40
  7. data/appveyor.yml +1 -1
  8. data/arel_extensions.gemspec +3 -3
  9. data/functions.html +3 -3
  10. data/gemfiles/rails3.gemfile +9 -9
  11. data/gemfiles/rails4.gemfile +13 -13
  12. data/gemfiles/rails5_0.gemfile +13 -13
  13. data/gemfiles/rails5_1_4.gemfile +13 -13
  14. data/gemfiles/rails5_2.gemfile +13 -13
  15. data/init/mssql.sql +4 -4
  16. data/init/mysql.sql +38 -38
  17. data/init/postgresql.sql +21 -21
  18. data/lib/arel_extensions/attributes.rb +1 -0
  19. data/lib/arel_extensions/boolean_functions.rb +14 -55
  20. data/lib/arel_extensions/common_sql_functions.rb +8 -7
  21. data/lib/arel_extensions/comparators.rb +15 -14
  22. data/lib/arel_extensions/date_duration.rb +5 -4
  23. data/lib/arel_extensions/insert_manager.rb +16 -17
  24. data/lib/arel_extensions/math.rb +12 -11
  25. data/lib/arel_extensions/math_functions.rb +22 -29
  26. data/lib/arel_extensions/nodes/abs.rb +1 -0
  27. data/lib/arel_extensions/nodes/blank.rb +1 -0
  28. data/lib/arel_extensions/nodes/case.rb +8 -11
  29. data/lib/arel_extensions/nodes/cast.rb +2 -4
  30. data/lib/arel_extensions/nodes/ceil.rb +1 -1
  31. data/lib/arel_extensions/nodes/change_case.rb +0 -0
  32. data/lib/arel_extensions/nodes/coalesce.rb +3 -2
  33. data/lib/arel_extensions/nodes/collate.rb +2 -1
  34. data/lib/arel_extensions/nodes/concat.rb +16 -7
  35. data/lib/arel_extensions/nodes/date_diff.rb +13 -10
  36. data/lib/arel_extensions/nodes/duration.rb +3 -0
  37. data/lib/arel_extensions/nodes/find_in_set.rb +1 -0
  38. data/lib/arel_extensions/nodes/floor.rb +1 -1
  39. data/lib/arel_extensions/nodes/format.rb +8 -34
  40. data/lib/arel_extensions/nodes/formatted_number.rb +23 -22
  41. data/lib/arel_extensions/nodes/function.rb +16 -25
  42. data/lib/arel_extensions/nodes/json.rb +36 -43
  43. data/lib/arel_extensions/nodes/length.rb +0 -5
  44. data/lib/arel_extensions/nodes/levenshtein_distance.rb +0 -0
  45. data/lib/arel_extensions/nodes/locate.rb +1 -0
  46. data/lib/arel_extensions/nodes/log10.rb +2 -1
  47. data/lib/arel_extensions/nodes/matches.rb +6 -4
  48. data/lib/arel_extensions/nodes/md5.rb +1 -0
  49. data/lib/arel_extensions/nodes/power.rb +5 -5
  50. data/lib/arel_extensions/nodes/rand.rb +1 -0
  51. data/lib/arel_extensions/nodes/repeat.rb +4 -2
  52. data/lib/arel_extensions/nodes/replace.rb +6 -22
  53. data/lib/arel_extensions/nodes/round.rb +6 -5
  54. data/lib/arel_extensions/nodes/soundex.rb +15 -15
  55. data/lib/arel_extensions/nodes/std.rb +21 -18
  56. data/lib/arel_extensions/nodes/substring.rb +16 -8
  57. data/lib/arel_extensions/nodes/then.rb +0 -0
  58. data/lib/arel_extensions/nodes/trim.rb +5 -3
  59. data/lib/arel_extensions/nodes/union.rb +5 -2
  60. data/lib/arel_extensions/nodes/union_all.rb +3 -0
  61. data/lib/arel_extensions/nodes/wday.rb +4 -0
  62. data/lib/arel_extensions/nodes.rb +1 -1
  63. data/lib/arel_extensions/null_functions.rb +7 -5
  64. data/lib/arel_extensions/predications.rb +34 -35
  65. data/lib/arel_extensions/railtie.rb +5 -5
  66. data/lib/arel_extensions/set_functions.rb +4 -2
  67. data/lib/arel_extensions/string_functions.rb +23 -52
  68. data/lib/arel_extensions/tasks.rb +5 -5
  69. data/lib/arel_extensions/version.rb +1 -1
  70. data/lib/arel_extensions/visitors/ibm_db.rb +12 -5
  71. data/lib/arel_extensions/visitors/mssql.rb +58 -64
  72. data/lib/arel_extensions/visitors/mysql.rb +98 -149
  73. data/lib/arel_extensions/visitors/oracle.rb +70 -73
  74. data/lib/arel_extensions/visitors/oracle12.rb +15 -2
  75. data/lib/arel_extensions/visitors/postgresql.rb +63 -116
  76. data/lib/arel_extensions/visitors/sqlite.rb +70 -83
  77. data/lib/arel_extensions/visitors/to_sql.rb +110 -142
  78. data/lib/arel_extensions/visitors.rb +60 -68
  79. data/lib/arel_extensions.rb +19 -81
  80. data/test/database.yml +0 -2
  81. data/test/helper.rb +18 -0
  82. data/test/real_db_test.rb +43 -28
  83. data/test/support/fake_record.rb +2 -2
  84. data/test/test_comparators.rb +12 -9
  85. data/test/visitors/test_bulk_insert_oracle.rb +8 -8
  86. data/test/visitors/test_bulk_insert_sqlite.rb +10 -9
  87. data/test/visitors/test_bulk_insert_to_sql.rb +10 -8
  88. data/test/visitors/test_oracle.rb +42 -42
  89. data/test/visitors/test_to_sql.rb +196 -361
  90. data/test/with_ar/all_agnostic_test.rb +160 -195
  91. data/test/with_ar/insert_agnostic_test.rb +4 -3
  92. data/test/with_ar/test_bulk_sqlite.rb +9 -6
  93. data/test/with_ar/test_math_sqlite.rb +12 -8
  94. data/test/with_ar/test_string_mysql.rb +11 -5
  95. data/test/with_ar/test_string_sqlite.rb +12 -4
  96. metadata +11 -22
  97. data/.github/workflows/ruby.yml +0 -102
  98. data/gemfiles/rails6.gemfile +0 -30
  99. data/gemfiles/rails6_1.gemfile +0 -30
  100. data/gemspecs/arel_extensions-v1.gemspec +0 -28
  101. data/gemspecs/arel_extensions-v2.gemspec +0 -28
  102. data/generate_gems.sh +0 -15
  103. data/lib/arel_extensions/nodes/aggregate_function.rb +0 -13
  104. data/lib/arel_extensions/nodes/sum.rb +0 -7
  105. data/lib/arel_extensions/visitors/convert_format.rb +0 -37
  106. data/test/arelx_test_helper.rb +0 -26
  107. data/version_v1.rb +0 -3
  108. data/version_v2.rb +0 -3
@@ -1,10 +1,10 @@
1
1
  module ArelExtensions
2
2
  module Predications
3
- def when right, expression = nil
3
+ def when right, expression=nil
4
4
  ArelExtensions::Nodes::Case.new(self).when(right,expression)
5
5
  end
6
6
 
7
- def matches(other, escape = nil,case_sensitive = nil)
7
+ def matches(other, escape=nil,case_sensitive= nil)
8
8
  if Arel::VERSION.to_i < 7
9
9
  Arel::Nodes::Matches.new(self, Arel::Nodes.build_quoted(other), escape)
10
10
  else
@@ -12,7 +12,7 @@ module ArelExtensions
12
12
  end
13
13
  end
14
14
 
15
- def imatches(other, escape = nil)
15
+ def imatches(other, escape=nil)
16
16
  ArelExtensions::Nodes::IMatches.new(self, other, escape)
17
17
  end
18
18
 
@@ -20,53 +20,51 @@ module ArelExtensions
20
20
  ArelExtensions::Nodes::Cast.new([self,right])
21
21
  end
22
22
 
23
- def in(*other) # In should handle nil element in the Array
24
- other = other.first if other.length <= 1
23
+ def in(other) #In should handle nil element in the Array
25
24
  case other
26
25
  when Range
27
26
  self.between(other)
28
- when Arel::Nodes::Grouping, ArelExtensions::Nodes::Union, ArelExtensions::Nodes::UnionAll
29
- Arel::Nodes::In.new(self, quoted_node(other))
30
27
  when Enumerable
31
- nils, values = other.partition{ |v| v.nil? }
32
- ranges, values = values.partition{ |v| v.is_a?(Range) || v.is_a?(Arel::SelectManager)}
33
- # In order of (imagined) decreasing efficiency: nil, values, and then more complex.
34
- clauses =
35
- nils.uniq.map { |r| self.in(r) } \
36
- + (case values.uniq.size
37
- when 0 then []
38
- when 1 then [values[0].is_a?(Arel::Nodes::Grouping) ? self.in(values[0]) : self.eq(values[0])]
39
- else [Arel::Nodes::In.new(self, quoted_array(values))] end) \
40
- + ranges.uniq.map { |r| self.in(r) }
41
- clauses.empty? ? Arel.false : clauses.reduce(&:or)
28
+ if other.include?(nil)
29
+ other.delete(nil)
30
+ case other.length
31
+ when 0
32
+ self.is_null
33
+ when 1
34
+ self.is_null.or(self==other[0])
35
+ else
36
+ self.is_null.or(Arel::Nodes::In.new(self,quoted_array(other)))
37
+ end
38
+ else
39
+ Arel::Nodes::In.new(self,quoted_array(other))
40
+ end
42
41
  when nil
43
42
  self.is_null
44
43
  when Arel::SelectManager
45
44
  Arel::Nodes::In.new(self, other.ast)
46
45
  else
47
- Arel::Nodes::In.new(self, quoted_node(other))
46
+ Arel::Nodes::In.new(self,quoted_node(other))
48
47
  end
49
48
  end
50
49
 
51
- def not_in(*other) # In should handle nil element in the Array
52
- other = other.first if other.length <= 1
50
+ def not_in(other) #In should handle nil element in the Array
53
51
  case other
54
52
  when Range
55
53
  Arel::Nodes::Not.new(self.between(other))
56
- when Arel::Nodes::Grouping, ArelExtensions::Nodes::Union, ArelExtensions::Nodes::UnionAll
57
- Arel::Nodes::NotIn.new(self, quoted_node(other))
58
54
  when Enumerable
59
- nils, values = other.partition{ |v| v.nil? }
60
- ranges, values = values.partition{ |v| v.is_a?(Range) || v.is_a?(Arel::SelectManager)}
61
- # In order of (imagined) decreasing efficiency: nil, values, and then more complex.
62
- clauses =
63
- nils.uniq.map { |r| self.not_in(r) } \
64
- + (case values.uniq.size
65
- when 0 then []
66
- when 1 then [values[0].is_a?(Arel::Nodes::Grouping) ? self.not_in(values[0]) : self.not_eq(values[0])]
67
- else [Arel::Nodes::NotIn.new(self, quoted_array(values))] end) \
68
- + ranges.uniq.map { |r| self.not_in(r) }
69
- Arel::Nodes::And.new clauses
55
+ if other.include?(nil)
56
+ other.delete(nil)
57
+ case other.length
58
+ when 0
59
+ self.is_not_null
60
+ when 1
61
+ self.is_not_null.and(self!=other[0])
62
+ else
63
+ self.is_not_null.and(Arel::Nodes::NotIn.new(self,quoted_array(other)))
64
+ end
65
+ else
66
+ Arel::Nodes::NotIn.new(self,quoted_array(other))
67
+ end
70
68
  when nil
71
69
  self.is_not_null
72
70
  when Arel::SelectManager
@@ -93,8 +91,9 @@ module ArelExtensions
93
91
  when ActiveSupport::Duration
94
92
  object.to_i
95
93
  else
96
- raise(ArgumentError, "#{object.class} cannot be converted to CONCAT arg")
94
+ raise(ArgumentError, "#{object.class} can not be converted to CONCAT arg")
97
95
  end
98
96
  end
97
+
99
98
  end
100
99
  end
@@ -1,9 +1,9 @@
1
1
  require 'rails'
2
2
 
3
3
  module ArelExtensions
4
- class Railtie < Rails::Railtie
5
- rake_tasks do
6
- load 'arel_extensions/tasks.rb'
7
- end
8
- end
4
+ class Railtie < Rails::Railtie
5
+ rake_tasks do
6
+ load 'arel_extensions/tasks.rb'
7
+ end
8
+ end
9
9
  end
@@ -3,6 +3,7 @@ require 'arel_extensions/nodes/union_all'
3
3
 
4
4
  module ArelExtensions
5
5
  module SetFunctions
6
+
6
7
  def +(other)
7
8
  ArelExtensions::Nodes::Union.new(self,other)
8
9
  end
@@ -18,13 +19,14 @@ module ArelExtensions
18
19
  def uniq
19
20
  self
20
21
  end
22
+
21
23
  end
22
24
  end
23
25
 
24
- class Arel::Nodes::Union
26
+ Arel::Nodes::Union.class_eval do
25
27
  include ArelExtensions::SetFunctions
26
28
  end
27
29
 
28
- class Arel::Nodes::UnionAll
30
+ Arel::Nodes::UnionAll.class_eval do
29
31
  include ArelExtensions::SetFunctions
30
32
  end
@@ -1,4 +1,4 @@
1
- require 'arel_extensions/nodes/concat' # if Arel::VERSION.to_i < 7
1
+ require 'arel_extensions/nodes/concat' #if Arel::VERSION.to_i < 7
2
2
  require 'arel_extensions/nodes/length'
3
3
  require 'arel_extensions/nodes/locate'
4
4
  require 'arel_extensions/nodes/substring'
@@ -19,26 +19,19 @@ require 'arel_extensions/nodes/md5'
19
19
 
20
20
  module ArelExtensions
21
21
  module StringFunctions
22
- # *FindInSet function .......
22
+
23
+ #*FindInSet function .......
23
24
  def &(other)
24
25
  ArelExtensions::Nodes::FindInSet.new [other, self]
25
26
  end
26
27
 
27
- # LENGTH function returns the length (bytewise) of the value in a text field.
28
+ #LENGTH function returns the length of the value in a text field.
28
29
  def length
29
- ArelExtensions::Nodes::Length.new self, true
30
- end
31
-
32
- def byte_length
33
- ArelExtensions::Nodes::Length.new self, true
30
+ ArelExtensions::Nodes::Length.new [self]
34
31
  end
35
32
 
36
- def char_length
37
- ArelExtensions::Nodes::Length.new self, false
38
- end
39
-
40
- # LOCATE function returns the first starting position of a string in another string.
41
- # If string1 or string2 is NULL then it returns NULL. If string1 not found in string2 then it returns 0.
33
+ #LOCATE function returns the first starting position of a string in another string.
34
+ #If string1 or string2 is NULL then it returns NULL. If string1 not found in string2 then it returns 0.
42
35
  def locate val
43
36
  ArelExtensions::Nodes::Locate.new [self, val]
44
37
  end
@@ -58,7 +51,7 @@ module ArelExtensions
58
51
  end
59
52
  end
60
53
 
61
- # SOUNDEX function returns a character string containing the phonetic representation of char.
54
+ #SOUNDEX function returns a character string containing the phonetic representation of char.
62
55
  def soundex
63
56
  ArelExtensions::Nodes::Soundex.new [self]
64
57
  end
@@ -71,19 +64,6 @@ module ArelExtensions
71
64
  grouping_any :imatches, others, escape
72
65
  end
73
66
 
74
- # def grouping_any method, others, *extra
75
- # puts "*******************"
76
- # puts method
77
- # puts others.inspect
78
- # puts extra.inspect
79
- # puts "-------------------"
80
- # res = super(method,others,*extra)
81
- # puts res.to_sql
82
- # puts res.inspect
83
- # puts "*******************"
84
- # res
85
- # end
86
-
87
67
  def imatches_all others, escape = nil
88
68
  grouping_all :imatches, others, escape, escape
89
69
  end
@@ -112,7 +92,7 @@ module ArelExtensions
112
92
  ArelExtensions::Nodes::SMatches.new(self,other)
113
93
  end
114
94
 
115
- def ai_collate
95
+ def ai_collate
116
96
  ArelExtensions::Nodes::Collate.new(self,nil,true,false)
117
97
  end
118
98
 
@@ -120,43 +100,34 @@ module ArelExtensions
120
100
  ArelExtensions::Nodes::Collate.new(self,nil,false,true)
121
101
  end
122
102
 
123
- def collate ai = false,ci = false, option = nil
103
+ def collate ai=false,ci=false, option=nil
124
104
  ArelExtensions::Nodes::Collate.new(self,option,ai,ci)
125
105
  end
126
106
 
127
- # REPLACE function replaces a sequence of characters in a string with another set of characters, not case-sensitive.
128
- def replace pattern, substitute
129
- if pattern.is_a? Regexp
130
- ArelExtensions::Nodes::RegexpReplace.new self, pattern, substitute
131
- else
132
- ArelExtensions::Nodes::Replace.new self, pattern, substitute
133
- end
134
- end
135
-
136
- def regexp_replace pattern, substitute
137
- ArelExtensions::Nodes::RegexpReplace.new self, pattern, substitute
107
+ #REPLACE function replaces a sequence of characters in a string with another set of characters, not case-sensitive.
108
+ def replace left, right
109
+ ArelExtensions::Nodes::Replace.new [self, left, right]
138
110
  end
139
-
111
+
140
112
  def concat other
141
113
  ArelExtensions::Nodes::Concat.new [self, other]
142
114
  end
143
115
 
144
- # concat elements of a group, separated by sep and ordered by a list of Ascending or Descending
145
- def group_concat(sep = nil, *orders, group: nil, order: nil)
146
- if orders.present?
147
- warn("Warning : ArelExtensions: group_concat: you should now use the kwarg 'order' to specify an order in the group_concat.")
148
- end
116
+ #concat elements of a group, separated by sep and ordered by a list of Ascending or Descending
117
+ def group_concat sep = nil, *orders
149
118
  order_tabs = [orders].flatten.map{ |o|
150
119
  if o.is_a?(Arel::Nodes::Ascending) || o.is_a?(Arel::Nodes::Descending)
151
120
  o
152
121
  elsif o.respond_to?(:asc)
153
122
  o.asc
123
+ else
124
+ nil
154
125
  end
155
126
  }.compact
156
- ArelExtensions::Nodes::GroupConcat.new(self, sep, group: group, order: (order || order_tabs))
127
+ ArelExtensions::Nodes::GroupConcat.new [self, sep, order_tabs]
157
128
  end
158
129
 
159
- # Function returns a string after removing left, right or the both prefixes or suffixes int argument
130
+ #Function returns a string after removing left, right or the both prefixes or suffixes int argument
160
131
  def trim other = ' '
161
132
  ArelExtensions::Nodes::Trim.new [self, other]
162
133
  end
@@ -184,11 +155,11 @@ module ArelExtensions
184
155
  def not_blank
185
156
  ArelExtensions::Nodes::NotBlank.new [self]
186
157
  end
187
-
188
- def repeat other = 1
158
+
159
+ def repeat other = 1
189
160
  ArelExtensions::Nodes::Repeat.new [self, other]
190
161
  end
191
-
162
+
192
163
  def levenshtein_distance other
193
164
  ArelExtensions::Nodes::LevenshteinDistance.new [self, other]
194
165
  end
@@ -1,12 +1,12 @@
1
1
  namespace :arel_extensions do
2
- desc 'Install DB functions into current DB'
3
- task install_functions: :environment do
4
- @env_db = if ENV['DB'] == 'oracle' && ((defined?(RUBY_ENGINE) && RUBY_ENGINE == "rbx") || (RUBY_PLATFORM == 'java')) # not supported
2
+ desc 'Install DB functions into current DB'
3
+ task :install_functions => :environment do
4
+ @env_db = if ENV['DB'] == 'oracle' && ((defined?(RUBY_ENGINE) && RUBY_ENGINE == "rbx") || (RUBY_PLATFORM == 'java')) # not supported
5
5
  (RUBY_PLATFORM == 'java' ? "jdbc-sqlite" : 'sqlite')
6
6
  else
7
7
  ENV['DB'] || ActiveRecord::Base.connection.adapter_name
8
8
  end
9
- ActiveRecord::Base.establish_connection(Rails.env.to_sym)
9
+ ActiveRecord::Base.establish_connection(Rails.env)
10
10
  CommonSqlFunctions.new(ActiveRecord::Base.connection).add_sql_functions(@env_db)
11
- end
11
+ end
12
12
  end
@@ -1,3 +1,3 @@
1
1
  module ArelExtensions
2
- VERSION = "1.2.25".freeze
2
+ VERSION = "2.0.0.rc3".freeze
3
3
  end
@@ -1,6 +1,7 @@
1
1
  module ArelExtensions
2
2
  module Visitors
3
- class Arel::Visitors::IBM_DB
3
+ Arel::Visitors::IBM_DB.class_eval do
4
+
4
5
  def visit_ArelExtensions_Nodes_Ceil o, collector
5
6
  collector << "CEILING("
6
7
  collector = visit o.expr, collector
@@ -11,13 +12,14 @@ module ArelExtensions
11
12
  def visit_ArelExtensions_Nodes_Trim o, collector
12
13
  collector << "LTRIM(RTRIM("
13
14
  o.expressions.each_with_index { |arg, i|
14
- collector << COMMA if i != 0
15
+ collector << Arel::Visitors::IBM_DB::COMMA unless i == 0
15
16
  collector = visit arg, collector
16
17
  }
17
18
  collector << "))"
18
19
  collector
19
20
  end
20
21
 
22
+
21
23
  def visit_ArelExtensions_Nodes_DateDiff o, collector
22
24
  collector << "DAY("
23
25
  collector = visit o.left, collector
@@ -31,8 +33,9 @@ module ArelExtensions
31
33
  collector
32
34
  end
33
35
 
36
+
34
37
  def visit_ArelExtensions_Nodes_Duration o, collector
35
- # visit left for period
38
+ #visit left for period
36
39
  if o.left == "d"
37
40
  collector << "DAY("
38
41
  elsif o.left == "m"
@@ -42,7 +45,7 @@ module ArelExtensions
42
45
  elsif o.left == "y"
43
46
  collector << "YEAR("
44
47
  end
45
- # visit right
48
+ #visit right
46
49
  if o.right.is_a?(Arel::Attributes::Attribute)
47
50
  collector = visit o.right, collector
48
51
  else
@@ -52,11 +55,12 @@ module ArelExtensions
52
55
  collector
53
56
  end
54
57
 
58
+
55
59
  def visit_ArelExtensions_Nodes_IsNull o, collector
56
60
  collector << "COALESCE("
57
61
  collector = visit o.left, collector
58
62
  collector << ","
59
- if (o.right.is_a?(Arel::Attributes::Attribute))
63
+ if(o.right.is_a?(Arel::Attributes::Attribute))
60
64
  collector = visit o.right, collector
61
65
  else
62
66
  collector << "'#{o.right}'"
@@ -64,6 +68,9 @@ module ArelExtensions
64
68
  collector << ")"
65
69
  collector
66
70
  end
71
+
72
+
73
+
67
74
  end
68
75
  end
69
76
  end
@@ -1,26 +1,13 @@
1
1
  module ArelExtensions
2
2
  module Visitors
3
3
  module MSSQL
4
-
5
- Arel::Visitors::MSSQL::DATE_MAPPING = {
6
- 'd' => 'day', 'm' => 'month', 'y' => 'year', 'wd' => 'weekday', 'w' => 'week', 'h' => 'hour', 'mn' => 'minute', 's' => 'second'
7
- }.freeze
8
-
4
+ Arel::Visitors::MSSQL::DATE_MAPPING = {'d' => 'day', 'm' => 'month', 'y' => 'year', 'wd' => 'weekday', 'w' => 'week', 'h' => 'hour', 'mn' => 'minute', 's' => 'second'}
9
5
  Arel::Visitors::MSSQL::DATE_FORMAT_DIRECTIVES = {
10
6
  '%Y' => 'YYYY', '%C' => '', '%y' => 'YY', '%m' => 'MM', '%B' => '', '%b' => '', '%^b' => '', # year, month
11
7
  '%d' => 'DD', '%e' => '', '%j' => '', '%w' => 'dw', '%A' => '', # day, weekday
12
8
  '%H' => 'hh', '%k' => '', '%I' => '', '%l' => '', '%P' => '', '%p' => '', # hours
13
9
  '%M' => 'mi', '%S' => 'ss', '%L' => 'ms', '%N' => 'ns', '%z' => 'tz'
14
- }.freeze
15
-
16
- Arel::Visitors::MSSQL::DATE_FORMAT_REGEX =
17
- Regexp.new(
18
- Arel::Visitors::MSSQL::DATE_FORMAT_DIRECTIVES
19
- .keys
20
- .map{|k| Regexp.escape(k)}
21
- .join('|')
22
- ).freeze
23
-
10
+ }
24
11
  # TODO; all others... http://www.sql-server-helper.com/tips/date-formats.aspx
25
12
  Arel::Visitors::MSSQL::DATE_CONVERT_FORMATS = {
26
13
  'YYYY-MM-DD' => 120,
@@ -32,7 +19,7 @@ module ArelExtensions
32
19
  'DD-MM-YY' => 5,
33
20
  'DD.MM.YYYY' => 104,
34
21
  'YYYY-MM-DDTHH:MM:SS:MMM' => 126
35
- }.freeze
22
+ }
36
23
 
37
24
  # Math Functions
38
25
  def visit_ArelExtensions_Nodes_Ceil o, collector
@@ -45,7 +32,7 @@ module ArelExtensions
45
32
  def visit_ArelExtensions_Nodes_Log10 o, collector
46
33
  collector << "LOG10("
47
34
  o.expressions.each_with_index { |arg, i|
48
- collector << Arel::Visitors::ToSql::COMMA if i != 0
35
+ collector << Arel::Visitors::ToSql::COMMA unless i == 0
49
36
  collector = visit arg, collector
50
37
  }
51
38
  collector << ")"
@@ -55,7 +42,7 @@ module ArelExtensions
55
42
  def visit_ArelExtensions_Nodes_Power o, collector
56
43
  collector << "POWER("
57
44
  o.expressions.each_with_index { |arg, i|
58
- collector << Arel::Visitors::ToSql::COMMA if i != 0
45
+ collector << Arel::Visitors::ToSql::COMMA unless i == 0
59
46
  collector = visit arg, collector
60
47
  }
61
48
  collector << ")"
@@ -79,7 +66,7 @@ module ArelExtensions
79
66
  def visit_ArelExtensions_Nodes_Concat o, collector
80
67
  collector << "CONCAT("
81
68
  o.expressions.each_with_index { |arg, i|
82
- collector << Arel::Visitors::MSSQL::COMMA if i != 0
69
+ collector << Arel::Visitors::MSSQL::COMMA unless i == 0
83
70
  collector = visit arg, collector
84
71
  }
85
72
  collector << ")"
@@ -89,7 +76,7 @@ module ArelExtensions
89
76
  def visit_ArelExtensions_Nodes_Repeat o, collector
90
77
  collector << "REPLICATE("
91
78
  o.expressions.each_with_index { |arg, i|
92
- collector << Arel::Visitors::ToSql::COMMA if i != 0
79
+ collector << Arel::Visitors::ToSql::COMMA unless i == 0
93
80
  collector = visit arg, collector
94
81
  }
95
82
  collector << ")"
@@ -99,12 +86,12 @@ module ArelExtensions
99
86
 
100
87
 
101
88
  def visit_ArelExtensions_Nodes_DateDiff o, collector
102
- case o.right_node_type
103
- when :ruby_date, :ruby_time, :date, :datetime, :time
104
- collector << case o.left_node_type
105
- when :ruby_time, :datetime, :time then 'DATEDIFF(second'
106
- else 'DATEDIFF(day'
107
- end
89
+ if o.right_node_type == :ruby_date || o.right_node_type == :ruby_time || o.right_node_type == :date || o.right_node_type == :datetime || o.right_node_type == :time
90
+ collector << if o.left_node_type == :ruby_time || o.left_node_type == :datetime || o.left_node_type == :time
91
+ 'DATEDIFF(second'
92
+ else
93
+ 'DATEDIFF(day'
94
+ end
108
95
  collector << Arel::Visitors::MSSQL::COMMA
109
96
  collector = visit o.right, collector
110
97
  collector << Arel::Visitors::MSSQL::COMMA
@@ -155,7 +142,7 @@ module ArelExtensions
155
142
  end
156
143
 
157
144
  def visit_ArelExtensions_Nodes_Length o, collector
158
- collector << "#{o.bytewise ? 'DATALENGTH' : 'LEN'}("
145
+ collector << "LEN("
159
146
  collector = visit o.expr, collector
160
147
  collector << ")"
161
148
  collector
@@ -164,7 +151,7 @@ module ArelExtensions
164
151
  def visit_ArelExtensions_Nodes_Round o, collector
165
152
  collector << "ROUND("
166
153
  o.expressions.each_with_index { |arg, i|
167
- collector << Arel::Visitors::MSSQL::COMMA if i != 0
154
+ collector << Arel::Visitors::MSSQL::COMMA unless i == 0
168
155
  collector = visit arg, collector
169
156
  }
170
157
  if o.expressions.length == 1
@@ -255,34 +242,42 @@ module ArelExtensions
255
242
  end
256
243
 
257
244
  def visit_ArelExtensions_Nodes_Format o, collector
258
- f = ArelExtensions::Visitors::strftime_to_format(o.iso_format, Arel::Visitors::MSSQL::DATE_FORMAT_DIRECTIVES)
259
- if fmt = Arel::Visitors::MSSQL::DATE_CONVERT_FORMATS[f]
245
+ f = o.iso_format.dup
246
+ Arel::Visitors::MSSQL::DATE_FORMAT_DIRECTIVES.each { |d, r| f.gsub!(d, r) }
247
+ if Arel::Visitors::MSSQL::DATE_CONVERT_FORMATS[f]
260
248
  collector << "CONVERT(VARCHAR(#{f.length})"
261
249
  collector << Arel::Visitors::MSSQL::COMMA
262
250
  collector = visit o.left, collector
263
251
  collector << Arel::Visitors::MSSQL::COMMA
264
- collector << fmt.to_s
252
+ collector << Arel::Visitors::MSSQL::DATE_CONVERT_FORMATS[f].to_s
265
253
  collector << ')'
266
254
  collector
267
255
  else
268
- s = StringScanner.new o.iso_format
269
256
  collector << "("
270
- sep = ''
271
- while !s.eos?
272
- collector << sep
273
- sep = ' + '
274
- case
275
- when s.scan(Arel::Visitors::MSSQL::DATE_FORMAT_REGEX)
276
- dir = Arel::Visitors::MSSQL::DATE_FORMAT_DIRECTIVES[s.matched]
277
- collector << 'LTRIM(STR(DATEPART('
278
- collector << dir
279
- collector << Arel::Visitors::MSSQL::COMMA
280
- collector = visit o.left, collector
281
- collector << ')))'
282
- when s.scan(/[^%]+|./)
283
- collector = visit Arel::Nodes.build_quoted(s.matched), collector
257
+ t = o.iso_format.split('%')
258
+ t.each_with_index {|str, i|
259
+ if i == 0 && t[0] != '%'
260
+ collector = visit Arel::Nodes.build_quoted(str), collector
261
+ if str.length > 1
262
+ collector << Arel::Visitors::MSSQL::COMMA
263
+ collector = visit Arel::Nodes.build_quoted(str.sub(/\A./, '')), collector
264
+ end
265
+ elsif str.length > 0
266
+ if !Arel::Visitors::MSSQL::DATE_FORMAT_DIRECTIVES['%' + str[0]].blank?
267
+ collector << 'LTRIM(STR(DATEPART('
268
+ collector << Arel::Visitors::MSSQL::DATE_FORMAT_DIRECTIVES['%' + str[0]]
269
+ collector << Arel::Visitors::MSSQL::COMMA
270
+ collector = visit o.left, collector
271
+ collector << ')))'
272
+ if str.length > 1
273
+ collector << ' + '
274
+ collector = visit Arel::Nodes.build_quoted(str.sub(/\A./, '')), collector
275
+ end
276
+ end
284
277
  end
285
- end
278
+ collector << ' + ' if t[i + 1]
279
+ }
280
+
286
281
  collector << ')'
287
282
  collector
288
283
  end
@@ -291,7 +286,7 @@ module ArelExtensions
291
286
  def visit_ArelExtensions_Nodes_Replace o, collector
292
287
  collector << "REPLACE("
293
288
  o.expressions.each_with_index { |arg, i|
294
- collector << Arel::Visitors::MSSQL::COMMA if i != 0
289
+ collector << Arel::Visitors::MSSQL::COMMA unless i == 0
295
290
  collector = visit arg, collector
296
291
  }
297
292
  collector << ")"
@@ -301,7 +296,7 @@ module ArelExtensions
301
296
  def visit_ArelExtensions_Nodes_FindInSet o, collector
302
297
  collector << "dbo.FIND_IN_SET("
303
298
  o.expressions.each_with_index { |arg, i|
304
- collector << Arel::Visitors::MSSQL::COMMA if i != 0
299
+ collector << Arel::Visitors::MSSQL::COMMA unless i == 0
305
300
  collector = visit arg, collector
306
301
  }
307
302
  collector << ")"
@@ -405,16 +400,15 @@ module ArelExtensions
405
400
  collector << "(STRING_AGG("
406
401
  collector = visit o.left, collector
407
402
  collector << Arel::Visitors::Oracle::COMMA
408
- collector =
409
- if o.separator && o.separator != 'NULL'
410
- visit o.separator, collector
411
- else
412
- visit Arel::Nodes.build_quoted(','), collector
413
- end
403
+ if o.right && o.right != 'NULL'
404
+ collector = visit o.right, collector
405
+ else
406
+ collector = visit Arel::Nodes.build_quoted(','), collector
407
+ end
414
408
  collector << ") WITHIN GROUP (ORDER BY "
415
- if o.order.present?
416
- o.order.each_with_index do |order,i|
417
- collector << Arel::Visitors::Oracle::COMMA if i != 0
409
+ if !o.orders.blank?
410
+ o.orders.each_with_index do |order,i|
411
+ collector << Arel::Visitors::Oracle::COMMA unless i == 0
418
412
  collector = visit order, collector
419
413
  end
420
414
  else
@@ -472,9 +466,8 @@ module ArelExtensions
472
466
  Arel::Nodes.build_quoted(1) :
473
467
  ArelExtensions::Nodes::Case.new.when(col<0).then(1).else(0)
474
468
 
475
- number =
476
- if o.scientific_notation
477
- ArelExtensions::Nodes::Concat.new([
469
+ if o.scientific_notation
470
+ number = ArelExtensions::Nodes::Concat.new([
478
471
  Arel::Nodes::NamedFunction.new('FORMAT',[
479
472
  col.abs/Arel::Nodes.build_quoted(10).pow(col.abs.log10.floor),
480
473
  param,
@@ -487,13 +480,13 @@ module ArelExtensions
487
480
  locale
488
481
  ])
489
482
  ])
490
- else
491
- Arel::Nodes::NamedFunction.new('FORMAT',[
483
+ else
484
+ number = Arel::Nodes::NamedFunction.new('FORMAT',[
492
485
  Arel::Nodes.build_quoted(col.abs),
493
486
  param,
494
487
  locale
495
488
  ])
496
- end
489
+ end
497
490
 
498
491
  repeated_char = (o.width == 0) ? Arel::Nodes.build_quoted('') : ArelExtensions::Nodes::Case.new().
499
492
  when(Arel::Nodes.build_quoted(o.width).abs-(number.length+sign_length)>0).
@@ -555,6 +548,7 @@ module ArelExtensions
555
548
  collector
556
549
  end
557
550
 
551
+
558
552
  end
559
553
  end
560
554
  end