arel_extensions 1.6.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 -7
- data/.rubocop.yml +3 -67
- 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 +91 -258
- data/Rakefile +30 -48
- data/TODO +1 -0
- data/appveyor.yml +22 -60
- data/arel_extensions.gemspec +14 -13
- 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 +14 -14
- data/gemfiles/rails5_2.gemfile +14 -16
- 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 -7
- data/lib/arel_extensions/boolean_functions.rb +14 -53
- data/lib/arel_extensions/common_sql_functions.rb +17 -16
- data/lib/arel_extensions/comparators.rb +28 -29
- data/lib/arel_extensions/date_duration.rb +13 -17
- data/lib/arel_extensions/insert_manager.rb +15 -18
- data/lib/arel_extensions/math.rb +53 -55
- data/lib/arel_extensions/math_functions.rb +39 -46
- data/lib/arel_extensions/nodes/abs.rb +1 -0
- data/lib/arel_extensions/nodes/blank.rb +2 -1
- data/lib/arel_extensions/nodes/case.rb +19 -20
- data/lib/arel_extensions/nodes/cast.rb +8 -10
- data/lib/arel_extensions/nodes/ceil.rb +1 -1
- data/lib/arel_extensions/nodes/coalesce.rb +4 -3
- data/lib/arel_extensions/nodes/collate.rb +10 -9
- data/lib/arel_extensions/nodes/concat.rb +18 -9
- data/lib/arel_extensions/nodes/date_diff.rb +26 -42
- 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 -35
- data/lib/arel_extensions/nodes/formatted_number.rb +23 -22
- data/lib/arel_extensions/nodes/function.rb +37 -46
- data/lib/arel_extensions/nodes/is_null.rb +0 -0
- data/lib/arel_extensions/nodes/json.rb +39 -52
- data/lib/arel_extensions/nodes/length.rb +0 -5
- data/lib/arel_extensions/nodes/levenshtein_distance.rb +1 -1
- data/lib/arel_extensions/nodes/locate.rb +2 -1
- 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 +1 -0
- data/lib/arel_extensions/nodes/repeat.rb +5 -3
- data/lib/arel_extensions/nodes/replace.rb +8 -16
- 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 +1 -1
- data/lib/arel_extensions/nodes/trim.rb +6 -4
- data/lib/arel_extensions/nodes/union.rb +8 -5
- data/lib/arel_extensions/nodes/union_all.rb +7 -4
- data/lib/arel_extensions/nodes/wday.rb +4 -0
- data/lib/arel_extensions/nodes.rb +1 -1
- data/lib/arel_extensions/null_functions.rb +5 -19
- data/lib/arel_extensions/predications.rb +44 -45
- data/lib/arel_extensions/railtie.rb +5 -5
- data/lib/arel_extensions/set_functions.rb +7 -5
- data/lib/arel_extensions/string_functions.rb +35 -91
- data/lib/arel_extensions/tasks.rb +6 -6
- data/lib/arel_extensions/version.rb +1 -1
- data/lib/arel_extensions/visitors/ibm_db.rb +31 -24
- data/lib/arel_extensions/visitors/mssql.rb +194 -440
- data/lib/arel_extensions/visitors/mysql.rb +212 -368
- data/lib/arel_extensions/visitors/oracle.rb +179 -236
- data/lib/arel_extensions/visitors/oracle12.rb +31 -18
- data/lib/arel_extensions/visitors/postgresql.rb +173 -271
- data/lib/arel_extensions/visitors/sqlite.rb +127 -157
- data/lib/arel_extensions/visitors/to_sql.rb +238 -300
- data/lib/arel_extensions/visitors.rb +62 -83
- data/lib/arel_extensions.rb +31 -235
- data/test/database.yml +10 -20
- data/test/helper.rb +18 -0
- data/test/real_db_test.rb +118 -121
- 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 +370 -773
- 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 +38 -52
- 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 -18
- data/NEWS.md +0 -116
- 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 -29
- data/gemfiles/rails6.gemfile +0 -34
- data/gemfiles/rails6_1.gemfile +0 -42
- data/gemfiles/rails7.gemfile +0 -42
- data/gemfiles/rails7_1.gemfile +0 -41
- data/gemfiles/rails7_2.gemfile +0 -41
- data/gemfiles/rails8.gemfile +0 -40
- data/gemfiles/rails8_1.gemfile +0 -41
- data/gemspecs/arel_extensions-v1.gemspec +0 -27
- data/gemspecs/arel_extensions-v2.gemspec +0 -27
- 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 -3
- data/version_v2.rb +0 -3
|
@@ -7,15 +7,15 @@ require 'arel_extensions/nodes/formatted_number'
|
|
|
7
7
|
require 'arel_extensions/nodes/log10'
|
|
8
8
|
require 'arel_extensions/nodes/power'
|
|
9
9
|
require 'arel_extensions/nodes/std'
|
|
10
|
-
require 'arel_extensions/nodes/sum'
|
|
11
10
|
|
|
12
11
|
module ArelExtensions
|
|
13
12
|
module MathFunctions
|
|
13
|
+
|
|
14
14
|
# Arel does not handle Decimal literal properly
|
|
15
15
|
def * other
|
|
16
16
|
case other
|
|
17
17
|
when Float, BigDecimal
|
|
18
|
-
super(Arel.
|
|
18
|
+
super(Arel::Nodes.build_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::Nodes.build_quoted(other))
|
|
29
29
|
else
|
|
30
30
|
super(other)
|
|
31
31
|
end
|
|
@@ -33,86 +33,79 @@ 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
|
|
65
|
-
def std
|
|
66
|
-
ArelExtensions::Nodes::Std.new self,
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
def variance opts = {unbiased: true}
|
|
70
|
-
ArelExtensions::Nodes::Variance.new self, **opts
|
|
65
|
+
def std unbiased = true
|
|
66
|
+
ArelExtensions::Nodes::Std.new [self,unbiased]
|
|
71
67
|
end
|
|
72
68
|
|
|
73
|
-
def
|
|
74
|
-
|
|
75
|
-
Arel::Nodes::Sum.new [self]
|
|
76
|
-
else
|
|
77
|
-
ArelExtensions::Nodes::Sum.new self, **opts
|
|
78
|
-
end
|
|
69
|
+
def variance unbiased = true
|
|
70
|
+
ArelExtensions::Nodes::Variance.new [self,unbiased]
|
|
79
71
|
end
|
|
80
72
|
|
|
81
|
-
#
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
alias_method
|
|
73
|
+
#function that can be invoked to produce random numbers between 0 and 1
|
|
74
|
+
# def rand seed = nil
|
|
75
|
+
# ArelExtensions::Nodes::Rand.new [seed]
|
|
76
|
+
# end
|
|
77
|
+
alias_method :random, :rand
|
|
86
78
|
|
|
87
|
-
#
|
|
79
|
+
#function is used to round a numeric field to the number of decimals specified
|
|
88
80
|
def round precision = nil
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
81
|
+
if precision
|
|
82
|
+
ArelExtensions::Nodes::Round.new [self, precision]
|
|
83
|
+
else
|
|
84
|
+
ArelExtensions::Nodes::Round.new [self]
|
|
85
|
+
end
|
|
94
86
|
end
|
|
95
87
|
|
|
96
88
|
# function returning a number at a specific format
|
|
97
|
-
def format_number format_string, locale
|
|
89
|
+
def format_number format_string, locale=nil
|
|
98
90
|
begin
|
|
99
|
-
sprintf(format_string,
|
|
91
|
+
sprintf(format_string,0) # this line is to get the right error message if the format_string is not correct
|
|
100
92
|
m = /^(.*)%([ #+\-0]*)([1-9][0-9]+|[1-9]?)[.]?([0-9]*)([a-zA-Z])(.*)$/.match(format_string)
|
|
101
93
|
opts = {
|
|
102
|
-
prefix
|
|
103
|
-
flags
|
|
104
|
-
width
|
|
105
|
-
precision
|
|
106
|
-
type
|
|
107
|
-
suffix
|
|
108
|
-
locale
|
|
109
|
-
original_string
|
|
94
|
+
:prefix => m[1],
|
|
95
|
+
:flags => m[2].split(//).uniq.join,
|
|
96
|
+
:width => m[3].to_i,
|
|
97
|
+
:precision => m[4] != '' ? m[4].to_i : 6,
|
|
98
|
+
:type => m[5],
|
|
99
|
+
:suffix => m[6],
|
|
100
|
+
:locale => locale,
|
|
101
|
+
:original_string => format_string
|
|
110
102
|
}
|
|
111
|
-
# opts = {locale
|
|
112
|
-
ArelExtensions::Nodes::FormattedNumber.new [self,
|
|
103
|
+
# opts = {:locale => 'fr_FR', :type => "e"/"f"/"d", :prefix => "$ ", :suffix => " %", :flags => " +-#0", :width => 5, :precision => 6}
|
|
104
|
+
ArelExtensions::Nodes::FormattedNumber.new [self,opts]
|
|
113
105
|
rescue Exception
|
|
114
|
-
Arel.
|
|
106
|
+
Arel::Nodes.build_quoted('Wrong Format')
|
|
115
107
|
end
|
|
116
108
|
end
|
|
109
|
+
|
|
117
110
|
end
|
|
118
111
|
end
|
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
module ArelExtensions
|
|
2
2
|
module Nodes
|
|
3
|
-
if
|
|
3
|
+
if Arel::VERSION < "7.1.0"
|
|
4
4
|
class Case < Arel::Nodes::Node
|
|
5
|
-
include Arel::Expressions
|
|
6
|
-
include Arel::Math
|
|
7
|
-
include Arel::Predications
|
|
8
|
-
include Arel::OrderPredications
|
|
9
5
|
attr_accessor :case, :conditions, :default
|
|
10
6
|
|
|
11
7
|
def initialize expression = nil, default = nil
|
|
@@ -19,6 +15,7 @@ module ArelExtensions
|
|
|
19
15
|
|
|
20
16
|
class Else < Arel::Nodes::Unary # :nodoc:
|
|
21
17
|
end
|
|
18
|
+
|
|
22
19
|
end
|
|
23
20
|
else
|
|
24
21
|
class Case < Arel::Nodes::Case
|
|
@@ -29,25 +26,23 @@ module ArelExtensions
|
|
|
29
26
|
end
|
|
30
27
|
end
|
|
31
28
|
|
|
32
|
-
|
|
29
|
+
ArelExtensions::Nodes::Case.class_eval do
|
|
33
30
|
include Arel::Expressions
|
|
34
|
-
include Arel::Math
|
|
35
|
-
include Arel::Predications
|
|
36
31
|
include Arel::OrderPredications
|
|
37
|
-
include ArelExtensions::Aliases
|
|
38
|
-
include ArelExtensions::Comparators
|
|
39
|
-
include ArelExtensions::DateDuration
|
|
40
32
|
include ArelExtensions::Math
|
|
41
|
-
include ArelExtensions::
|
|
42
|
-
include ArelExtensions::NullFunctions
|
|
33
|
+
include ArelExtensions::Comparators
|
|
43
34
|
include ArelExtensions::Predications
|
|
35
|
+
include ArelExtensions::MathFunctions
|
|
44
36
|
include ArelExtensions::StringFunctions
|
|
37
|
+
include ArelExtensions::NullFunctions
|
|
45
38
|
|
|
46
39
|
def return_type
|
|
47
40
|
obj = if @conditions.length > 0
|
|
48
|
-
|
|
41
|
+
@conditions.last.right
|
|
49
42
|
elsif @default
|
|
50
43
|
@default.expr
|
|
44
|
+
else
|
|
45
|
+
nil
|
|
51
46
|
end
|
|
52
47
|
if obj.respond_to?(:return_type)
|
|
53
48
|
obj.return_type
|
|
@@ -55,10 +50,14 @@ module ArelExtensions
|
|
|
55
50
|
case obj
|
|
56
51
|
when Integer, Float
|
|
57
52
|
:number
|
|
58
|
-
when Date, DateTime,
|
|
53
|
+
when Date, DateTime,Time
|
|
59
54
|
:datetime
|
|
60
55
|
when Arel::Attributes::Attribute
|
|
61
|
-
|
|
56
|
+
begin
|
|
57
|
+
Arel::Table.engine.connection.schema_cache.columns_hash(obj.relation.table_name)[obj.name.to_s].type
|
|
58
|
+
rescue Exception
|
|
59
|
+
:string
|
|
60
|
+
end
|
|
62
61
|
else
|
|
63
62
|
:string
|
|
64
63
|
end
|
|
@@ -93,14 +92,14 @@ module ArelExtensions
|
|
|
93
92
|
|
|
94
93
|
def eql? other
|
|
95
94
|
self.class == other.class &&
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
95
|
+
self.case == other.case &&
|
|
96
|
+
self.conditions == other.conditions &&
|
|
97
|
+
self.default == other.default
|
|
99
98
|
end
|
|
100
99
|
alias :== :eql?
|
|
101
100
|
|
|
102
101
|
def as other
|
|
103
|
-
Arel::Nodes::As.new self, Arel.
|
|
102
|
+
Arel::Nodes::As.new self, Arel::Nodes::SqlLiteral.new(other)
|
|
104
103
|
end
|
|
105
104
|
end
|
|
106
105
|
end
|
|
@@ -14,16 +14,13 @@ module ArelExtensions
|
|
|
14
14
|
@return_type = :decimal
|
|
15
15
|
when :number
|
|
16
16
|
@return_type = :number
|
|
17
|
-
when 'char', 'varchar', 'nchar', 'nvarchar'
|
|
17
|
+
when 'char', 'varchar', 'text', 'nchar', 'nvarchar', 'ntext'
|
|
18
18
|
@return_type = :string
|
|
19
|
-
when
|
|
20
|
-
@as_attr = expr[1].to_sym
|
|
21
|
-
@return_type = :string
|
|
22
|
-
when :datetime, 'datetime', 'smalldatetime'
|
|
19
|
+
when :datetime, 'datetime','smalldatetime'
|
|
23
20
|
@return_type = :datetime
|
|
24
|
-
when :time,
|
|
21
|
+
when :time,'time'
|
|
25
22
|
@return_type = :time
|
|
26
|
-
when :date,
|
|
23
|
+
when :date,'date'
|
|
27
24
|
@return_type = :date
|
|
28
25
|
when :binary, 'binary', 'varbinary', 'image'
|
|
29
26
|
@return_type = :binary
|
|
@@ -32,23 +29,24 @@ module ArelExtensions
|
|
|
32
29
|
@as_attr = :string
|
|
33
30
|
end
|
|
34
31
|
tab = [convert_to_node(expr.first)]
|
|
35
|
-
super(tab)
|
|
32
|
+
return super(tab)
|
|
36
33
|
end
|
|
37
34
|
|
|
38
35
|
def +(other)
|
|
39
36
|
case @return_type
|
|
40
37
|
when :string
|
|
41
|
-
ArelExtensions::Nodes::Concat.new [self, other]
|
|
38
|
+
return ArelExtensions::Nodes::Concat.new [self, other]
|
|
42
39
|
when :ruby_time
|
|
43
40
|
ArelExtensions::Nodes::DateAdd.new [self, other]
|
|
44
41
|
else
|
|
45
|
-
Arel.
|
|
42
|
+
Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new self, other)
|
|
46
43
|
end
|
|
47
44
|
end
|
|
48
45
|
|
|
49
46
|
def return_type
|
|
50
47
|
@return_type
|
|
51
48
|
end
|
|
49
|
+
|
|
52
50
|
end
|
|
53
51
|
end
|
|
54
52
|
end
|
|
@@ -2,7 +2,7 @@ module ArelExtensions
|
|
|
2
2
|
module Nodes
|
|
3
3
|
class Coalesce < Function
|
|
4
4
|
RETURN_TYPE = :string
|
|
5
|
-
|
|
5
|
+
|
|
6
6
|
attr_accessor :left_node_type
|
|
7
7
|
|
|
8
8
|
def return_type
|
|
@@ -20,15 +20,16 @@ module ArelExtensions
|
|
|
20
20
|
@left_node_type = :number
|
|
21
21
|
when ArelExtensions::Nodes::Coalesce, ArelExtensions::Nodes::Function
|
|
22
22
|
@left_node_type = expr.first.respond_to?(:left_node_type) ? expr.first.left_node_type : nil
|
|
23
|
-
when Arel::Nodes::Node, Arel::Attributes::Attribute
|
|
23
|
+
when Arel::Nodes::Node, Arel::Attributes::Attribute
|
|
24
24
|
@left_node_type = type_of_attribute(expr.first)
|
|
25
25
|
when Date
|
|
26
26
|
@left_node_type = :ruby_date
|
|
27
27
|
when DateTime, Time
|
|
28
28
|
@left_node_type = :ruby_time
|
|
29
29
|
end
|
|
30
|
-
super(tab)
|
|
30
|
+
return super(tab)
|
|
31
31
|
end
|
|
32
|
+
|
|
32
33
|
end
|
|
33
34
|
end
|
|
34
35
|
end
|
|
@@ -1,17 +1,18 @@
|
|
|
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
|
+
|
|
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
|
+
return super(tab)
|
|
14
|
+
end
|
|
7
15
|
|
|
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
16
|
end
|
|
16
17
|
end
|
|
17
18
|
end
|
|
@@ -11,12 +11,12 @@ module ArelExtensions::Nodes
|
|
|
11
11
|
else
|
|
12
12
|
node
|
|
13
13
|
end
|
|
14
|
-
}.flatten.reduce([]) { |res, b|
|
|
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::Nodes.build_quoted(res.last.expr + b.expr)
|
|
20
20
|
else
|
|
21
21
|
res << b
|
|
22
22
|
end
|
|
@@ -37,16 +37,25 @@ module ArelExtensions::Nodes
|
|
|
37
37
|
def concat(other)
|
|
38
38
|
Concat.new(self.expressions + [other])
|
|
39
39
|
end
|
|
40
|
+
|
|
40
41
|
end
|
|
41
42
|
|
|
42
|
-
class GroupConcat <
|
|
43
|
+
class GroupConcat < Function
|
|
43
44
|
RETURN_TYPE = :string
|
|
44
45
|
|
|
45
|
-
attr_accessor :
|
|
46
|
-
|
|
47
|
-
def initialize
|
|
48
|
-
|
|
49
|
-
|
|
46
|
+
attr_accessor :orders
|
|
47
|
+
|
|
48
|
+
def initialize expr
|
|
49
|
+
tab = expr.map { |arg|
|
|
50
|
+
if arg.is_a?(Array)
|
|
51
|
+
@orders = arg
|
|
52
|
+
nil
|
|
53
|
+
else
|
|
54
|
+
convert_to_node(arg)
|
|
55
|
+
end
|
|
56
|
+
}.compact
|
|
57
|
+
super(tab)
|
|
50
58
|
end
|
|
59
|
+
|
|
51
60
|
end
|
|
52
61
|
end
|
|
@@ -2,7 +2,7 @@ require 'date'
|
|
|
2
2
|
|
|
3
3
|
module ArelExtensions
|
|
4
4
|
module Nodes
|
|
5
|
-
class DateDiff < Function #
|
|
5
|
+
class DateDiff < Function #difference entre colonne date et date string/date
|
|
6
6
|
attr_accessor :left_node_type
|
|
7
7
|
attr_accessor :right_node_type
|
|
8
8
|
|
|
@@ -12,23 +12,23 @@ module ArelExtensions
|
|
|
12
12
|
res = []
|
|
13
13
|
col = expr.first
|
|
14
14
|
case col
|
|
15
|
-
when Arel::Nodes::Node, Arel::Attributes::Attribute
|
|
15
|
+
when Arel::Nodes::Node, Arel::Attributes::Attribute
|
|
16
16
|
@left_node_type = type_of_attribute(col)
|
|
17
17
|
when Date
|
|
18
18
|
@left_node_type = :ruby_date
|
|
19
19
|
when DateTime, Time
|
|
20
20
|
@left_node_type = :ruby_time
|
|
21
21
|
end
|
|
22
|
-
res << (
|
|
22
|
+
res << ([:date, :ruby_date].include?(@left_node_type) ? convert_to_date_node(col) : convert_to_datetime_node(col))
|
|
23
23
|
case expr[1]
|
|
24
|
-
when Arel::Nodes::Node, Arel::Attributes::Attribute
|
|
24
|
+
when Arel::Nodes::Node, Arel::Attributes::Attribute
|
|
25
25
|
@right_node_type = type_of_attribute(expr[1])
|
|
26
26
|
when Date
|
|
27
27
|
@right_node_type = :ruby_date
|
|
28
28
|
when DateTime, Time
|
|
29
29
|
@right_node_type = :ruby_time
|
|
30
30
|
end
|
|
31
|
-
res << (
|
|
31
|
+
res << ([: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
|
-
super(tab)
|
|
46
|
+
return 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
|
-
Arel.
|
|
53
|
+
return Arel::Nodes.build_quoted((v.value >= 0 ? '+' : '-') + v.inspect)
|
|
54
54
|
elsif @date_type == :datetime
|
|
55
|
-
Arel.
|
|
55
|
+
return Arel::Nodes.build_quoted((v.value >= 0 ? '+' : '-') + v.inspect)
|
|
56
56
|
end
|
|
57
57
|
else
|
|
58
|
-
v
|
|
58
|
+
return v
|
|
59
59
|
end
|
|
60
60
|
end
|
|
61
61
|
|
|
@@ -97,7 +97,7 @@ module ArelExtensions
|
|
|
97
97
|
v ||= self.expressions.last
|
|
98
98
|
if defined?(ActiveSupport::Duration) && ActiveSupport::Duration === v
|
|
99
99
|
if @date_type == :ruby_date
|
|
100
|
-
Arel.sql("(INTERVAL '1' DAY) * %s" % v.inspect.to_i)
|
|
100
|
+
Arel.sql("(INTERVAL '1' DAY) * %s" % v.inspect.to_i )
|
|
101
101
|
else
|
|
102
102
|
Arel.sql("(INTERVAL '1' SECOND) * %s" % v.to_i)
|
|
103
103
|
end
|
|
@@ -115,18 +115,9 @@ 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
|
|
118
|
+
v.to_i / (24*3600)
|
|
119
119
|
elsif @date_type == :datetime
|
|
120
|
-
|
|
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
|
|
120
|
+
v.to_i
|
|
130
121
|
end
|
|
131
122
|
else
|
|
132
123
|
v
|
|
@@ -139,37 +130,28 @@ module ArelExtensions
|
|
|
139
130
|
if @date_type == :date
|
|
140
131
|
Arel.sql('day')
|
|
141
132
|
elsif @date_type == :datetime
|
|
142
|
-
|
|
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)
|
|
133
|
+
Arel.sql('second')
|
|
153
134
|
end
|
|
154
135
|
else
|
|
155
136
|
if ArelExtensions::Nodes::Duration === v
|
|
156
137
|
v.with_interval = true
|
|
157
138
|
case v.left
|
|
158
|
-
when
|
|
139
|
+
when 'd','m','y'
|
|
159
140
|
Arel.sql('day')
|
|
160
|
-
when 'h',
|
|
141
|
+
when 'h','mn','s'
|
|
161
142
|
Arel.sql('second')
|
|
162
143
|
when /i\z/
|
|
163
|
-
Arel.sql(
|
|
144
|
+
Arel.sql(Arel::Visitors::MSSQL::DATE_MAPPING[v.left[0..-2]])
|
|
164
145
|
else
|
|
165
|
-
Arel.sql(
|
|
146
|
+
Arel.sql(Arel::Visitors::MSSQL::DATE_MAPPING[v.left])
|
|
166
147
|
end
|
|
148
|
+
else
|
|
149
|
+
nil
|
|
167
150
|
end
|
|
168
151
|
end
|
|
169
152
|
end
|
|
170
153
|
|
|
171
154
|
private
|
|
172
|
-
|
|
173
155
|
def convert(object)
|
|
174
156
|
case object
|
|
175
157
|
when Arel::Attributes::Attribute, Arel::Nodes::Node, ActiveSupport::Duration
|
|
@@ -177,16 +159,16 @@ module ArelExtensions
|
|
|
177
159
|
when Integer
|
|
178
160
|
object.days
|
|
179
161
|
when DateTime, Time, Date
|
|
180
|
-
raise(ArgumentError, "#{object.class}
|
|
162
|
+
raise(ArgumentError, "#{object.class} can not be converted to Integer")
|
|
181
163
|
when String
|
|
182
|
-
Arel.
|
|
164
|
+
Arel::Nodes.build_quoted(object)
|
|
183
165
|
else
|
|
184
|
-
raise(ArgumentError, "#{object.class}
|
|
166
|
+
raise(ArgumentError, "#{object.class} can not be converted to Integer")
|
|
185
167
|
end
|
|
186
168
|
end
|
|
187
169
|
end
|
|
188
170
|
|
|
189
|
-
class DateSub < Function #
|
|
171
|
+
class DateSub < Function #difference entre colonne date et date string/date
|
|
190
172
|
RETURN_TYPE = :integer
|
|
191
173
|
|
|
192
174
|
def initialize(expr)
|
|
@@ -203,10 +185,12 @@ module ArelExtensions
|
|
|
203
185
|
if defined?(ActiveSupport::Duration) && ActiveSupport::Duration === object
|
|
204
186
|
object.to_i
|
|
205
187
|
else
|
|
206
|
-
raise(ArgumentError, "#{object.class}
|
|
188
|
+
raise(ArgumentError, "#{object.class} can not be converted to Number")
|
|
207
189
|
end
|
|
208
190
|
end
|
|
209
191
|
end
|
|
192
|
+
|
|
210
193
|
end
|
|
194
|
+
|
|
211
195
|
end
|
|
212
196
|
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
|