arel_extensions 2.0.9 → 2.0.14

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 (92) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -0
  3. data/Gemfile +10 -10
  4. data/Rakefile +4 -4
  5. data/gemfiles/rails3.gemfile +9 -9
  6. data/gemfiles/rails4.gemfile +13 -13
  7. data/gemfiles/rails5_0.gemfile +13 -13
  8. data/gemfiles/rails5_1_4.gemfile +13 -13
  9. data/gemfiles/rails5_2.gemfile +13 -13
  10. data/gemfiles/rails6.gemfile +13 -13
  11. data/lib/arel_extensions.rb +3 -3
  12. data/lib/arel_extensions/attributes.rb +0 -0
  13. data/lib/arel_extensions/boolean_functions.rb +21 -5
  14. data/lib/arel_extensions/common_sql_functions.rb +2 -4
  15. data/lib/arel_extensions/comparators.rb +11 -14
  16. data/lib/arel_extensions/date_duration.rb +4 -5
  17. data/lib/arel_extensions/insert_manager.rb +16 -17
  18. data/lib/arel_extensions/math.rb +8 -9
  19. data/lib/arel_extensions/math_functions.rb +15 -17
  20. data/lib/arel_extensions/nodes/abs.rb +0 -1
  21. data/lib/arel_extensions/nodes/aggregate_function.rb +0 -1
  22. data/lib/arel_extensions/nodes/blank.rb +0 -1
  23. data/lib/arel_extensions/nodes/case.rb +3 -4
  24. data/lib/arel_extensions/nodes/cast.rb +4 -2
  25. data/lib/arel_extensions/nodes/ceil.rb +1 -1
  26. data/lib/arel_extensions/nodes/change_case.rb +0 -0
  27. data/lib/arel_extensions/nodes/coalesce.rb +0 -1
  28. data/lib/arel_extensions/nodes/collate.rb +0 -1
  29. data/lib/arel_extensions/nodes/concat.rb +1 -3
  30. data/lib/arel_extensions/nodes/date_diff.rb +7 -8
  31. data/lib/arel_extensions/nodes/duration.rb +0 -1
  32. data/lib/arel_extensions/nodes/find_in_set.rb +0 -1
  33. data/lib/arel_extensions/nodes/floor.rb +1 -1
  34. data/lib/arel_extensions/nodes/format.rb +27 -1
  35. data/lib/arel_extensions/nodes/formatted_number.rb +0 -1
  36. data/lib/arel_extensions/nodes/function.rb +18 -15
  37. data/lib/arel_extensions/nodes/is_null.rb +0 -0
  38. data/lib/arel_extensions/nodes/json.rb +39 -30
  39. data/lib/arel_extensions/nodes/length.rb +0 -1
  40. data/lib/arel_extensions/nodes/levenshtein_distance.rb +0 -0
  41. data/lib/arel_extensions/nodes/locate.rb +0 -1
  42. data/lib/arel_extensions/nodes/log10.rb +1 -2
  43. data/lib/arel_extensions/nodes/matches.rb +0 -2
  44. data/lib/arel_extensions/nodes/md5.rb +0 -1
  45. data/lib/arel_extensions/nodes/power.rb +0 -1
  46. data/lib/arel_extensions/nodes/rand.rb +0 -1
  47. data/lib/arel_extensions/nodes/repeat.rb +0 -2
  48. data/lib/arel_extensions/nodes/replace.rb +0 -2
  49. data/lib/arel_extensions/nodes/round.rb +0 -1
  50. data/lib/arel_extensions/nodes/soundex.rb +0 -1
  51. data/lib/arel_extensions/nodes/std.rb +0 -1
  52. data/lib/arel_extensions/nodes/substring.rb +0 -1
  53. data/lib/arel_extensions/nodes/sum.rb +0 -0
  54. data/lib/arel_extensions/nodes/then.rb +0 -0
  55. data/lib/arel_extensions/nodes/trim.rb +0 -2
  56. data/lib/arel_extensions/nodes/union.rb +0 -2
  57. data/lib/arel_extensions/nodes/union_all.rb +0 -2
  58. data/lib/arel_extensions/nodes/wday.rb +0 -4
  59. data/lib/arel_extensions/null_functions.rb +3 -5
  60. data/lib/arel_extensions/predications.rb +5 -6
  61. data/lib/arel_extensions/railtie.rb +5 -5
  62. data/lib/arel_extensions/set_functions.rb +0 -2
  63. data/lib/arel_extensions/string_functions.rb +21 -22
  64. data/lib/arel_extensions/tasks.rb +1 -1
  65. data/lib/arel_extensions/version.rb +1 -1
  66. data/lib/arel_extensions/visitors.rb +9 -7
  67. data/lib/arel_extensions/visitors/convert_format.rb +37 -0
  68. data/lib/arel_extensions/visitors/ibm_db.rb +4 -11
  69. data/lib/arel_extensions/visitors/mssql.rb +48 -44
  70. data/lib/arel_extensions/visitors/mysql.rb +65 -67
  71. data/lib/arel_extensions/visitors/oracle.rb +58 -55
  72. data/lib/arel_extensions/visitors/oracle12.rb +2 -3
  73. data/lib/arel_extensions/visitors/postgresql.rb +41 -34
  74. data/lib/arel_extensions/visitors/sqlite.rb +23 -18
  75. data/lib/arel_extensions/visitors/to_sql.rb +69 -61
  76. data/test/arelx_test_helper.rb +0 -2
  77. data/test/real_db_test.rb +27 -42
  78. data/test/support/fake_record.rb +1 -1
  79. data/test/test_comparators.rb +0 -4
  80. data/test/visitors/test_bulk_insert_oracle.rb +0 -1
  81. data/test/visitors/test_bulk_insert_sqlite.rb +0 -2
  82. data/test/visitors/test_oracle.rb +1 -2
  83. data/test/visitors/test_to_sql.rb +16 -25
  84. data/test/with_ar/all_agnostic_test.rb +135 -139
  85. data/test/with_ar/insert_agnostic_test.rb +0 -2
  86. data/test/with_ar/test_bulk_sqlite.rb +0 -4
  87. data/test/with_ar/test_math_sqlite.rb +4 -8
  88. data/test/with_ar/test_string_mysql.rb +1 -5
  89. data/test/with_ar/test_string_sqlite.rb +1 -5
  90. data/version_v1.rb +1 -1
  91. data/version_v2.rb +1 -1
  92. metadata +3 -2
@@ -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,7 +3,6 @@ require 'arel_extensions/nodes/union_all'
3
3
 
4
4
  module ArelExtensions
5
5
  module SetFunctions
6
-
7
6
  def +(other)
8
7
  ArelExtensions::Nodes::Union.new(self,other)
9
8
  end
@@ -19,7 +18,6 @@ module ArelExtensions
19
18
  def uniq
20
19
  self
21
20
  end
22
-
23
21
  end
24
22
  end
25
23
 
@@ -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,19 +19,18 @@ require 'arel_extensions/nodes/md5'
19
19
 
20
20
  module ArelExtensions
21
21
  module StringFunctions
22
-
23
- #*FindInSet function .......
22
+ # *FindInSet function .......
24
23
  def &(other)
25
24
  ArelExtensions::Nodes::FindInSet.new [other, self]
26
25
  end
27
26
 
28
- #LENGTH function returns the length of the value in a text field.
27
+ # LENGTH function returns the length of the value in a text field.
29
28
  def length
30
29
  ArelExtensions::Nodes::Length.new [self]
31
30
  end
32
31
 
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.
32
+ # LOCATE function returns the first starting position of a string in another string.
33
+ # If string1 or string2 is NULL then it returns NULL. If string1 not found in string2 then it returns 0.
35
34
  def locate val
36
35
  ArelExtensions::Nodes::Locate.new [self, val]
37
36
  end
@@ -51,7 +50,7 @@ module ArelExtensions
51
50
  end
52
51
  end
53
52
 
54
- #SOUNDEX function returns a character string containing the phonetic representation of char.
53
+ # SOUNDEX function returns a character string containing the phonetic representation of char.
55
54
  def soundex
56
55
  ArelExtensions::Nodes::Soundex.new [self]
57
56
  end
@@ -64,18 +63,18 @@ module ArelExtensions
64
63
  grouping_any :imatches, others, escape
65
64
  end
66
65
 
67
- # def grouping_any method, others, *extra
68
- # puts "*******************"
69
- # puts method
70
- # puts others.inspect
71
- # puts extra.inspect
72
- # puts "-------------------"
73
- # res = super(method,others,*extra)
74
- # puts res.to_sql
75
- # puts res.inspect
76
- # puts "*******************"
77
- # res
78
- # end
66
+ # def grouping_any method, others, *extra
67
+ # puts "*******************"
68
+ # puts method
69
+ # puts others.inspect
70
+ # puts extra.inspect
71
+ # puts "-------------------"
72
+ # res = super(method,others,*extra)
73
+ # puts res.to_sql
74
+ # puts res.inspect
75
+ # puts "*******************"
76
+ # res
77
+ # end
79
78
 
80
79
  def imatches_all others, escape = nil
81
80
  grouping_all :imatches, others, escape, escape
@@ -117,7 +116,7 @@ module ArelExtensions
117
116
  ArelExtensions::Nodes::Collate.new(self,option,ai,ci)
118
117
  end
119
118
 
120
- #REPLACE function replaces a sequence of characters in a string with another set of characters, not case-sensitive.
119
+ # REPLACE function replaces a sequence of characters in a string with another set of characters, not case-sensitive.
121
120
  def replace pattern, substitute
122
121
  if pattern.is_a? Regexp
123
122
  ArelExtensions::Nodes::RegexpReplace.new self, pattern, substitute
@@ -134,7 +133,7 @@ module ArelExtensions
134
133
  ArelExtensions::Nodes::Concat.new [self, other]
135
134
  end
136
135
 
137
- #concat elements of a group, separated by sep and ordered by a list of Ascending or Descending
136
+ # concat elements of a group, separated by sep and ordered by a list of Ascending or Descending
138
137
  def group_concat(sep = nil, *orders, group: nil, order: nil)
139
138
  if orders.present?
140
139
  warn("Warning : ArelExtensions: group_concat: you should now use the kwarg 'order' to specify an order in the group_concat.")
@@ -149,7 +148,7 @@ module ArelExtensions
149
148
  ArelExtensions::Nodes::GroupConcat.new(self, sep, group: group, order: (order || order_tabs))
150
149
  end
151
150
 
152
- #Function returns a string after removing left, right or the both prefixes or suffixes int argument
151
+ # Function returns a string after removing left, right or the both prefixes or suffixes int argument
153
152
  def trim other = ' '
154
153
  ArelExtensions::Nodes::Trim.new [self, other]
155
154
  end
@@ -1,6 +1,6 @@
1
1
  namespace :arel_extensions do
2
2
  desc 'Install DB functions into current DB'
3
- task :install_functions => :environment do
3
+ task install_functions: :environment do
4
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
@@ -1,3 +1,3 @@
1
1
  module ArelExtensions
2
- VERSION = "2.0.9".freeze
2
+ VERSION = "2.0.14".freeze
3
3
  end
@@ -1,3 +1,4 @@
1
+ require 'arel_extensions/visitors/convert_format'
1
2
  require 'arel_extensions/visitors/to_sql'
2
3
  require 'arel_extensions/visitors/mysql'
3
4
  require 'arel_extensions/visitors/oracle'
@@ -9,7 +10,7 @@ require 'arel_extensions/visitors/mssql'
9
10
  class Arel::Visitors::MSSQL
10
11
  include ArelExtensions::Visitors::MSSQL
11
12
 
12
- alias_method :old_visit_Arel_Nodes_As, :visit_Arel_Nodes_As
13
+ alias_method(:old_visit_Arel_Nodes_As, :visit_Arel_Nodes_As) rescue nil
13
14
  def visit_Arel_Nodes_As o, collector
14
15
  if o.left.is_a?(Arel::Nodes::Binary)
15
16
  collector << '('
@@ -24,7 +25,7 @@ class Arel::Visitors::MSSQL
24
25
  collector
25
26
  end
26
27
 
27
- alias_method :old_visit_Arel_Nodes_SelectStatement, :visit_Arel_Nodes_SelectStatement
28
+ alias_method(:old_visit_Arel_Nodes_SelectStatement, :visit_Arel_Nodes_SelectStatement) rescue nil
28
29
  def visit_Arel_Nodes_SelectStatement o, collector
29
30
  if !collector.value.blank? && o.limit.blank? && o.offset.blank?
30
31
  o = o.dup
@@ -41,7 +42,7 @@ begin
41
42
  Arel::Visitors::VISITORS['sqlserver'].class_eval do
42
43
  include ArelExtensions::Visitors::MSSQL
43
44
 
44
- alias_method :old_visit_Arel_Nodes_SelectStatement, :visit_Arel_Nodes_SelectStatement
45
+ alias_method(:old_visit_Arel_Nodes_SelectStatement, :visit_Arel_Nodes_SelectStatement) rescue nil
45
46
  def visit_Arel_Nodes_SelectStatement o, collector
46
47
  if !collector.value.blank? && o.limit.blank? && o.offset.blank?
47
48
  o = o.dup
@@ -50,7 +51,7 @@ begin
50
51
  old_visit_Arel_Nodes_SelectStatement(o,collector)
51
52
  end
52
53
 
53
- alias_method :old_visit_Arel_Nodes_As, :visit_Arel_Nodes_As
54
+ alias_method(:old_visit_Arel_Nodes_As, :visit_Arel_Nodes_As) rescue nil
54
55
  def visit_Arel_Nodes_As o, collector
55
56
  if o.left.is_a?(Arel::Nodes::Binary)
56
57
  collector << '('
@@ -65,17 +66,18 @@ begin
65
66
  collector
66
67
  end
67
68
 
68
- alias_method :old_primary_Key_From_Table, :primary_Key_From_Table
69
+ alias_method(:old_primary_Key_From_Table, :primary_Key_From_Table) rescue nil
69
70
  def primary_Key_From_Table t
70
71
  return unless t
72
+
71
73
  column_name = @connection.schema_cache.primary_keys(t.name) ||
72
- @connection.schema_cache.columns_hash(t.name).first.try(:second).try(:name)
74
+ @connection.schema_cache.columns_hash(t.name).first.try(:second).try(:name)
73
75
  column_name ? t[column_name] : nil
74
76
  end
75
77
  end
76
78
  end
77
79
  end
78
- rescue LoadError
80
+ rescue LoadError
79
81
  rescue => e
80
82
  e
81
83
  end
@@ -0,0 +1,37 @@
1
+ module ArelExtensions
2
+ module Visitors
3
+ # Convert date format in strftime syntax to whatever the RDBMs
4
+ # wants, based on the table of conversion +mapping+.
5
+ def self.strftime_to_format format, mapping
6
+ @mapping_regexps ||= {}
7
+ @mapping_regexps[mapping] ||=
8
+ Regexp.new(
9
+ mapping
10
+ .keys
11
+ .map{|k| Regexp.escape(k)}
12
+ .join('|')
13
+ )
14
+
15
+ regexp = @mapping_regexps[mapping]
16
+ s = StringScanner.new format
17
+ res = StringIO.new
18
+ while !s.eos?
19
+ res <<
20
+ case
21
+ when s.scan(regexp)
22
+ if v = mapping[s.matched]
23
+ v
24
+ else
25
+ # Should never happen.
26
+ s.matched
27
+ end
28
+ when s.scan(/[^%]+/)
29
+ s.matched
30
+ when s.scan(/./)
31
+ s.matched
32
+ end
33
+ end
34
+ res.string
35
+ end
36
+ end
37
+ end
@@ -1,7 +1,6 @@
1
1
  module ArelExtensions
2
2
  module Visitors
3
3
  class Arel::Visitors::IBM_DB
4
-
5
4
  def visit_ArelExtensions_Nodes_Ceil o, collector
6
5
  collector << "CEILING("
7
6
  collector = visit o.expr, collector
@@ -12,14 +11,13 @@ module ArelExtensions
12
11
  def visit_ArelExtensions_Nodes_Trim o, collector
13
12
  collector << "LTRIM(RTRIM("
14
13
  o.expressions.each_with_index { |arg, i|
15
- collector << Arel::Visitors::IBM_DB::COMMA unless i == 0
14
+ collector << COMMA if i != 0
16
15
  collector = visit arg, collector
17
16
  }
18
17
  collector << "))"
19
18
  collector
20
19
  end
21
20
 
22
-
23
21
  def visit_ArelExtensions_Nodes_DateDiff o, collector
24
22
  collector << "DAY("
25
23
  collector = visit o.left, collector
@@ -33,9 +31,8 @@ module ArelExtensions
33
31
  collector
34
32
  end
35
33
 
36
-
37
34
  def visit_ArelExtensions_Nodes_Duration o, collector
38
- #visit left for period
35
+ # visit left for period
39
36
  if o.left == "d"
40
37
  collector << "DAY("
41
38
  elsif o.left == "m"
@@ -45,7 +42,7 @@ module ArelExtensions
45
42
  elsif o.left == "y"
46
43
  collector << "YEAR("
47
44
  end
48
- #visit right
45
+ # visit right
49
46
  if o.right.is_a?(Arel::Attributes::Attribute)
50
47
  collector = visit o.right, collector
51
48
  else
@@ -55,12 +52,11 @@ module ArelExtensions
55
52
  collector
56
53
  end
57
54
 
58
-
59
55
  def visit_ArelExtensions_Nodes_IsNull o, collector
60
56
  collector << "COALESCE("
61
57
  collector = visit o.left, collector
62
58
  collector << ","
63
- if(o.right.is_a?(Arel::Attributes::Attribute))
59
+ if (o.right.is_a?(Arel::Attributes::Attribute))
64
60
  collector = visit o.right, collector
65
61
  else
66
62
  collector << "'#{o.right}'"
@@ -68,9 +64,6 @@ module ArelExtensions
68
64
  collector << ")"
69
65
  collector
70
66
  end
71
-
72
-
73
-
74
67
  end
75
68
  end
76
69
  end
@@ -1,13 +1,25 @@
1
1
  module ArelExtensions
2
2
  module Visitors
3
3
  module MSSQL
4
- Arel::Visitors::MSSQL::DATE_MAPPING = {'d' => 'day', 'm' => 'month', 'y' => 'year', 'wd' => 'weekday', 'w' => 'week', 'h' => 'hour', 'mn' => 'minute', 's' => 'second'}
4
+ Arel::Visitors::MSSQL::DATE_MAPPING = {
5
+ 'd' => 'day', 'm' => 'month', 'y' => 'year', 'wd' => 'weekday', 'w' => 'week', 'h' => 'hour', 'mn' => 'minute', 's' => 'second'
6
+ }.freeze
7
+
5
8
  Arel::Visitors::MSSQL::DATE_FORMAT_DIRECTIVES = {
6
9
  '%Y' => 'YYYY', '%C' => '', '%y' => 'YY', '%m' => 'MM', '%B' => '', '%b' => '', '%^b' => '', # year, month
7
10
  '%d' => 'DD', '%e' => '', '%j' => '', '%w' => 'dw', '%A' => '', # day, weekday
8
11
  '%H' => 'hh', '%k' => '', '%I' => '', '%l' => '', '%P' => '', '%p' => '', # hours
9
12
  '%M' => 'mi', '%S' => 'ss', '%L' => 'ms', '%N' => 'ns', '%z' => 'tz'
10
- }
13
+ }.freeze
14
+
15
+ Arel::Visitors::MSSQL::DATE_FORMAT_REGEX =
16
+ Regexp.new(
17
+ Arel::Visitors::MSSQL::DATE_FORMAT_DIRECTIVES
18
+ .keys
19
+ .map{|k| Regexp.escape(k)}
20
+ .join('|')
21
+ ).freeze
22
+
11
23
  # TODO; all others... http://www.sql-server-helper.com/tips/date-formats.aspx
12
24
  Arel::Visitors::MSSQL::DATE_CONVERT_FORMATS = {
13
25
  'YYYY-MM-DD' => 120,
@@ -19,7 +31,7 @@ module ArelExtensions
19
31
  'DD-MM-YY' => 5,
20
32
  'DD.MM.YYYY' => 104,
21
33
  'YYYY-MM-DDTHH:MM:SS:MMM' => 126
22
- }
34
+ }.freeze
23
35
 
24
36
  # Math Functions
25
37
  def visit_ArelExtensions_Nodes_Ceil o, collector
@@ -32,7 +44,7 @@ module ArelExtensions
32
44
  def visit_ArelExtensions_Nodes_Log10 o, collector
33
45
  collector << "LOG10("
34
46
  o.expressions.each_with_index { |arg, i|
35
- collector << Arel::Visitors::ToSql::COMMA unless i == 0
47
+ collector << Arel::Visitors::ToSql::COMMA if i != 0
36
48
  collector = visit arg, collector
37
49
  }
38
50
  collector << ")"
@@ -42,7 +54,7 @@ module ArelExtensions
42
54
  def visit_ArelExtensions_Nodes_Power o, collector
43
55
  collector << "POWER("
44
56
  o.expressions.each_with_index { |arg, i|
45
- collector << Arel::Visitors::ToSql::COMMA unless i == 0
57
+ collector << Arel::Visitors::ToSql::COMMA if i != 0
46
58
  collector = visit arg, collector
47
59
  }
48
60
  collector << ")"
@@ -66,7 +78,7 @@ module ArelExtensions
66
78
  def visit_ArelExtensions_Nodes_Concat o, collector
67
79
  collector << "CONCAT("
68
80
  o.expressions.each_with_index { |arg, i|
69
- collector << Arel::Visitors::MSSQL::COMMA unless i == 0
81
+ collector << Arel::Visitors::MSSQL::COMMA if i != 0
70
82
  collector = visit arg, collector
71
83
  }
72
84
  collector << ")"
@@ -76,7 +88,7 @@ module ArelExtensions
76
88
  def visit_ArelExtensions_Nodes_Repeat o, collector
77
89
  collector << "REPLICATE("
78
90
  o.expressions.each_with_index { |arg, i|
79
- collector << Arel::Visitors::ToSql::COMMA unless i == 0
91
+ collector << Arel::Visitors::ToSql::COMMA if i != 0
80
92
  collector = visit arg, collector
81
93
  }
82
94
  collector << ")"
@@ -86,12 +98,12 @@ module ArelExtensions
86
98
 
87
99
 
88
100
  def visit_ArelExtensions_Nodes_DateDiff o, collector
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
101
+ case o.right_node_type
102
+ when :ruby_date, :ruby_time, :date, :datetime, :time
103
+ collector << case o.left_node_type
104
+ when :ruby_time, :datetime, :time then 'DATEDIFF(second'
105
+ else 'DATEDIFF(day'
106
+ end
95
107
  collector << Arel::Visitors::MSSQL::COMMA
96
108
  collector = visit o.right, collector
97
109
  collector << Arel::Visitors::MSSQL::COMMA
@@ -151,7 +163,7 @@ module ArelExtensions
151
163
  def visit_ArelExtensions_Nodes_Round o, collector
152
164
  collector << "ROUND("
153
165
  o.expressions.each_with_index { |arg, i|
154
- collector << Arel::Visitors::MSSQL::COMMA unless i == 0
166
+ collector << Arel::Visitors::MSSQL::COMMA if i != 0
155
167
  collector = visit arg, collector
156
168
  }
157
169
  if o.expressions.length == 1
@@ -242,42 +254,34 @@ module ArelExtensions
242
254
  end
243
255
 
244
256
  def visit_ArelExtensions_Nodes_Format o, collector
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]
257
+ f = ArelExtensions::Visitors::strftime_to_format(o.iso_format, Arel::Visitors::MSSQL::DATE_FORMAT_DIRECTIVES)
258
+ if fmt = Arel::Visitors::MSSQL::DATE_CONVERT_FORMATS[f]
248
259
  collector << "CONVERT(VARCHAR(#{f.length})"
249
260
  collector << Arel::Visitors::MSSQL::COMMA
250
261
  collector = visit o.left, collector
251
262
  collector << Arel::Visitors::MSSQL::COMMA
252
- collector << Arel::Visitors::MSSQL::DATE_CONVERT_FORMATS[f].to_s
263
+ collector << fmt.to_s
253
264
  collector << ')'
254
265
  collector
255
266
  else
267
+ s = StringScanner.new o.iso_format
256
268
  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
269
+ sep = ''
270
+ while !s.eos?
271
+ collector << sep
272
+ sep = ' + '
273
+ case
274
+ when s.scan(Arel::Visitors::MSSQL::DATE_FORMAT_REGEX)
275
+ dir = Arel::Visitors::MSSQL::DATE_FORMAT_DIRECTIVES[s.matched]
276
+ collector << 'LTRIM(STR(DATEPART('
277
+ collector << dir
278
+ collector << Arel::Visitors::MSSQL::COMMA
279
+ collector = visit o.left, collector
280
+ collector << ')))'
281
+ when s.scan(/[^%]+|./)
282
+ collector = visit Arel::Nodes.build_quoted(s.matched), collector
277
283
  end
278
- collector << ' + ' if t[i + 1]
279
- }
280
-
284
+ end
281
285
  collector << ')'
282
286
  collector
283
287
  end
@@ -286,7 +290,7 @@ module ArelExtensions
286
290
  def visit_ArelExtensions_Nodes_Replace o, collector
287
291
  collector << "REPLACE("
288
292
  o.expressions.each_with_index { |arg, i|
289
- collector << Arel::Visitors::MSSQL::COMMA unless i == 0
293
+ collector << Arel::Visitors::MSSQL::COMMA if i != 0
290
294
  collector = visit arg, collector
291
295
  }
292
296
  collector << ")"
@@ -296,7 +300,7 @@ module ArelExtensions
296
300
  def visit_ArelExtensions_Nodes_FindInSet o, collector
297
301
  collector << "dbo.FIND_IN_SET("
298
302
  o.expressions.each_with_index { |arg, i|
299
- collector << Arel::Visitors::MSSQL::COMMA unless i == 0
303
+ collector << Arel::Visitors::MSSQL::COMMA if i != 0
300
304
  collector = visit arg, collector
301
305
  }
302
306
  collector << ")"
@@ -409,7 +413,7 @@ module ArelExtensions
409
413
  collector << ") WITHIN GROUP (ORDER BY "
410
414
  if o.order.present?
411
415
  o.order.each_with_index do |order,i|
412
- collector << Arel::Visitors::Oracle::COMMA unless i == 0
416
+ collector << Arel::Visitors::Oracle::COMMA if i != 0
413
417
  collector = visit order, collector
414
418
  end
415
419
  else