arel_extensions 1.2.5 → 1.2.15

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 (76) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +7 -4
  3. data/.travis.yml +54 -86
  4. data/README.md +7 -2
  5. data/Rakefile +38 -27
  6. data/arel_extensions.gemspec +1 -1
  7. data/functions.html +2 -2
  8. data/gemfiles/rails4.gemfile +1 -1
  9. data/gemfiles/rails6.gemfile +30 -0
  10. data/gemspec_v2/arel_extensions-v2.gemspec +28 -0
  11. data/generate_gems.sh +14 -0
  12. data/lib/arel_extensions.rb +49 -21
  13. data/lib/arel_extensions/attributes.rb +0 -1
  14. data/lib/arel_extensions/boolean_functions.rb +38 -13
  15. data/lib/arel_extensions/common_sql_functions.rb +5 -4
  16. data/lib/arel_extensions/insert_manager.rb +26 -24
  17. data/lib/arel_extensions/math.rb +3 -3
  18. data/lib/arel_extensions/math_functions.rb +4 -4
  19. data/lib/arel_extensions/nodes/abs.rb +0 -0
  20. data/lib/arel_extensions/nodes/case.rb +8 -4
  21. data/lib/arel_extensions/nodes/ceil.rb +0 -0
  22. data/lib/arel_extensions/nodes/coalesce.rb +0 -0
  23. data/lib/arel_extensions/nodes/collate.rb +1 -1
  24. data/lib/arel_extensions/nodes/concat.rb +0 -0
  25. data/lib/arel_extensions/nodes/date_diff.rb +1 -3
  26. data/lib/arel_extensions/nodes/duration.rb +0 -2
  27. data/lib/arel_extensions/nodes/find_in_set.rb +0 -0
  28. data/lib/arel_extensions/nodes/floor.rb +0 -0
  29. data/lib/arel_extensions/nodes/formatted_number.rb +20 -20
  30. data/lib/arel_extensions/nodes/function.rb +0 -0
  31. data/lib/arel_extensions/nodes/is_null.rb +0 -0
  32. data/lib/arel_extensions/nodes/json.rb +43 -30
  33. data/lib/arel_extensions/nodes/length.rb +0 -0
  34. data/lib/arel_extensions/nodes/locate.rb +0 -0
  35. data/lib/arel_extensions/nodes/power.rb +5 -4
  36. data/lib/arel_extensions/nodes/rand.rb +0 -0
  37. data/lib/arel_extensions/nodes/replace.rb +23 -5
  38. data/lib/arel_extensions/nodes/round.rb +5 -5
  39. data/lib/arel_extensions/nodes/soundex.rb +14 -13
  40. data/lib/arel_extensions/nodes/substring.rb +8 -15
  41. data/lib/arel_extensions/nodes/trim.rb +1 -1
  42. data/lib/arel_extensions/nodes/union.rb +0 -1
  43. data/lib/arel_extensions/nodes/union_all.rb +0 -1
  44. data/lib/arel_extensions/nodes/wday.rb +0 -0
  45. data/lib/arel_extensions/predications.rb +35 -33
  46. data/lib/arel_extensions/set_functions.rb +2 -2
  47. data/lib/arel_extensions/string_functions.rb +25 -6
  48. data/lib/arel_extensions/tasks.rb +5 -5
  49. data/lib/arel_extensions/version.rb +1 -1
  50. data/lib/arel_extensions/visitors.rb +1 -1
  51. data/lib/arel_extensions/visitors/ibm_db.rb +1 -1
  52. data/lib/arel_extensions/visitors/mssql.rb +13 -12
  53. data/lib/arel_extensions/visitors/mysql.rb +67 -37
  54. data/lib/arel_extensions/visitors/oracle.rb +14 -14
  55. data/lib/arel_extensions/visitors/oracle12.rb +1 -1
  56. data/lib/arel_extensions/visitors/postgresql.rb +46 -28
  57. data/lib/arel_extensions/visitors/sqlite.rb +52 -44
  58. data/lib/arel_extensions/visitors/to_sql.rb +73 -59
  59. data/test/arelx_test_helper.rb +28 -0
  60. data/test/support/fake_record.rb +4 -0
  61. data/test/test_comparators.rb +8 -7
  62. data/test/visitors/test_bulk_insert_oracle.rb +8 -7
  63. data/test/visitors/test_bulk_insert_sqlite.rb +8 -7
  64. data/test/visitors/test_bulk_insert_to_sql.rb +3 -3
  65. data/test/visitors/test_oracle.rb +41 -41
  66. data/test/visitors/test_to_sql.rb +367 -199
  67. data/test/with_ar/all_agnostic_test.rb +63 -41
  68. data/test/with_ar/insert_agnostic_test.rb +1 -1
  69. data/test/with_ar/test_bulk_sqlite.rb +5 -4
  70. data/test/with_ar/test_math_sqlite.rb +2 -2
  71. data/test/with_ar/test_string_mysql.rb +2 -4
  72. data/test/with_ar/test_string_sqlite.rb +2 -6
  73. data/version_v1.rb +3 -0
  74. data/version_v2.rb +3 -0
  75. metadata +10 -5
  76. data/test/helper.rb +0 -18
@@ -0,0 +1,14 @@
1
+
2
+ gem uninstall arel_extensions
3
+
4
+ # VERSION ~> 1
5
+ cp ./version_v1.rb lib/arel_extensions/version.rb
6
+ gem build ./arel_extensions.gemspec
7
+
8
+ # VERSION ~> 2
9
+ cp ./version_v2.rb lib/arel_extensions/version.rb
10
+ mv ./arel_extensions.gemspec ./arel_extensions.gemspec.bck
11
+ cp ./gemspec_v2/arel_extensions-v2.gemspec ./arel_extensions.gemspec
12
+ gem build ./arel_extensions.gemspec
13
+ cp ./version_v1.rb lib/arel_extensions/version.rb
14
+ cp ./arel_extensions.gemspec.bck ./arel_extensions.gemspec
@@ -7,35 +7,37 @@ require 'arel_extensions/railtie' if defined?(Rails::Railtie)
7
7
  # Count|NamedFunction < Function < Arel::Nodes::Node
8
8
 
9
9
  # pure Arel internals improvements
10
- Arel::Nodes::Binary.class_eval do
10
+ class Arel::Nodes::Binary
11
11
  include Arel::AliasPredication
12
12
  include Arel::Expressions
13
13
  end
14
14
 
15
- Arel::Nodes::Casted.class_eval do
15
+ class Arel::Nodes::Casted
16
16
  include Arel::AliasPredication
17
+
18
+ # They forget to define hash.
19
+ def hash
20
+ [self.class, self.val, self.attribute].hash
21
+ end
17
22
  end
18
23
 
19
- Arel::Nodes::Unary.class_eval do
24
+ class Arel::Nodes::Unary
20
25
  include Arel::Math
21
26
  include Arel::AliasPredication
22
27
  include Arel::Expressions
23
28
  end
24
29
 
25
- Arel::Nodes::Grouping.class_eval do
26
- include Arel::Math
27
- include Arel::AliasPredication
30
+ class Arel::Nodes::Grouping
28
31
  include Arel::OrderPredications
29
- include Arel::Expressions
30
32
  end
31
33
 
32
- Arel::Nodes::Function.class_eval do
34
+ class Arel::Nodes::Function
33
35
  include Arel::Math
34
36
  include Arel::Expressions
35
37
  end
36
38
 
37
- if Arel::VERSION >= "7.1.0"
38
- Arel::Nodes::Case.class_eval do
39
+ if Gem::Version.new(Arel::VERSION) >= Gem::Version.new("7.1.0")
40
+ class Arel::Nodes::Case
39
41
  include Arel::Math
40
42
  include Arel::Expressions
41
43
  end
@@ -101,14 +103,18 @@ module Arel
101
103
  Arel::Nodes::Equality.new(1,0)
102
104
  end
103
105
 
106
+ def self.tuple *v
107
+ tmp = Arel::Nodes::Grouping.new(nil)
108
+ Arel::Nodes::Grouping.new(v.map{|e| tmp.convert_to_node(e)})
109
+ end
104
110
  end
105
111
 
106
- Arel::Attributes::Attribute.class_eval do
112
+ class Arel::Attributes::Attribute
107
113
  include Arel::Math
108
114
  include ArelExtensions::Attributes
109
115
  end
110
116
 
111
- Arel::Nodes::Function.class_eval do
117
+ class Arel::Nodes::Function
112
118
  include ArelExtensions::Math
113
119
  include ArelExtensions::Comparators
114
120
  include ArelExtensions::DateDuration
@@ -118,12 +124,23 @@ Arel::Nodes::Function.class_eval do
118
124
  include ArelExtensions::NullFunctions
119
125
  include ArelExtensions::Predications
120
126
 
127
+ alias_method :old_as, :as
121
128
  def as other
122
129
  Arel::Nodes::As.new(self, Arel.sql(other))
123
130
  end
124
131
  end
125
132
 
126
- Arel::Nodes::Unary.class_eval do
133
+ class Arel::Nodes::Grouping
134
+ include ArelExtensions::Math
135
+ include ArelExtensions::Comparators
136
+ include ArelExtensions::DateDuration
137
+ include ArelExtensions::MathFunctions
138
+ include ArelExtensions::NullFunctions
139
+ include ArelExtensions::StringFunctions
140
+ include ArelExtensions::Predications
141
+ end
142
+
143
+ class Arel::Nodes::Unary
127
144
  include ArelExtensions::Math
128
145
  include ArelExtensions::Attributes
129
146
  include ArelExtensions::MathFunctions
@@ -131,7 +148,7 @@ Arel::Nodes::Unary.class_eval do
131
148
  include ArelExtensions::Predications
132
149
  end
133
150
 
134
- Arel::Nodes::Binary.class_eval do
151
+ class Arel::Nodes::Binary
135
152
  include ArelExtensions::Math
136
153
  include ArelExtensions::Attributes
137
154
  include ArelExtensions::MathFunctions
@@ -140,29 +157,40 @@ Arel::Nodes::Binary.class_eval do
140
157
  include ArelExtensions::Predications
141
158
  end
142
159
 
143
- Arel::Nodes::Equality.class_eval do
160
+ class Arel::Nodes::Equality
144
161
  include ArelExtensions::Comparators
145
162
  include ArelExtensions::DateDuration
146
163
  include ArelExtensions::MathFunctions
147
164
  include ArelExtensions::StringFunctions
148
165
  end
149
166
 
150
-
151
- Arel::InsertManager.class_eval do
167
+ class Arel::InsertManager
152
168
  include ArelExtensions::InsertManager
153
169
  end
154
170
 
155
- Arel::SelectManager.class_eval do
171
+ class Arel::SelectManager
156
172
  include ArelExtensions::SetFunctions
157
173
  include ArelExtensions::Nodes
158
174
  end
159
175
 
160
- Arel::Nodes::As.class_eval do
176
+ class Arel::Nodes::As
161
177
  include ArelExtensions::Nodes
162
178
  end
163
179
 
164
- Arel::Table.class_eval do
180
+ class Arel::Table
181
+ alias_method :old_alias, :alias
165
182
  def alias(name = "#{self.name}_2")
166
- name.blank? ? self : Arel::Nodes::TableAlias.new(self,name)
183
+ name.blank? ? self : Arel::Nodes::TableAlias.new(self,name)
184
+ end
185
+ end
186
+
187
+ class Arel::Nodes::TableAlias
188
+ def method_missing(*args)
189
+ met = args.shift.to_sym
190
+ if self.relation.respond_to?(met)
191
+ self.relation.send(met,args)
192
+ else
193
+ super(met,*args)
194
+ end
167
195
  end
168
196
  end
@@ -23,6 +23,5 @@ module ArelExtensions
23
23
  def !=(other)
24
24
  Arel::Nodes::NotEqual.new self, Arel::Nodes.build_quoted(other, self)
25
25
  end
26
-
27
26
  end
28
27
  end
@@ -1,3 +1,4 @@
1
+ # coding: utf-8
1
2
  require 'arel_extensions/nodes/then'
2
3
 
3
4
  module ArelExtensions
@@ -8,7 +9,7 @@ module ArelExtensions
8
9
  end
9
10
 
10
11
  def and *others
11
- Arel::Nodes::And.new([self]+ others.flatten)
12
+ Arel::Nodes::And.new self, others
12
13
  end
13
14
 
14
15
  def ⋁(other)
@@ -16,30 +17,54 @@ module ArelExtensions
16
17
  end
17
18
 
18
19
  def or *others
19
- args = others.flatten
20
- if args.length == 1
21
- Arel::Nodes::Or.new(self, args.first)
22
- else
23
- ArelExtensions::Nodes::Or.new([self]+ args)
24
- end
20
+ Arel::Nodes::Or.new self, others
25
21
  end
26
22
 
27
23
  def then(t, f = nil)
28
24
  ArelExtensions::Nodes::Then.new [self, t, f]
29
25
  end
26
+
30
27
  end
31
28
  end
32
29
 
33
- Arel::Nodes::And.class_eval do
30
+ class Arel::Nodes::And
34
31
  include ArelExtensions::BooleanFunctions
35
- end
36
32
 
37
- Arel::Nodes::Or.class_eval do
38
- include ArelExtensions::BooleanFunctions
33
+ def self.new *children
34
+ children =
35
+ children.flatten.map { |c|
36
+ c.is_a?(self) ? c.children : c
37
+ }.flatten
38
+ super(children)
39
+ end
40
+
39
41
  end
40
42
 
41
- ArelExtensions::Nodes.const_set('Or',Class.new(Arel::Nodes::And)).class_eval do
43
+ # For some reason, Arel's And is properly defined as variadic (it
44
+ # stores @children, and hashes it all). However Arel's Or is defined
45
+ # as binary, with only @left and @right, and hashing only @left and @right.
46
+ #
47
+ # So reimplement its ctor and accessors.
48
+
49
+ class Arel::Nodes::Or
42
50
  include ArelExtensions::BooleanFunctions
43
- end
44
51
 
52
+ attr_reader :children
45
53
 
54
+ def self.new *children
55
+ children =
56
+ children.flatten.map { |c|
57
+ c.is_a?(self) ? c.children : c
58
+ }.flatten
59
+ super(*children)
60
+ end
61
+
62
+ def initialize *children
63
+ @children = children
64
+ end
65
+
66
+ def hash
67
+ children.hash
68
+ end
69
+
70
+ end
@@ -39,6 +39,7 @@ module ArelExtensions
39
39
 
40
40
  def add_sql_functions(env_db = nil)
41
41
  env_db ||= @cnx.adapter_name
42
+ env_db = 'mysql' if env_db =~ /mysql/i
42
43
  if env_db =~ /sqlite/i
43
44
  begin
44
45
  add_sqlite_functions
@@ -52,10 +53,10 @@ module ArelExtensions
52
53
  sql.split(/^GO\s*$/).each {|str|
53
54
  @cnx.execute(str.strip) unless str.blank?
54
55
  }
55
- elsif env_db == 'mysql'
56
- sql.split("$$")[1..-2].each { |str|
57
- @cnx.execute(str.strip) unless str.strip.blank?
58
- }
56
+ elsif env_db =='mysql'
57
+ sql.split("$$")[1..-2].each { |str|
58
+ @cnx.execute(str.strip) unless str.strip.blank?
59
+ }
59
60
  else
60
61
  @cnx.execute(sql) unless sql.blank?
61
62
  end
@@ -3,31 +3,33 @@ require 'arel'
3
3
  module ArelExtensions
4
4
  module InsertManager
5
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
6
+ def bulk_insert(cols, data)
7
+ res_columns = []
8
+ case cols.first
9
+ when String, Symbol
10
+ cols.each { |c|
11
+ res_columns << @ast.relation[c]
12
+ }
13
+ when Array
14
+ if String === cols.first.first
15
+ res_columns = cols.map {|c| [@ast.relation[c.first]] }
16
+ elsif Arel::Attributes::Attribute == cols.first.first
17
+ res_columns = cols
18
+ end
19
+ when NilClass
20
+ res_columns = @ast.relation.columns
21
+ end
22
+ self.values = BulkValues.new(res_columns, data)
23
+ @ast.columns = res_columns
24
+ end
23
25
 
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
26
+ class BulkValues < Arel::Nodes::Node
27
+ attr_accessor :left, :cols
28
+ def initialize(cols, values)
29
+ @left = values
30
+ @cols = cols
31
+ end
32
+ end
31
33
 
32
34
  end
33
35
  end
@@ -24,7 +24,7 @@ module ArelExtensions
24
24
  else
25
25
  return Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new self, other)
26
26
  end
27
- when ArelExtensions::Nodes::Function,ArelExtensions::Nodes::Case
27
+ when ArelExtensions::Nodes::Function,ArelExtensions::Nodes::Case
28
28
  return case self.return_type
29
29
  when :string, :text
30
30
  self.concat(other)
@@ -35,7 +35,7 @@ module ArelExtensions
35
35
  else
36
36
  self.concat(other)
37
37
  end
38
- when Arel::Nodes::Function
38
+ when Arel::Nodes::Function
39
39
  Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new self, other)
40
40
  else
41
41
  begin
@@ -115,7 +115,7 @@ module ArelExtensions
115
115
  end
116
116
  when Arel::Nodes::Node, DateTime, Time, String, Date
117
117
  ArelExtensions::Nodes::DateDiff.new [self, other]
118
- when ArelExtensions::Nodes::Duration, Integer
118
+ when ArelExtensions::Nodes::Duration, Integer
119
119
  ArelExtensions::Nodes::DateSub.new [self, other]
120
120
  else # ActiveSupport::Duration
121
121
  ArelExtensions::Nodes::DateAdd.new [self, -other]
@@ -63,15 +63,15 @@ module ArelExtensions
63
63
  end
64
64
 
65
65
  # Aggregate Functions
66
- def std opts={unbiased: true}
66
+ def std opts = {unbiased: true}
67
67
  ArelExtensions::Nodes::Std.new self, opts
68
68
  end
69
69
 
70
- def variance opts={unbiased: true}
70
+ def variance opts = {unbiased: true}
71
71
  ArelExtensions::Nodes::Variance.new self, opts
72
72
  end
73
73
 
74
- def sum opts={unbiased: true}
74
+ def sum opts = {unbiased: true}
75
75
  ArelExtensions::Nodes::Sum.new self, opts
76
76
  end
77
77
 
@@ -91,7 +91,7 @@ module ArelExtensions
91
91
  end
92
92
 
93
93
  # function returning a number at a specific format
94
- def format_number format_string, locale=nil
94
+ def format_number format_string, locale = nil
95
95
  begin
96
96
  sprintf(format_string,0) # this line is to get the right error message if the format_string is not correct
97
97
  m = /^(.*)%([ #+\-0]*)([1-9][0-9]+|[1-9]?)[.]?([0-9]*)([a-zA-Z])(.*)$/.match(format_string)
File without changes
@@ -1,7 +1,11 @@
1
1
  module ArelExtensions
2
2
  module Nodes
3
- if Arel::VERSION < "7.1.0"
3
+ if Gem::Version.new(Arel::VERSION) < Gem::Version.new("7.1.0")
4
4
  class Case < Arel::Nodes::Node
5
+ include Arel::Expressions
6
+ include Arel::Math
7
+ include Arel::Predications
8
+ include Arel::OrderPredications
5
9
  attr_accessor :case, :conditions, :default
6
10
 
7
11
  def initialize expression = nil, default = nil
@@ -26,8 +30,10 @@ module ArelExtensions
26
30
  end
27
31
  end
28
32
 
29
- ArelExtensions::Nodes::Case.class_eval do
33
+ class ArelExtensions::Nodes::Case
30
34
  include Arel::Expressions
35
+ include Arel::Math
36
+ include Arel::Predications
31
37
  include Arel::OrderPredications
32
38
  include ArelExtensions::Math
33
39
  include ArelExtensions::Comparators
@@ -41,8 +47,6 @@ module ArelExtensions
41
47
  @conditions.last.right
42
48
  elsif @default
43
49
  @default.expr
44
- else
45
- nil
46
50
  end
47
51
  if obj.respond_to?(:return_type)
48
52
  obj.return_type
File without changes
File without changes
@@ -5,7 +5,7 @@ module ArelExtensions
5
5
 
6
6
  attr_accessor :ai, :ci, :option
7
7
 
8
- def initialize left, option=nil, ai=false, ci=false
8
+ def initialize left, option = nil, ai = false, ci = false
9
9
  @ai = ai
10
10
  @ci = ci
11
11
  @option = option
File without changes
@@ -136,7 +136,7 @@ module ArelExtensions
136
136
  if ArelExtensions::Nodes::Duration === v
137
137
  v.with_interval = true
138
138
  case v.left
139
- when 'd','m','y'
139
+ when 'd','m','y'
140
140
  Arel.sql('day')
141
141
  when 'h','mn','s'
142
142
  Arel.sql('second')
@@ -145,8 +145,6 @@ module ArelExtensions
145
145
  else
146
146
  Arel.sql(Arel::Visitors::MSSQL::DATE_MAPPING[v.left])
147
147
  end
148
- else
149
- nil
150
148
  end
151
149
  end
152
150
  end