arel_extensions 2.0.1 → 2.0.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 (76) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +7 -4
  3. data/.travis.yml +10 -10
  4. data/Gemfile +14 -19
  5. data/README.md +17 -12
  6. data/Rakefile +23 -23
  7. data/appveyor.yml +1 -1
  8. data/arel_extensions.gemspec +2 -2
  9. data/functions.html +3 -3
  10. data/gemfiles/rails6.gemfile +30 -0
  11. data/gemspec_v2/arel_extensions-v2.gemspec +28 -0
  12. data/generate_gems.sh +13 -0
  13. data/init/mssql.sql +4 -4
  14. data/init/mysql.sql +38 -38
  15. data/init/postgresql.sql +21 -21
  16. data/lib/arel_extensions/boolean_functions.rb +0 -2
  17. data/lib/arel_extensions/common_sql_functions.rb +5 -4
  18. data/lib/arel_extensions/comparators.rb +4 -2
  19. data/lib/arel_extensions/insert_manager.rb +12 -12
  20. data/lib/arel_extensions/math.rb +3 -3
  21. data/lib/arel_extensions/math_functions.rb +10 -5
  22. data/lib/arel_extensions/nodes/aggregate_function.rb +14 -0
  23. data/lib/arel_extensions/nodes/case.rb +0 -2
  24. data/lib/arel_extensions/nodes/coalesce.rb +2 -2
  25. data/lib/arel_extensions/nodes/collate.rb +1 -1
  26. data/lib/arel_extensions/nodes/concat.rb +6 -13
  27. data/lib/arel_extensions/nodes/date_diff.rb +3 -5
  28. data/lib/arel_extensions/nodes/duration.rb +0 -2
  29. data/lib/arel_extensions/nodes/format.rb +8 -8
  30. data/lib/arel_extensions/nodes/formatted_number.rb +23 -23
  31. data/lib/arel_extensions/nodes/function.rb +2 -0
  32. data/lib/arel_extensions/nodes/json.rb +28 -30
  33. data/lib/arel_extensions/nodes/matches.rb +4 -4
  34. data/lib/arel_extensions/nodes/power.rb +6 -5
  35. data/lib/arel_extensions/nodes/repeat.rb +2 -2
  36. data/lib/arel_extensions/nodes/replace.rb +24 -6
  37. data/lib/arel_extensions/nodes/round.rb +5 -5
  38. data/lib/arel_extensions/nodes/soundex.rb +16 -15
  39. data/lib/arel_extensions/nodes/std.rb +19 -21
  40. data/lib/arel_extensions/nodes/substring.rb +8 -15
  41. data/lib/arel_extensions/nodes/sum.rb +7 -0
  42. data/lib/arel_extensions/nodes/trim.rb +3 -3
  43. data/lib/arel_extensions/nodes/union.rb +2 -3
  44. data/lib/arel_extensions/nodes/union_all.rb +0 -1
  45. data/lib/arel_extensions/nodes.rb +1 -1
  46. data/lib/arel_extensions/null_functions.rb +2 -2
  47. data/lib/arel_extensions/predications.rb +16 -17
  48. data/lib/arel_extensions/string_functions.rb +21 -12
  49. data/lib/arel_extensions/tasks.rb +5 -5
  50. data/lib/arel_extensions/version.rb +1 -1
  51. data/lib/arel_extensions/visitors/mssql.rb +14 -13
  52. data/lib/arel_extensions/visitors/mysql.rb +72 -37
  53. data/lib/arel_extensions/visitors/oracle.rb +12 -11
  54. data/lib/arel_extensions/visitors/oracle12.rb +1 -1
  55. data/lib/arel_extensions/visitors/postgresql.rb +77 -31
  56. data/lib/arel_extensions/visitors/sqlite.rb +54 -40
  57. data/lib/arel_extensions/visitors/to_sql.rb +50 -31
  58. data/lib/arel_extensions.rb +20 -1
  59. data/test/helper.rb +1 -1
  60. data/test/real_db_test.rb +1 -1
  61. data/test/support/fake_record.rb +0 -4
  62. data/test/test_comparators.rb +1 -1
  63. data/test/visitors/test_bulk_insert_oracle.rb +6 -6
  64. data/test/visitors/test_bulk_insert_sqlite.rb +6 -6
  65. data/test/visitors/test_bulk_insert_to_sql.rb +7 -9
  66. data/test/visitors/test_oracle.rb +1 -0
  67. data/test/visitors/test_to_sql.rb +15 -1
  68. data/test/with_ar/all_agnostic_test.rb +54 -32
  69. data/test/with_ar/insert_agnostic_test.rb +2 -1
  70. data/test/with_ar/test_bulk_sqlite.rb +2 -2
  71. data/test/with_ar/test_math_sqlite.rb +3 -3
  72. data/test/with_ar/test_string_mysql.rb +3 -5
  73. data/test/with_ar/test_string_sqlite.rb +2 -6
  74. data/version_v1.rb +3 -0
  75. data/version_v2.rb +3 -0
  76. metadata +13 -6
@@ -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
@@ -1,6 +1,7 @@
1
1
  module ArelExtensions
2
2
  module Comparators
3
3
 
4
+
4
5
  def >(other)
5
6
  Arel::Nodes::GreaterThan.new self, Arel::Nodes.build_quoted(other, self)
6
7
  end
@@ -37,13 +38,14 @@ module ArelExtensions
37
38
  end
38
39
 
39
40
  private
40
- #Function use for not_regexp
41
+ # Function used for not_regexp.
41
42
  def convert_regexp(other)
42
43
  case other
43
44
  when String
44
- #Do nothing
45
+ # Do nothing.
45
46
  when Regexp
46
47
  other = other.source.gsub('\A','^')
48
+ other.gsub!('\z','$')
47
49
  other.gsub!('\Z','$')
48
50
  other.gsub!('\d','[0-9]')
49
51
  other.gsub!('\D','[^0-9]')
@@ -5,18 +5,18 @@ module ArelExtensions
5
5
 
6
6
  def bulk_insert(cols, data)
7
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
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
20
  end
21
21
  self.values = BulkValues.new(@ast.columns, data)
22
22
  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]
@@ -7,6 +7,7 @@ require 'arel_extensions/nodes/formatted_number'
7
7
  require 'arel_extensions/nodes/log10'
8
8
  require 'arel_extensions/nodes/power'
9
9
  require 'arel_extensions/nodes/std'
10
+ require 'arel_extensions/nodes/sum'
10
11
 
11
12
  module ArelExtensions
12
13
  module MathFunctions
@@ -62,12 +63,16 @@ module ArelExtensions
62
63
  end
63
64
 
64
65
  # Aggregate Functions
65
- def std unbiased = true
66
- ArelExtensions::Nodes::Std.new [self,unbiased]
66
+ def std opts = {unbiased: true}
67
+ ArelExtensions::Nodes::Std.new self, opts
67
68
  end
68
69
 
69
- def variance unbiased = true
70
- ArelExtensions::Nodes::Variance.new [self,unbiased]
70
+ def variance opts = {unbiased: true}
71
+ ArelExtensions::Nodes::Variance.new self, opts
72
+ end
73
+
74
+ def sum opts = {unbiased: true}
75
+ ArelExtensions::Nodes::Sum.new self, opts
71
76
  end
72
77
 
73
78
  #function that can be invoked to produce random numbers between 0 and 1
@@ -86,7 +91,7 @@ module ArelExtensions
86
91
  end
87
92
 
88
93
  # function returning a number at a specific format
89
- def format_number format_string, locale=nil
94
+ def format_number format_string, locale = nil
90
95
  begin
91
96
  sprintf(format_string,0) # this line is to get the right error message if the format_string is not correct
92
97
  m = /^(.*)%([ #+\-0]*)([1-9][0-9]+|[1-9]?)[.]?([0-9]*)([a-zA-Z])(.*)$/.match(format_string)
@@ -0,0 +1,14 @@
1
+ module ArelExtensions
2
+ module Nodes
3
+ class AggregateFunction < Function
4
+ attr_accessor :order, :group
5
+
6
+ def initialize node, **opts
7
+ @order = Array(opts[:order]).map{|e| convert_to_node(e)}
8
+ @group = Array(opts[:group]).map{|e| convert_to_node(e)}
9
+ super [node]
10
+ end
11
+ end
12
+
13
+ end
14
+ end
@@ -41,8 +41,6 @@ module ArelExtensions
41
41
  @conditions.last.right
42
42
  elsif @default
43
43
  @default.expr
44
- else
45
- nil
46
44
  end
47
45
  if obj.respond_to?(:return_type)
48
46
  obj.return_type
@@ -2,7 +2,7 @@ module ArelExtensions
2
2
  module Nodes
3
3
  class Coalesce < Function
4
4
  RETURN_TYPE = :string
5
-
5
+
6
6
  attr_accessor :left_node_type
7
7
 
8
8
  def return_type
@@ -20,7 +20,7 @@ module ArelExtensions
20
20
  @left_node_type = :number
21
21
  when ArelExtensions::Nodes::Coalesce, ArelExtensions::Nodes::Function
22
22
  @left_node_type = expr.first.respond_to?(:left_node_type) ? expr.first.left_node_type : nil
23
- when Arel::Nodes::Node, Arel::Attributes::Attribute
23
+ when Arel::Nodes::Node, Arel::Attributes::Attribute
24
24
  @left_node_type = type_of_attribute(expr.first)
25
25
  when Date
26
26
  @left_node_type = :ruby_date
@@ -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
@@ -40,21 +40,14 @@ module ArelExtensions::Nodes
40
40
 
41
41
  end
42
42
 
43
- class GroupConcat < Function
43
+ class GroupConcat < AggregateFunction
44
44
  RETURN_TYPE = :string
45
45
 
46
- attr_accessor :orders
47
-
48
- def initialize expr
49
- tab = expr.map { |arg|
50
- if arg.is_a?(Array)
51
- @orders = arg
52
- nil
53
- else
54
- convert_to_node(arg)
55
- end
56
- }.compact
57
- super(tab)
46
+ attr_accessor :separator
47
+
48
+ def initialize node, separator = ', ', **opts
49
+ @separator = convert_to_node(separator)
50
+ super node, opts
58
51
  end
59
52
 
60
53
  end
@@ -12,7 +12,7 @@ module ArelExtensions
12
12
  res = []
13
13
  col = expr.first
14
14
  case col
15
- when Arel::Nodes::Node, Arel::Attributes::Attribute
15
+ when Arel::Nodes::Node, Arel::Attributes::Attribute
16
16
  @left_node_type = type_of_attribute(col)
17
17
  when Date
18
18
  @left_node_type = :ruby_date
@@ -21,7 +21,7 @@ module ArelExtensions
21
21
  end
22
22
  res << ([:date, :ruby_date].include?(@left_node_type) ? convert_to_date_node(col) : convert_to_datetime_node(col))
23
23
  case expr[1]
24
- when Arel::Nodes::Node, Arel::Attributes::Attribute
24
+ when Arel::Nodes::Node, Arel::Attributes::Attribute
25
25
  @right_node_type = type_of_attribute(expr[1])
26
26
  when Date
27
27
  @right_node_type = :ruby_date
@@ -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
@@ -13,12 +13,10 @@ module ArelExtensions
13
13
  super(tab, aliaz)
14
14
  end
15
15
 
16
-
17
16
  def left
18
17
  @expressions.first
19
18
  end
20
19
 
21
-
22
20
  def right
23
21
  @expressions[1]
24
22
  end
@@ -1,15 +1,15 @@
1
1
  module ArelExtensions
2
2
  module Nodes
3
- class Format < Function
3
+ class Format < Function
4
4
  RETURN_TYPE = :string
5
5
 
6
- attr_accessor :col_type, :iso_format
7
- def initialize expr
8
- col = expr.first
9
- @iso_format = expr[1]
10
- @col_type = type_of_attribute(col)
11
- super [col, convert_to_string_node(@iso_format)]
12
- end
6
+ attr_accessor :col_type, :iso_format
7
+ def initialize expr
8
+ col = expr.first
9
+ @iso_format = expr[1]
10
+ @col_type = type_of_attribute(col)
11
+ super [col, convert_to_string_node(@iso_format)]
12
+ end
13
13
  end
14
14
  end
15
15
  end
@@ -1,25 +1,25 @@
1
1
  module ArelExtensions
2
- module Nodes
3
- class FormattedNumber < Function
4
- RETURN_TYPE = :string
5
-
6
- attr_accessor :locale, :prefix, :suffix, :flags, :scientific_notation, :width,:precision, :type, :original_string
7
-
8
- def initialize expr
9
- # expr[1] = {:locale => 'fr_FR', :type => "e"/"f"/"d", :prefix => "$ ", :suffix => " %", :flags => " +-#0", :width => 5, :precision => 6}
10
- col = expr.first
11
- @locale = expr[1][:locale]
12
- @prefix = expr[1][:prefix]
13
- @suffix = expr[1][:suffix]
14
- @width = expr[1][:width]
15
- @precision = expr[1][:precision]
16
- @type = expr[1][:type]
17
- @flags = expr[1][:flags]
18
- @scientific_notation = /[eE]/.match(expr[1][:type]) || false
19
- @original_string = expr[1][:original_string]
20
- super [col]
21
- end
22
-
23
- end
24
- end
2
+ module Nodes
3
+ class FormattedNumber < Function
4
+ RETURN_TYPE = :string
5
+
6
+ attr_accessor :locale, :prefix, :suffix, :flags, :scientific_notation, :width,:precision, :type, :original_string
7
+
8
+ def initialize expr
9
+ # expr[1] = {:locale => 'fr_FR', :type => "e"/"f"/"d", :prefix => "$ ", :suffix => " %", :flags => " +-#0", :width => 5, :precision => 6}
10
+ col = expr.first
11
+ @locale = expr[1][:locale]
12
+ @prefix = expr[1][:prefix]
13
+ @suffix = expr[1][:suffix]
14
+ @width = expr[1][:width]
15
+ @precision = expr[1][:precision]
16
+ @type = expr[1][:type]
17
+ @flags = expr[1][:flags]
18
+ @scientific_notation = /[eE]/.match(expr[1][:type]) || false
19
+ @original_string = expr[1][:original_string]
20
+ super [col]
21
+ end
22
+
23
+ end
24
+ end
25
25
  end
@@ -71,6 +71,8 @@ module ArelExtensions
71
71
  Arel.sql('NULL')
72
72
  when ActiveSupport::Duration
73
73
  Arel.sql(object.to_i)
74
+ when Array
75
+ Arel::Nodes::Grouping.new(object.map{|r| convert_to_node(e)})
74
76
  else
75
77
  raise(ArgumentError, "#{object.class} can not be converted to CONCAT arg")
76
78
  end
@@ -18,7 +18,7 @@ module ArelExtensions
18
18
  JsonSet.new(self,key,value)
19
19
  end
20
20
 
21
- def group as_array = true, orders= nil
21
+ def group as_array = true, orders = nil
22
22
  JsonGroup.new(self,as_array, orders)
23
23
  end
24
24
 
@@ -31,33 +31,35 @@ module ArelExtensions
31
31
  class Json < JsonNode
32
32
 
33
33
  def initialize *expr
34
- if expr.length == 1
35
- case expr.first
36
- when JsonNode
37
- @dict = expr.first.dict
38
- when Array
39
- @dict = expr.first.map{|e|
40
- (e.is_a?(Array) || e.is_a?(Hash)) ? Json.new(e) : convert_to_node(e)
41
- }
42
- when Hash
43
- @dict = expr.first.inject({}){|acc,v|
44
- acc[convert_to_node(v[0])] = (v[1].is_a?(Array) || v[1].is_a?(Hash)) ? Json.new(v[1]) : convert_to_node(v[1])
45
- acc
46
- }
47
- when String, Numeric, TrueClass, FalseClass
48
- @dict = convert_to_node(expr.first)
49
- when NilClass
50
- @dict = Arel.sql('null')
51
- else
52
- if expr.first.is_a?(String) || (expr.first.is_a?(Arel::Attributes::Attribute) && type_of_attribute(expr.first) == :string) || (expr.first.return_type == :string)
53
- @dict = convert_to_node(expr.first)
34
+ @dict =
35
+ if expr.length == 1
36
+ case exp = expr.first
37
+ when JsonNode
38
+ exp.dict
39
+ when Array
40
+ exp.map{|e|
41
+ (e.is_a?(Array) || e.is_a?(Hash)) ? Json.new(e) : convert_to_node(e)
42
+ }
43
+ when Hash
44
+ exp.reduce({}){|acc,v|
45
+ acc[convert_to_node(v[0])] = (v[1].is_a?(Array) || v[1].is_a?(Hash)) ? Json.new(v[1]) : convert_to_node(v[1])
46
+ acc
47
+ }
48
+ when String, Numeric, TrueClass, FalseClass
49
+ convert_to_node(exp)
50
+ when NilClass
51
+ Arel.sql('null')
54
52
  else
55
- @dict = [convert_to_node(expr.first)]
53
+ if (exp.is_a?(Arel::Attributes::Attribute) && type_of_attribute(exp) == :string) \
54
+ || (exp.return_type == :string)
55
+ convert_to_node(exp)
56
+ else
57
+ [convert_to_node(exp)]
58
+ end
56
59
  end
60
+ else
61
+ expr.map{|e| (e.is_a?(Array) || e.is_a?(Hash)) ? Json.new(e) : convert_to_node(e) }
57
62
  end
58
- else
59
- @dict = expr.map{|e| (e.is_a?(Array) || e.is_a?(Hash)) ? Json.new(e) : convert_to_node(e) }
60
- end
61
63
  super
62
64
  end
63
65
 
@@ -73,11 +75,7 @@ module ArelExtensions
73
75
  @dict = as_array ? json : json.dict
74
76
  @as_array = as_array
75
77
  if orders
76
- if orders.is_a?(Array)
77
- @orders = orders
78
- else
79
- @orders = [orders]
80
- end
78
+ @orders = Array(orders)
81
79
  end
82
80
  end
83
81
  end
@@ -3,7 +3,7 @@ module ArelExtensions
3
3
  class IMatches < Arel::Nodes::Matches
4
4
 
5
5
  attr_accessor :case_sensitive if Arel::VERSION.to_i < 7
6
-
6
+
7
7
  def initialize(left, right, escape = nil)
8
8
  r = Arel::Nodes.build_quoted(right)
9
9
  if Arel::VERSION.to_i < 7 # managed by default in version 7+ (rails 5), so useful for rails 3 & 4
@@ -17,13 +17,13 @@ module ArelExtensions
17
17
 
18
18
  class IDoesNotMatch < IMatches
19
19
  end
20
-
20
+
21
21
  class AiMatches < IMatches
22
22
  end
23
-
23
+
24
24
  class AiIMatches < IMatches
25
25
  end
26
-
26
+
27
27
  class SMatches < IMatches
28
28
  end
29
29
 
@@ -1,11 +1,12 @@
1
1
  module ArelExtensions
2
2
  module Nodes
3
3
  class Power < Function
4
- RETURN_TYPE = :number
5
-
6
- def initialize expr
7
- super [convert_to_node(expr.first), convert_to_number(expr[1])]
8
- end
4
+ RETURN_TYPE = :number
5
+
6
+ def initialize expr
7
+ super [convert_to_node(expr.first), convert_to_number(expr[1])]
8
+ end
9
+
9
10
  end
10
11
  end
11
12
  end
@@ -2,7 +2,7 @@ module ArelExtensions
2
2
  module Nodes
3
3
  class Repeat < Function
4
4
  RETURN_TYPE = :string
5
-
5
+
6
6
  def initialize expr
7
7
  tab = expr.map { |arg|
8
8
  convert_to_node(arg)
@@ -11,7 +11,7 @@ module ArelExtensions
11
11
  end
12
12
 
13
13
  def +(other)
14
- return ArelExtensions::Nodes::Concat.new(self.expressions + [other])
14
+ return ArelExtensions::Nodes::Concat.new(self.expressions + [other])
15
15
  end
16
16
 
17
17
  end
@@ -2,18 +2,36 @@ module ArelExtensions
2
2
  module Nodes
3
3
  class Replace < Function
4
4
  RETURN_TYPE = :string
5
+ attr_accessor :left, :pattern, :substitute
5
6
 
6
- def initialize expr
7
- tab = expr.map { |arg|
8
- convert_to_node(arg)
9
- }
10
- return super(tab)
7
+ def initialize left, pattern, substitute
8
+ @left = convert_to_node(left)
9
+ @pattern = convert_to_node(pattern)
10
+ @substitute = convert_to_node(substitute)
11
+ super([@left,@pattern,@substitute])
11
12
  end
12
13
 
13
14
  def +(other)
14
- return ArelExtensions::Nodes::Concat.new(self.expressions + [other])
15
+ return ArelExtensions::Nodes::Concat.new(self.expressions + [other])
15
16
  end
16
17
 
17
18
  end
19
+
20
+ class RegexpReplace < Function
21
+ RETURN_TYPE = :string
22
+ attr_accessor :left, :pattern, :substitute
23
+
24
+ def initialize left, pattern, substitute
25
+ @left = convert_to_node(left)
26
+ @pattern = (pattern.is_a?(Regexp) ? pattern : %r[#{pattern}])
27
+ @substitute = convert_to_node(substitute)
28
+ super([@left,@pattern,@substitute])
29
+ end
30
+
31
+ def +(other)
32
+ return ArelExtensions::Nodes::Concat.new(self.expressions + [other])
33
+ end
34
+ end
35
+
18
36
  end
19
37
  end
@@ -4,11 +4,11 @@ module ArelExtensions
4
4
  RETURN_TYPE = :number
5
5
 
6
6
  def initialize expr
7
- if expr && expr.length == 1
8
- super [convert_to_node(expr.first)]
9
- else
10
- super [convert_to_node(expr.first), convert_to_number(expr[1])]
11
- end
7
+ if expr && expr.length == 1
8
+ super [convert_to_node(expr.first)]
9
+ else
10
+ super [convert_to_node(expr.first), convert_to_number(expr[1])]
11
+ end
12
12
  end
13
13
 
14
14
  end
@@ -1,18 +1,19 @@
1
1
  module ArelExtensions
2
- module Nodes
3
- class Soundex < Function
4
- include Arel::Expressions
5
- include ArelExtensions::Comparators
6
-
7
- RETURN_TYPE = :string
8
-
9
- def ==(other)
10
- Arel::Nodes::Equality.new self, Arel::Nodes.build_quoted(other, self)
11
- end
2
+ module Nodes
3
+ class Soundex < Function
4
+ include Arel::Expressions
5
+ include ArelExtensions::Comparators
12
6
 
13
- def !=(other)
14
- Arel::Nodes::NotEqual.new self, Arel::Nodes.build_quoted(other, self)
15
- end
16
- end
17
- end
7
+ RETURN_TYPE = :string
8
+
9
+ def ==(other)
10
+ Arel::Nodes::Equality.new self, Arel::Nodes.build_quoted(other, self)
11
+ end
12
+
13
+ def !=(other)
14
+ Arel::Nodes::NotEqual.new self, Arel::Nodes.build_quoted(other, self)
15
+ end
16
+
17
+ end
18
+ end
18
19
  end
@@ -1,26 +1,24 @@
1
1
  module ArelExtensions
2
2
  module Nodes
3
- class Std < Function
4
- RETURN_TYPE = :number
5
-
6
- attr_accessor :unbiased_estimator
7
- def initialize expr
8
- col = expr.first
9
- @unbiased_estimator = expr[1]
10
- super [col]
11
- end
3
+ class Std < AggregateFunction
4
+ RETURN_TYPE = :number
5
+ attr_accessor :unbiased_estimator
6
+
7
+ def initialize node, opts = {}
8
+ @unbiased_estimator = opts[:unbiased] ? true : false
9
+ super node, opts
10
+ end
12
11
  end
13
-
14
- class Variance < Function
15
- RETURN_TYPE = :number
16
-
17
- attr_accessor :unbiased_estimator
18
- def initialize expr
19
- col = expr.first
20
- @unbiased_estimator = expr[1]
21
- super [col]
22
- end
23
- end
24
-
12
+
13
+ class Variance < AggregateFunction
14
+ RETURN_TYPE = :number
15
+ attr_accessor :unbiased_estimator
16
+
17
+ def initialize node, opts = {}
18
+ @unbiased_estimator = opts[:unbiased] ? true : false
19
+ super node, opts
20
+ end
21
+ end
22
+
25
23
  end
26
24
  end