arel_extensions 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.travis.yml +46 -0
  4. data/Gemfile +10 -0
  5. data/MIT-LICENSE.txt +20 -0
  6. data/README.md +101 -0
  7. data/Rakefile +14 -0
  8. data/arel_extensions.gemspec +32 -0
  9. data/functions.html +344 -0
  10. data/gemfiles/Gemfile.rails3 +10 -0
  11. data/gemfiles/Gemfile.rails5 +10 -0
  12. data/init/mssql.sql +6 -0
  13. data/init/mysql.sql +0 -0
  14. data/init/oracle.sql +31 -0
  15. data/init/postgresql.sql +12 -0
  16. data/init/sqlite.sql +1 -0
  17. data/lib/arel_extensions.rb +84 -0
  18. data/lib/arel_extensions/attributes.rb +26 -0
  19. data/lib/arel_extensions/comparators.rb +59 -0
  20. data/lib/arel_extensions/date_duration.rb +28 -0
  21. data/lib/arel_extensions/insert_manager.rb +33 -0
  22. data/lib/arel_extensions/math.rb +48 -0
  23. data/lib/arel_extensions/math_functions.rb +35 -0
  24. data/lib/arel_extensions/nodes.rb +27 -0
  25. data/lib/arel_extensions/nodes/abs.rb +6 -0
  26. data/lib/arel_extensions/nodes/ceil.rb +6 -0
  27. data/lib/arel_extensions/nodes/coalesce.rb +22 -0
  28. data/lib/arel_extensions/nodes/concat.rb +33 -0
  29. data/lib/arel_extensions/nodes/date_diff.rb +106 -0
  30. data/lib/arel_extensions/nodes/duration.rb +30 -0
  31. data/lib/arel_extensions/nodes/find_in_set.rb +16 -0
  32. data/lib/arel_extensions/nodes/floor.rb +6 -0
  33. data/lib/arel_extensions/nodes/function.rb +17 -0
  34. data/lib/arel_extensions/nodes/isnull.rb +30 -0
  35. data/lib/arel_extensions/nodes/length.rb +6 -0
  36. data/lib/arel_extensions/nodes/locate.rb +33 -0
  37. data/lib/arel_extensions/nodes/ltrim.rb +28 -0
  38. data/lib/arel_extensions/nodes/matches.rb +22 -0
  39. data/lib/arel_extensions/nodes/rand.rb +23 -0
  40. data/lib/arel_extensions/nodes/replace.rb +36 -0
  41. data/lib/arel_extensions/nodes/round.rb +15 -0
  42. data/lib/arel_extensions/nodes/rtrim.rb +29 -0
  43. data/lib/arel_extensions/nodes/soundex.rb +23 -0
  44. data/lib/arel_extensions/nodes/sum.rb +23 -0
  45. data/lib/arel_extensions/nodes/trim.rb +26 -0
  46. data/lib/arel_extensions/nodes/wday.rb +23 -0
  47. data/lib/arel_extensions/null_functions.rb +16 -0
  48. data/lib/arel_extensions/string_functions.rb +68 -0
  49. data/lib/arel_extensions/version.rb +4 -0
  50. data/lib/arel_extensions/visitors.rb +6 -0
  51. data/lib/arel_extensions/visitors/ibm_db.rb +206 -0
  52. data/lib/arel_extensions/visitors/mssql.rb +213 -0
  53. data/lib/arel_extensions/visitors/mysql.rb +184 -0
  54. data/lib/arel_extensions/visitors/oracle.rb +267 -0
  55. data/lib/arel_extensions/visitors/postgresql.rb +258 -0
  56. data/lib/arel_extensions/visitors/sqlite.rb +218 -0
  57. data/lib/arel_extensions/visitors/to_sql.rb +199 -0
  58. data/test/helper.rb +18 -0
  59. data/test/real_db_test.rb +251 -0
  60. data/test/support/fake_record.rb +137 -0
  61. data/test/test_comparators.rb +49 -0
  62. data/test/visitors/test_bulk_insert_oracle.rb +30 -0
  63. data/test/visitors/test_bulk_insert_sqlite.rb +31 -0
  64. data/test/visitors/test_bulk_insert_to_sql.rb +32 -0
  65. data/test/visitors/test_oracle.rb +105 -0
  66. data/test/visitors/test_to_sql.rb +148 -0
  67. data/test/with_ar/test_bulk_sqlite.rb +44 -0
  68. data/test/with_ar/test_math_sqlite.rb +59 -0
  69. data/test/with_ar/test_string_sqlite.rb +69 -0
  70. metadata +230 -0
@@ -0,0 +1,29 @@
1
+ module ArelExtensions
2
+ module Nodes
3
+ class Rtrim < Arel::Nodes::Function
4
+
5
+ def initialize left,right,aliaz = nil
6
+ tab = Array.new
7
+ tab << left
8
+ tab << right
9
+
10
+ super(tab, aliaz)
11
+ end
12
+
13
+ def left
14
+ @expressions.first
15
+ end
16
+
17
+ def right
18
+ @expressions[1]
19
+ end
20
+
21
+
22
+ def as other
23
+ Arel::Nodes::As.new self, Arel::Nodes::SqlLiteral.new(other)
24
+ end
25
+
26
+
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,23 @@
1
+ module ArelExtensions
2
+ module Nodes
3
+ class Soundex < Arel::Nodes::Function
4
+
5
+
6
+ def initialize other, aliaz = nil
7
+ tab = Array.new
8
+ tab << other
9
+ super(tab, aliaz)
10
+ end
11
+
12
+ def expr
13
+ @expressions.first
14
+ end
15
+
16
+
17
+ def as other
18
+ Arel::Nodes::As.new self, Arel::Nodes::SqlLiteral.new(other)
19
+ end
20
+
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ module ArelExtensions
2
+ module Nodes
3
+ class Sum < Arel::Nodes::Function
4
+
5
+
6
+ def initialize other, aliaz = nil
7
+ tab = Array.new
8
+ tab << other
9
+ super(tab, aliaz)
10
+ end
11
+
12
+ def expr
13
+ @expressions.first
14
+ end
15
+
16
+
17
+ def as other
18
+ Arel::Nodes::As.new self, Arel::Nodes::SqlLiteral.new(other)
19
+ end
20
+
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,26 @@
1
+ module ArelExtensions
2
+ module Nodes
3
+ class Trim < Arel::Nodes::Function
4
+
5
+ def initialize left,right, aliaz = nil
6
+ tab = Array.new
7
+ tab << left
8
+ tab << right
9
+ super(tab, aliaz)
10
+ end
11
+
12
+ def left
13
+ @expressions.first
14
+ end
15
+
16
+ def right
17
+ @expressions[1]
18
+ end
19
+
20
+
21
+ def as other
22
+ Arel::Nodes::As.new self, Arel::Nodes::SqlLiteral.new(other)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,23 @@
1
+ module ArelExtensions
2
+ module Nodes
3
+ class Wday < Arel::Nodes::Function
4
+
5
+
6
+ def initialize other, aliaz = nil
7
+ tab = Array.new
8
+ tab << other
9
+ super(tab, aliaz)
10
+ end
11
+
12
+
13
+ def date
14
+ @expressions.first
15
+ end
16
+
17
+ def as other
18
+ Arel::Nodes::As.new self, Arel::Nodes::SqlLiteral.new(other)
19
+ end
20
+
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,16 @@
1
+ module ArelExtensions
2
+ module NullFunctions
3
+
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
7
+ end
8
+ # returns the first non-null expr in the expression list. You must specify at least two expressions.
9
+ #If all occurrences of expr evaluate to null, then the function returns null.
10
+ def coalesce (*args)
11
+ args.unshift(self)
12
+ ArelExtensions::Nodes::Coalesce.new args
13
+ end
14
+
15
+ end
16
+ end
@@ -0,0 +1,68 @@
1
+ module ArelExtensions
2
+ module StringFunctions
3
+
4
+ #*FindInSet function .......
5
+ def &(other)
6
+ ArelExtensions::Nodes::FindInSet.new [other, self]
7
+ end
8
+
9
+ #LENGTH function returns the length of the value in a text field.
10
+ def length
11
+ ArelExtensions::Nodes::Length.new [self]
12
+ end
13
+
14
+ #LOCATE function returns the first starting position of a string in another string.
15
+ #If string1 or string2 is NULL then it returns NULL. If string1 not found in string2 then it returns 0.
16
+ def locate val
17
+ ArelExtensions::Nodes::Locate.new [self, val]
18
+ end
19
+
20
+ #SOUNDEX function returns a character string containing the phonetic representation of char.
21
+ def soundex
22
+ ArelExtensions::Nodes::Soundex.new self
23
+ end
24
+
25
+ def imatches others, escape = nil
26
+ ArelExtensions::Nodes::IMatches.new self, others, escape
27
+ end
28
+
29
+ def imatches_any others, escape = nil
30
+ grouping_any :imatches, others, escape
31
+ end
32
+
33
+ def imatches_all others, escape = nil
34
+ grouping_all :imatches, others, escape, escape
35
+ end
36
+
37
+ def idoes_not_match others, escape = nil
38
+ ArelExtensions::Nodes::IDoesNotMatch.new self, others, escape
39
+ end
40
+
41
+ def idoes_not_match_any others, escape = nil
42
+ grouping_any :idoes_not_match, others, escape
43
+ end
44
+
45
+ def idoes_not_match_all others, escape = nil
46
+ grouping_all :idoes_not_match, others, escape
47
+ end
48
+
49
+ #REPLACE function replaces a sequence of characters in a string with another set of characters, not case-sensitive.
50
+ def replace left, right
51
+ ArelExtensions::Nodes::Replace.new self, left, right
52
+ end
53
+
54
+ #Function returns a string after removing left, right or the both prefixes or suffixes int argument
55
+ def trim other
56
+ ArelExtensions::Nodes::Trim.new self,other
57
+ end
58
+
59
+ def ltrim other
60
+ ArelExtensions::Nodes::Ltrim.new self,other
61
+ end
62
+
63
+ def rtrim other
64
+ ArelExtensions::Nodes::Rtrim.new self, other
65
+ end
66
+
67
+ end
68
+ end
@@ -0,0 +1,4 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module ArelExtensions
3
+ VERSION = "0.8.0".freeze
4
+ end
@@ -0,0 +1,6 @@
1
+ require 'arel_extensions/visitors/to_sql'
2
+ require 'arel_extensions/visitors/mysql'
3
+ require 'arel_extensions/visitors/oracle'
4
+ require 'arel_extensions/visitors/postgresql'
5
+ require 'arel_extensions/visitors/sqlite'
6
+ require 'arel_extensions/visitors/mssql'
@@ -0,0 +1,206 @@
1
+ module ArelExtensions
2
+ module Visitors
3
+ Arel::Visitors::IBM_DB.class_eval do
4
+
5
+ def visit_ArelExtensions_Nodes_Ceil o, collector
6
+ collector << "CEILING("
7
+ if((o.expr).is_a?(Arel::Attributes::Attribute))
8
+ collector = visit o.expr, collector
9
+ else
10
+ collector <<"#{o.expr}"
11
+ end
12
+ collector << ")"
13
+ collector
14
+ end
15
+
16
+ def visit_ArelExtensions_Nodes_Concat o, collector
17
+ arg = o.left.relation.engine.columns.find{|c| c.name == o.left.name.to_s}.type
18
+ if(o.right.is_a?(Arel::Attributes::Attribute))
19
+ collector << "CONCAT("
20
+ collector = visit o.left, collector
21
+ collector<< ","
22
+ collector = visit o.right, collector
23
+ collector << ")"
24
+ elsif ( arg == :date || arg == :datetime)
25
+ collector = visit o.left, collector
26
+ collector<< "+"
27
+ collector << "#{o.right} days"
28
+ else
29
+ collector << "CONCAT("
30
+ collector = visit o.left, collector
31
+ collector<< ","
32
+ collector <<"#{o.right})"
33
+ end
34
+ collector
35
+ end
36
+
37
+
38
+ def visit_ArelExtensions_Nodes_Coalesce o, collector
39
+ collector << "COALESCE("
40
+ if(o.left.is_a?(Arel::Attributes::Attribute))
41
+ collector = visit o.left, collector
42
+ else
43
+ collector << "#{o.left}"
44
+ end
45
+ o.other.each { |a|
46
+ collector << ","
47
+ if(a.is_a?(Arel::Attributes::Attribute))
48
+ collector = visit a, collector
49
+ else
50
+ collector << "#{a}"
51
+ end
52
+ }
53
+ collector << ")"
54
+ collector
55
+ end
56
+
57
+
58
+ def visit_ArelExtensions_Nodes_DateDiff o, collector
59
+
60
+ collector << "DAY("
61
+ collector = visit o.left, collector
62
+ collector<< ","
63
+ if(o.right.is_a?(Arel::Attributes::Attribute))
64
+ collector = visit o.right, collector
65
+ else
66
+ collector<< "'#{o.right}'"
67
+ end
68
+ collector << ")"
69
+ collector
70
+ end
71
+
72
+
73
+ def visit_ArelExtensions_Nodes_Duration o , collector
74
+ #visit left for period
75
+ if(o.left == "d")
76
+ collector << "DAY("
77
+ elsif(o.left == "m")
78
+ collector << "MONTH("
79
+ elsif (o.left == "w")
80
+ collector << "WEEK"
81
+ elsif (o.left == "y")
82
+ collector << "YEAR("
83
+ end
84
+ #visit right
85
+ if(o.right.is_a?(Arel::Attributes::Attribute))
86
+ collector = visit o.right, collector
87
+ else
88
+ collector << "'#{o.right}'"
89
+ end
90
+ collector << ")"
91
+ collector
92
+ end
93
+
94
+
95
+ def visit_ArelExtensions_Nodes_Findis o, collector
96
+
97
+ end
98
+
99
+ def visit_ArelExtensions_Nodes_Isnull o, collector
100
+ collector << "COALESCE("
101
+ collector = visit o.left, collector
102
+ collector << ","
103
+ if(o.right.is_a?(Arel::Attributes::Attribute))
104
+ collector = visit o.right, collector
105
+ else
106
+ collector << "'#{o.right}'"
107
+ end
108
+ collector <<")"
109
+ collector
110
+ end
111
+
112
+
113
+ def visit_ArelExtensions_Nodes_Replace o, collector
114
+ collector << "REPLACE("
115
+ collector = visit o.expr,collector
116
+ collector << ","
117
+ if(o.left.is_a?(Arel::Attributes::Attribute))
118
+ collector = visit o.left, collector
119
+ else
120
+ collector << "'#{o.left}'"
121
+ end
122
+ collector << ","
123
+ if(o.right.is_a?(Arel::Attributes::Attribute))
124
+ collector = visit o.right, collector
125
+ else
126
+ collector << "'#{o.right}'"
127
+ end
128
+ collector <<")"
129
+ collector
130
+ end
131
+
132
+
133
+
134
+ def visit_ArelExtensions_Nodes_Soundex o, collector
135
+ collector << "SOUNDEX("
136
+ if((o.expr).is_a?(Arel::Attributes::Attribute))
137
+ collector = visit o.expr, collector
138
+ else
139
+ collector <<"'#{o.expr}'"
140
+ end
141
+ collector << ")"
142
+ collector
143
+ end
144
+
145
+
146
+ def visit_Arel_Nodes_Regexp o , collector
147
+ collector = visit o.left, collector
148
+ collector << " REGEXP "
149
+ collector << "'#{o.right}'"
150
+ collector
151
+ end
152
+
153
+
154
+
155
+ def visit_Arel_Nodes_NotRegexp o , collector
156
+ collector = visit o.left, collector
157
+ collector << " NOT REGEXP "
158
+ collector << "'#{o.right}'"
159
+ collector
160
+ end
161
+
162
+
163
+ def visit_ArelExtensions_Nodes_Trim o , collector
164
+ collector << "TRIM("
165
+ collector = visit o.left, collector
166
+ collector << ","
167
+ if(o.right.is_a?(Arel::Attributes::Attribute))
168
+ collector = visit o.right, collector
169
+ else
170
+ collector << "'#{o.right}'"
171
+ end
172
+ collector << ")"
173
+ collector
174
+ end
175
+
176
+ def visit_ArelExtensions_Nodes_Ltrim o , collector
177
+ collector << "LTRIM("
178
+ collector = visit o.left, collector
179
+ collector << ","
180
+ if(o.right.is_a?(Arel::Attributes::Attribute))
181
+ collector = visit o.right, collector
182
+ else
183
+ collector << "'#{o.right}'"
184
+ end
185
+ collector << ")"
186
+ collector
187
+ end
188
+
189
+
190
+ def visit_ArelExtensions_Nodes_Rtrim o , collector
191
+ collector << "RTRIM("
192
+ collector = visit o.left, collector
193
+ collector << ","
194
+ if(o.right.is_a?(Arel::Attributes::Attribute))
195
+ collector = visit o.right, collector
196
+ else
197
+ collector << "'#{o.right}'"
198
+ end
199
+ collector << ")"
200
+ collector
201
+ end
202
+
203
+
204
+ end
205
+ end
206
+ end
@@ -0,0 +1,213 @@
1
+ module ArelExtensions
2
+ module Visitors
3
+ Arel::Visitors::MSSQL.class_eval do
4
+
5
+ # Math Functions
6
+ def visit_ArelExtensions_Nodes_Ceil o, collector
7
+ collector << "CEILING("
8
+ collector = visit o.expr, collector
9
+ collector << ")"
10
+ collector
11
+ end
12
+
13
+ def visit_ArelExtensions_Nodes_Concat o, collector
14
+ arg = o.left.relation.engine.columns.find{|c| c.name == o.left.name.to_s}.type
15
+ if(o.right.is_a?(Arel::Attributes::Attribute))
16
+ collector = visit o.left, collector
17
+ collector << ' + '
18
+ collector = visit o.right, collector
19
+ collector
20
+ elsif ( arg == :date || arg == :datetime)
21
+ collector << "DATEADD(day,#{o.right},"
22
+ collector = visit o.left, collector
23
+ collector
24
+ else
25
+ collector = visit o.left, collector
26
+ collector << " + '"
27
+ collector << "#{o.right}'"
28
+ collector
29
+ end
30
+ end
31
+
32
+ def visit_ArelExtensions_Nodes_Coalesce o, collector
33
+ collector << "COALESCE("
34
+ if(o.left.is_a?(Arel::Attributes::Attribute))
35
+ collector = visit o.left, collector
36
+ else
37
+ collector << "#{o.left}"
38
+ end
39
+ o.other.each { |a|
40
+ collector << ","
41
+ if(a.is_a?(Arel::Attributes::Attribute))
42
+ collector = visit a, collector
43
+ else
44
+ collector << "#{a}"
45
+ end
46
+ }
47
+ collector << ")"
48
+ collector
49
+ end
50
+
51
+ def visit_ArelExtensions_Nodes_DateDiff o, collector
52
+
53
+ collector << "DATEDIFF(day,"
54
+ collector = visit o.left, collector
55
+ collector<< ","
56
+ if(o.right.is_a?(Arel::Attributes::Attribute))
57
+ collector = visit o.right, collector
58
+ else
59
+ collector<< "'#{o.right}'"
60
+
61
+ end
62
+ collector << ")"
63
+ collector
64
+ end
65
+
66
+
67
+ def visit_ArelExtensions_Nodes_Duration o, collector
68
+ #visit left for period
69
+ if(o.left == "d")
70
+ collector << "DAY("
71
+ elsif(o.left == "m")
72
+ collector << "MONTH("
73
+ elsif (o.left == "w")
74
+ collector << "WEEK"
75
+ elsif (o.left == "y")
76
+ collector << "YEAR("
77
+ end
78
+ #visit right
79
+ if(o.right.is_a?(Arel::Attributes::Attribute))
80
+ collector = visit o.right, collector
81
+ else
82
+ collector << "'#{o.right}'"
83
+ end
84
+ collector << ")"
85
+ collector
86
+ end
87
+
88
+
89
+ def visit_ArelExtensions_Nodes_Findis o,collector
90
+ end
91
+
92
+
93
+ def visit_ArelExtensions_Nodes_Length o, collector
94
+ collector << "LEN("
95
+ collector = visit o.expr, collector
96
+ collector << ")"
97
+ collector
98
+ end
99
+
100
+
101
+ def visit_ArelExtensions_Nodes_Locate o, collector
102
+ collector << "CHARINDEX("
103
+ if(o.val.is_a?(Arel::Attributes::Attribute))
104
+ collector = visit o.val, collector
105
+ else
106
+ collector << "'#{o.val}'"
107
+ end
108
+ collector << ","
109
+ collector = visit o.expr, collector
110
+ collector << ")"
111
+ collector
112
+ end
113
+
114
+ def visit_ArelExtensions_Nodes_Isnull o, collector
115
+ collector << "ISNULL("
116
+ collector = visit o.left, collector
117
+ collector << ","
118
+ if(o.right.is_a?(Arel::Attributes::Attribute))
119
+ collector = visit o.right, collector
120
+ else
121
+ collector << "'#{o.right}'"
122
+ end
123
+ collector << ")"
124
+ collector
125
+ end
126
+
127
+ def visit_ArelExtensions_Nodes_Replace o, collector
128
+ collector << "REPLACE("
129
+ collector = visit o.expr,collector
130
+ collector << ","
131
+ if(o.left.is_a?(Arel::Attributes::Attribute))
132
+ collector = visit o.left, collector
133
+ else
134
+ collector << "'#{o.left}'"
135
+ end
136
+ collector << ","
137
+ if(o.right.is_a?(Arel::Attributes::Attribute))
138
+ collector = visit o.right, collector
139
+ else
140
+ collector << "'#{o.right}'"
141
+ end
142
+ collector << ")"
143
+ collector
144
+ end
145
+
146
+
147
+ # SQL Server does not know about REGEXP
148
+ def visit_Arel_Nodes_Regexp o, collector
149
+ collector = visit o.left, collector
150
+ collector << "LIKE '% #{o.right}%'"
151
+ collector
152
+ end
153
+
154
+ def visit_Arel_Nodes_NotRegexp o, collector
155
+ collector = visit o.left, collector
156
+ collector << "NOT LIKE '% #{o.right}%'"
157
+ collector
158
+ end
159
+
160
+ def visit_ArelExtensions_Nodes_Soundex o, collector
161
+ collector << "SOUNDEX("
162
+ if((o.expr).is_a?(Arel::Attributes::Attribute))
163
+ collector = visit o.expr, collector
164
+ else
165
+ collector << "'#{o.expr}'"
166
+ end
167
+ collector << ")"
168
+ collector
169
+ end
170
+
171
+ def visit_ArelExtensions_Nodes_Trim o , collector
172
+ collector << "TRIM("
173
+ collector = visit o.left, collector
174
+ collector << ","
175
+ if(o.right.is_a?(Arel::Attributes::Attribute))
176
+ collector = visit o.right, collector
177
+ else
178
+ collector << "'#{o.right}'"
179
+ end
180
+ collector << ")"
181
+ collector
182
+ end
183
+
184
+ def visit_ArelExtensions_Nodes_Ltrim o , collector
185
+ collector << "LTRIM("
186
+ collector = visit o.left, collector
187
+ collector << ","
188
+ if(o.right.is_a?(Arel::Attributes::Attribute))
189
+ collector = visit o.right, collector
190
+ else
191
+ collector << "'#{o.right}'"
192
+ end
193
+ collector << ")"
194
+ collector
195
+ end
196
+
197
+
198
+ def visit_ArelExtensions_Nodes_Rtrim o , collector
199
+ collector << "RTRIM("
200
+ collector = visit o.left, collector
201
+ collector << ","
202
+ if(o.right.is_a?(Arel::Attributes::Attribute))
203
+ collector = visit o.right, collector
204
+ else
205
+ collector << "'#{o.right}'"
206
+ end
207
+ collector << ")"
208
+ collector
209
+ end
210
+
211
+ end
212
+ end
213
+ end