arel_extensions 1.2.13 → 1.2.18

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 (93) 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/arel_extensions.gemspec +1 -1
  6. data/gemfiles/rails3.gemfile +9 -9
  7. data/gemfiles/rails4.gemfile +13 -13
  8. data/gemfiles/rails5_0.gemfile +13 -13
  9. data/gemfiles/rails5_1_4.gemfile +13 -13
  10. data/gemfiles/rails5_2.gemfile +13 -13
  11. data/gemfiles/rails6.gemfile +13 -13
  12. data/lib/arel_extensions.rb +3 -3
  13. data/lib/arel_extensions/attributes.rb +0 -0
  14. data/lib/arel_extensions/boolean_functions.rb +21 -5
  15. data/lib/arel_extensions/common_sql_functions.rb +2 -4
  16. data/lib/arel_extensions/comparators.rb +11 -14
  17. data/lib/arel_extensions/date_duration.rb +4 -5
  18. data/lib/arel_extensions/insert_manager.rb +16 -17
  19. data/lib/arel_extensions/math.rb +8 -9
  20. data/lib/arel_extensions/math_functions.rb +15 -17
  21. data/lib/arel_extensions/nodes/abs.rb +0 -1
  22. data/lib/arel_extensions/nodes/aggregate_function.rb +0 -1
  23. data/lib/arel_extensions/nodes/blank.rb +0 -1
  24. data/lib/arel_extensions/nodes/case.rb +3 -4
  25. data/lib/arel_extensions/nodes/cast.rb +4 -2
  26. data/lib/arel_extensions/nodes/ceil.rb +1 -1
  27. data/lib/arel_extensions/nodes/change_case.rb +0 -0
  28. data/lib/arel_extensions/nodes/coalesce.rb +0 -1
  29. data/lib/arel_extensions/nodes/collate.rb +0 -1
  30. data/lib/arel_extensions/nodes/concat.rb +1 -3
  31. data/lib/arel_extensions/nodes/date_diff.rb +7 -8
  32. data/lib/arel_extensions/nodes/duration.rb +0 -1
  33. data/lib/arel_extensions/nodes/find_in_set.rb +0 -1
  34. data/lib/arel_extensions/nodes/floor.rb +1 -1
  35. data/lib/arel_extensions/nodes/format.rb +27 -1
  36. data/lib/arel_extensions/nodes/formatted_number.rb +0 -1
  37. data/lib/arel_extensions/nodes/function.rb +18 -15
  38. data/lib/arel_extensions/nodes/is_null.rb +0 -0
  39. data/lib/arel_extensions/nodes/json.rb +39 -30
  40. data/lib/arel_extensions/nodes/length.rb +0 -1
  41. data/lib/arel_extensions/nodes/levenshtein_distance.rb +0 -0
  42. data/lib/arel_extensions/nodes/locate.rb +0 -1
  43. data/lib/arel_extensions/nodes/log10.rb +1 -2
  44. data/lib/arel_extensions/nodes/matches.rb +0 -2
  45. data/lib/arel_extensions/nodes/md5.rb +0 -1
  46. data/lib/arel_extensions/nodes/power.rb +0 -1
  47. data/lib/arel_extensions/nodes/rand.rb +0 -1
  48. data/lib/arel_extensions/nodes/repeat.rb +0 -2
  49. data/lib/arel_extensions/nodes/replace.rb +0 -2
  50. data/lib/arel_extensions/nodes/round.rb +0 -1
  51. data/lib/arel_extensions/nodes/soundex.rb +0 -1
  52. data/lib/arel_extensions/nodes/std.rb +0 -1
  53. data/lib/arel_extensions/nodes/substring.rb +0 -1
  54. data/lib/arel_extensions/nodes/sum.rb +0 -0
  55. data/lib/arel_extensions/nodes/then.rb +0 -0
  56. data/lib/arel_extensions/nodes/trim.rb +0 -2
  57. data/lib/arel_extensions/nodes/union.rb +0 -2
  58. data/lib/arel_extensions/nodes/union_all.rb +0 -2
  59. data/lib/arel_extensions/nodes/wday.rb +0 -4
  60. data/lib/arel_extensions/null_functions.rb +3 -5
  61. data/lib/arel_extensions/predications.rb +5 -6
  62. data/lib/arel_extensions/railtie.rb +5 -5
  63. data/lib/arel_extensions/set_functions.rb +0 -2
  64. data/lib/arel_extensions/string_functions.rb +21 -22
  65. data/lib/arel_extensions/tasks.rb +1 -1
  66. data/lib/arel_extensions/version.rb +1 -1
  67. data/lib/arel_extensions/visitors.rb +68 -60
  68. data/lib/arel_extensions/visitors/convert_format.rb +37 -0
  69. data/lib/arel_extensions/visitors/ibm_db.rb +4 -11
  70. data/lib/arel_extensions/visitors/mssql.rb +49 -44
  71. data/lib/arel_extensions/visitors/mysql.rb +65 -67
  72. data/lib/arel_extensions/visitors/oracle.rb +58 -55
  73. data/lib/arel_extensions/visitors/oracle12.rb +2 -3
  74. data/lib/arel_extensions/visitors/postgresql.rb +41 -34
  75. data/lib/arel_extensions/visitors/sqlite.rb +23 -18
  76. data/lib/arel_extensions/visitors/to_sql.rb +69 -61
  77. data/test/arelx_test_helper.rb +0 -2
  78. data/test/real_db_test.rb +27 -42
  79. data/test/support/fake_record.rb +1 -1
  80. data/test/test_comparators.rb +0 -4
  81. data/test/visitors/test_bulk_insert_oracle.rb +0 -1
  82. data/test/visitors/test_bulk_insert_sqlite.rb +0 -2
  83. data/test/visitors/test_oracle.rb +1 -2
  84. data/test/visitors/test_to_sql.rb +16 -25
  85. data/test/with_ar/all_agnostic_test.rb +135 -139
  86. data/test/with_ar/insert_agnostic_test.rb +0 -2
  87. data/test/with_ar/test_bulk_sqlite.rb +0 -4
  88. data/test/with_ar/test_math_sqlite.rb +4 -8
  89. data/test/with_ar/test_string_mysql.rb +1 -5
  90. data/test/with_ar/test_string_sqlite.rb +1 -5
  91. data/version_v1.rb +1 -1
  92. data/version_v2.rb +1 -1
  93. metadata +4 -3
@@ -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 = "1.2.13".freeze
2
+ VERSION = "1.2.18".freeze
3
3
  end
@@ -1,81 +1,89 @@
1
+ require 'arel_extensions/visitors/convert_format'
1
2
  require 'arel_extensions/visitors/to_sql'
2
3
  require 'arel_extensions/visitors/mysql'
3
- require 'arel_extensions/visitors/oracle'
4
- require 'arel_extensions/visitors/oracle12'
5
4
  require 'arel_extensions/visitors/postgresql'
6
5
  require 'arel_extensions/visitors/sqlite'
7
- require 'arel_extensions/visitors/mssql'
8
6
 
9
- class Arel::Visitors::MSSQL
10
- include ArelExtensions::Visitors::MSSQL
7
+ if defined?(Arel::Visitors::Oracle)
8
+ require 'arel_extensions/visitors/oracle'
9
+ require 'arel_extensions/visitors/oracle12'
10
+ end
11
+
12
+ if defined?(Arel::Visitors::MSSQL)
13
+ require 'arel_extensions/visitors/mssql'
11
14
 
12
- alias_method :old_visit_Arel_Nodes_As, :visit_Arel_Nodes_As
13
- def visit_Arel_Nodes_As o, collector
14
- if o.left.is_a?(Arel::Nodes::Binary)
15
- collector << '('
16
- collector = visit o.left, collector
17
- collector << ')'
18
- else
19
- collector = visit o.left, collector
15
+ class Arel::Visitors::MSSQL
16
+ include ArelExtensions::Visitors::MSSQL
17
+
18
+ alias_method(:old_visit_Arel_Nodes_As, :visit_Arel_Nodes_As) rescue nil
19
+ def visit_Arel_Nodes_As o, collector
20
+ if o.left.is_a?(Arel::Nodes::Binary)
21
+ collector << '('
22
+ collector = visit o.left, collector
23
+ collector << ')'
24
+ else
25
+ collector = visit o.left, collector
26
+ end
27
+ collector << " AS ["
28
+ collector = visit o.right, collector
29
+ collector << "]"
30
+ collector
20
31
  end
21
- collector << " AS ["
22
- collector = visit o.right, collector
23
- collector << "]"
24
- collector
25
- end
26
32
 
27
- alias_method :old_visit_Arel_Nodes_SelectStatement, :visit_Arel_Nodes_SelectStatement
28
- def visit_Arel_Nodes_SelectStatement o, collector
29
- if !collector.value.blank? && o.limit.blank? && o.offset.blank?
30
- o = o.dup
31
- o.orders = []
33
+ alias_method(:old_visit_Arel_Nodes_SelectStatement, :visit_Arel_Nodes_SelectStatement) rescue nil
34
+ def visit_Arel_Nodes_SelectStatement o, collector
35
+ if !collector.value.blank? && o.limit.blank? && o.offset.blank?
36
+ o = o.dup
37
+ o.orders = []
38
+ end
39
+ old_visit_Arel_Nodes_SelectStatement(o,collector)
32
40
  end
33
- old_visit_Arel_Nodes_SelectStatement(o,collector)
34
41
  end
35
- end
36
42
 
37
- begin
38
- require 'arel_sqlserver'
39
- if Arel::VERSION.to_i == 6
40
- if Arel::Visitors::VISITORS['sqlserver'] && Arel::Visitors::VISITORS['sqlserver'] != Arel::Visitors::MSSQL
41
- Arel::Visitors::VISITORS['sqlserver'].class_eval do
42
- include ArelExtensions::Visitors::MSSQL
43
+ begin
44
+ require 'arel_sqlserver'
45
+ if Arel::VERSION.to_i == 6
46
+ if Arel::Visitors::VISITORS['sqlserver'] && Arel::Visitors::VISITORS['sqlserver'] != Arel::Visitors::MSSQL
47
+ Arel::Visitors::VISITORS['sqlserver'].class_eval do
48
+ include ArelExtensions::Visitors::MSSQL
43
49
 
44
- alias_method :old_visit_Arel_Nodes_SelectStatement, :visit_Arel_Nodes_SelectStatement
45
- def visit_Arel_Nodes_SelectStatement o, collector
46
- if !collector.value.blank? && o.limit.blank? && o.offset.blank?
47
- o = o.dup
48
- o.orders = []
50
+ alias_method(:old_visit_Arel_Nodes_SelectStatement, :visit_Arel_Nodes_SelectStatement) rescue nil
51
+ def visit_Arel_Nodes_SelectStatement o, collector
52
+ if !collector.value.blank? && o.limit.blank? && o.offset.blank?
53
+ o = o.dup
54
+ o.orders = []
55
+ end
56
+ old_visit_Arel_Nodes_SelectStatement(o,collector)
49
57
  end
50
- old_visit_Arel_Nodes_SelectStatement(o,collector)
51
- end
52
58
 
53
- alias_method :old_visit_Arel_Nodes_As, :visit_Arel_Nodes_As
54
- def visit_Arel_Nodes_As o, collector
55
- if o.left.is_a?(Arel::Nodes::Binary)
56
- collector << '('
57
- collector = visit o.left, collector
58
- collector << ')'
59
- else
60
- collector = visit o.left, collector
59
+ alias_method(:old_visit_Arel_Nodes_As, :visit_Arel_Nodes_As) rescue nil
60
+ def visit_Arel_Nodes_As o, collector
61
+ if o.left.is_a?(Arel::Nodes::Binary)
62
+ collector << '('
63
+ collector = visit o.left, collector
64
+ collector << ')'
65
+ else
66
+ collector = visit o.left, collector
67
+ end
68
+ collector << " AS ["
69
+ collector = visit o.right, collector
70
+ collector << "]"
71
+ collector
61
72
  end
62
- collector << " AS ["
63
- collector = visit o.right, collector
64
- collector << "]"
65
- collector
66
- end
67
73
 
68
- alias_method :old_primary_Key_From_Table, :primary_Key_From_Table
69
- def primary_Key_From_Table t
70
- return unless t
71
- column_name = @connection.schema_cache.primary_keys(t.name) ||
72
- @connection.schema_cache.columns_hash(t.name).first.try(:second).try(:name)
73
- column_name ? t[column_name] : nil
74
+ alias_method(:old_primary_Key_From_Table, :primary_Key_From_Table) rescue nil
75
+ def primary_Key_From_Table t
76
+ return unless t
77
+
78
+ column_name = @connection.schema_cache.primary_keys(t.name) ||
79
+ @connection.schema_cache.columns_hash(t.name).first.try(:second).try(:name)
80
+ column_name ? t[column_name] : nil
81
+ end
74
82
  end
75
83
  end
76
84
  end
77
- end
78
85
  rescue LoadError
79
- rescue => e
80
- e
86
+ rescue => e
87
+ e
88
+ end
81
89
  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,26 @@
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
+
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
+
5
9
  Arel::Visitors::MSSQL::DATE_FORMAT_DIRECTIVES = {
6
10
  '%Y' => 'YYYY', '%C' => '', '%y' => 'YY', '%m' => 'MM', '%B' => '', '%b' => '', '%^b' => '', # year, month
7
11
  '%d' => 'DD', '%e' => '', '%j' => '', '%w' => 'dw', '%A' => '', # day, weekday
8
12
  '%H' => 'hh', '%k' => '', '%I' => '', '%l' => '', '%P' => '', '%p' => '', # hours
9
13
  '%M' => 'mi', '%S' => 'ss', '%L' => 'ms', '%N' => 'ns', '%z' => 'tz'
10
- }
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
+
11
24
  # TODO; all others... http://www.sql-server-helper.com/tips/date-formats.aspx
12
25
  Arel::Visitors::MSSQL::DATE_CONVERT_FORMATS = {
13
26
  'YYYY-MM-DD' => 120,
@@ -19,7 +32,7 @@ module ArelExtensions
19
32
  'DD-MM-YY' => 5,
20
33
  'DD.MM.YYYY' => 104,
21
34
  'YYYY-MM-DDTHH:MM:SS:MMM' => 126
22
- }
35
+ }.freeze
23
36
 
24
37
  # Math Functions
25
38
  def visit_ArelExtensions_Nodes_Ceil o, collector
@@ -32,7 +45,7 @@ module ArelExtensions
32
45
  def visit_ArelExtensions_Nodes_Log10 o, collector
33
46
  collector << "LOG10("
34
47
  o.expressions.each_with_index { |arg, i|
35
- collector << Arel::Visitors::ToSql::COMMA unless i == 0
48
+ collector << Arel::Visitors::ToSql::COMMA if i != 0
36
49
  collector = visit arg, collector
37
50
  }
38
51
  collector << ")"
@@ -42,7 +55,7 @@ module ArelExtensions
42
55
  def visit_ArelExtensions_Nodes_Power o, collector
43
56
  collector << "POWER("
44
57
  o.expressions.each_with_index { |arg, i|
45
- collector << Arel::Visitors::ToSql::COMMA unless i == 0
58
+ collector << Arel::Visitors::ToSql::COMMA if i != 0
46
59
  collector = visit arg, collector
47
60
  }
48
61
  collector << ")"
@@ -66,7 +79,7 @@ module ArelExtensions
66
79
  def visit_ArelExtensions_Nodes_Concat o, collector
67
80
  collector << "CONCAT("
68
81
  o.expressions.each_with_index { |arg, i|
69
- collector << Arel::Visitors::MSSQL::COMMA unless i == 0
82
+ collector << Arel::Visitors::MSSQL::COMMA if i != 0
70
83
  collector = visit arg, collector
71
84
  }
72
85
  collector << ")"
@@ -76,7 +89,7 @@ module ArelExtensions
76
89
  def visit_ArelExtensions_Nodes_Repeat o, collector
77
90
  collector << "REPLICATE("
78
91
  o.expressions.each_with_index { |arg, i|
79
- collector << Arel::Visitors::ToSql::COMMA unless i == 0
92
+ collector << Arel::Visitors::ToSql::COMMA if i != 0
80
93
  collector = visit arg, collector
81
94
  }
82
95
  collector << ")"
@@ -86,12 +99,12 @@ module ArelExtensions
86
99
 
87
100
 
88
101
  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
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
95
108
  collector << Arel::Visitors::MSSQL::COMMA
96
109
  collector = visit o.right, collector
97
110
  collector << Arel::Visitors::MSSQL::COMMA
@@ -151,7 +164,7 @@ module ArelExtensions
151
164
  def visit_ArelExtensions_Nodes_Round o, collector
152
165
  collector << "ROUND("
153
166
  o.expressions.each_with_index { |arg, i|
154
- collector << Arel::Visitors::MSSQL::COMMA unless i == 0
167
+ collector << Arel::Visitors::MSSQL::COMMA if i != 0
155
168
  collector = visit arg, collector
156
169
  }
157
170
  if o.expressions.length == 1
@@ -242,42 +255,34 @@ module ArelExtensions
242
255
  end
243
256
 
244
257
  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]
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]
248
260
  collector << "CONVERT(VARCHAR(#{f.length})"
249
261
  collector << Arel::Visitors::MSSQL::COMMA
250
262
  collector = visit o.left, collector
251
263
  collector << Arel::Visitors::MSSQL::COMMA
252
- collector << Arel::Visitors::MSSQL::DATE_CONVERT_FORMATS[f].to_s
264
+ collector << fmt.to_s
253
265
  collector << ')'
254
266
  collector
255
267
  else
268
+ s = StringScanner.new o.iso_format
256
269
  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
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
277
284
  end
278
- collector << ' + ' if t[i + 1]
279
- }
280
-
285
+ end
281
286
  collector << ')'
282
287
  collector
283
288
  end
@@ -286,7 +291,7 @@ module ArelExtensions
286
291
  def visit_ArelExtensions_Nodes_Replace o, collector
287
292
  collector << "REPLACE("
288
293
  o.expressions.each_with_index { |arg, i|
289
- collector << Arel::Visitors::MSSQL::COMMA unless i == 0
294
+ collector << Arel::Visitors::MSSQL::COMMA if i != 0
290
295
  collector = visit arg, collector
291
296
  }
292
297
  collector << ")"
@@ -296,7 +301,7 @@ module ArelExtensions
296
301
  def visit_ArelExtensions_Nodes_FindInSet o, collector
297
302
  collector << "dbo.FIND_IN_SET("
298
303
  o.expressions.each_with_index { |arg, i|
299
- collector << Arel::Visitors::MSSQL::COMMA unless i == 0
304
+ collector << Arel::Visitors::MSSQL::COMMA if i != 0
300
305
  collector = visit arg, collector
301
306
  }
302
307
  collector << ")"
@@ -409,7 +414,7 @@ module ArelExtensions
409
414
  collector << ") WITHIN GROUP (ORDER BY "
410
415
  if o.order.present?
411
416
  o.order.each_with_index do |order,i|
412
- collector << Arel::Visitors::Oracle::COMMA unless i == 0
417
+ collector << Arel::Visitors::Oracle::COMMA if i != 0
413
418
  collector = visit order, collector
414
419
  end
415
420
  else