arel_extensions 0.8.3 → 0.8.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/.travis/oracle/download.js +116 -0
  3. data/.travis/oracle/download.sh +16 -0
  4. data/.travis/oracle/install.sh +32 -0
  5. data/.travis.yml +72 -69
  6. data/Rakefile +29 -4
  7. data/arel_extensions.gemspec +1 -1
  8. data/functions.html +21 -12
  9. data/gemfiles/rails4.gemfile +11 -3
  10. data/gemfiles/rails5.gemfile +8 -4
  11. data/lib/arel_extensions/math.rb +2 -2
  12. data/lib/arel_extensions/math_functions.rb +1 -1
  13. data/lib/arel_extensions/nodes/concat.rb +16 -0
  14. data/lib/arel_extensions/nodes/date_diff.rb +37 -25
  15. data/lib/arel_extensions/nodes/function.rb +30 -0
  16. data/lib/arel_extensions/nodes/is_null.rb +6 -0
  17. data/lib/arel_extensions/nodes/replace.rb +8 -26
  18. data/lib/arel_extensions/nodes/round.rb +6 -6
  19. data/lib/arel_extensions/nodes.rb +1 -1
  20. data/lib/arel_extensions/null_functions.rb +2 -2
  21. data/lib/arel_extensions/string_functions.rb +5 -1
  22. data/lib/arel_extensions/version.rb +1 -1
  23. data/lib/arel_extensions/visitors/mysql.rb +89 -113
  24. data/lib/arel_extensions/visitors/oracle.rb +28 -65
  25. data/lib/arel_extensions/visitors/postgresql.rb +82 -121
  26. data/lib/arel_extensions/visitors/sqlite.rb +60 -55
  27. data/lib/arel_extensions/visitors/to_sql.rb +30 -5
  28. data/test/database.yml +15 -3
  29. data/test/real_db_test.rb +0 -1
  30. data/test/visitors/test_bulk_insert_sqlite.rb +2 -1
  31. data/test/visitors/test_oracle.rb +2 -2
  32. data/test/visitors/test_to_sql.rb +3 -4
  33. data/test/with_ar/all_agnostic_test.rb +294 -0
  34. data/test/with_ar/insert_agnostic_test.rb +52 -0
  35. data/test/with_ar/test_bulk_sqlite.rb +3 -2
  36. metadata +10 -5
  37. data/lib/arel_extensions/nodes/isnull.rb +0 -30
  38. data/test/with_ar/test_string_postgresql.rb +0 -81
@@ -41,6 +41,36 @@ module ArelExtensions
41
41
  end
42
42
  end
43
43
 
44
+ def convert_to_date_node(object)
45
+ case object
46
+ when Arel::Attributes::Attribute, Arel::Nodes::Node
47
+ object
48
+ when DateTime, Time
49
+ Arel::Nodes.build_quoted(Date.new(object.year, object.month, object.day), self)
50
+ when String
51
+ Arel::Nodes.build_quoted(Date.parse(object), self)
52
+ when Date
53
+ Arel::Nodes.build_quoted(object, self)
54
+ else
55
+ raise(ArgumentError, "#{object.class} can not be converted to Date")
56
+ end
57
+ end
58
+
59
+ def convert_to_number(object)
60
+ case object
61
+ when Arel::Attributes::Attribute, Arel::Nodes::Node
62
+ object
63
+ when Fixnum, Integer
64
+ object.to_i.abs
65
+ when DateTime, Date, Time, String, ActiveSupport::Duration
66
+ object.to_i.abs
67
+ when NilClass
68
+ 0
69
+ else
70
+ raise(ArgumentError, "#{object.class} can not be converted to NUMBER arg")
71
+ end
72
+ end
73
+
44
74
  end
45
75
  end
46
76
  end
@@ -0,0 +1,6 @@
1
+ module ArelExtensions
2
+ module Nodes
3
+ class IsNull < Function
4
+ end
5
+ end
6
+ end
@@ -1,34 +1,16 @@
1
1
  module ArelExtensions
2
2
  module Nodes
3
- class Replace < Arel::Nodes::Function
3
+ class Replace < Function
4
4
 
5
-
6
- def initialize expr, left, right, aliaz = nil
7
- tab = Array.new
8
- tab << expr
9
- tab << left
10
- tab << right
11
- super(tab, aliaz)
12
- end
13
-
14
-
15
- def expr
16
- @expressions.first
5
+ def initialize expr
6
+ tab = expr.map { |arg|
7
+ convert_to_node(arg)
8
+ }
9
+ return super(tab)
17
10
  end
18
11
 
19
-
20
- def left
21
- @expressions[1]
22
- end
23
-
24
-
25
- def right
26
- @expressions[2]
27
- end
28
-
29
-
30
- def as other
31
- Arel::Nodes::As.new self, Arel::Nodes::SqlLiteral.new(other)
12
+ def +(other)
13
+ return ArelExtensions::Nodes::Concat.new(self.expressions + [other])
32
14
  end
33
15
 
34
16
  end
@@ -2,14 +2,14 @@ module ArelExtensions
2
2
  module Nodes
3
3
  class Round < Function
4
4
 
5
- def left
6
- @expressions.first
5
+ def initialize expr
6
+ if expr && expr.length == 1
7
+ super [convert_to_node(expr.first)]
8
+ else
9
+ super [convert_to_node(expr.first), convert_to_number(expr[1])]
10
+ end
7
11
  end
8
12
 
9
-
10
- def right
11
- @expressions[1]
12
- end
13
13
  end
14
14
  end
15
15
  end
@@ -24,5 +24,5 @@ require 'arel_extensions/nodes/date_diff'
24
24
  require 'arel_extensions/nodes/duration'
25
25
 
26
26
  require 'arel_extensions/nodes/coalesce'
27
- require 'arel_extensions/nodes/isnull'
27
+ require 'arel_extensions/nodes/is_null'
28
28
  require 'arel_extensions/nodes/wday'
@@ -2,8 +2,8 @@ module ArelExtensions
2
2
  module NullFunctions
3
3
 
4
4
  #ISNULL function lets you return an alternative value when an expression is NULL.
5
- def isnull(other)
6
- ArelExtensions::Nodes::Isnull.new self, other
5
+ def is_null
6
+ ArelExtensions::Nodes::IsNull.new [self]
7
7
  end
8
8
  # returns the first non-null expr in the expression list. You must specify at least two expressions.
9
9
  #If all occurrences of expr evaluate to null, then the function returns null.
@@ -48,7 +48,11 @@ module ArelExtensions
48
48
 
49
49
  #REPLACE function replaces a sequence of characters in a string with another set of characters, not case-sensitive.
50
50
  def replace left, right
51
- ArelExtensions::Nodes::Replace.new self, left, right
51
+ ArelExtensions::Nodes::Replace.new [self, left, right]
52
+ end
53
+
54
+ def group_concat sep = nil
55
+ ArelExtensions::Nodes::GroupConcat.new [self, sep]
52
56
  end
53
57
 
54
58
  #Function returns a string after removing left, right or the both prefixes or suffixes int argument
@@ -1,4 +1,4 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
  module ArelExtensions
3
- VERSION = "0.8.3".freeze
3
+ VERSION = "0.8.4".freeze
4
4
  end
@@ -2,39 +2,31 @@ module ArelExtensions
2
2
  module Visitors
3
3
  Arel::Visitors::MySQL.class_eval do
4
4
 
5
-
6
- def visit_ArelExtensions_Nodes_DateDiff o, collector
7
- collector << "DATEDIFF("
5
+ #String functions
6
+ def visit_ArelExtensions_Nodes_IMatches o, collector # insensitive on ASCII
8
7
  collector = visit o.left, collector
9
- collector << ","
8
+ collector << ' LIKE '
10
9
  collector = visit o.right, collector
11
- collector << ")"
12
- collector
10
+ if o.escape
11
+ collector << ' ESCAPE '
12
+ visit o.escape, collector
13
+ else
14
+ collector
15
+ end
13
16
  end
14
17
 
15
-
16
- def visit_ArelExtensions_Nodes_Duration o, collector
17
- #visit left for period
18
- if(o.left == "d")
19
- collector << "DAY("
20
- elsif(o.left == "m")
21
- collector << "MONTH("
22
- elsif (o.left == "w")
23
- collector << "WEEK("
24
- elsif (o.left == "y")
25
- collector << "YEAR("
26
- end
27
- #visit right
28
- if(o.right.is_a?(Arel::Attributes::Attribute))
29
- collector = visit o.right, collector
18
+ def visit_ArelExtensions_Nodes_IDoesNotMatch o, collector
19
+ collector = visit o.left.lower, collector
20
+ collector << ' NOT LIKE '
21
+ collector = visit o.right.lower(o.right), collector
22
+ if o.escape
23
+ collector << ' ESCAPE '
24
+ visit o.escape, collector
30
25
  else
31
- collector << "#{o.right}"
26
+ collector
32
27
  end
33
- collector << ")"
34
- collector
35
28
  end
36
29
 
37
- #****************************************************************#
38
30
  def visit_ArelExtensions_Nodes_Concat o, collector
39
31
  collector << "CONCAT("
40
32
  o.expressions.each_with_index { |arg, i|
@@ -45,123 +37,107 @@ module ArelExtensions
45
37
  collector
46
38
  end
47
39
 
48
-
49
- def visit_ArelExtensions_Nodes_Coalesce o, collector
50
- collector << "COALESCE("
51
- if(o.left.is_a?(Arel::Attributes::Attribute))
52
- collector = visit o.left, collector
53
- else
54
- collector << "#{o.left}"
40
+ def visit_ArelExtensions_Nodes_GroupConcat o, collector
41
+ collector << "GROUP_CONCAT("
42
+ collector = visit o.left, collector
43
+ if o.right
44
+ collector << ' SEPARATOR '
45
+ collector = visit o.right, collector
55
46
  end
56
- o.other.each { |a|
57
- collector << ","
58
- if(a.is_a?(Arel::Attributes::Attribute))
59
- collector = visit a, collector
60
- else
61
- collector << "#{a}"
62
- end
63
- }
64
- collector << ")"
65
- collector
66
- end
67
-
68
- def visit_ArelExtensions_Nodes_Isnull o, collector
69
- collector << "IFNULL("
70
- collector = visit o.left, collector
71
- collector << ","
72
- if(o.right.is_a?(Arel::Attributes::Attribute))
73
- collector = visit o.right, collector
74
- else
75
- collector << "'#{o.right}'"
76
- end
77
- collector << ")"
78
- collector
79
- end
80
-
81
-
82
- def visit_ArelExtensions_Nodes_Replace o, collector
83
- collector << "REPLACE("
84
- collector = visit o.expr,collector
85
- collector << ","
86
- if(o.left.is_a?(Arel::Attributes::Attribute))
87
- collector = visit o.left, collector
88
- else
89
- collector << "'#{o.left}'"
90
- end
91
- collector << ","
92
- if(o.right.is_a?(Arel::Attributes::Attribute))
93
- collector = visit o.right, collector
94
- else
95
- collector << "'#{o.right}'"
96
- end
97
- collector << ")"
98
- collector
99
- end
100
-
101
-
102
- def visit_ArelExtensions_Nodes_Soundex o, collector
103
- collector << "SOUNDEX("
104
- if((o.expr).is_a?(Arel::Attributes::Attribute))
105
- collector = visit o.expr, collector
106
- else
107
- collector << "'#{o.expr}'"
108
- end
109
47
  collector << ")"
110
48
  collector
111
49
  end
112
50
 
113
-
114
-
115
- def visit_ArelExtensions_Nodes_Trim o , collector
116
- collector << 'TRIM(BOTH '
117
- if(o.right.is_a?(Arel::Attributes::Attribute))
118
- collector = visit o.right, collector
119
- else
120
- collector << "'#{o.right}'"
121
- end
51
+ def visit_ArelExtensions_Nodes_Trim o, collector
52
+ collector << 'TRIM(' # BOTH
53
+ collector = visit o.right, collector
122
54
  collector << " FROM "
123
55
  collector = visit o.left, collector
124
-
125
56
  collector << ")"
126
57
  collector
127
58
  end
128
59
 
129
60
  def visit_ArelExtensions_Nodes_Ltrim o , collector
130
61
  collector << 'TRIM(LEADING '
131
- if(o.right.is_a?(Arel::Attributes::Attribute))
132
- collector = visit o.right, collector
133
- else
134
- collector << "'#{o.right}'"
135
- end
62
+ collector = visit o.right, collector
136
63
  collector << " FROM "
137
64
  collector = visit o.left, collector
138
-
139
65
  collector << ")"
140
66
  collector
141
67
  end
142
68
 
143
-
144
69
  def visit_ArelExtensions_Nodes_Rtrim o , collector
145
- collector << 'TRIM(TRAILING '
146
- if(o.right.is_a?(Arel::Attributes::Attribute))
147
- collector = visit o.right, collector
148
- else
149
- collector << "'#{o.right}'"
150
- end
70
+ collector << 'TRIM(TRAILING '
71
+ collector = visit o.right, collector
151
72
  collector << " FROM "
152
73
  collector = visit o.left, collector
74
+ collector << ")"
75
+ collector
76
+ end
77
+ def visit_ArelExtensions_Nodes_DateDiff o, collector
78
+ collector << "DATEDIFF("
79
+ collector = visit o.left, collector
80
+ collector << Arel::Visitors::MySQL::COMMA
81
+ collector = visit o.right, collector
82
+ collector << ")"
83
+ collector
84
+ end
153
85
 
86
+ def visit_ArelExtensions_Nodes_DateAdd o, collector
87
+ collector << "DATE_ADD("
88
+ collector = visit o.left, collector
89
+ collector << Arel::Visitors::MySQL::COMMA
90
+ collector = visit o.mysql_value(o.right), collector
154
91
  collector << ")"
155
92
  collector
156
93
  end
157
94
 
95
+
96
+ def visit_ArelExtensions_Nodes_Duration o, collector
97
+ #visit left for period
98
+ if o.left == "d"
99
+ collector << "DAY("
100
+ elsif(o.left == "m")
101
+ collector << "MONTH("
102
+ elsif (o.left == "w")
103
+ collector << "WEEK("
104
+ elsif (o.left == "y")
105
+ collector << "YEAR("
106
+ end
107
+ #visit right
108
+ collector = visit o.right, collector
109
+ collector << ")"
110
+ collector
111
+ end
112
+
113
+ #****************************************************************#
114
+
115
+ def visit_ArelExtensions_Nodes_IsNull o, collector
116
+ collector << "ISNULL("
117
+ collector = visit o.left, collector
118
+ if o.right
119
+ collector << Arel::Visitors::MySQL::COMMA
120
+ collector = visit o.right, collector
121
+ end
122
+ collector << ")"
123
+ collector
124
+ end
125
+
126
+
127
+ def visit_ArelExtensions_Nodes_Replace o, collector
128
+ collector << "REPLACE("
129
+ o.expressions.each_with_index { |arg, i|
130
+ collector << Arel::Visitors::MySQL::COMMA unless i == 0
131
+ collector = visit arg, collector
132
+ }
133
+ collector << ")"
134
+ collector
135
+ end
136
+
137
+
158
138
  def visit_ArelExtensions_Nodes_Wday o, collector
159
139
  collector << "(WEEKDAY("
160
- if((o.date).is_a?(Arel::Attributes::Attribute))
161
- collector = visit o.date, collector
162
- else
163
- collector << "'#{o.date}'"
164
- end
140
+ collector = visit o.date, collector
165
141
  collector << ") + 1) % 7"
166
142
  collector
167
143
  end
@@ -26,47 +26,27 @@ module ArelExtensions
26
26
  end
27
27
  end
28
28
 
29
- #deprecated
30
- def visit_ArelExtensions_Nodes_ConcatDep o, collector
31
- arg = o.left.relation.engine.columns.find{|c| c.name == o.left.name.to_s}.type
32
- if(o.right.is_a?(Arel::Attributes::Attribute))
33
- collector << "CONCAT("
34
- collector = visit o.left, collector
35
- collector << ","
36
- collector = visit o.right, collector
37
- collector << ")"
38
- elsif ( arg === :date || arg === :datetime)
39
- collector << "DATEADD("
40
- collector = visit o.left, collector
41
- collector << ", + interval '#{o.right}' DAY)"
42
- else
43
- collector << "CONCAT("
44
- collector = visit o.left, collector
45
- collector << ","
46
- collector << "#{o.right})"
47
- end
48
- collector
49
- end
50
-
29
+ def visit_ArelExtensions_Nodes_GroupConcat o, collector
30
+ collector << "LISTAGG("
31
+ collector = visit o.left, collector
32
+ if o.right
33
+ collector << Arel::Visitors::Oracle::COMMA
34
+ collector = visit o.right, collector
35
+ end
36
+ collector << ")"
37
+ collector
38
+ end
51
39
 
52
- def visit_ArelExtensions_Nodes_Coalesce o, collector
53
- collector << "COALESCE("
54
- if(o.left.is_a?(Arel::Attributes::Attribute))
55
- collector = visit o.left, collector
56
- else
57
- collector << "#{o.left}"
58
- end
59
- o.other.each { |a|
60
- collector << ","
61
- if(a.is_a?(Arel::Attributes::Attribute))
62
- collector = visit a, collector
63
- else
64
- collector << "#{a}"
40
+ def visit_ArelExtensions_Nodes_Coalesce o, collector
41
+ collector << "COALESCE("
42
+ collector = visit o.left, collector
43
+ o.other.each { |a|
44
+ collector << Arel::Visitors::Oracle::COMMA
45
+ collector = visit a, collector
46
+ }
47
+ collector << ")"
48
+ collector
65
49
  end
66
- }
67
- collector << ")"
68
- collector
69
- end
70
50
 
71
51
  def visit_ArelExtensions_Nodes_DateDiff o, collector
72
52
  collector << '('
@@ -90,11 +70,7 @@ module ArelExtensions
90
70
  collector << "YEAR("
91
71
  end
92
72
  #visit right
93
- if(o.right.is_a?(Arel::Attributes::Attribute))
94
- collector = visit o.right, collector
95
- else
96
- collector << "'#{o.right}'"
97
- end
73
+ collector = visit o.right, collector
98
74
  collector << ")"
99
75
  collector
100
76
  end
@@ -108,25 +84,20 @@ module ArelExtensions
108
84
  end
109
85
 
110
86
 
111
- def visit_ArelExtensions_Nodes_Isnull o, collector
87
+ def visit_ArelExtensions_Nodes_IsNull o, collector
112
88
  collector << "NVL("
113
89
  collector = visit o.left, collector
114
- collector << ","
115
- if(o.right.is_a?(Arel::Attributes::Attribute))
116
- collector = visit o.right, collector
117
- else
118
- collector << "'#{o.right}'"
119
- end
90
+ collector << Arel::Visitors::Oracle::COMMA
91
+ collector = visit Arel::Nodes.build_quoted(true), collector
120
92
  collector << ")"
121
93
  collector
122
94
  end
123
95
 
124
-
125
96
  def visit_ArelExtensions_Nodes_Rand o, collector
126
97
  collector << "dbms_random.value("
127
98
  if(o.left != nil && o.right != nil)
128
99
  collector << "'#{o.left}'"
129
- collector << ","
100
+ collector << Arel::Visitors::Oracle::COMMA
130
101
  collector << "'#{o.right}'"
131
102
  end
132
103
  collector << ")"
@@ -136,18 +107,10 @@ module ArelExtensions
136
107
  def visit_ArelExtensions_Nodes_Replace o, collector
137
108
  collector << "REPLACE("
138
109
  collector = visit o.expr,collector
139
- collector << ","
140
- if(o.left.is_a?(Arel::Attributes::Attribute))
141
- collector = visit o.left, collector
142
- else
143
- collector << "'#{o.left}'"
144
- end
145
- collector << ","
146
- if(o.right.is_a?(Arel::Attributes::Attribute))
147
- collector = visit o.right, collector
148
- else
149
- collector << "'#{o.right}'"
150
- end
110
+ collector << Arel::Visitors::Oracle::COMMA
111
+ collector = visit o.left, collector
112
+ collector << Arel::Visitors::Oracle::COMMA
113
+ collector = visit o.right, collector
151
114
  collector << ")"
152
115
  collector
153
116
  end