arel_extensions 1.2.25 → 2.0.0.rc3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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