arel_extensions 0.8.0
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 +7 -0
- data/.gitignore +9 -0
- data/.travis.yml +46 -0
- data/Gemfile +10 -0
- data/MIT-LICENSE.txt +20 -0
- data/README.md +101 -0
- data/Rakefile +14 -0
- data/arel_extensions.gemspec +32 -0
- data/functions.html +344 -0
- data/gemfiles/Gemfile.rails3 +10 -0
- data/gemfiles/Gemfile.rails5 +10 -0
- data/init/mssql.sql +6 -0
- data/init/mysql.sql +0 -0
- data/init/oracle.sql +31 -0
- data/init/postgresql.sql +12 -0
- data/init/sqlite.sql +1 -0
- data/lib/arel_extensions.rb +84 -0
- data/lib/arel_extensions/attributes.rb +26 -0
- data/lib/arel_extensions/comparators.rb +59 -0
- data/lib/arel_extensions/date_duration.rb +28 -0
- data/lib/arel_extensions/insert_manager.rb +33 -0
- data/lib/arel_extensions/math.rb +48 -0
- data/lib/arel_extensions/math_functions.rb +35 -0
- data/lib/arel_extensions/nodes.rb +27 -0
- data/lib/arel_extensions/nodes/abs.rb +6 -0
- data/lib/arel_extensions/nodes/ceil.rb +6 -0
- data/lib/arel_extensions/nodes/coalesce.rb +22 -0
- data/lib/arel_extensions/nodes/concat.rb +33 -0
- data/lib/arel_extensions/nodes/date_diff.rb +106 -0
- data/lib/arel_extensions/nodes/duration.rb +30 -0
- data/lib/arel_extensions/nodes/find_in_set.rb +16 -0
- data/lib/arel_extensions/nodes/floor.rb +6 -0
- data/lib/arel_extensions/nodes/function.rb +17 -0
- data/lib/arel_extensions/nodes/isnull.rb +30 -0
- data/lib/arel_extensions/nodes/length.rb +6 -0
- data/lib/arel_extensions/nodes/locate.rb +33 -0
- data/lib/arel_extensions/nodes/ltrim.rb +28 -0
- data/lib/arel_extensions/nodes/matches.rb +22 -0
- data/lib/arel_extensions/nodes/rand.rb +23 -0
- data/lib/arel_extensions/nodes/replace.rb +36 -0
- data/lib/arel_extensions/nodes/round.rb +15 -0
- data/lib/arel_extensions/nodes/rtrim.rb +29 -0
- data/lib/arel_extensions/nodes/soundex.rb +23 -0
- data/lib/arel_extensions/nodes/sum.rb +23 -0
- data/lib/arel_extensions/nodes/trim.rb +26 -0
- data/lib/arel_extensions/nodes/wday.rb +23 -0
- data/lib/arel_extensions/null_functions.rb +16 -0
- data/lib/arel_extensions/string_functions.rb +68 -0
- data/lib/arel_extensions/version.rb +4 -0
- data/lib/arel_extensions/visitors.rb +6 -0
- data/lib/arel_extensions/visitors/ibm_db.rb +206 -0
- data/lib/arel_extensions/visitors/mssql.rb +213 -0
- data/lib/arel_extensions/visitors/mysql.rb +184 -0
- data/lib/arel_extensions/visitors/oracle.rb +267 -0
- data/lib/arel_extensions/visitors/postgresql.rb +258 -0
- data/lib/arel_extensions/visitors/sqlite.rb +218 -0
- data/lib/arel_extensions/visitors/to_sql.rb +199 -0
- data/test/helper.rb +18 -0
- data/test/real_db_test.rb +251 -0
- data/test/support/fake_record.rb +137 -0
- data/test/test_comparators.rb +49 -0
- data/test/visitors/test_bulk_insert_oracle.rb +30 -0
- data/test/visitors/test_bulk_insert_sqlite.rb +31 -0
- data/test/visitors/test_bulk_insert_to_sql.rb +32 -0
- data/test/visitors/test_oracle.rb +105 -0
- data/test/visitors/test_to_sql.rb +148 -0
- data/test/with_ar/test_bulk_sqlite.rb +44 -0
- data/test/with_ar/test_math_sqlite.rb +59 -0
- data/test/with_ar/test_string_sqlite.rb +69 -0
- metadata +230 -0
data/init/mssql.sql
ADDED
data/init/mysql.sql
ADDED
File without changes
|
data/init/oracle.sql
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
CREATE OR REPLACE FUNCTION find_in_set(
|
2
|
+
i_value IN VARCHAR2,
|
3
|
+
i_list IN VARCHAR2,
|
4
|
+
i_delim IN VARCHAR2 DEFAULT ','
|
5
|
+
) RETURN INT DETERMINISTIC
|
6
|
+
AS
|
7
|
+
p_result INT := 0;
|
8
|
+
p_start NUMBER(5) := 1;
|
9
|
+
p_end NUMBER(5);
|
10
|
+
c_len CONSTANT NUMBER(5) := LENGTH( i_list );
|
11
|
+
c_ld CONSTANT NUMBER(5) := LENGTH( i_delim );
|
12
|
+
BEGIN
|
13
|
+
IF c_len > 0 THEN
|
14
|
+
p_end := INSTR( i_list, i_delim, p_start );
|
15
|
+
WHILE p_end > 0 LOOP
|
16
|
+
p_result := p_result + 1;
|
17
|
+
IF ( SUBSTR( i_list, p_start, p_end - p_start ) = i_value )
|
18
|
+
THEN
|
19
|
+
RETURN p_result;
|
20
|
+
END IF;
|
21
|
+
p_start := p_end + c_ld;
|
22
|
+
p_end := INSTR( i_list, i_delim, p_start );
|
23
|
+
END LOOP;
|
24
|
+
IF p_start <= c_len + 1
|
25
|
+
AND SUBSTR( i_list, p_start, c_len - p_start + 1 ) = i_value
|
26
|
+
THEN
|
27
|
+
RETURN p_result + 1;
|
28
|
+
END IF;
|
29
|
+
END IF;
|
30
|
+
RETURN 0;
|
31
|
+
END;
|
data/init/postgresql.sql
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
CREATE OR REPLACE FUNCTION public.find_in_set(n INTEGER, s TEXT)
|
2
|
+
RETURNS BOOLEAN
|
3
|
+
LANGUAGE sql
|
4
|
+
AS $function$
|
5
|
+
select bool(int4(z.row_number))
|
6
|
+
from
|
7
|
+
(
|
8
|
+
select row_number() over(), y.x
|
9
|
+
from (select unnest(('{' || $2 || '}')::int[]) as x) as y
|
10
|
+
) as z
|
11
|
+
where z.x = $1
|
12
|
+
$function$
|
data/init/sqlite.sql
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'arel'
|
2
|
+
|
3
|
+
# UnaryOperation|Grouping|Extract < Unary < Arel::Nodes::Node
|
4
|
+
# Equality|Regexp|Matches < Binary < Arel::Nodes::Node
|
5
|
+
# Count|NamedFunction < Function < Arel::Nodes::Node
|
6
|
+
|
7
|
+
# pure Arel internals improvements
|
8
|
+
Arel::Nodes::Binary.class_eval do
|
9
|
+
include Arel::AliasPredication
|
10
|
+
end
|
11
|
+
|
12
|
+
Arel::Nodes::Unary.class_eval do
|
13
|
+
include Arel::Math
|
14
|
+
include Arel::AliasPredication
|
15
|
+
include Arel::Expressions
|
16
|
+
end
|
17
|
+
|
18
|
+
Arel::Nodes::Grouping.class_eval do
|
19
|
+
include Arel::Math
|
20
|
+
include Arel::AliasPredication
|
21
|
+
include Arel::Expressions
|
22
|
+
end
|
23
|
+
|
24
|
+
Arel::Nodes::Function.class_eval do
|
25
|
+
include Arel::Math
|
26
|
+
include Arel::Expressions
|
27
|
+
end
|
28
|
+
|
29
|
+
require 'arel_extensions/version'
|
30
|
+
require 'arel_extensions/attributes'
|
31
|
+
require 'arel_extensions/visitors'
|
32
|
+
require 'arel_extensions/nodes'
|
33
|
+
require 'arel_extensions/comparators'
|
34
|
+
require 'arel_extensions/date_duration'
|
35
|
+
require 'arel_extensions/null_functions'
|
36
|
+
require 'arel_extensions/math'
|
37
|
+
require 'arel_extensions/math_functions'
|
38
|
+
require 'arel_extensions/string_functions'
|
39
|
+
|
40
|
+
require 'arel_extensions/insert_manager'
|
41
|
+
|
42
|
+
module Arel
|
43
|
+
def self.rand
|
44
|
+
ArelExtensions::Nodes::Rand.new
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
Arel::Attributes::Attribute.class_eval do
|
49
|
+
include Arel::Math
|
50
|
+
include ArelExtensions::Attributes
|
51
|
+
end
|
52
|
+
|
53
|
+
Arel::Nodes::Function.class_eval do
|
54
|
+
include ArelExtensions::Comparators
|
55
|
+
include ArelExtensions::DateDuration
|
56
|
+
include ArelExtensions::MathFunctions
|
57
|
+
include ArelExtensions::StringFunctions
|
58
|
+
end
|
59
|
+
|
60
|
+
Arel::Nodes::Unary.class_eval do
|
61
|
+
include ArelExtensions::Math
|
62
|
+
include ArelExtensions::Attributes
|
63
|
+
include ArelExtensions::MathFunctions
|
64
|
+
include ArelExtensions::Comparators
|
65
|
+
end
|
66
|
+
|
67
|
+
Arel::Nodes::Binary.class_eval do
|
68
|
+
include ArelExtensions::Math
|
69
|
+
include ArelExtensions::Attributes
|
70
|
+
include ArelExtensions::MathFunctions
|
71
|
+
include ArelExtensions::Comparators
|
72
|
+
end
|
73
|
+
|
74
|
+
Arel::Nodes::Equality.class_eval do
|
75
|
+
include ArelExtensions::Comparators
|
76
|
+
include ArelExtensions::DateDuration
|
77
|
+
include ArelExtensions::MathFunctions
|
78
|
+
include ArelExtensions::StringFunctions
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
Arel::InsertManager.class_eval do
|
83
|
+
include ArelExtensions::InsertManager
|
84
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'arel_extensions/comparators'
|
2
|
+
require 'arel_extensions/date_duration'
|
3
|
+
require 'arel_extensions/math'
|
4
|
+
require 'arel_extensions/math_functions'
|
5
|
+
require 'arel_extensions/null_functions'
|
6
|
+
require 'arel_extensions/string_functions'
|
7
|
+
|
8
|
+
module ArelExtensions
|
9
|
+
module Attributes
|
10
|
+
include ArelExtensions::Comparators
|
11
|
+
include ArelExtensions::DateDuration
|
12
|
+
include ArelExtensions::Math
|
13
|
+
include ArelExtensions::MathFunctions
|
14
|
+
include ArelExtensions::NullFunctions
|
15
|
+
include ArelExtensions::StringFunctions
|
16
|
+
|
17
|
+
def ==(other)
|
18
|
+
Arel::Nodes::Equality.new self, Arel::Nodes.build_quoted(other, self)
|
19
|
+
end
|
20
|
+
|
21
|
+
def !=(other)
|
22
|
+
Arel::Nodes::NotEqual.new self, Arel::Nodes.build_quoted(other, self)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module ArelExtensions
|
2
|
+
module Comparators
|
3
|
+
|
4
|
+
def >(other)
|
5
|
+
Arel::Nodes::GreaterThan.new self, Arel::Nodes.build_quoted(other, self)
|
6
|
+
end
|
7
|
+
|
8
|
+
def >=(other)
|
9
|
+
Arel::Nodes::GreaterThanOrEqual.new self, Arel::Nodes.build_quoted(other, self)
|
10
|
+
end
|
11
|
+
|
12
|
+
def <(other)
|
13
|
+
Arel::Nodes::LessThan.new self, Arel::Nodes.build_quoted(other, self)
|
14
|
+
end
|
15
|
+
|
16
|
+
def <=(other)
|
17
|
+
Arel::Nodes::LessThanOrEqual.new self, Arel::Nodes.build_quoted(other, self)
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
#REGEXP function
|
22
|
+
#Pattern matching using regular expressions
|
23
|
+
def =~(other)
|
24
|
+
# arg = self.relation.engine.connection.schema_cache.columns_hash(self.relation.table_name)[self.name.to_s].type
|
25
|
+
# if arg == :string || arg == :text
|
26
|
+
Arel::Nodes::Regexp.new self, convert_regexp(other)
|
27
|
+
# end
|
28
|
+
end
|
29
|
+
|
30
|
+
#NOT_REGEXP function
|
31
|
+
#Negation of Regexp
|
32
|
+
def !~(other)
|
33
|
+
# arg = self.relation.engine.connection.schema_cache.columns_hash(self.relation.table_name)[self.name.to_s].type
|
34
|
+
# if arg == :string || arg == :text
|
35
|
+
Arel::Nodes::NotRegexp.new self, convert_regexp(other)
|
36
|
+
# end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
#Function use for not_regexp
|
41
|
+
def convert_regexp(other)
|
42
|
+
case other
|
43
|
+
when String
|
44
|
+
#Do nothing
|
45
|
+
when Regexp
|
46
|
+
other = other.source.gsub('\A','^')
|
47
|
+
other.gsub!('\Z','$')
|
48
|
+
other.gsub!('\d','[0-9]')
|
49
|
+
other.gsub!('\D','[^0-9]')
|
50
|
+
other.gsub!('\w','[0-9A-Za-z]')
|
51
|
+
other.gsub!('\W','[^A-Za-z0-9_]')
|
52
|
+
else
|
53
|
+
raise(ArgumentError)
|
54
|
+
end
|
55
|
+
Arel::Nodes.build_quoted(other, self)
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module ArelExtensions
|
2
|
+
module DateDuration
|
3
|
+
#function returns the year (as a number) given a date value.
|
4
|
+
def year
|
5
|
+
ArelExtensions::Nodes::Duration.new "y",self
|
6
|
+
end
|
7
|
+
|
8
|
+
#function returns the month (as a number) given a date value.
|
9
|
+
def month
|
10
|
+
ArelExtensions::Nodes::Duration.new "m",self
|
11
|
+
end
|
12
|
+
|
13
|
+
#function returns the week (as a number) given a date value.
|
14
|
+
def week
|
15
|
+
ArelExtensions::Nodes::Duration.new "w",self
|
16
|
+
end
|
17
|
+
|
18
|
+
#function returns the month (as a number) given a date value.
|
19
|
+
def day
|
20
|
+
ArelExtensions::Nodes::Duration.new "d",self
|
21
|
+
end
|
22
|
+
|
23
|
+
def wday
|
24
|
+
ArelExtensions::Nodes::Wday.new self
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'arel'
|
2
|
+
|
3
|
+
module ArelExtensions
|
4
|
+
module InsertManager
|
5
|
+
|
6
|
+
def bulk_insert(cols, data)
|
7
|
+
case cols.first
|
8
|
+
when String, Symbol
|
9
|
+
cols.each { |c|
|
10
|
+
@ast.columns << @ast.relation[c]
|
11
|
+
}
|
12
|
+
when Array
|
13
|
+
if String === cols.first.first
|
14
|
+
@ast.columns = cols.map {|c| [@ast.relation[c.first]] }
|
15
|
+
elsif Arel::Attributes::Attribute == cols.first.first
|
16
|
+
@ast.columns = cols
|
17
|
+
end
|
18
|
+
when NilClass
|
19
|
+
@ast.columns = @ast.relation.columns
|
20
|
+
end
|
21
|
+
self.values = BulkValues.new(@ast.columns, data)
|
22
|
+
end
|
23
|
+
|
24
|
+
class BulkValues < Arel::Nodes::Node
|
25
|
+
attr_accessor :left, :cols
|
26
|
+
def initialize(cols, values)
|
27
|
+
@left = values
|
28
|
+
@cols = cols
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module ArelExtensions
|
2
|
+
module Math
|
3
|
+
#function + between
|
4
|
+
#String and others (convert in string) allows you to concatenate 2 or more strings together.
|
5
|
+
#Date and integer adds or subtracts a specified time interval from a date.
|
6
|
+
def +(other)
|
7
|
+
return ArelExtensions::Nodes::Concat.new(self.expressions + [other]) if self.is_a?(ArelExtensions::Nodes::Concat)
|
8
|
+
arg = self.relation.engine.connection.schema_cache.columns_hash(self.relation.table_name)[self.name.to_s].type
|
9
|
+
if arg == :integer || arg == :decimal || arg == :float
|
10
|
+
if other.is_a?(String)
|
11
|
+
other = other.to_i
|
12
|
+
end
|
13
|
+
Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new self, other)
|
14
|
+
elsif arg == :datetime || arg == :date
|
15
|
+
ArelExtensions::Nodes::DateAdd.new [self, other]
|
16
|
+
elsif arg == :string
|
17
|
+
ArelExtensions::Nodes::Concat.new [self, other]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
#function returns the time between two dates
|
22
|
+
#function returns the susbration between two int
|
23
|
+
def -(other)
|
24
|
+
arg = self.relation.engine.connection.schema_cache.columns_hash(self.relation.table_name)[self.name.to_s].type
|
25
|
+
if (arg == :date || arg == :datetime)
|
26
|
+
case other
|
27
|
+
when Arel::Attributes::Attribute
|
28
|
+
arg2 = other.relation.engine.connection.schema_cache.columns_hash(other.relation.table_name)[other.name.to_s].type
|
29
|
+
if arg2 == :date || arg2 == :datetime
|
30
|
+
ArelExtensions::Nodes::DateDiff.new self, other
|
31
|
+
else
|
32
|
+
ArelExtensions::Nodes::DateSub.new self, other
|
33
|
+
end
|
34
|
+
when Arel::Nodes::Node, DateTime, Time, String, Date
|
35
|
+
ArelExtensions::Nodes::DateDiff.new self, other
|
36
|
+
when Fixnum
|
37
|
+
ArelExtensions::Nodes::DateSub.new self, other
|
38
|
+
end
|
39
|
+
else
|
40
|
+
if other.is_a?(String)
|
41
|
+
other = other.to_i
|
42
|
+
end
|
43
|
+
Arel::Nodes::Grouping.new(Arel::Nodes::Subtraction.new(self, other))
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module ArelExtensions
|
2
|
+
module MathFunctions
|
3
|
+
|
4
|
+
# Abs function returns the absolute value of a number passed as argument #
|
5
|
+
def abs
|
6
|
+
ArelExtensions::Nodes::Abs.new [self]
|
7
|
+
end
|
8
|
+
|
9
|
+
# will rounded up any positive or negative decimal value within the function upwards #
|
10
|
+
def ceil
|
11
|
+
ArelExtensions::Nodes::Ceil.new [self]
|
12
|
+
end
|
13
|
+
|
14
|
+
# function rounded up any positive or negative decimal value down to the next least integer
|
15
|
+
def floor
|
16
|
+
ArelExtensions::Nodes::Floor.new [self]
|
17
|
+
end
|
18
|
+
|
19
|
+
#function that can be invoked to produce random numbers between 0 and 1
|
20
|
+
# def rand seed = nil
|
21
|
+
# ArelExtensions::Nodes::Rand.new [seed]
|
22
|
+
# end
|
23
|
+
alias_method :random, :rand
|
24
|
+
|
25
|
+
#function is used to round a numeric field to the number of decimals specified
|
26
|
+
def round precision = nil
|
27
|
+
if precision
|
28
|
+
ArelExtensions::Nodes::Round.new [self, Arel::Nodes.build_quoted(precision)]
|
29
|
+
else
|
30
|
+
ArelExtensions::Nodes::Round.new [self]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'arel_extensions/nodes/function'
|
2
|
+
# Math functions
|
3
|
+
require 'arel_extensions/nodes/abs'
|
4
|
+
require 'arel_extensions/nodes/ceil'
|
5
|
+
require 'arel_extensions/nodes/floor'
|
6
|
+
require 'arel_extensions/nodes/round'
|
7
|
+
require 'arel_extensions/nodes/rand'
|
8
|
+
require 'arel_extensions/nodes/sum'
|
9
|
+
|
10
|
+
# String functions
|
11
|
+
require 'arel_extensions/nodes/concat' if Arel::VERSION.to_i < 7
|
12
|
+
require 'arel_extensions/nodes/length'
|
13
|
+
require 'arel_extensions/nodes/locate'
|
14
|
+
require 'arel_extensions/nodes/matches'
|
15
|
+
require 'arel_extensions/nodes/find_in_set'
|
16
|
+
require 'arel_extensions/nodes/replace'
|
17
|
+
require 'arel_extensions/nodes/soundex'
|
18
|
+
require 'arel_extensions/nodes/trim'
|
19
|
+
require 'arel_extensions/nodes/ltrim'
|
20
|
+
require 'arel_extensions/nodes/rtrim'
|
21
|
+
|
22
|
+
|
23
|
+
require 'arel_extensions/nodes/coalesce'
|
24
|
+
require 'arel_extensions/nodes/date_diff'
|
25
|
+
require 'arel_extensions/nodes/duration'
|
26
|
+
require 'arel_extensions/nodes/isnull'
|
27
|
+
require 'arel_extensions/nodes/wday'
|