arel_extensions 0.8.3 → 0.8.4

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.
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