arel_extensions 1.7.0 → 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/.codeclimate.yml +2 -1
- data/.gitignore +6 -8
- data/.rubocop.yml +4 -194
- data/.travis/oracle/download.js +152 -0
- data/.travis/oracle/download.sh +30 -0
- data/.travis/oracle/download_ojdbc.js +116 -0
- data/.travis/oracle/install.sh +34 -0
- data/.travis/setup_accounts.sh +9 -0
- data/.travis/sqlite3/extension-functions.sh +6 -0
- data/.travis.yml +223 -0
- data/Gemfile +28 -2
- data/README.md +89 -265
- data/Rakefile +30 -50
- data/TODO +1 -0
- data/appveyor.yml +22 -60
- data/arel_extensions.gemspec +17 -14
- data/functions.html +3 -3
- data/gemfiles/rails3.gemfile +20 -0
- data/gemfiles/rails4.gemfile +29 -0
- data/gemfiles/rails5_0.gemfile +29 -0
- data/gemfiles/rails5_1_4.gemfile +17 -19
- data/gemfiles/rails5_2.gemfile +17 -26
- data/init/mssql.sql +4 -4
- data/init/mysql.sql +38 -38
- data/init/oracle.sql +0 -0
- data/init/postgresql.sql +25 -24
- data/init/sqlite.sql +0 -0
- data/lib/arel_extensions/attributes.rb +3 -9
- data/lib/arel_extensions/boolean_functions.rb +16 -57
- data/lib/arel_extensions/common_sql_functions.rb +20 -21
- data/lib/arel_extensions/comparators.rb +28 -31
- data/lib/arel_extensions/date_duration.rb +13 -19
- data/lib/arel_extensions/insert_manager.rb +15 -22
- data/lib/arel_extensions/math.rb +70 -68
- data/lib/arel_extensions/math_functions.rb +52 -57
- data/lib/arel_extensions/nodes/abs.rb +1 -0
- data/lib/arel_extensions/nodes/blank.rb +5 -6
- data/lib/arel_extensions/nodes/case.rb +27 -31
- data/lib/arel_extensions/nodes/cast.rb +12 -12
- data/lib/arel_extensions/nodes/ceil.rb +1 -1
- data/lib/arel_extensions/nodes/coalesce.rb +5 -4
- data/lib/arel_extensions/nodes/collate.rb +10 -9
- data/lib/arel_extensions/nodes/concat.rb +22 -13
- data/lib/arel_extensions/nodes/date_diff.rb +70 -77
- data/lib/arel_extensions/nodes/duration.rb +5 -2
- 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 -35
- data/lib/arel_extensions/nodes/formatted_number.rb +23 -22
- data/lib/arel_extensions/nodes/function.rb +39 -50
- data/lib/arel_extensions/nodes/is_null.rb +0 -2
- data/lib/arel_extensions/nodes/json.rb +47 -72
- data/lib/arel_extensions/nodes/length.rb +0 -5
- data/lib/arel_extensions/nodes/levenshtein_distance.rb +2 -2
- data/lib/arel_extensions/nodes/locate.rb +3 -2
- data/lib/arel_extensions/nodes/log10.rb +2 -1
- data/lib/arel_extensions/nodes/matches.rb +8 -6
- 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 +3 -2
- data/lib/arel_extensions/nodes/repeat.rb +6 -4
- data/lib/arel_extensions/nodes/replace.rb +8 -16
- data/lib/arel_extensions/nodes/round.rb +7 -6
- 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 -58
- data/lib/arel_extensions/nodes/then.rb +2 -2
- data/lib/arel_extensions/nodes/trim.rb +7 -5
- data/lib/arel_extensions/nodes/union.rb +9 -6
- data/lib/arel_extensions/nodes/union_all.rb +8 -5
- data/lib/arel_extensions/nodes/wday.rb +6 -2
- data/lib/arel_extensions/nodes.rb +1 -1
- data/lib/arel_extensions/null_functions.rb +6 -18
- data/lib/arel_extensions/predications.rb +49 -54
- data/lib/arel_extensions/railtie.rb +5 -5
- data/lib/arel_extensions/set_functions.rb +7 -5
- data/lib/arel_extensions/string_functions.rb +55 -110
- data/lib/arel_extensions/tasks.rb +6 -6
- data/lib/arel_extensions/version.rb +1 -3
- data/lib/arel_extensions/visitors/ibm_db.rb +36 -29
- data/lib/arel_extensions/visitors/mssql.rb +248 -493
- data/lib/arel_extensions/visitors/mysql.rb +244 -420
- data/lib/arel_extensions/visitors/oracle.rb +258 -311
- data/lib/arel_extensions/visitors/oracle12.rb +34 -20
- data/lib/arel_extensions/visitors/postgresql.rb +239 -350
- data/lib/arel_extensions/visitors/sqlite.rb +169 -191
- data/lib/arel_extensions/visitors/to_sql.rb +299 -371
- data/lib/arel_extensions/visitors.rb +62 -83
- data/lib/arel_extensions.rb +32 -243
- data/test/database.yml +10 -20
- data/test/helper.rb +18 -0
- data/test/real_db_test.rb +120 -123
- data/test/support/fake_record.rb +3 -11
- data/test/test_comparators.rb +17 -14
- data/test/visitors/test_bulk_insert_oracle.rb +12 -12
- data/test/visitors/test_bulk_insert_sqlite.rb +14 -13
- data/test/visitors/test_bulk_insert_to_sql.rb +13 -11
- data/test/visitors/test_oracle.rb +55 -55
- data/test/visitors/test_to_sql.rb +226 -419
- data/test/with_ar/all_agnostic_test.rb +375 -912
- data/test/with_ar/insert_agnostic_test.rb +22 -28
- data/test/with_ar/test_bulk_sqlite.rb +17 -18
- data/test/with_ar/test_math_sqlite.rb +27 -27
- data/test/with_ar/test_string_mysql.rb +34 -32
- data/test/with_ar/test_string_sqlite.rb +35 -31
- metadata +64 -50
- data/.github/workflows/publish.yml +0 -30
- data/.github/workflows/release.yml +0 -30
- data/.github/workflows/ruby.yml +0 -452
- data/CONTRIBUTING.md +0 -102
- data/Makefile +0 -48
- data/NEWS.md +0 -131
- data/bin/build +0 -15
- data/bin/publish +0 -8
- data/dev/arelx.dockerfile +0 -41
- data/dev/compose.yaml +0 -69
- data/dev/postgres.dockerfile +0 -5
- data/dev/rbenv +0 -189
- data/gemfiles/rails5.gemfile +0 -36
- data/gemfiles/rails6.gemfile +0 -40
- data/gemfiles/rails6_1.gemfile +0 -48
- data/gemfiles/rails7.gemfile +0 -48
- data/gemfiles/rails7_1.gemfile +0 -48
- data/gemfiles/rails7_2.gemfile +0 -47
- data/gemfiles/rails8.gemfile +0 -40
- data/gemfiles/rails8_1.gemfile +0 -41
- data/gemspecs/arel_extensions-v1.gemspec +0 -25
- data/gemspecs/arel_extensions-v2.gemspec +0 -25
- data/generate_gems.sh +0 -15
- data/lib/arel_extensions/aliases.rb +0 -14
- data/lib/arel_extensions/constants.rb +0 -13
- data/lib/arel_extensions/helpers.rb +0 -61
- data/lib/arel_extensions/nodes/aggregate_function.rb +0 -13
- data/lib/arel_extensions/nodes/byte_size.rb +0 -11
- data/lib/arel_extensions/nodes/char_length.rb +0 -11
- data/lib/arel_extensions/nodes/formatted_date.rb +0 -42
- data/lib/arel_extensions/nodes/rollup.rb +0 -36
- data/lib/arel_extensions/nodes/select.rb +0 -10
- data/lib/arel_extensions/nodes/sum.rb +0 -7
- data/lib/arel_extensions/visitors/convert_format.rb +0 -37
- data/lib/arel_extensions/warning.rb +0 -42
- data/test/arelx_test_helper.rb +0 -94
- data/test/config_loader.rb +0 -9
- data/version_v1.rb +0 -5
- data/version_v2.rb +0 -5
|
@@ -2,8 +2,9 @@ require 'date'
|
|
|
2
2
|
|
|
3
3
|
module ArelExtensions
|
|
4
4
|
module Nodes
|
|
5
|
-
class DateDiff < Function #
|
|
6
|
-
attr_accessor :left_node_type
|
|
5
|
+
class DateDiff < Function #difference entre colonne date et date string/date
|
|
6
|
+
attr_accessor :left_node_type
|
|
7
|
+
attr_accessor :right_node_type
|
|
7
8
|
|
|
8
9
|
RETURN_TYPE = :integer # by default...
|
|
9
10
|
|
|
@@ -11,24 +12,24 @@ module ArelExtensions
|
|
|
11
12
|
res = []
|
|
12
13
|
col = expr.first
|
|
13
14
|
case col
|
|
14
|
-
when Arel::Nodes::Node, Arel::Attributes::Attribute
|
|
15
|
+
when Arel::Nodes::Node, Arel::Attributes::Attribute
|
|
15
16
|
@left_node_type = type_of_attribute(col)
|
|
16
17
|
when Date
|
|
17
18
|
@left_node_type = :ruby_date
|
|
18
19
|
when DateTime, Time
|
|
19
20
|
@left_node_type = :ruby_time
|
|
20
21
|
end
|
|
21
|
-
res << (
|
|
22
|
+
res << ([:date, :ruby_date].include?(@left_node_type) ? convert_to_date_node(col) : convert_to_datetime_node(col))
|
|
22
23
|
case expr[1]
|
|
23
|
-
when Arel::Nodes::Node, Arel::Attributes::Attribute
|
|
24
|
+
when Arel::Nodes::Node, Arel::Attributes::Attribute
|
|
24
25
|
@right_node_type = type_of_attribute(expr[1])
|
|
25
26
|
when Date
|
|
26
27
|
@right_node_type = :ruby_date
|
|
27
28
|
when DateTime, Time
|
|
28
29
|
@right_node_type = :ruby_time
|
|
29
30
|
end
|
|
30
|
-
res << (
|
|
31
|
-
super
|
|
31
|
+
res << ([:date, :ruby_date].include?(@left_node_type) ? convert_to_date_node(expr[1]) : convert_to_datetime_node(expr[1]))
|
|
32
|
+
super res
|
|
32
33
|
end
|
|
33
34
|
end
|
|
34
35
|
|
|
@@ -36,90 +37,87 @@ module ArelExtensions
|
|
|
36
37
|
RETURN_TYPE = :date
|
|
37
38
|
attr_accessor :date_type
|
|
38
39
|
|
|
39
|
-
def initialize
|
|
40
|
+
def initialize expr
|
|
40
41
|
col = expr.first
|
|
41
42
|
@date_type = type_of_attribute(col)
|
|
42
43
|
tab = expr.map do |arg|
|
|
43
44
|
convert(arg)
|
|
44
45
|
end
|
|
45
|
-
super(tab)
|
|
46
|
+
return super(tab)
|
|
46
47
|
end
|
|
47
48
|
|
|
48
49
|
def sqlite_value
|
|
49
|
-
v = expressions.last
|
|
50
|
-
if defined?(ActiveSupport::Duration) &&
|
|
50
|
+
v = self.expressions.last
|
|
51
|
+
if defined?(ActiveSupport::Duration) && ActiveSupport::Duration === v
|
|
51
52
|
if @date_type == :date
|
|
52
|
-
Arel.
|
|
53
|
+
return Arel::Nodes.build_quoted((v.value >= 0 ? '+' : '-') + v.inspect)
|
|
53
54
|
elsif @date_type == :datetime
|
|
54
|
-
Arel.
|
|
55
|
+
return Arel::Nodes.build_quoted((v.value >= 0 ? '+' : '-') + v.inspect)
|
|
55
56
|
end
|
|
56
57
|
else
|
|
57
|
-
v
|
|
58
|
+
return v
|
|
58
59
|
end
|
|
59
60
|
end
|
|
60
61
|
|
|
61
62
|
def mysql_value(v = nil)
|
|
62
|
-
v ||= expressions.last
|
|
63
|
-
if defined?(ActiveSupport::Duration) &&
|
|
63
|
+
v ||= self.expressions.last
|
|
64
|
+
if defined?(ActiveSupport::Duration) && ActiveSupport::Duration === v
|
|
64
65
|
if @date_type == :date || @date_type == :datetime
|
|
65
66
|
Arel.sql('INTERVAL %s' % v.inspect.sub(/s\Z/, ''))
|
|
66
67
|
end
|
|
67
|
-
elsif v.is_a?(ArelExtensions::Nodes::Duration)
|
|
68
|
-
v.with_interval = true
|
|
69
|
-
v
|
|
70
68
|
else
|
|
71
|
-
v
|
|
69
|
+
if ArelExtensions::Nodes::Duration === v
|
|
70
|
+
v.with_interval = true
|
|
71
|
+
v
|
|
72
|
+
else
|
|
73
|
+
v
|
|
74
|
+
end
|
|
72
75
|
end
|
|
73
76
|
end
|
|
74
77
|
|
|
75
78
|
def postgresql_value(v = nil)
|
|
76
|
-
v ||= expressions.last
|
|
77
|
-
if defined?(ActiveSupport::Duration) &&
|
|
79
|
+
v ||= self.expressions.last
|
|
80
|
+
if defined?(ActiveSupport::Duration) && ActiveSupport::Duration === v
|
|
78
81
|
if @date_type == :date
|
|
79
82
|
Arel.sql("INTERVAL '%s'" % v.inspect.sub(/s\Z/, '').upcase)
|
|
80
83
|
elsif @date_type == :datetime
|
|
81
84
|
Arel.sql("INTERVAL '%s'" % v.inspect.sub(/s\Z/, '').upcase)
|
|
82
85
|
end
|
|
83
|
-
elsif v.is_a?(ArelExtensions::Nodes::Duration)
|
|
84
|
-
v.with_interval = true
|
|
85
|
-
v
|
|
86
86
|
else
|
|
87
|
-
v
|
|
87
|
+
if ArelExtensions::Nodes::Duration === v
|
|
88
|
+
v.with_interval = true
|
|
89
|
+
v
|
|
90
|
+
else
|
|
91
|
+
v
|
|
92
|
+
end
|
|
88
93
|
end
|
|
89
94
|
end
|
|
90
95
|
|
|
91
96
|
def oracle_value(v = nil)
|
|
92
|
-
v ||= expressions.last
|
|
93
|
-
if defined?(ActiveSupport::Duration) &&
|
|
97
|
+
v ||= self.expressions.last
|
|
98
|
+
if defined?(ActiveSupport::Duration) && ActiveSupport::Duration === v
|
|
94
99
|
if @date_type == :ruby_date
|
|
95
|
-
Arel.sql("(INTERVAL '1' DAY) * %s" % v.inspect.to_i)
|
|
100
|
+
Arel.sql("(INTERVAL '1' DAY) * %s" % v.inspect.to_i )
|
|
96
101
|
else
|
|
97
102
|
Arel.sql("(INTERVAL '1' SECOND) * %s" % v.to_i)
|
|
98
103
|
end
|
|
99
|
-
elsif v.is_a?(ArelExtensions::Nodes::Duration)
|
|
100
|
-
v.with_interval = true
|
|
101
|
-
v
|
|
102
104
|
else
|
|
103
|
-
v
|
|
105
|
+
if ArelExtensions::Nodes::Duration === v
|
|
106
|
+
v.with_interval = true
|
|
107
|
+
v
|
|
108
|
+
else
|
|
109
|
+
v
|
|
110
|
+
end
|
|
104
111
|
end
|
|
105
112
|
end
|
|
106
113
|
|
|
107
114
|
def mssql_value(v = nil)
|
|
108
|
-
v ||= expressions.last
|
|
109
|
-
if defined?(ActiveSupport::Duration) &&
|
|
115
|
+
v ||= self.expressions.last
|
|
116
|
+
if defined?(ActiveSupport::Duration) && ActiveSupport::Duration === v
|
|
110
117
|
if @date_type == :date
|
|
111
|
-
v.to_i / (24
|
|
118
|
+
v.to_i / (24*3600)
|
|
112
119
|
elsif @date_type == :datetime
|
|
113
|
-
|
|
114
|
-
# first entry in the dict v.parts; one of [:years, :months, :weeks, :days, :hours, :minutes, :seconds]
|
|
115
|
-
# | the value
|
|
116
|
-
# | |
|
|
117
|
-
# | |
|
|
118
|
-
# v v
|
|
119
|
-
v.parts.first.second
|
|
120
|
-
else
|
|
121
|
-
v.to_i
|
|
122
|
-
end
|
|
120
|
+
v.to_i
|
|
123
121
|
end
|
|
124
122
|
else
|
|
125
123
|
v
|
|
@@ -127,40 +125,33 @@ module ArelExtensions
|
|
|
127
125
|
end
|
|
128
126
|
|
|
129
127
|
def mssql_datepart(v = nil)
|
|
130
|
-
v ||= expressions.last
|
|
131
|
-
if defined?(ActiveSupport::Duration) &&
|
|
128
|
+
v ||= self.expressions.last
|
|
129
|
+
if defined?(ActiveSupport::Duration) && ActiveSupport::Duration === v
|
|
132
130
|
if @date_type == :date
|
|
133
131
|
Arel.sql('day')
|
|
134
132
|
elsif @date_type == :datetime
|
|
135
|
-
res = if v.parts.size == 1
|
|
136
|
-
# first entry in the dict v.parts; one of [:years, :months, :weeks, :days, :hours, :minutes, :seconds]
|
|
137
|
-
# | the key
|
|
138
|
-
# | | convert symbol to string
|
|
139
|
-
# | | | remove the plural suffix `s`
|
|
140
|
-
# v v v v
|
|
141
|
-
v.parts.first.first.to_s[0..-2]
|
|
142
|
-
else
|
|
143
|
-
'second'
|
|
144
|
-
end
|
|
145
|
-
Arel.sql(res)
|
|
146
|
-
end
|
|
147
|
-
elsif v.is_a?(ArelExtensions::Nodes::Duration)
|
|
148
|
-
v.with_interval = true
|
|
149
|
-
case v.left
|
|
150
|
-
when 'd', 'm', 'y'
|
|
151
|
-
Arel.sql('day')
|
|
152
|
-
when 'h', 'mn', 's'
|
|
153
133
|
Arel.sql('second')
|
|
154
|
-
|
|
155
|
-
|
|
134
|
+
end
|
|
135
|
+
else
|
|
136
|
+
if ArelExtensions::Nodes::Duration === v
|
|
137
|
+
v.with_interval = true
|
|
138
|
+
case v.left
|
|
139
|
+
when 'd','m','y'
|
|
140
|
+
Arel.sql('day')
|
|
141
|
+
when 'h','mn','s'
|
|
142
|
+
Arel.sql('second')
|
|
143
|
+
when /i\z/
|
|
144
|
+
Arel.sql(Arel::Visitors::MSSQL::DATE_MAPPING[v.left[0..-2]])
|
|
145
|
+
else
|
|
146
|
+
Arel.sql(Arel::Visitors::MSSQL::DATE_MAPPING[v.left])
|
|
147
|
+
end
|
|
156
148
|
else
|
|
157
|
-
|
|
149
|
+
nil
|
|
158
150
|
end
|
|
159
151
|
end
|
|
160
152
|
end
|
|
161
153
|
|
|
162
154
|
private
|
|
163
|
-
|
|
164
155
|
def convert(object)
|
|
165
156
|
case object
|
|
166
157
|
when Arel::Attributes::Attribute, Arel::Nodes::Node, ActiveSupport::Duration
|
|
@@ -168,20 +159,20 @@ module ArelExtensions
|
|
|
168
159
|
when Integer
|
|
169
160
|
object.days
|
|
170
161
|
when DateTime, Time, Date
|
|
171
|
-
raise(ArgumentError, "#{object.class}
|
|
162
|
+
raise(ArgumentError, "#{object.class} can not be converted to Integer")
|
|
172
163
|
when String
|
|
173
|
-
Arel.
|
|
164
|
+
Arel::Nodes.build_quoted(object)
|
|
174
165
|
else
|
|
175
|
-
raise(ArgumentError, "#{object.class}
|
|
166
|
+
raise(ArgumentError, "#{object.class} can not be converted to Integer")
|
|
176
167
|
end
|
|
177
168
|
end
|
|
178
169
|
end
|
|
179
170
|
|
|
180
|
-
class DateSub < Function #
|
|
171
|
+
class DateSub < Function #difference entre colonne date et date string/date
|
|
181
172
|
RETURN_TYPE = :integer
|
|
182
173
|
|
|
183
174
|
def initialize(expr)
|
|
184
|
-
super
|
|
175
|
+
super [expr.first, convert_number(expr[1])]
|
|
185
176
|
end
|
|
186
177
|
|
|
187
178
|
def convert_number(object)
|
|
@@ -191,13 +182,15 @@ module ArelExtensions
|
|
|
191
182
|
when String
|
|
192
183
|
object.to_i
|
|
193
184
|
else
|
|
194
|
-
if defined?(ActiveSupport::Duration) &&
|
|
185
|
+
if defined?(ActiveSupport::Duration) && ActiveSupport::Duration === object
|
|
195
186
|
object.to_i
|
|
196
187
|
else
|
|
197
|
-
raise(ArgumentError, "#{object.class}
|
|
188
|
+
raise(ArgumentError, "#{object.class} can not be converted to Number")
|
|
198
189
|
end
|
|
199
190
|
end
|
|
200
191
|
end
|
|
192
|
+
|
|
201
193
|
end
|
|
194
|
+
|
|
202
195
|
end
|
|
203
196
|
end
|
|
@@ -5,21 +5,24 @@ module ArelExtensions
|
|
|
5
5
|
|
|
6
6
|
attr_accessor :with_interval
|
|
7
7
|
|
|
8
|
-
def initialize
|
|
9
|
-
tab =
|
|
8
|
+
def initialize left, right, aliaz = nil
|
|
9
|
+
tab = Array.new
|
|
10
10
|
tab << left
|
|
11
11
|
tab << right
|
|
12
12
|
@with_interval = left.end_with?('i')
|
|
13
13
|
super(tab, aliaz)
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
+
|
|
16
17
|
def left
|
|
17
18
|
@expressions.first
|
|
18
19
|
end
|
|
19
20
|
|
|
21
|
+
|
|
20
22
|
def right
|
|
21
23
|
@expressions[1]
|
|
22
24
|
end
|
|
25
|
+
|
|
23
26
|
end
|
|
24
27
|
end
|
|
25
28
|
end
|
|
@@ -1,42 +1,15 @@
|
|
|
1
|
-
require 'strscan'
|
|
2
|
-
|
|
3
1
|
module ArelExtensions
|
|
4
2
|
module Nodes
|
|
5
|
-
class Format < Function
|
|
3
|
+
class Format < Function
|
|
6
4
|
RETURN_TYPE = :string
|
|
7
5
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
super([col, convert_to_string_node(@iso_format)])
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
private
|
|
19
|
-
|
|
20
|
-
# Address portability issues with some of the formats.
|
|
21
|
-
def convert_format(fmt)
|
|
22
|
-
s = StringScanner.new fmt
|
|
23
|
-
res = StringIO.new
|
|
24
|
-
while !s.eos?
|
|
25
|
-
res <<
|
|
26
|
-
case
|
|
27
|
-
when s.scan(/%D/) then '%m/%d/%y'
|
|
28
|
-
when s.scan(/%F/) then '%Y-%m-%d'
|
|
29
|
-
when s.scan(/%R/) then '%H:%M'
|
|
30
|
-
when s.scan(/%r/) then '%I:%M:%S %p'
|
|
31
|
-
when s.scan(/%T/) then '%H:%M:%S'
|
|
32
|
-
when s.scan(/%v/) then '%e-%b-%Y'
|
|
33
|
-
|
|
34
|
-
when s.scan(/[^%]+/) then s.matched
|
|
35
|
-
when s.scan(/./) then s.matched
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
res.string
|
|
39
|
-
end
|
|
6
|
+
attr_accessor :col_type, :iso_format
|
|
7
|
+
def initialize expr
|
|
8
|
+
col = expr.first
|
|
9
|
+
@iso_format = expr[1]
|
|
10
|
+
@col_type = type_of_attribute(col)
|
|
11
|
+
super [col, convert_to_string_node(@iso_format)]
|
|
12
|
+
end
|
|
40
13
|
end
|
|
41
14
|
end
|
|
42
15
|
end
|
|
@@ -1,24 +1,25 @@
|
|
|
1
1
|
module ArelExtensions
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
2
|
+
module Nodes
|
|
3
|
+
class FormattedNumber < Function
|
|
4
|
+
RETURN_TYPE = :string
|
|
5
|
+
|
|
6
|
+
attr_accessor :locale, :prefix, :suffix, :flags, :scientific_notation, :width,:precision, :type, :original_string
|
|
7
|
+
|
|
8
|
+
def initialize expr
|
|
9
|
+
# expr[1] = {:locale => 'fr_FR', :type => "e"/"f"/"d", :prefix => "$ ", :suffix => " %", :flags => " +-#0", :width => 5, :precision => 6}
|
|
10
|
+
col = expr.first
|
|
11
|
+
@locale = expr[1][:locale]
|
|
12
|
+
@prefix = expr[1][:prefix]
|
|
13
|
+
@suffix = expr[1][:suffix]
|
|
14
|
+
@width = expr[1][:width]
|
|
15
|
+
@precision = expr[1][:precision]
|
|
16
|
+
@type = expr[1][:type]
|
|
17
|
+
@flags = expr[1][:flags]
|
|
18
|
+
@scientific_notation = /[eE]/.match(expr[1][:type]) || false
|
|
19
|
+
@original_string = expr[1][:original_string]
|
|
20
|
+
super [col]
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
end
|
|
24
|
+
end
|
|
24
25
|
end
|
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
require 'arel_extensions/predications'
|
|
2
2
|
|
|
3
|
-
# This is required for rails 6.1
|
|
4
|
-
# See https://github.com/thoughtbot/shoulda-matchers/issues/335
|
|
5
|
-
if !Array.respond_to?(:wrap)
|
|
6
|
-
require 'active_support/core_ext/array/wrap'
|
|
7
|
-
end
|
|
8
|
-
|
|
9
3
|
module ArelExtensions
|
|
10
4
|
module Nodes
|
|
11
5
|
class Function < Arel::Nodes::Function
|
|
@@ -16,24 +10,18 @@ module ArelExtensions
|
|
|
16
10
|
|
|
17
11
|
RETURN_TYPE = :string # by default...
|
|
18
12
|
|
|
19
|
-
# Support multibyte string if they are available.
|
|
20
|
-
MBSTRING =
|
|
21
|
-
defined?(ActiveSupport::Multibyte::Chars) ? ActiveSupport::Multibyte::Chars : String
|
|
22
|
-
|
|
23
13
|
# overrides as to make new Node like AliasPredication
|
|
24
14
|
|
|
25
15
|
def return_type
|
|
26
16
|
self.class.const_get(:RETURN_TYPE)
|
|
27
17
|
end
|
|
28
18
|
|
|
29
|
-
def as
|
|
30
|
-
|
|
31
|
-
self.alias = Arel.sql(other)
|
|
32
|
-
res
|
|
19
|
+
def as other
|
|
20
|
+
Arel::Nodes::As.new(self, Arel.sql(other))
|
|
33
21
|
end
|
|
34
22
|
|
|
35
23
|
def expr
|
|
36
|
-
|
|
24
|
+
@expressions.first
|
|
37
25
|
end
|
|
38
26
|
|
|
39
27
|
def left
|
|
@@ -45,21 +33,25 @@ module ArelExtensions
|
|
|
45
33
|
end
|
|
46
34
|
|
|
47
35
|
def ==(other)
|
|
48
|
-
Arel::Nodes::Equality.new self, Arel.
|
|
36
|
+
Arel::Nodes::Equality.new self, Arel::Nodes.build_quoted(other, self)
|
|
49
37
|
end
|
|
50
38
|
|
|
51
39
|
def !=(other)
|
|
52
|
-
Arel::Nodes::NotEqual.new self, Arel.
|
|
40
|
+
Arel::Nodes::NotEqual.new self, Arel::Nodes.build_quoted(other, self)
|
|
53
41
|
end
|
|
54
42
|
|
|
55
43
|
def type_of_attribute(att)
|
|
56
44
|
case att
|
|
57
45
|
when Arel::Attributes::Attribute
|
|
58
|
-
|
|
46
|
+
begin
|
|
47
|
+
Arel::Table.engine.connection.schema_cache.columns_hash(att.relation.table_name)[att.name.to_s].type
|
|
48
|
+
rescue
|
|
49
|
+
att
|
|
50
|
+
end
|
|
59
51
|
when ArelExtensions::Nodes::Function
|
|
60
52
|
att.return_type
|
|
61
|
-
|
|
62
|
-
|
|
53
|
+
# else
|
|
54
|
+
# nil
|
|
63
55
|
end
|
|
64
56
|
end
|
|
65
57
|
|
|
@@ -68,23 +60,19 @@ module ArelExtensions
|
|
|
68
60
|
when Arel::Attributes::Attribute, Arel::Nodes::Node, Integer
|
|
69
61
|
object
|
|
70
62
|
when DateTime
|
|
71
|
-
Arel.
|
|
63
|
+
Arel::Nodes.build_quoted(object, self)
|
|
72
64
|
when Time
|
|
73
|
-
Arel.
|
|
74
|
-
when
|
|
75
|
-
Arel.
|
|
76
|
-
when TrueClass, FalseClass
|
|
77
|
-
Arel.quoted(object)
|
|
65
|
+
Arel::Nodes.build_quoted(object.strftime('%H:%M:%S'), self)
|
|
66
|
+
when String, Symbol
|
|
67
|
+
Arel::Nodes.build_quoted(object.to_s)
|
|
78
68
|
when Date
|
|
79
|
-
Arel.
|
|
69
|
+
Arel::Nodes.build_quoted(object.to_s, self)
|
|
80
70
|
when NilClass
|
|
81
71
|
Arel.sql('NULL')
|
|
82
72
|
when ActiveSupport::Duration
|
|
83
73
|
Arel.sql(object.to_i)
|
|
84
|
-
when Array
|
|
85
|
-
Arel.grouping(object.map { |e| convert_to_node(e) })
|
|
86
74
|
else
|
|
87
|
-
raise(ArgumentError, "#{object.class}
|
|
75
|
+
raise(ArgumentError, "#{object.class} can not be converted to CONCAT arg")
|
|
88
76
|
end
|
|
89
77
|
end
|
|
90
78
|
|
|
@@ -93,9 +81,9 @@ module ArelExtensions
|
|
|
93
81
|
when Arel::Nodes::Node
|
|
94
82
|
object
|
|
95
83
|
when Integer
|
|
96
|
-
Arel.
|
|
84
|
+
Arel::Nodes.build_quoted(object.to_s)
|
|
97
85
|
when Arel::Attributes::Attribute
|
|
98
|
-
case type_of_attribute(object)
|
|
86
|
+
case self.type_of_attribute(object)
|
|
99
87
|
when :date
|
|
100
88
|
ArelExtensions::Nodes::Format.new [object, 'yyyy-mm-dd']
|
|
101
89
|
when :time
|
|
@@ -104,19 +92,19 @@ module ArelExtensions
|
|
|
104
92
|
object
|
|
105
93
|
end
|
|
106
94
|
when DateTime
|
|
107
|
-
Arel.
|
|
95
|
+
Arel::Nodes.build_quoted(object, self)
|
|
108
96
|
when Time
|
|
109
|
-
Arel.
|
|
110
|
-
when
|
|
111
|
-
Arel.
|
|
97
|
+
Arel::Nodes.build_quoted(object.strftime('%H:%M:%S'), self)
|
|
98
|
+
when String
|
|
99
|
+
Arel::Nodes.build_quoted(object)
|
|
112
100
|
when Date
|
|
113
|
-
Arel.
|
|
101
|
+
Arel::Nodes.build_quoted(object, self)
|
|
114
102
|
when NilClass
|
|
115
103
|
Arel.sql(nil)
|
|
116
104
|
when ActiveSupport::Duration
|
|
117
|
-
Arel.
|
|
105
|
+
Arel::Nodes.build_quoted(object.to_i.to_s)
|
|
118
106
|
else
|
|
119
|
-
raise(ArgumentError, "#{object.class}
|
|
107
|
+
raise(ArgumentError, "#{object.class} can not be converted to CONCAT arg")
|
|
120
108
|
end
|
|
121
109
|
end
|
|
122
110
|
|
|
@@ -125,13 +113,13 @@ module ArelExtensions
|
|
|
125
113
|
when Arel::Attributes::Attribute, Arel::Nodes::Node
|
|
126
114
|
object
|
|
127
115
|
when DateTime, Time
|
|
128
|
-
Arel.
|
|
129
|
-
when
|
|
130
|
-
Arel.
|
|
116
|
+
Arel::Nodes.build_quoted(Date.new(object.year, object.month, object.day), self)
|
|
117
|
+
when String
|
|
118
|
+
Arel::Nodes.build_quoted(Date.parse(object), self)
|
|
131
119
|
when Date
|
|
132
|
-
Arel.
|
|
120
|
+
Arel::Nodes.build_quoted(object, self)
|
|
133
121
|
else
|
|
134
|
-
raise(ArgumentError, "#{object.class}
|
|
122
|
+
raise(ArgumentError, "#{object.class} can not be converted to Date")
|
|
135
123
|
end
|
|
136
124
|
end
|
|
137
125
|
|
|
@@ -140,13 +128,13 @@ module ArelExtensions
|
|
|
140
128
|
when Arel::Attributes::Attribute, Arel::Nodes::Node
|
|
141
129
|
object
|
|
142
130
|
when DateTime, Time
|
|
143
|
-
Arel.
|
|
144
|
-
when
|
|
145
|
-
Arel.
|
|
131
|
+
Arel::Nodes.build_quoted(object, self)
|
|
132
|
+
when String
|
|
133
|
+
Arel::Nodes.build_quoted(Time.parse(object), self)
|
|
146
134
|
when Date
|
|
147
|
-
Arel.
|
|
135
|
+
Arel::Nodes.build_quoted(Time.utc(object.year, object.month, object.day, 0, 0, 0), self)
|
|
148
136
|
else
|
|
149
|
-
raise(ArgumentError, "#{object.class}
|
|
137
|
+
raise(ArgumentError, "#{object.class} can not be converted to Datetime")
|
|
150
138
|
end
|
|
151
139
|
end
|
|
152
140
|
|
|
@@ -164,9 +152,10 @@ module ArelExtensions
|
|
|
164
152
|
when NilClass
|
|
165
153
|
0
|
|
166
154
|
else
|
|
167
|
-
raise(ArgumentError, "#{object.class}
|
|
155
|
+
raise(ArgumentError, "#{object.class} can not be converted to NUMBER arg")
|
|
168
156
|
end
|
|
169
157
|
end
|
|
158
|
+
|
|
170
159
|
end
|
|
171
160
|
end
|
|
172
161
|
end
|
|
@@ -4,13 +4,11 @@ module ArelExtensions
|
|
|
4
4
|
module Nodes
|
|
5
5
|
class IsNull < Arel::Nodes::Unary
|
|
6
6
|
include ArelExtensions::BooleanFunctions
|
|
7
|
-
|
|
8
7
|
RETURN_TYPE = :boolean
|
|
9
8
|
end
|
|
10
9
|
|
|
11
10
|
class IsNotNull < Arel::Nodes::Unary
|
|
12
11
|
include ArelExtensions::BooleanFunctions
|
|
13
|
-
|
|
14
12
|
RETURN_TYPE = :boolean
|
|
15
13
|
end
|
|
16
14
|
end
|