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.
- checksums.yaml +4 -4
- data/.rubocop.yml +4 -7
- data/.travis.yml +91 -61
- data/Gemfile +20 -15
- data/README.md +12 -17
- data/Rakefile +29 -40
- data/appveyor.yml +1 -1
- data/arel_extensions.gemspec +3 -3
- data/functions.html +3 -3
- data/gemfiles/rails3.gemfile +9 -9
- data/gemfiles/rails4.gemfile +13 -13
- data/gemfiles/rails5_0.gemfile +13 -13
- data/gemfiles/rails5_1_4.gemfile +13 -13
- data/gemfiles/rails5_2.gemfile +13 -13
- data/init/mssql.sql +4 -4
- data/init/mysql.sql +38 -38
- data/init/postgresql.sql +21 -21
- data/lib/arel_extensions/attributes.rb +1 -0
- data/lib/arel_extensions/boolean_functions.rb +14 -55
- data/lib/arel_extensions/common_sql_functions.rb +8 -7
- data/lib/arel_extensions/comparators.rb +15 -14
- data/lib/arel_extensions/date_duration.rb +5 -4
- data/lib/arel_extensions/insert_manager.rb +16 -17
- data/lib/arel_extensions/math.rb +12 -11
- data/lib/arel_extensions/math_functions.rb +22 -29
- data/lib/arel_extensions/nodes/abs.rb +1 -0
- data/lib/arel_extensions/nodes/blank.rb +1 -0
- data/lib/arel_extensions/nodes/case.rb +8 -11
- data/lib/arel_extensions/nodes/cast.rb +2 -4
- data/lib/arel_extensions/nodes/ceil.rb +1 -1
- data/lib/arel_extensions/nodes/change_case.rb +0 -0
- data/lib/arel_extensions/nodes/coalesce.rb +3 -2
- data/lib/arel_extensions/nodes/collate.rb +2 -1
- data/lib/arel_extensions/nodes/concat.rb +16 -7
- data/lib/arel_extensions/nodes/date_diff.rb +13 -10
- data/lib/arel_extensions/nodes/duration.rb +3 -0
- data/lib/arel_extensions/nodes/find_in_set.rb +1 -0
- data/lib/arel_extensions/nodes/floor.rb +1 -1
- data/lib/arel_extensions/nodes/format.rb +8 -34
- data/lib/arel_extensions/nodes/formatted_number.rb +23 -22
- data/lib/arel_extensions/nodes/function.rb +16 -25
- data/lib/arel_extensions/nodes/json.rb +36 -43
- data/lib/arel_extensions/nodes/length.rb +0 -5
- data/lib/arel_extensions/nodes/levenshtein_distance.rb +0 -0
- data/lib/arel_extensions/nodes/locate.rb +1 -0
- data/lib/arel_extensions/nodes/log10.rb +2 -1
- data/lib/arel_extensions/nodes/matches.rb +6 -4
- data/lib/arel_extensions/nodes/md5.rb +1 -0
- data/lib/arel_extensions/nodes/power.rb +5 -5
- data/lib/arel_extensions/nodes/rand.rb +1 -0
- data/lib/arel_extensions/nodes/repeat.rb +4 -2
- data/lib/arel_extensions/nodes/replace.rb +6 -22
- data/lib/arel_extensions/nodes/round.rb +6 -5
- data/lib/arel_extensions/nodes/soundex.rb +15 -15
- data/lib/arel_extensions/nodes/std.rb +21 -18
- data/lib/arel_extensions/nodes/substring.rb +16 -8
- data/lib/arel_extensions/nodes/then.rb +0 -0
- data/lib/arel_extensions/nodes/trim.rb +5 -3
- data/lib/arel_extensions/nodes/union.rb +5 -2
- data/lib/arel_extensions/nodes/union_all.rb +3 -0
- data/lib/arel_extensions/nodes/wday.rb +4 -0
- data/lib/arel_extensions/nodes.rb +1 -1
- data/lib/arel_extensions/null_functions.rb +7 -5
- data/lib/arel_extensions/predications.rb +34 -35
- data/lib/arel_extensions/railtie.rb +5 -5
- data/lib/arel_extensions/set_functions.rb +4 -2
- data/lib/arel_extensions/string_functions.rb +23 -52
- data/lib/arel_extensions/tasks.rb +5 -5
- data/lib/arel_extensions/version.rb +1 -1
- data/lib/arel_extensions/visitors/ibm_db.rb +12 -5
- data/lib/arel_extensions/visitors/mssql.rb +58 -64
- data/lib/arel_extensions/visitors/mysql.rb +98 -149
- data/lib/arel_extensions/visitors/oracle.rb +70 -73
- data/lib/arel_extensions/visitors/oracle12.rb +15 -2
- data/lib/arel_extensions/visitors/postgresql.rb +63 -116
- data/lib/arel_extensions/visitors/sqlite.rb +70 -83
- data/lib/arel_extensions/visitors/to_sql.rb +110 -142
- data/lib/arel_extensions/visitors.rb +60 -68
- data/lib/arel_extensions.rb +19 -81
- data/test/database.yml +0 -2
- data/test/helper.rb +18 -0
- data/test/real_db_test.rb +43 -28
- data/test/support/fake_record.rb +2 -2
- data/test/test_comparators.rb +12 -9
- data/test/visitors/test_bulk_insert_oracle.rb +8 -8
- data/test/visitors/test_bulk_insert_sqlite.rb +10 -9
- data/test/visitors/test_bulk_insert_to_sql.rb +10 -8
- data/test/visitors/test_oracle.rb +42 -42
- data/test/visitors/test_to_sql.rb +196 -361
- data/test/with_ar/all_agnostic_test.rb +160 -195
- data/test/with_ar/insert_agnostic_test.rb +4 -3
- data/test/with_ar/test_bulk_sqlite.rb +9 -6
- data/test/with_ar/test_math_sqlite.rb +12 -8
- data/test/with_ar/test_string_mysql.rb +11 -5
- data/test/with_ar/test_string_sqlite.rb +12 -4
- metadata +11 -22
- data/.github/workflows/ruby.yml +0 -102
- data/gemfiles/rails6.gemfile +0 -30
- data/gemfiles/rails6_1.gemfile +0 -30
- data/gemspecs/arel_extensions-v1.gemspec +0 -28
- data/gemspecs/arel_extensions-v2.gemspec +0 -28
- data/generate_gems.sh +0 -15
- data/lib/arel_extensions/nodes/aggregate_function.rb +0 -13
- data/lib/arel_extensions/nodes/sum.rb +0 -7
- data/lib/arel_extensions/visitors/convert_format.rb +0 -37
- data/test/arelx_test_helper.rb +0 -26
- data/version_v1.rb +0 -3
- data/version_v2.rb +0 -3
@@ -1,10 +1,10 @@
|
|
1
1
|
module ArelExtensions
|
2
2
|
module Predications
|
3
|
-
def when right, expression
|
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
|
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
|
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(
|
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
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
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,
|
46
|
+
Arel::Nodes::In.new(self,quoted_node(other))
|
48
47
|
end
|
49
48
|
end
|
50
49
|
|
51
|
-
def not_in(
|
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
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
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}
|
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
|
@@ -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
|
-
|
26
|
+
Arel::Nodes::Union.class_eval do
|
25
27
|
include ArelExtensions::SetFunctions
|
26
28
|
end
|
27
29
|
|
28
|
-
|
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' #
|
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
|
-
|
22
|
+
|
23
|
+
#*FindInSet function .......
|
23
24
|
def &(other)
|
24
25
|
ArelExtensions::Nodes::FindInSet.new [other, self]
|
25
26
|
end
|
26
27
|
|
27
|
-
#
|
28
|
+
#LENGTH function returns the length of the value in a text field.
|
28
29
|
def length
|
29
|
-
ArelExtensions::Nodes::Length.new self
|
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
|
-
|
37
|
-
|
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
|
-
#
|
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
|
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
|
-
#
|
128
|
-
def replace
|
129
|
-
|
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
|
-
#
|
145
|
-
def group_concat
|
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
|
127
|
+
ArelExtensions::Nodes::GroupConcat.new [self, sep, order_tabs]
|
157
128
|
end
|
158
129
|
|
159
|
-
#
|
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
|
-
|
3
|
-
|
4
|
-
|
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
|
9
|
+
ActiveRecord::Base.establish_connection(Rails.env)
|
10
10
|
CommonSqlFunctions.new(ActiveRecord::Base.connection).add_sql_functions(@env_db)
|
11
|
-
|
11
|
+
end
|
12
12
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
module ArelExtensions
|
2
2
|
module Visitors
|
3
|
-
|
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
|
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
|
-
#
|
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
|
-
#
|
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
|
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
|
-
}
|
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
|
-
}
|
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
|
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
|
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
|
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
|
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
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
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 << "
|
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
|
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 =
|
259
|
-
|
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 <<
|
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
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
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
|
-
|
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
|
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
|
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
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
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.
|
416
|
-
o.
|
417
|
-
collector << Arel::Visitors::Oracle::COMMA
|
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
|
-
|
476
|
-
|
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
|
-
|
491
|
-
|
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
|
-
|
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
|