arel_extensions 2.0.21 → 2.2.2
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 +1 -2
- data/.github/workflows/publish.yml +29 -0
- data/.github/workflows/release.yml +30 -0
- data/.github/workflows/ruby.yml +377 -80
- data/.gitignore +7 -6
- data/.rubocop.yml +62 -1
- data/CONTRIBUTING.md +102 -0
- data/Gemfile +2 -23
- data/NEWS.md +89 -0
- data/README.md +228 -84
- data/Rakefile +11 -4
- data/TODO +0 -1
- data/appveyor.yml +60 -22
- data/arel_extensions.gemspec +11 -12
- data/bin/build +15 -0
- data/bin/compose +6 -0
- data/bin/publish +8 -0
- data/dev/arelx.dockerfile +44 -0
- data/dev/compose.yaml +71 -0
- data/dev/postgres.dockerfile +5 -0
- data/dev/rbenv +189 -0
- data/gemfiles/rails3.gemfile +10 -10
- data/gemfiles/rails4_2.gemfile +38 -0
- data/gemfiles/rails5.gemfile +29 -0
- data/gemfiles/rails5_1_4.gemfile +13 -13
- data/gemfiles/rails5_2.gemfile +16 -14
- data/gemfiles/rails6.gemfile +18 -15
- data/gemfiles/rails6_1.gemfile +18 -15
- data/gemfiles/rails7.gemfile +33 -0
- data/gemfiles/rails7_1.gemfile +33 -0
- data/gemfiles/rails7_2.gemfile +33 -0
- data/gemspecs/arel_extensions-v1.gemspec +12 -13
- data/gemspecs/arel_extensions-v2.gemspec +11 -12
- data/init/mssql.sql +0 -0
- data/init/mysql.sql +0 -0
- data/init/oracle.sql +0 -0
- data/init/postgresql.sql +0 -0
- data/init/sqlite.sql +0 -0
- data/lib/arel_extensions/aliases.rb +14 -0
- data/lib/arel_extensions/attributes.rb +10 -2
- data/lib/arel_extensions/boolean_functions.rb +2 -4
- data/lib/arel_extensions/common_sql_functions.rb +12 -12
- data/lib/arel_extensions/comparators.rb +14 -14
- data/lib/arel_extensions/date_duration.rb +14 -9
- data/lib/arel_extensions/helpers.rb +62 -0
- data/lib/arel_extensions/insert_manager.rb +19 -17
- data/lib/arel_extensions/math.rb +48 -45
- data/lib/arel_extensions/math_functions.rb +18 -18
- data/lib/arel_extensions/nodes/abs.rb +0 -0
- data/lib/arel_extensions/nodes/aggregate_function.rb +0 -0
- data/lib/arel_extensions/nodes/blank.rb +1 -1
- data/lib/arel_extensions/nodes/case.rb +10 -12
- data/lib/arel_extensions/nodes/cast.rb +6 -6
- data/lib/arel_extensions/nodes/ceil.rb +0 -0
- data/lib/arel_extensions/nodes/change_case.rb +0 -0
- data/lib/arel_extensions/nodes/coalesce.rb +1 -1
- data/lib/arel_extensions/nodes/collate.rb +9 -9
- data/lib/arel_extensions/nodes/concat.rb +2 -2
- data/lib/arel_extensions/nodes/date_diff.rb +33 -14
- data/lib/arel_extensions/nodes/duration.rb +0 -0
- data/lib/arel_extensions/nodes/find_in_set.rb +0 -0
- data/lib/arel_extensions/nodes/floor.rb +0 -0
- data/lib/arel_extensions/nodes/format.rb +3 -2
- data/lib/arel_extensions/nodes/formatted_date.rb +42 -0
- data/lib/arel_extensions/nodes/formatted_number.rb +2 -2
- data/lib/arel_extensions/nodes/function.rb +22 -26
- data/lib/arel_extensions/nodes/is_null.rb +0 -0
- data/lib/arel_extensions/nodes/json.rb +15 -9
- data/lib/arel_extensions/nodes/length.rb +6 -0
- data/lib/arel_extensions/nodes/levenshtein_distance.rb +1 -1
- data/lib/arel_extensions/nodes/locate.rb +1 -1
- data/lib/arel_extensions/nodes/log10.rb +0 -0
- data/lib/arel_extensions/nodes/matches.rb +1 -1
- data/lib/arel_extensions/nodes/md5.rb +0 -0
- data/lib/arel_extensions/nodes/power.rb +0 -0
- data/lib/arel_extensions/nodes/rand.rb +0 -0
- data/lib/arel_extensions/nodes/repeat.rb +2 -2
- data/lib/arel_extensions/nodes/replace.rb +2 -10
- data/lib/arel_extensions/nodes/rollup.rb +36 -0
- data/lib/arel_extensions/nodes/round.rb +0 -0
- data/lib/arel_extensions/nodes/select.rb +10 -0
- data/lib/arel_extensions/nodes/soundex.rb +2 -2
- data/lib/arel_extensions/nodes/std.rb +0 -0
- data/lib/arel_extensions/nodes/substring.rb +1 -1
- data/lib/arel_extensions/nodes/sum.rb +0 -0
- data/lib/arel_extensions/nodes/then.rb +1 -1
- data/lib/arel_extensions/nodes/trim.rb +2 -2
- data/lib/arel_extensions/nodes/union.rb +5 -5
- data/lib/arel_extensions/nodes/union_all.rb +4 -4
- data/lib/arel_extensions/nodes/wday.rb +0 -0
- data/lib/arel_extensions/nodes.rb +0 -0
- data/lib/arel_extensions/null_functions.rb +16 -0
- data/lib/arel_extensions/predications.rb +10 -10
- data/lib/arel_extensions/railtie.rb +1 -1
- data/lib/arel_extensions/set_functions.rb +3 -3
- data/lib/arel_extensions/string_functions.rb +19 -10
- data/lib/arel_extensions/tasks.rb +2 -2
- data/lib/arel_extensions/version.rb +1 -1
- data/lib/arel_extensions/visitors/convert_format.rb +0 -0
- data/lib/arel_extensions/visitors/ibm_db.rb +20 -20
- data/lib/arel_extensions/visitors/mssql.rb +394 -169
- data/lib/arel_extensions/visitors/mysql.rb +238 -151
- data/lib/arel_extensions/visitors/oracle.rb +170 -131
- data/lib/arel_extensions/visitors/oracle12.rb +16 -16
- data/lib/arel_extensions/visitors/postgresql.rb +170 -140
- data/lib/arel_extensions/visitors/sqlite.rb +88 -87
- data/lib/arel_extensions/visitors/to_sql.rb +185 -156
- data/lib/arel_extensions/visitors.rb +73 -60
- data/lib/arel_extensions.rb +173 -36
- data/test/arelx_test_helper.rb +49 -1
- data/test/database.yml +13 -7
- data/test/real_db_test.rb +101 -83
- data/test/support/fake_record.rb +8 -2
- data/test/test_comparators.rb +5 -5
- data/test/visitors/test_bulk_insert_oracle.rb +5 -5
- data/test/visitors/test_bulk_insert_sqlite.rb +5 -5
- data/test/visitors/test_bulk_insert_to_sql.rb +5 -5
- data/test/visitors/test_oracle.rb +14 -14
- data/test/visitors/test_to_sql.rb +121 -93
- data/test/with_ar/all_agnostic_test.rb +630 -320
- data/test/with_ar/insert_agnostic_test.rb +25 -18
- data/test/with_ar/test_bulk_sqlite.rb +11 -7
- data/test/with_ar/test_math_sqlite.rb +18 -14
- data/test/with_ar/test_string_mysql.rb +26 -22
- data/test/with_ar/test_string_sqlite.rb +26 -22
- data/version_v1.rb +1 -1
- data/version_v2.rb +1 -1
- metadata +24 -26
- data/.travis/oracle/download.js +0 -152
- data/.travis/oracle/download.sh +0 -30
- data/.travis/oracle/download_ojdbc.js +0 -116
- data/.travis/oracle/install.sh +0 -34
- data/.travis/setup_accounts.sh +0 -9
- data/.travis/sqlite3/extension-functions.sh +0 -6
- data/.travis.yml +0 -193
- data/gemfiles/rails4.gemfile +0 -29
- data/gemfiles/rails5_0.gemfile +0 -29
data/lib/arel_extensions/math.rb
CHANGED
@@ -16,43 +16,44 @@ module ArelExtensions
|
|
16
16
|
# Date and integer adds or subtracts a specified time interval from a date.
|
17
17
|
def +(other)
|
18
18
|
case self
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
19
|
+
when Arel::Nodes::Quoted
|
20
|
+
self.concat(other)
|
21
|
+
when Arel::Nodes::Grouping
|
22
|
+
if self.expr.left.is_a?(String) || self.expr.right.is_a?(String)
|
23
|
+
self.concat(other)
|
24
|
+
else
|
25
|
+
Arel.grouping(Arel::Nodes::Addition.new self, other)
|
26
|
+
end
|
27
|
+
when ArelExtensions::Nodes::Function, ArelExtensions::Nodes::Case
|
28
|
+
case self.return_type
|
29
29
|
when :string, :text
|
30
30
|
self.concat(other)
|
31
31
|
when :integer, :decimal, :float, :number, :int
|
32
|
-
Arel
|
32
|
+
Arel.grouping(Arel::Nodes::Addition.new self, other)
|
33
33
|
when :date, :datetime
|
34
34
|
ArelExtensions::Nodes::DateAdd.new [self, other]
|
35
35
|
else
|
36
36
|
self.concat(other)
|
37
37
|
end
|
38
38
|
when Arel::Nodes::Function
|
39
|
-
Arel
|
39
|
+
Arel.grouping(Arel::Nodes::Addition.new self, other)
|
40
40
|
else
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
41
|
+
col =
|
42
|
+
if self.is_a?(Arel::Attribute) && self.respond_to?(:type_caster) && self.able_to_type_cast?
|
43
|
+
self.type_caster
|
44
|
+
else
|
45
|
+
Arel.column_of(self.relation.table_name, self.name.to_s) if self.respond_to?(:relation)
|
46
|
+
end
|
47
|
+
if !col # if the column doesn't exist in the database
|
48
|
+
Arel.grouping(Arel::Nodes::Addition.new(self, Arel.quoted(other)))
|
48
49
|
else
|
49
50
|
arg = col.type
|
50
|
-
if arg == :integer ||
|
51
|
+
if arg == :integer || !arg
|
51
52
|
other = other.to_i if other.is_a?(String)
|
52
|
-
Arel
|
53
|
+
Arel.grouping(Arel::Nodes::Addition.new self, Arel.quoted(other))
|
53
54
|
elsif arg == :decimal || arg == :float
|
54
55
|
other = Arel.sql(other) if other.is_a?(String) # Arel should accept Float & BigDecimal!
|
55
|
-
Arel
|
56
|
+
Arel.grouping(Arel::Nodes::Addition.new self, Arel.quoted(other))
|
56
57
|
elsif arg == :datetime || arg == :date
|
57
58
|
ArelExtensions::Nodes::DateAdd.new [self, other]
|
58
59
|
elsif arg == :string || arg == :text
|
@@ -68,42 +69,44 @@ module ArelExtensions
|
|
68
69
|
case self
|
69
70
|
when Arel::Nodes::Grouping
|
70
71
|
if self.expr.left.is_a?(Date) || self.expr.left.is_a?(DateTime)
|
71
|
-
Arel
|
72
|
+
Arel.grouping(ArelExtensions::Nodes::DateSub.new [self, Arel.quoted(other)])
|
72
73
|
else
|
73
|
-
Arel
|
74
|
+
Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.quoted(other)))
|
74
75
|
end
|
75
76
|
when ArelExtensions::Nodes::Function, ArelExtensions::Nodes::Case
|
76
77
|
case self.return_type
|
77
78
|
when :string, :text # ???
|
78
|
-
Arel
|
79
|
+
Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.quoted(other))) # ??
|
79
80
|
when :integer, :decimal, :float, :number
|
80
|
-
Arel
|
81
|
+
Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.quoted(other)))
|
81
82
|
when :date, :datetime
|
82
|
-
ArelExtensions::Nodes::DateSub.new [self, other]
|
83
|
+
ArelExtensions::Nodes::DateSub.new [self, Arel.quoted(other)]
|
83
84
|
else
|
84
|
-
Arel
|
85
|
+
Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.quoted(other)))
|
85
86
|
end
|
86
87
|
when Arel::Nodes::Function
|
87
|
-
Arel
|
88
|
+
Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.quoted(other)))
|
88
89
|
else
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
90
|
+
col =
|
91
|
+
if self.is_a?(Arel::Attribute) && self.respond_to?(:type_caster) && self.able_to_type_cast?
|
92
|
+
self.type_caster
|
93
|
+
else
|
94
|
+
Arel.column_of(self.relation.table_name, self.name.to_s) if self.respond_to?(:relation)
|
95
|
+
end
|
96
|
+
if !col # if the column doesn't exist in the database
|
97
|
+
Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.quoted(other)))
|
96
98
|
else
|
97
99
|
arg = col.type
|
98
100
|
if (arg == :date || arg == :datetime)
|
99
101
|
case other
|
100
102
|
when Arel::Attributes::Attribute
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
103
|
+
col2 =
|
104
|
+
if other.is_a?(Arel::Attribute) && other.respond_to?(:type_caster) && other.able_to_type_cast?
|
105
|
+
other.type_caster
|
106
|
+
else
|
107
|
+
Arel.column_of(other.relation.table_name, other.name.to_s) if other.respond_to?(:relation)
|
108
|
+
end
|
109
|
+
if !col2 # if the column doesn't exist in the database
|
107
110
|
ArelExtensions::Nodes::DateSub.new [self, other]
|
108
111
|
else
|
109
112
|
arg2 = col2.type
|
@@ -123,11 +126,11 @@ module ArelExtensions
|
|
123
126
|
else
|
124
127
|
case other
|
125
128
|
when Integer, Float, BigDecimal
|
126
|
-
Arel
|
129
|
+
Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.sql(other.to_s)))
|
127
130
|
when String
|
128
|
-
Arel
|
131
|
+
Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.sql(other)))
|
129
132
|
else
|
130
|
-
Arel
|
133
|
+
Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.quoted(other)))
|
131
134
|
end
|
132
135
|
end
|
133
136
|
end
|
@@ -15,7 +15,7 @@ module ArelExtensions
|
|
15
15
|
def * other
|
16
16
|
case other
|
17
17
|
when Float, BigDecimal
|
18
|
-
super(Arel
|
18
|
+
super(Arel.quoted(other))
|
19
19
|
else
|
20
20
|
super(other)
|
21
21
|
end
|
@@ -25,7 +25,7 @@ module ArelExtensions
|
|
25
25
|
def / other
|
26
26
|
case other
|
27
27
|
when Float, BigDecimal
|
28
|
-
super(Arel
|
28
|
+
super(Arel.quoted(other))
|
29
29
|
else
|
30
30
|
super(other)
|
31
31
|
end
|
@@ -33,32 +33,32 @@ module ArelExtensions
|
|
33
33
|
|
34
34
|
# Abs function returns the absolute value of a number passed as argument #
|
35
35
|
def abs
|
36
|
-
|
36
|
+
ArelExtensions::Nodes::Abs.new [self]
|
37
37
|
end
|
38
38
|
|
39
39
|
# will rounded up any positive or negative decimal value within the function upwards #
|
40
40
|
def ceil
|
41
|
-
|
41
|
+
ArelExtensions::Nodes::Ceil.new [self]
|
42
42
|
end
|
43
43
|
|
44
44
|
# function rounded up any positive or negative decimal value down to the next least integer
|
45
45
|
def floor
|
46
|
-
|
46
|
+
ArelExtensions::Nodes::Floor.new [self]
|
47
47
|
end
|
48
48
|
|
49
49
|
# function gives the base 10 log
|
50
50
|
def log10
|
51
|
-
|
51
|
+
ArelExtensions::Nodes::Log10.new [self]
|
52
52
|
end
|
53
53
|
|
54
54
|
# function gives the power of a number
|
55
55
|
def pow exposant = 0
|
56
|
-
|
56
|
+
ArelExtensions::Nodes::Power.new [self, exposant]
|
57
57
|
end
|
58
58
|
|
59
59
|
# function gives the power of a number
|
60
60
|
def power exposant = 0
|
61
|
-
|
61
|
+
ArelExtensions::Nodes::Power.new [self, exposant]
|
62
62
|
end
|
63
63
|
|
64
64
|
# Aggregate Functions
|
@@ -71,7 +71,7 @@ module ArelExtensions
|
|
71
71
|
end
|
72
72
|
|
73
73
|
def sum opts = {unbiased: true}
|
74
|
-
if Gem::Version.new(Arel::VERSION) >= Gem::Version.new(
|
74
|
+
if Gem::Version.new(Arel::VERSION) >= Gem::Version.new('9.0.0')
|
75
75
|
Arel::Nodes::Sum.new [self]
|
76
76
|
else
|
77
77
|
ArelExtensions::Nodes::Sum.new self, **opts
|
@@ -86,17 +86,17 @@ module ArelExtensions
|
|
86
86
|
|
87
87
|
# function is used to round a numeric field to the number of decimals specified
|
88
88
|
def round precision = nil
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
89
|
+
if precision
|
90
|
+
ArelExtensions::Nodes::Round.new [self, precision]
|
91
|
+
else
|
92
|
+
ArelExtensions::Nodes::Round.new [self]
|
93
|
+
end
|
94
94
|
end
|
95
95
|
|
96
96
|
# function returning a number at a specific format
|
97
97
|
def format_number format_string, locale = nil
|
98
98
|
begin
|
99
|
-
sprintf(format_string,0) # this line is to get the right error message if the format_string is not correct
|
99
|
+
sprintf(format_string, 0) # this line is to get the right error message if the format_string is not correct
|
100
100
|
m = /^(.*)%([ #+\-0]*)([1-9][0-9]+|[1-9]?)[.]?([0-9]*)([a-zA-Z])(.*)$/.match(format_string)
|
101
101
|
opts = {
|
102
102
|
prefix: m[1],
|
@@ -108,10 +108,10 @@ module ArelExtensions
|
|
108
108
|
locale: locale,
|
109
109
|
original_string: format_string
|
110
110
|
}
|
111
|
-
# opts = {:
|
112
|
-
ArelExtensions::Nodes::FormattedNumber.new [self,opts]
|
111
|
+
# opts = {locale: 'fr_FR', type: "e"/"f"/"d", prefix: "$ ", suffix: " %", flags: " +-#0", width: 5, precision: 6}
|
112
|
+
ArelExtensions::Nodes::FormattedNumber.new [self, opts]
|
113
113
|
rescue Exception
|
114
|
-
Arel
|
114
|
+
Arel.quoted('Wrong Format')
|
115
115
|
end
|
116
116
|
end
|
117
117
|
end
|
File without changes
|
File without changes
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module ArelExtensions
|
2
2
|
module Nodes
|
3
|
-
if Gem::Version.new(Arel::VERSION) < Gem::Version.new(
|
3
|
+
if Gem::Version.new(Arel::VERSION) < Gem::Version.new('7.1.0')
|
4
4
|
class Case < Arel::Nodes::Node
|
5
5
|
include Arel::Expressions
|
6
6
|
include Arel::Math
|
@@ -34,16 +34,18 @@ module ArelExtensions
|
|
34
34
|
include Arel::Math
|
35
35
|
include Arel::Predications
|
36
36
|
include Arel::OrderPredications
|
37
|
-
include ArelExtensions::
|
37
|
+
include ArelExtensions::Aliases
|
38
38
|
include ArelExtensions::Comparators
|
39
|
-
include ArelExtensions::
|
39
|
+
include ArelExtensions::DateDuration
|
40
|
+
include ArelExtensions::Math
|
40
41
|
include ArelExtensions::MathFunctions
|
41
|
-
include ArelExtensions::StringFunctions
|
42
42
|
include ArelExtensions::NullFunctions
|
43
|
+
include ArelExtensions::Predications
|
44
|
+
include ArelExtensions::StringFunctions
|
43
45
|
|
44
46
|
def return_type
|
45
47
|
obj = if @conditions.length > 0
|
46
|
-
|
48
|
+
@conditions.last.right
|
47
49
|
elsif @default
|
48
50
|
@default.expr
|
49
51
|
end
|
@@ -53,14 +55,10 @@ module ArelExtensions
|
|
53
55
|
case obj
|
54
56
|
when Integer, Float
|
55
57
|
:number
|
56
|
-
when Date, DateTime,Time
|
58
|
+
when Date, DateTime, Time
|
57
59
|
:datetime
|
58
60
|
when Arel::Attributes::Attribute
|
59
|
-
|
60
|
-
Arel::Table.engine.connection.schema_cache.columns_hash(obj.relation.table_name)[obj.name.to_s].type
|
61
|
-
rescue Exception
|
62
|
-
:string
|
63
|
-
end
|
61
|
+
Arel.column_of(obj.relation.table_name, obj.name.to_s)&.type || :string
|
64
62
|
else
|
65
63
|
:string
|
66
64
|
end
|
@@ -102,7 +100,7 @@ module ArelExtensions
|
|
102
100
|
alias :== :eql?
|
103
101
|
|
104
102
|
def as other
|
105
|
-
Arel::Nodes::As.new self, Arel
|
103
|
+
Arel::Nodes::As.new self, Arel.sql(other)
|
106
104
|
end
|
107
105
|
end
|
108
106
|
end
|
@@ -19,11 +19,11 @@ module ArelExtensions
|
|
19
19
|
when 'text', :text, 'ntext', :ntext
|
20
20
|
@as_attr = expr[1].to_sym
|
21
21
|
@return_type = :string
|
22
|
-
when :datetime, 'datetime','smalldatetime'
|
22
|
+
when :datetime, 'datetime', 'smalldatetime'
|
23
23
|
@return_type = :datetime
|
24
|
-
when :time,'time'
|
24
|
+
when :time, 'time'
|
25
25
|
@return_type = :time
|
26
|
-
when :date,'date'
|
26
|
+
when :date, 'date'
|
27
27
|
@return_type = :date
|
28
28
|
when :binary, 'binary', 'varbinary', 'image'
|
29
29
|
@return_type = :binary
|
@@ -32,17 +32,17 @@ module ArelExtensions
|
|
32
32
|
@as_attr = :string
|
33
33
|
end
|
34
34
|
tab = [convert_to_node(expr.first)]
|
35
|
-
|
35
|
+
super(tab)
|
36
36
|
end
|
37
37
|
|
38
38
|
def +(other)
|
39
39
|
case @return_type
|
40
40
|
when :string
|
41
|
-
|
41
|
+
ArelExtensions::Nodes::Concat.new [self, other]
|
42
42
|
when :ruby_time
|
43
43
|
ArelExtensions::Nodes::DateAdd.new [self, other]
|
44
44
|
else
|
45
|
-
Arel
|
45
|
+
Arel.grouping(Arel::Nodes::Addition.new self, other)
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
File without changes
|
File without changes
|
@@ -1,17 +1,17 @@
|
|
1
1
|
module ArelExtensions
|
2
2
|
module Nodes
|
3
3
|
class Collate < Function
|
4
|
-
|
4
|
+
RETURN_TYPE = :string
|
5
5
|
|
6
|
-
|
6
|
+
attr_accessor :ai, :ci, :option
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
8
|
+
def initialize left, option = nil, ai = false, ci = false
|
9
|
+
@ai = ai
|
10
|
+
@ci = ci
|
11
|
+
@option = option
|
12
|
+
tab = [convert_to_node(left)]
|
13
|
+
super(tab)
|
14
|
+
end
|
15
15
|
end
|
16
16
|
end
|
17
17
|
end
|
@@ -13,10 +13,10 @@ module ArelExtensions::Nodes
|
|
13
13
|
end
|
14
14
|
}.flatten.reduce([]) { |res, b|
|
15
15
|
# concatenate successive literal strings.
|
16
|
-
if b.is_a?(Arel::Nodes::Quoted) && b.expr ==
|
16
|
+
if b.is_a?(Arel::Nodes::Quoted) && b.expr == ''
|
17
17
|
res
|
18
18
|
elsif res.last && res.last.is_a?(Arel::Nodes::Quoted) && b.is_a?(Arel::Nodes::Quoted)
|
19
|
-
res[-1] = Arel
|
19
|
+
res[-1] = Arel.quoted(res.last.expr.to_s + b.expr.to_s)
|
20
20
|
else
|
21
21
|
res << b
|
22
22
|
end
|
@@ -19,7 +19,7 @@ module ArelExtensions
|
|
19
19
|
when DateTime, Time
|
20
20
|
@left_node_type = :ruby_time
|
21
21
|
end
|
22
|
-
res << ([
|
22
|
+
res << (%i[date ruby_date].include?(@left_node_type) ? convert_to_date_node(col) : convert_to_datetime_node(col))
|
23
23
|
case expr[1]
|
24
24
|
when Arel::Nodes::Node, Arel::Attributes::Attribute
|
25
25
|
@right_node_type = type_of_attribute(expr[1])
|
@@ -28,7 +28,7 @@ module ArelExtensions
|
|
28
28
|
when DateTime, Time
|
29
29
|
@right_node_type = :ruby_time
|
30
30
|
end
|
31
|
-
res << ([
|
31
|
+
res << (%i[date ruby_date].include?(@left_node_type) ? convert_to_date_node(expr[1]) : convert_to_datetime_node(expr[1]))
|
32
32
|
super res
|
33
33
|
end
|
34
34
|
end
|
@@ -43,19 +43,19 @@ module ArelExtensions
|
|
43
43
|
tab = expr.map do |arg|
|
44
44
|
convert(arg)
|
45
45
|
end
|
46
|
-
|
46
|
+
super(tab)
|
47
47
|
end
|
48
48
|
|
49
49
|
def sqlite_value
|
50
50
|
v = self.expressions.last
|
51
51
|
if defined?(ActiveSupport::Duration) && ActiveSupport::Duration === v
|
52
52
|
if @date_type == :date
|
53
|
-
|
53
|
+
Arel.quoted((v.value >= 0 ? '+' : '-') + v.inspect)
|
54
54
|
elsif @date_type == :datetime
|
55
|
-
|
55
|
+
Arel.quoted((v.value >= 0 ? '+' : '-') + v.inspect)
|
56
56
|
end
|
57
57
|
else
|
58
|
-
|
58
|
+
v
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
@@ -115,9 +115,18 @@ module ArelExtensions
|
|
115
115
|
v ||= self.expressions.last
|
116
116
|
if defined?(ActiveSupport::Duration) && ActiveSupport::Duration === v
|
117
117
|
if @date_type == :date
|
118
|
-
v.to_i / (24*3600)
|
118
|
+
v.to_i / (24 * 3600)
|
119
119
|
elsif @date_type == :datetime
|
120
|
-
v.
|
120
|
+
if v.parts.size == 1
|
121
|
+
# first entry in the dict v.parts; one of [:years, :months, :weeks, :days, :hours, :minutes, :seconds]
|
122
|
+
# | the value
|
123
|
+
# | |
|
124
|
+
# | |
|
125
|
+
# v v
|
126
|
+
v.parts.first.second
|
127
|
+
else
|
128
|
+
v.to_i
|
129
|
+
end
|
121
130
|
end
|
122
131
|
else
|
123
132
|
v
|
@@ -130,20 +139,30 @@ module ArelExtensions
|
|
130
139
|
if @date_type == :date
|
131
140
|
Arel.sql('day')
|
132
141
|
elsif @date_type == :datetime
|
133
|
-
|
142
|
+
res = if v.parts.size == 1
|
143
|
+
# first entry in the dict v.parts; one of [:years, :months, :weeks, :days, :hours, :minutes, :seconds]
|
144
|
+
# | the key
|
145
|
+
# | | convert symbol to string
|
146
|
+
# | | | remove the plural suffix `s`
|
147
|
+
# v v v v
|
148
|
+
v.parts.first.first.to_s[0..-2]
|
149
|
+
else
|
150
|
+
'second'
|
151
|
+
end
|
152
|
+
Arel.sql(res)
|
134
153
|
end
|
135
154
|
else
|
136
155
|
if ArelExtensions::Nodes::Duration === v
|
137
156
|
v.with_interval = true
|
138
157
|
case v.left
|
139
|
-
when 'd','m','y'
|
158
|
+
when 'd', 'm', 'y'
|
140
159
|
Arel.sql('day')
|
141
|
-
when 'h','mn','s'
|
160
|
+
when 'h', 'mn', 's'
|
142
161
|
Arel.sql('second')
|
143
162
|
when /i\z/
|
144
|
-
Arel.sql(
|
163
|
+
Arel.sql(ArelExtensions::Visitors::MSSQL::LOADED_VISITOR::DATE_MAPPING[v.left[0..-2]])
|
145
164
|
else
|
146
|
-
Arel.sql(
|
165
|
+
Arel.sql(ArelExtensions::Visitors::MSSQL::LOADED_VISITOR::DATE_MAPPING[v.left])
|
147
166
|
end
|
148
167
|
end
|
149
168
|
end
|
@@ -160,7 +179,7 @@ module ArelExtensions
|
|
160
179
|
when DateTime, Time, Date
|
161
180
|
raise(ArgumentError, "#{object.class} cannot be converted to Integer")
|
162
181
|
when String
|
163
|
-
Arel
|
182
|
+
Arel.quoted(object)
|
164
183
|
else
|
165
184
|
raise(ArgumentError, "#{object.class} cannot be converted to Integer")
|
166
185
|
end
|
File without changes
|
File without changes
|
File without changes
|
@@ -5,11 +5,12 @@ module ArelExtensions
|
|
5
5
|
class Format < Function
|
6
6
|
RETURN_TYPE = :string
|
7
7
|
|
8
|
-
attr_accessor :col_type, :iso_format
|
8
|
+
attr_accessor :col_type, :iso_format, :time_zone
|
9
9
|
|
10
10
|
def initialize expr
|
11
|
-
col = expr
|
11
|
+
col = expr[0]
|
12
12
|
@iso_format = convert_format(expr[1])
|
13
|
+
@time_zone = expr[2]
|
13
14
|
@col_type = type_of_attribute(col)
|
14
15
|
super [col, convert_to_string_node(@iso_format)]
|
15
16
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'strscan'
|
2
|
+
|
3
|
+
module ArelExtensions
|
4
|
+
module Nodes
|
5
|
+
class FormattedDate < Function
|
6
|
+
RETURN_TYPE = :string
|
7
|
+
|
8
|
+
attr_accessor :col_type, :iso_format, :time_zone
|
9
|
+
|
10
|
+
def initialize expr
|
11
|
+
col = expr[0]
|
12
|
+
@iso_format = convert_format(expr[1])
|
13
|
+
@time_zone = expr[2]
|
14
|
+
@col_type = type_of_attribute(col)
|
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
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -3,10 +3,10 @@ module ArelExtensions
|
|
3
3
|
class FormattedNumber < Function
|
4
4
|
RETURN_TYPE = :string
|
5
5
|
|
6
|
-
attr_accessor :locale, :prefix, :suffix, :flags, :scientific_notation, :width
|
6
|
+
attr_accessor :locale, :prefix, :suffix, :flags, :scientific_notation, :width, :precision, :type, :original_string
|
7
7
|
|
8
8
|
def initialize expr
|
9
|
-
# expr[1] = {:
|
9
|
+
# expr[1] = {locale: 'fr_FR', type: "e"/"f"/"d", prefix: "$ ", suffix: " %", flags: " +-#0", width: 5, precision: 6}
|
10
10
|
col = expr.first
|
11
11
|
@locale = expr[1][:locale]
|
12
12
|
@prefix = expr[1][:prefix]
|