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