arel_extensions 2.3.3 → 2.5.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 (104) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +92 -43
  3. data/.gitignore +2 -1
  4. data/.rubocop.yml +131 -5
  5. data/Makefile +48 -0
  6. data/NEWS.md +22 -0
  7. data/README.md +32 -5
  8. data/Rakefile +5 -3
  9. data/arel_extensions.gemspec +3 -5
  10. data/dev/arelx.dockerfile +13 -16
  11. data/dev/compose.yaml +26 -28
  12. data/gemfiles/rails5.gemfile +15 -8
  13. data/gemfiles/rails5_1_4.gemfile +11 -9
  14. data/gemfiles/rails5_2.gemfile +16 -9
  15. data/gemfiles/rails6.gemfile +13 -7
  16. data/gemfiles/rails6_1.gemfile +13 -7
  17. data/gemfiles/rails7.gemfile +15 -9
  18. data/gemfiles/rails7_1.gemfile +15 -8
  19. data/gemfiles/rails7_2.gemfile +12 -6
  20. data/gemfiles/rails8.gemfile +40 -0
  21. data/gemfiles/rails8_1.gemfile +41 -0
  22. data/gemspecs/arel_extensions-v1.gemspec +3 -5
  23. data/gemspecs/arel_extensions-v2.gemspec +3 -5
  24. data/lib/arel_extensions/aliases.rb +3 -3
  25. data/lib/arel_extensions/attributes.rb +2 -0
  26. data/lib/arel_extensions/boolean_functions.rb +9 -7
  27. data/lib/arel_extensions/common_sql_functions.rb +5 -3
  28. data/lib/arel_extensions/comparators.rb +6 -4
  29. data/lib/arel_extensions/constants.rb +13 -0
  30. data/lib/arel_extensions/date_duration.rb +2 -0
  31. data/lib/arel_extensions/helpers.rb +18 -19
  32. data/lib/arel_extensions/insert_manager.rb +5 -1
  33. data/lib/arel_extensions/math.rb +40 -44
  34. data/lib/arel_extensions/math_functions.rb +29 -31
  35. data/lib/arel_extensions/nodes/aggregate_function.rb +4 -4
  36. data/lib/arel_extensions/nodes/blank.rb +6 -4
  37. data/lib/arel_extensions/nodes/byte_size.rb +11 -0
  38. data/lib/arel_extensions/nodes/case.rb +16 -13
  39. data/lib/arel_extensions/nodes/cast.rb +3 -5
  40. data/lib/arel_extensions/nodes/char_length.rb +11 -0
  41. data/lib/arel_extensions/nodes/coalesce.rb +1 -1
  42. data/lib/arel_extensions/nodes/collate.rb +1 -1
  43. data/lib/arel_extensions/nodes/concat.rb +6 -6
  44. data/lib/arel_extensions/nodes/date_diff.rb +40 -49
  45. data/lib/arel_extensions/nodes/duration.rb +2 -2
  46. data/lib/arel_extensions/nodes/format.rb +2 -2
  47. data/lib/arel_extensions/nodes/formatted_date.rb +2 -2
  48. data/lib/arel_extensions/nodes/formatted_number.rb +2 -2
  49. data/lib/arel_extensions/nodes/function.rb +7 -7
  50. data/lib/arel_extensions/nodes/is_null.rb +2 -0
  51. data/lib/arel_extensions/nodes/json.rb +27 -15
  52. data/lib/arel_extensions/nodes/levenshtein_distance.rb +2 -2
  53. data/lib/arel_extensions/nodes/locate.rb +1 -1
  54. data/lib/arel_extensions/nodes/matches.rb +2 -2
  55. data/lib/arel_extensions/nodes/power.rb +2 -2
  56. data/lib/arel_extensions/nodes/rand.rb +2 -2
  57. data/lib/arel_extensions/nodes/repeat.rb +2 -2
  58. data/lib/arel_extensions/nodes/replace.rb +3 -3
  59. data/lib/arel_extensions/nodes/rollup.rb +4 -4
  60. data/lib/arel_extensions/nodes/round.rb +3 -3
  61. data/lib/arel_extensions/nodes/select.rb +1 -1
  62. data/lib/arel_extensions/nodes/std.rb +4 -4
  63. data/lib/arel_extensions/nodes/substring.rb +52 -2
  64. data/lib/arel_extensions/nodes/then.rb +1 -1
  65. data/lib/arel_extensions/nodes/trim.rb +2 -2
  66. data/lib/arel_extensions/nodes/union.rb +3 -3
  67. data/lib/arel_extensions/nodes/union_all.rb +3 -3
  68. data/lib/arel_extensions/nodes/wday.rb +2 -2
  69. data/lib/arel_extensions/null_functions.rb +5 -7
  70. data/lib/arel_extensions/predications.rb +23 -19
  71. data/lib/arel_extensions/string_functions.rb +37 -28
  72. data/lib/arel_extensions/version.rb +3 -1
  73. data/lib/arel_extensions/visitors/convert_format.rb +2 -2
  74. data/lib/arel_extensions/visitors/ibm_db.rb +5 -5
  75. data/lib/arel_extensions/visitors/mssql.rb +111 -97
  76. data/lib/arel_extensions/visitors/mysql.rb +101 -67
  77. data/lib/arel_extensions/visitors/oracle.rb +113 -103
  78. data/lib/arel_extensions/visitors/oracle12.rb +5 -6
  79. data/lib/arel_extensions/visitors/postgresql.rb +119 -92
  80. data/lib/arel_extensions/visitors/sqlite.rb +72 -64
  81. data/lib/arel_extensions/visitors/to_sql.rb +85 -75
  82. data/lib/arel_extensions/visitors.rb +7 -7
  83. data/lib/arel_extensions/warning.rb +5 -5
  84. data/lib/arel_extensions.rb +47 -31
  85. data/test/arelx_test_helper.rb +8 -6
  86. data/test/config_loader.rb +9 -0
  87. data/test/database.yml +8 -6
  88. data/test/real_db_test.rb +33 -33
  89. data/test/support/fake_record.rb +3 -1
  90. data/test/visitors/test_bulk_insert_oracle.rb +2 -2
  91. data/test/visitors/test_bulk_insert_sqlite.rb +2 -2
  92. data/test/visitors/test_to_sql.rb +2 -2
  93. data/test/with_ar/all_agnostic_test.rb +214 -32
  94. data/test/with_ar/insert_agnostic_test.rb +2 -2
  95. data/test/with_ar/test_bulk_sqlite.rb +2 -2
  96. data/test/with_ar/test_math_sqlite.rb +2 -2
  97. data/test/with_ar/test_string_mysql.rb +2 -2
  98. data/test/with_ar/test_string_sqlite.rb +2 -2
  99. data/version_v1.rb +3 -1
  100. data/version_v2.rb +3 -1
  101. metadata +9 -33
  102. data/bin/compose +0 -6
  103. data/gemfiles/rails3.gemfile +0 -20
  104. data/gemfiles/rails4_2.gemfile +0 -38
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'arel_extensions/nodes/then'
2
4
 
3
5
  module ArelExtensions
@@ -6,7 +8,7 @@ module ArelExtensions
6
8
  self.and(other)
7
9
  end
8
10
 
9
- def and *others
11
+ def and(*others)
10
12
  Arel::Nodes::And.new self, others
11
13
  end
12
14
 
@@ -14,7 +16,7 @@ module ArelExtensions
14
16
  self.or(other)
15
17
  end
16
18
 
17
- def or *others
19
+ def or(*others)
18
20
  Arel::Nodes::Or.new self, others
19
21
  end
20
22
 
@@ -27,7 +29,7 @@ end
27
29
  class Arel::Nodes::And
28
30
  include ArelExtensions::BooleanFunctions
29
31
 
30
- def self.new *children
32
+ def self.new(*children)
31
33
  children =
32
34
  children.flatten.map { |c|
33
35
  c.is_a?(self) ? c.children : c
@@ -47,15 +49,15 @@ class Arel::Nodes::Or
47
49
 
48
50
  attr_reader :children
49
51
 
50
- def self.new *children
52
+ def self.new(*children)
51
53
  children =
52
54
  children.flatten.map { |c|
53
55
  c.is_a?(self) ? c.children : c
54
56
  }.flatten
55
- super(*children)
57
+ super
56
58
  end
57
59
 
58
- def initialize *children
60
+ def initialize(*children)
59
61
  @children = children
60
62
  end
61
63
 
@@ -80,5 +82,5 @@ class Arel::Nodes::Or
80
82
  self.class == other.class &&
81
83
  children == other.children
82
84
  end
83
- alias :== :eql?
85
+ alias == eql?
84
86
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ArelExtensions
2
4
  class CommonSqlFunctions
3
5
  def initialize(cnx)
@@ -9,7 +11,7 @@ module ArelExtensions
9
11
  db.load_extension('/usr/lib/sqlite3/pcre.so')
10
12
  db.load_extension('/usr/lib/sqlite3/extension-functions.so')
11
13
  db.enable_load_extension(0)
12
- rescue => e
14
+ rescue StandardError => e
13
15
  $load_extension_disabled = true
14
16
  puts "cannot load extensions #{e.inspect}"
15
17
  end
@@ -42,14 +44,14 @@ module ArelExtensions
42
44
  if /sqlite/i.match?(env_db)
43
45
  begin
44
46
  add_sqlite_functions
45
- rescue => e
47
+ rescue StandardError => e
46
48
  puts "cannot add sqlite functions #{e.inspect}"
47
49
  end
48
50
  end
49
51
  if File.exist?("init/#{env_db}.sql")
50
52
  sql = File.read("init/#{env_db}.sql")
51
53
  if env_db == 'mssql'
52
- sql.split(/^GO\s*$/).each {|str|
54
+ sql.split(/^GO\s*$/).each { |str|
53
55
  @cnx.execute(str.strip) unless str.blank?
54
56
  }
55
57
  elsif env_db == 'mysql'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ArelExtensions
2
4
  module Comparators
3
5
  def >(other)
@@ -19,8 +21,8 @@ module ArelExtensions
19
21
  # REGEXP function
20
22
  # Pattern matching using regular expressions
21
23
  def =~(other)
22
- # arg = self.relation.engine.connection.schema_cache.columns_hash(self.relation.table_name)[self.name.to_s].type
23
- # if arg == :string || arg == :text
24
+ # arg = self.relation.engine.connection.schema_cache.columns_hash(self.relation.table_name)[self.name.to_s].type
25
+ # if arg == :string || arg == :text
24
26
  Arel::Nodes::Regexp.new self, convert_regexp(other)
25
27
  # end
26
28
  end
@@ -30,8 +32,8 @@ module ArelExtensions
30
32
  # NOT_REGEXP function
31
33
  # Negation of Regexp
32
34
  def !~(other)
33
- # arg = self.relation.engine.connection.schema_cache.columns_hash(self.relation.table_name)[self.name.to_s].type
34
- # if arg == :string || arg == :text
35
+ # arg = self.relation.engine.connection.schema_cache.columns_hash(self.relation.table_name)[self.name.to_s].type
36
+ # if arg == :string || arg == :text
35
37
  Arel::Nodes::NotRegexp.new self, convert_regexp(other)
36
38
  # end
37
39
  end
@@ -0,0 +1,13 @@
1
+ module ArelExtensions
2
+ ACTIVE_RECORD_VERSION = Gem::Version.new(ActiveRecord::VERSION::STRING).freeze
3
+ AREL_VERSION = Gem::Version.new(Arel::VERSION).freeze
4
+ V10 = Gem::Version.new('10.0').freeze
5
+ V5 = Gem::Version.new('5.0').freeze
6
+ V6 = Gem::Version.new('6.0').freeze
7
+ V7 = Gem::Version.new('7.0').freeze
8
+ V7_0 = Gem::Version.new('7.0').freeze
9
+ V7_1 = Gem::Version.new('7.1').freeze
10
+ V7_2 = Gem::Version.new('7.2').freeze
11
+ V8_1 = Gem::Version.new('8.1').freeze
12
+ V9_0 = Gem::Version.new('9.0').freeze
13
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'arel_extensions/nodes/format'
2
4
  require 'arel_extensions/nodes/formatted_date'
3
5
  require 'arel_extensions/nodes/duration'
@@ -1,5 +1,6 @@
1
- module ArelExtensions
1
+ # frozen_string_literal: true
2
2
 
3
+ module ArelExtensions
3
4
  #
4
5
  # column_of
5
6
  #
@@ -19,7 +20,7 @@ module ArelExtensions
19
20
  Arel::Table.engine.connection.schema_cache.columns_hash(table_name)[column_name]
20
21
  rescue NoMethodError
21
22
  nil
22
- rescue => e
23
+ rescue StandardError => e
23
24
  warn("Warning: Unexpected exception caught while fetching column name for #{table_name}.#{column_name} in `column_of_via_arel_table`\n#{e.class}")
24
25
  warn(e.backtrace)
25
26
  nil
@@ -27,33 +28,31 @@ module ArelExtensions
27
28
 
28
29
  def self.column_of(table_name, column_name)
29
30
  pool = ActiveRecord::Base.connection.pool
30
- use_arel_table = !ActiveRecord::Base.connected? || \
31
- (pool.respond_to?(:schema_cache) && pool.schema_cache.nil?)
31
+ use_arel_table = !ActiveRecord::Base.connected? \
32
+ || (pool.respond_to?(:schema_cache) && pool.schema_cache.nil?)
32
33
 
33
34
  if use_arel_table
34
35
  column_of_via_arel_table(table_name, column_name)
35
- else
36
- if pool.respond_to?(:pool_config)
37
- if pool.pool_config.respond_to?(:schema_reflection) # activerecord >= 7.1
38
- if ActiveRecord.version >= Gem::Version.create('7.2')
39
- pool.pool_config.schema_reflection.columns_hash(pool, table_name)[column_name]
40
- else
41
- pool.pool_config.schema_reflection.columns_hash(ActiveRecord::Base.connection, table_name)[column_name]
42
- end
43
- else # activerecord < 7.1
44
- pool.pool_config.schema_cache.columns_hash(table_name)[column_name]
36
+ elsif pool.respond_to?(:pool_config)
37
+ if pool.pool_config.respond_to?(:schema_reflection) # activerecord >= 7.1
38
+ if ActiveRecord.version >= Gem::Version.create('7.2')
39
+ pool.pool_config.schema_reflection.columns_hash(pool, table_name)[column_name]
40
+ else
41
+ pool.pool_config.schema_reflection.columns_hash(ActiveRecord::Base.connection, table_name)[column_name]
45
42
  end
46
- elsif pool.respond_to?(:schema_cache) # activerecord < 6.1
47
- pool.schema_cache.columns_hash(table_name)[column_name]
48
- else # activerecord < 5.0
49
- column_of_via_arel_table(table_name, column_name)
43
+ else # activerecord < 7.1
44
+ pool.pool_config.schema_cache.columns_hash(table_name)[column_name]
50
45
  end
46
+ elsif pool.respond_to?(:schema_cache) # activerecord < 6.1
47
+ pool.schema_cache.columns_hash(table_name)[column_name]
48
+ else # activerecord < 5.0
49
+ column_of_via_arel_table(table_name, column_name)
51
50
  end
52
51
  rescue ActiveRecord::ConnectionNotEstablished
53
52
  column_of_via_arel_table(table_name, column_name)
54
53
  rescue ActiveRecord::StatementInvalid
55
54
  nil
56
- rescue => e
55
+ rescue StandardError => e
57
56
  warn("Warning: Unexpected exception caught while fetching column name for #{table_name}.#{column_name} in `column_of`")
58
57
  warn(e)
59
58
  warn(e.backtrace)
@@ -1,9 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'arel'
2
4
 
3
5
  module ArelExtensions
4
6
  module InsertManager
5
7
  def bulk_insert(cols, data)
6
8
  raise ArgumentError, 'cols must be present' if cols.blank?
9
+
7
10
  columns =
8
11
  case cols.first
9
12
  when Array
@@ -11,7 +14,7 @@ module ArelExtensions
11
14
  when Arel::Attributes::Attribute
12
15
  cols
13
16
  when String, Symbol
14
- cols.map {|c| [@ast.relation[c.first]] }
17
+ cols.map { |c| [@ast.relation[c.first]] }
15
18
  else
16
19
  raise ArgumentError, "cols has an invalid type: #{cols.first.first.class}"
17
20
  end
@@ -28,6 +31,7 @@ module ArelExtensions
28
31
  attr_accessor :left, :cols
29
32
 
30
33
  def initialize(cols, values)
34
+ super()
31
35
  @left = values
32
36
  @cols = cols
33
37
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'arel_extensions/nodes'
2
4
  require 'arel_extensions/nodes/function'
3
5
  require 'arel_extensions/nodes/concat'
@@ -17,48 +19,46 @@ module ArelExtensions
17
19
  def +(other)
18
20
  case self
19
21
  when Arel::Nodes::Quoted
20
- self.concat(other)
22
+ concat(other)
21
23
  when Arel::Nodes::Grouping
22
- if self.expr.left.is_a?(String) || self.expr.right.is_a?(String)
23
- self.concat(other)
24
+ if expr.left.is_a?(String) || expr.right.is_a?(String)
25
+ concat(other)
24
26
  else
25
- Arel.grouping(Arel::Nodes::Addition.new self, other)
27
+ Arel.grouping(Arel::Nodes::Addition.new(self, other))
26
28
  end
27
29
  when ArelExtensions::Nodes::Function, ArelExtensions::Nodes::Case
28
- case self.return_type
29
- when :string, :text
30
- self.concat(other)
30
+ case return_type
31
31
  when :integer, :decimal, :float, :number, :int
32
- Arel.grouping(Arel::Nodes::Addition.new self, other)
32
+ Arel.grouping(Arel::Nodes::Addition.new(self, other))
33
33
  when :date, :datetime
34
34
  ArelExtensions::Nodes::DateAdd.new [self, other]
35
35
  else
36
- self.concat(other)
36
+ concat(other)
37
37
  end
38
38
  when Arel::Nodes::Function
39
- Arel.grouping(Arel::Nodes::Addition.new self, other)
39
+ Arel.grouping(Arel::Nodes::Addition.new(self, other))
40
40
  else
41
41
  col =
42
- if self.is_a?(Arel::Attribute) && self.respond_to?(:type_caster) && self.able_to_type_cast?
43
- self.type_caster
44
- else
45
- Arel.column_of(self.relation.table_name, self.name.to_s) if self.respond_to?(:relation)
42
+ if is_a?(Arel::Attribute) && respond_to?(:type_caster) && able_to_type_cast?
43
+ type_caster
44
+ elsif respond_to?(:relation)
45
+ Arel.column_of(relation.table_name, name.to_s)
46
46
  end
47
- if !col # if the column doesn't exist in the database
48
- Arel.grouping(Arel::Nodes::Addition.new(self, Arel.quoted(other)))
49
- else
47
+ if col
50
48
  arg = col.type
51
49
  if arg == :integer || !arg
52
50
  other = other.to_i if other.is_a?(String)
53
- Arel.grouping(Arel::Nodes::Addition.new self, Arel.quoted(other))
54
- elsif arg == :decimal || arg == :float
51
+ Arel.grouping(Arel::Nodes::Addition.new(self, Arel.quoted(other)))
52
+ elsif %i[decimal float].include?(arg)
55
53
  other = Arel.sql(other) if other.is_a?(String) # Arel should accept Float & BigDecimal!
56
- Arel.grouping(Arel::Nodes::Addition.new self, Arel.quoted(other))
57
- elsif arg == :datetime || arg == :date
54
+ Arel.grouping(Arel::Nodes::Addition.new(self, Arel.quoted(other)))
55
+ elsif %i[datetime date].include?(arg)
58
56
  ArelExtensions::Nodes::DateAdd.new [self, other]
59
- elsif arg == :string || arg == :text
60
- self.concat(other)
57
+ elsif %i[string text].include?(arg)
58
+ concat(other)
61
59
  end
60
+ else
61
+ Arel.grouping(Arel::Nodes::Addition.new(self, Arel.quoted(other)))
62
62
  end
63
63
  end
64
64
  end
@@ -68,17 +68,13 @@ module ArelExtensions
68
68
  def -(other)
69
69
  case self
70
70
  when Arel::Nodes::Grouping
71
- if self.expr.left.is_a?(Date) || self.expr.left.is_a?(DateTime)
72
- Arel.grouping(ArelExtensions::Nodes::DateSub.new [self, Arel.quoted(other)])
71
+ if expr.left.is_a?(Date) || expr.left.is_a?(DateTime)
72
+ Arel.grouping(ArelExtensions::Nodes::DateSub.new([self, Arel.quoted(other)]))
73
73
  else
74
74
  Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.quoted(other)))
75
75
  end
76
76
  when ArelExtensions::Nodes::Function, ArelExtensions::Nodes::Case
77
- case self.return_type
78
- when :string, :text # ???
79
- Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.quoted(other))) # ??
80
- when :integer, :decimal, :float, :number
81
- Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.quoted(other)))
77
+ case return_type
82
78
  when :date, :datetime
83
79
  ArelExtensions::Nodes::DateSub.new [self, Arel.quoted(other)]
84
80
  else
@@ -88,33 +84,31 @@ module ArelExtensions
88
84
  Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.quoted(other)))
89
85
  else
90
86
  col =
91
- if self.is_a?(Arel::Attribute) && self.respond_to?(:type_caster) && self.able_to_type_cast?
92
- self.type_caster
93
- else
94
- Arel.column_of(self.relation.table_name, self.name.to_s) if self.respond_to?(:relation)
87
+ if is_a?(Arel::Attribute) && respond_to?(:type_caster) && able_to_type_cast?
88
+ type_caster
89
+ elsif respond_to?(:relation)
90
+ Arel.column_of(relation.table_name, name.to_s)
95
91
  end
96
- if !col # if the column doesn't exist in the database
97
- Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.quoted(other)))
98
- else
92
+ if col
99
93
  arg = col.type
100
- if (arg == :date || arg == :datetime)
94
+ if %i[date datetime].include?(arg)
101
95
  case other
102
96
  when Arel::Attributes::Attribute
103
97
  col2 =
104
98
  if other.is_a?(Arel::Attribute) && other.respond_to?(:type_caster) && other.able_to_type_cast?
105
99
  other.type_caster
106
- else
107
- Arel.column_of(other.relation.table_name, other.name.to_s) if other.respond_to?(:relation)
100
+ elsif other.respond_to?(:relation)
101
+ Arel.column_of(other.relation.table_name, other.name.to_s)
108
102
  end
109
- if !col2 # if the column doesn't exist in the database
110
- ArelExtensions::Nodes::DateSub.new [self, other]
111
- else
103
+ if col2
112
104
  arg2 = col2.type
113
- if arg2 == :date || arg2 == :datetime
105
+ if %i[date datetime].include?(arg2)
114
106
  ArelExtensions::Nodes::DateDiff.new [self, other]
115
107
  else
116
108
  ArelExtensions::Nodes::DateSub.new [self, other]
117
109
  end
110
+ else
111
+ ArelExtensions::Nodes::DateSub.new [self, other]
118
112
  end
119
113
  when Arel::Nodes::Node, DateTime, Time, String, Date
120
114
  ArelExtensions::Nodes::DateDiff.new [self, other]
@@ -133,6 +127,8 @@ module ArelExtensions
133
127
  Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.quoted(other)))
134
128
  end
135
129
  end
130
+ else
131
+ Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.quoted(other)))
136
132
  end
137
133
  end
138
134
  end
@@ -12,22 +12,22 @@ require 'arel_extensions/nodes/sum'
12
12
  module ArelExtensions
13
13
  module MathFunctions
14
14
  # Arel does not handle Decimal literal properly
15
- def * other
15
+ def *(other)
16
16
  case other
17
17
  when Float, BigDecimal
18
18
  super(Arel.quoted(other))
19
19
  else
20
- super(other)
20
+ super
21
21
  end
22
22
  end
23
23
 
24
24
  # Arel does not handle Decimal literal properly
25
- def / other
25
+ def /(other)
26
26
  case other
27
27
  when Float, BigDecimal
28
28
  super(Arel.quoted(other))
29
29
  else
30
- super(other)
30
+ super
31
31
  end
32
32
  end
33
33
 
@@ -52,26 +52,26 @@ module ArelExtensions
52
52
  end
53
53
 
54
54
  # function gives the power of a number
55
- def pow exposant = 0
55
+ def pow(exposant = 0)
56
56
  ArelExtensions::Nodes::Power.new [self, exposant]
57
57
  end
58
58
 
59
59
  # function gives the power of a number
60
- def power exposant = 0
60
+ def power(exposant = 0)
61
61
  ArelExtensions::Nodes::Power.new [self, exposant]
62
62
  end
63
63
 
64
64
  # Aggregate Functions
65
- def std opts = {unbiased: true}
65
+ def std(opts = {unbiased: true})
66
66
  ArelExtensions::Nodes::Std.new self, **opts
67
67
  end
68
68
 
69
- def variance opts = {unbiased: true}
69
+ def variance(opts = {unbiased: true})
70
70
  ArelExtensions::Nodes::Variance.new self, **opts
71
71
  end
72
72
 
73
- def sum opts = {unbiased: true}
74
- if Gem::Version.new(Arel::VERSION) >= Gem::Version.new('9.0.0')
73
+ def sum(opts = {unbiased: true})
74
+ if AREL_VERSION >= V9_0
75
75
  Arel::Nodes::Sum.new [self]
76
76
  else
77
77
  ArelExtensions::Nodes::Sum.new self, **opts
@@ -82,10 +82,10 @@ module ArelExtensions
82
82
  # def rand seed = nil
83
83
  # ArelExtensions::Nodes::Rand.new [seed]
84
84
  # end
85
- alias_method(:random, :rand) rescue nil
85
+ alias random rand rescue nil
86
86
 
87
87
  # function is used to round a numeric field to the number of decimals specified
88
- def round precision = nil
88
+ def round(precision = nil)
89
89
  if precision
90
90
  ArelExtensions::Nodes::Round.new [self, precision]
91
91
  else
@@ -94,25 +94,23 @@ module ArelExtensions
94
94
  end
95
95
 
96
96
  # function returning a number at a specific format
97
- def format_number format_string, locale = nil
98
- begin
99
- sprintf(format_string, 0) # this line is to get the right error message if the format_string is not correct
100
- m = /^(.*)%([ #+\-0]*)([1-9][0-9]+|[1-9]?)[.]?([0-9]*)([a-zA-Z])(.*)$/.match(format_string)
101
- opts = {
102
- prefix: m[1],
103
- flags: m[2].split(//).uniq.join,
104
- width: m[3].to_i,
105
- precision: m[4] != '' ? m[4].to_i : 6,
106
- type: m[5],
107
- suffix: m[6],
108
- locale: locale,
109
- original_string: format_string
110
- }
111
- # opts = {locale: 'fr_FR', type: "e"/"f"/"d", prefix: "$ ", suffix: " %", flags: " +-#0", width: 5, precision: 6}
112
- ArelExtensions::Nodes::FormattedNumber.new [self, opts]
113
- rescue Exception
114
- Arel.quoted('Wrong Format')
115
- end
97
+ def format_number(format_string, locale = nil)
98
+ format(format_string, 0) # this line is to get the right error message if the format_string is not correct
99
+ m = /^(.*)%([ #+\-0]*)([1-9][0-9]+|[1-9]?)[.]?([0-9]*)([a-zA-Z])(.*)$/.match(format_string)
100
+ opts = {
101
+ prefix: m[1],
102
+ flags: m[2].split('').uniq.join,
103
+ width: m[3].to_i,
104
+ precision: m[4] == '' ? 6 : m[4].to_i,
105
+ type: m[5],
106
+ suffix: m[6],
107
+ locale: locale,
108
+ original_string: format_string
109
+ }
110
+ # opts = {locale: 'fr_FR', type: "e"/"f"/"d", prefix: "$ ", suffix: " %", flags: " +-#0", width: 5, precision: 6}
111
+ ArelExtensions::Nodes::FormattedNumber.new [self, opts]
112
+ rescue Exception
113
+ Arel.quoted('Wrong Format')
116
114
  end
117
115
  end
118
116
  end
@@ -3,10 +3,10 @@ module ArelExtensions
3
3
  class AggregateFunction < Function
4
4
  attr_accessor :order, :group
5
5
 
6
- def initialize node, **opts
7
- @order = Array.wrap(opts[:order]).map{|e| convert_to_node(e)}
8
- @group = Array.wrap(opts[:group]).map{|e| convert_to_node(e)}
9
- super [node]
6
+ def initialize(node, **opts)
7
+ @order = Array.wrap(opts[:order]).map { |e| convert_to_node(e) }
8
+ @group = Array.wrap(opts[:group]).map { |e| convert_to_node(e) }
9
+ super([node])
10
10
  end
11
11
  end
12
12
  end
@@ -4,19 +4,21 @@ module ArelExtensions
4
4
  module Nodes
5
5
  class Blank < Arel::Nodes::Unary
6
6
  include ArelExtensions::BooleanFunctions
7
+
7
8
  RETURN_TYPE = :boolean
8
9
 
9
- def initialize expr
10
- super expr.first
10
+ def initialize(expr)
11
+ super(expr.first)
11
12
  end
12
13
  end
13
14
 
14
15
  class NotBlank < Arel::Nodes::Unary
15
16
  include ArelExtensions::BooleanFunctions
17
+
16
18
  RETURN_TYPE = :boolean
17
19
 
18
- def initialize expr
19
- super expr.first
20
+ def initialize(expr)
21
+ super(expr.first)
20
22
  end
21
23
  end
22
24
  end
@@ -0,0 +1,11 @@
1
+ module ArelExtensions
2
+ module Nodes
3
+ class ByteSize < Function
4
+ RETURN_TYPE = :integer
5
+
6
+ def initialize(node)
7
+ super([node])
8
+ end
9
+ end
10
+ end
11
+ end
@@ -1,14 +1,15 @@
1
1
  module ArelExtensions
2
2
  module Nodes
3
- if Gem::Version.new(Arel::VERSION) < Gem::Version.new('7.1.0')
3
+ if AREL_VERSION < V7_1
4
4
  class Case < Arel::Nodes::Node
5
5
  include Arel::Expressions
6
6
  include Arel::Math
7
7
  include Arel::Predications
8
8
  include Arel::OrderPredications
9
+
9
10
  attr_accessor :case, :conditions, :default
10
11
 
11
- def initialize expression = nil, default = nil
12
+ def initialize(expression = nil, default = nil)
12
13
  @case = expression
13
14
  @conditions = []
14
15
  @default = default
@@ -24,6 +25,7 @@ module ArelExtensions
24
25
  class Case < Arel::Nodes::Case
25
26
  class When < Arel::Nodes::When # :nodoc:
26
27
  end
28
+
27
29
  class Else < Arel::Nodes::Else # :nodoc:
28
30
  end
29
31
  end
@@ -44,8 +46,9 @@ module ArelExtensions
44
46
  include ArelExtensions::StringFunctions
45
47
 
46
48
  def return_type
47
- obj = if @conditions.length > 0
48
- @conditions.last.right
49
+ obj =
50
+ if @conditions.length > 0
51
+ @conditions.last.right
49
52
  elsif @default
50
53
  @default.expr
51
54
  end
@@ -65,22 +68,22 @@ module ArelExtensions
65
68
  end
66
69
  end
67
70
 
68
- def when condition, expression = nil
71
+ def when(condition, expression = nil)
69
72
  @conditions << Case::When.new(condition, expression)
70
73
  self
71
74
  end
72
75
 
73
- def then expression
76
+ def then(expression)
74
77
  @conditions.last.right = expression
75
78
  self
76
79
  end
77
80
 
78
- def else expression
81
+ def else(expression)
79
82
  @default = Case::Else.new expression
80
83
  self
81
84
  end
82
85
 
83
- def initialize_copy other
86
+ def initialize_copy(other)
84
87
  super
85
88
  @case = @case.clone if @case
86
89
  @conditions = @conditions.map { |x| x.clone }
@@ -91,15 +94,15 @@ module ArelExtensions
91
94
  [@case, @conditions, @default].hash
92
95
  end
93
96
 
94
- def eql? other
97
+ def eql?(other)
95
98
  self.class == other.class &&
96
99
  self.case == other.case &&
97
- self.conditions == other.conditions &&
98
- self.default == other.default
100
+ conditions == other.conditions &&
101
+ default == other.default
99
102
  end
100
- alias :== :eql?
103
+ alias == eql?
101
104
 
102
- def as other
105
+ def as(other)
103
106
  Arel::Nodes::As.new self, Arel.sql(other)
104
107
  end
105
108
  end
@@ -5,7 +5,7 @@ module ArelExtensions
5
5
 
6
6
  attr_accessor :as_attr
7
7
 
8
- def initialize expr
8
+ def initialize(expr)
9
9
  @as_attr = expr[1]
10
10
  case expr[1]
11
11
  when :int, 'bigint', 'int', 'smallint', 'tinyint', 'bit'
@@ -42,13 +42,11 @@ module ArelExtensions
42
42
  when :ruby_time
43
43
  ArelExtensions::Nodes::DateAdd.new [self, other]
44
44
  else
45
- Arel.grouping(Arel::Nodes::Addition.new self, other)
45
+ Arel.grouping(Arel::Nodes::Addition.new(self, other))
46
46
  end
47
47
  end
48
48
 
49
- def return_type
50
- @return_type
51
- end
49
+ attr_reader :return_type
52
50
  end
53
51
  end
54
52
  end