arel_extensions 2.0.21 → 2.2.2

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 (138) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +1 -2
  3. data/.github/workflows/publish.yml +29 -0
  4. data/.github/workflows/release.yml +30 -0
  5. data/.github/workflows/ruby.yml +377 -80
  6. data/.gitignore +7 -6
  7. data/.rubocop.yml +62 -1
  8. data/CONTRIBUTING.md +102 -0
  9. data/Gemfile +2 -23
  10. data/NEWS.md +89 -0
  11. data/README.md +228 -84
  12. data/Rakefile +11 -4
  13. data/TODO +0 -1
  14. data/appveyor.yml +60 -22
  15. data/arel_extensions.gemspec +11 -12
  16. data/bin/build +15 -0
  17. data/bin/compose +6 -0
  18. data/bin/publish +8 -0
  19. data/dev/arelx.dockerfile +44 -0
  20. data/dev/compose.yaml +71 -0
  21. data/dev/postgres.dockerfile +5 -0
  22. data/dev/rbenv +189 -0
  23. data/gemfiles/rails3.gemfile +10 -10
  24. data/gemfiles/rails4_2.gemfile +38 -0
  25. data/gemfiles/rails5.gemfile +29 -0
  26. data/gemfiles/rails5_1_4.gemfile +13 -13
  27. data/gemfiles/rails5_2.gemfile +16 -14
  28. data/gemfiles/rails6.gemfile +18 -15
  29. data/gemfiles/rails6_1.gemfile +18 -15
  30. data/gemfiles/rails7.gemfile +33 -0
  31. data/gemfiles/rails7_1.gemfile +33 -0
  32. data/gemfiles/rails7_2.gemfile +33 -0
  33. data/gemspecs/arel_extensions-v1.gemspec +12 -13
  34. data/gemspecs/arel_extensions-v2.gemspec +11 -12
  35. data/init/mssql.sql +0 -0
  36. data/init/mysql.sql +0 -0
  37. data/init/oracle.sql +0 -0
  38. data/init/postgresql.sql +0 -0
  39. data/init/sqlite.sql +0 -0
  40. data/lib/arel_extensions/aliases.rb +14 -0
  41. data/lib/arel_extensions/attributes.rb +10 -2
  42. data/lib/arel_extensions/boolean_functions.rb +2 -4
  43. data/lib/arel_extensions/common_sql_functions.rb +12 -12
  44. data/lib/arel_extensions/comparators.rb +14 -14
  45. data/lib/arel_extensions/date_duration.rb +14 -9
  46. data/lib/arel_extensions/helpers.rb +62 -0
  47. data/lib/arel_extensions/insert_manager.rb +19 -17
  48. data/lib/arel_extensions/math.rb +48 -45
  49. data/lib/arel_extensions/math_functions.rb +18 -18
  50. data/lib/arel_extensions/nodes/abs.rb +0 -0
  51. data/lib/arel_extensions/nodes/aggregate_function.rb +0 -0
  52. data/lib/arel_extensions/nodes/blank.rb +1 -1
  53. data/lib/arel_extensions/nodes/case.rb +10 -12
  54. data/lib/arel_extensions/nodes/cast.rb +6 -6
  55. data/lib/arel_extensions/nodes/ceil.rb +0 -0
  56. data/lib/arel_extensions/nodes/change_case.rb +0 -0
  57. data/lib/arel_extensions/nodes/coalesce.rb +1 -1
  58. data/lib/arel_extensions/nodes/collate.rb +9 -9
  59. data/lib/arel_extensions/nodes/concat.rb +2 -2
  60. data/lib/arel_extensions/nodes/date_diff.rb +33 -14
  61. data/lib/arel_extensions/nodes/duration.rb +0 -0
  62. data/lib/arel_extensions/nodes/find_in_set.rb +0 -0
  63. data/lib/arel_extensions/nodes/floor.rb +0 -0
  64. data/lib/arel_extensions/nodes/format.rb +3 -2
  65. data/lib/arel_extensions/nodes/formatted_date.rb +42 -0
  66. data/lib/arel_extensions/nodes/formatted_number.rb +2 -2
  67. data/lib/arel_extensions/nodes/function.rb +22 -26
  68. data/lib/arel_extensions/nodes/is_null.rb +0 -0
  69. data/lib/arel_extensions/nodes/json.rb +15 -9
  70. data/lib/arel_extensions/nodes/length.rb +6 -0
  71. data/lib/arel_extensions/nodes/levenshtein_distance.rb +1 -1
  72. data/lib/arel_extensions/nodes/locate.rb +1 -1
  73. data/lib/arel_extensions/nodes/log10.rb +0 -0
  74. data/lib/arel_extensions/nodes/matches.rb +1 -1
  75. data/lib/arel_extensions/nodes/md5.rb +0 -0
  76. data/lib/arel_extensions/nodes/power.rb +0 -0
  77. data/lib/arel_extensions/nodes/rand.rb +0 -0
  78. data/lib/arel_extensions/nodes/repeat.rb +2 -2
  79. data/lib/arel_extensions/nodes/replace.rb +2 -10
  80. data/lib/arel_extensions/nodes/rollup.rb +36 -0
  81. data/lib/arel_extensions/nodes/round.rb +0 -0
  82. data/lib/arel_extensions/nodes/select.rb +10 -0
  83. data/lib/arel_extensions/nodes/soundex.rb +2 -2
  84. data/lib/arel_extensions/nodes/std.rb +0 -0
  85. data/lib/arel_extensions/nodes/substring.rb +1 -1
  86. data/lib/arel_extensions/nodes/sum.rb +0 -0
  87. data/lib/arel_extensions/nodes/then.rb +1 -1
  88. data/lib/arel_extensions/nodes/trim.rb +2 -2
  89. data/lib/arel_extensions/nodes/union.rb +5 -5
  90. data/lib/arel_extensions/nodes/union_all.rb +4 -4
  91. data/lib/arel_extensions/nodes/wday.rb +0 -0
  92. data/lib/arel_extensions/nodes.rb +0 -0
  93. data/lib/arel_extensions/null_functions.rb +16 -0
  94. data/lib/arel_extensions/predications.rb +10 -10
  95. data/lib/arel_extensions/railtie.rb +1 -1
  96. data/lib/arel_extensions/set_functions.rb +3 -3
  97. data/lib/arel_extensions/string_functions.rb +19 -10
  98. data/lib/arel_extensions/tasks.rb +2 -2
  99. data/lib/arel_extensions/version.rb +1 -1
  100. data/lib/arel_extensions/visitors/convert_format.rb +0 -0
  101. data/lib/arel_extensions/visitors/ibm_db.rb +20 -20
  102. data/lib/arel_extensions/visitors/mssql.rb +394 -169
  103. data/lib/arel_extensions/visitors/mysql.rb +238 -151
  104. data/lib/arel_extensions/visitors/oracle.rb +170 -131
  105. data/lib/arel_extensions/visitors/oracle12.rb +16 -16
  106. data/lib/arel_extensions/visitors/postgresql.rb +170 -140
  107. data/lib/arel_extensions/visitors/sqlite.rb +88 -87
  108. data/lib/arel_extensions/visitors/to_sql.rb +185 -156
  109. data/lib/arel_extensions/visitors.rb +73 -60
  110. data/lib/arel_extensions.rb +173 -36
  111. data/test/arelx_test_helper.rb +49 -1
  112. data/test/database.yml +13 -7
  113. data/test/real_db_test.rb +101 -83
  114. data/test/support/fake_record.rb +8 -2
  115. data/test/test_comparators.rb +5 -5
  116. data/test/visitors/test_bulk_insert_oracle.rb +5 -5
  117. data/test/visitors/test_bulk_insert_sqlite.rb +5 -5
  118. data/test/visitors/test_bulk_insert_to_sql.rb +5 -5
  119. data/test/visitors/test_oracle.rb +14 -14
  120. data/test/visitors/test_to_sql.rb +121 -93
  121. data/test/with_ar/all_agnostic_test.rb +630 -320
  122. data/test/with_ar/insert_agnostic_test.rb +25 -18
  123. data/test/with_ar/test_bulk_sqlite.rb +11 -7
  124. data/test/with_ar/test_math_sqlite.rb +18 -14
  125. data/test/with_ar/test_string_mysql.rb +26 -22
  126. data/test/with_ar/test_string_sqlite.rb +26 -22
  127. data/version_v1.rb +1 -1
  128. data/version_v2.rb +1 -1
  129. metadata +24 -26
  130. data/.travis/oracle/download.js +0 -152
  131. data/.travis/oracle/download.sh +0 -30
  132. data/.travis/oracle/download_ojdbc.js +0 -116
  133. data/.travis/oracle/install.sh +0 -34
  134. data/.travis/setup_accounts.sh +0 -9
  135. data/.travis/sqlite3/extension-functions.sh +0 -6
  136. data/.travis.yml +0 -193
  137. data/gemfiles/rails4.gemfile +0 -29
  138. data/gemfiles/rails5_0.gemfile +0 -29
@@ -16,43 +16,44 @@ module ArelExtensions
16
16
  # Date and integer adds or subtracts a specified time interval from a date.
17
17
  def +(other)
18
18
  case self
19
- when Arel::Nodes::Quoted
20
- return self.concat(other)
21
- when Arel::Nodes::Grouping
22
- if self.expr.left.is_a?(String) || self.expr.right.is_a?(String)
23
- return self.concat(other)
24
- else
25
- return Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new self, other)
26
- end
27
- when ArelExtensions::Nodes::Function,ArelExtensions::Nodes::Case
28
- return case self.return_type
19
+ when Arel::Nodes::Quoted
20
+ self.concat(other)
21
+ when Arel::Nodes::Grouping
22
+ if self.expr.left.is_a?(String) || self.expr.right.is_a?(String)
23
+ self.concat(other)
24
+ else
25
+ Arel.grouping(Arel::Nodes::Addition.new self, other)
26
+ end
27
+ when ArelExtensions::Nodes::Function, ArelExtensions::Nodes::Case
28
+ case self.return_type
29
29
  when :string, :text
30
30
  self.concat(other)
31
31
  when :integer, :decimal, :float, :number, :int
32
- Arel::Nodes::Grouping.new(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
36
  self.concat(other)
37
37
  end
38
38
  when Arel::Nodes::Function
39
- Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new self, other)
39
+ Arel.grouping(Arel::Nodes::Addition.new self, other)
40
40
  else
41
- begin
42
- col = Arel::Table.engine.connection.schema_cache.columns_hash(self.relation.table_name)[self.name.to_s]
43
- rescue Exception
44
- col = nil
45
- end
46
- if (!col) # if the column doesn't exist in the database
47
- Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new(self, other))
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)
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)))
48
49
  else
49
50
  arg = col.type
50
- if arg == :integer || (!arg)
51
+ if arg == :integer || !arg
51
52
  other = other.to_i if other.is_a?(String)
52
- Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new self, other)
53
+ Arel.grouping(Arel::Nodes::Addition.new self, Arel.quoted(other))
53
54
  elsif arg == :decimal || arg == :float
54
55
  other = Arel.sql(other) if other.is_a?(String) # Arel should accept Float & BigDecimal!
55
- Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new self, other)
56
+ Arel.grouping(Arel::Nodes::Addition.new self, Arel.quoted(other))
56
57
  elsif arg == :datetime || arg == :date
57
58
  ArelExtensions::Nodes::DateAdd.new [self, other]
58
59
  elsif arg == :string || arg == :text
@@ -68,42 +69,44 @@ module ArelExtensions
68
69
  case self
69
70
  when Arel::Nodes::Grouping
70
71
  if self.expr.left.is_a?(Date) || self.expr.left.is_a?(DateTime)
71
- Arel::Nodes::Grouping.new(ArelExtensions::Nodes::DateSub.new [self, other])
72
+ Arel.grouping(ArelExtensions::Nodes::DateSub.new [self, Arel.quoted(other)])
72
73
  else
73
- Arel::Nodes::Grouping.new(Arel::Nodes::Subtraction.new(self, other))
74
+ Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.quoted(other)))
74
75
  end
75
76
  when ArelExtensions::Nodes::Function, ArelExtensions::Nodes::Case
76
77
  case self.return_type
77
78
  when :string, :text # ???
78
- Arel::Nodes::Grouping.new(Arel::Nodes::Subtraction.new(self, other)) # ??
79
+ Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.quoted(other))) # ??
79
80
  when :integer, :decimal, :float, :number
80
- Arel::Nodes::Grouping.new(Arel::Nodes::Subtraction.new(self, other))
81
+ Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.quoted(other)))
81
82
  when :date, :datetime
82
- ArelExtensions::Nodes::DateSub.new [self, other]
83
+ ArelExtensions::Nodes::DateSub.new [self, Arel.quoted(other)]
83
84
  else
84
- Arel::Nodes::Grouping.new(Arel::Nodes::Subtraction.new(self, other))
85
+ Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.quoted(other)))
85
86
  end
86
87
  when Arel::Nodes::Function
87
- Arel::Nodes::Grouping.new(Arel::Nodes::Subtraction.new(self, other))
88
+ Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.quoted(other)))
88
89
  else
89
- begin
90
- col = Arel::Table.engine.connection.schema_cache.columns_hash(self.relation.table_name)[self.name.to_s]
91
- rescue Exception
92
- col = nil
93
- end
94
- if (!col) # if the column doesn't exist in the database
95
- Arel::Nodes::Grouping.new(Arel::Nodes::Subtraction.new(self, other))
90
+ 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)
95
+ end
96
+ if !col # if the column doesn't exist in the database
97
+ Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.quoted(other)))
96
98
  else
97
99
  arg = col.type
98
100
  if (arg == :date || arg == :datetime)
99
101
  case other
100
102
  when Arel::Attributes::Attribute
101
- begin
102
- col2 = Arel::Table.engine.connection.schema_cache.columns_hash(other.relation.table_name)[other.name.to_s]
103
- rescue Exception
104
- col2 = nil
105
- end
106
- if (!col2) # if the column doesn't exist in the database
103
+ col2 =
104
+ if other.is_a?(Arel::Attribute) && other.respond_to?(:type_caster) && other.able_to_type_cast?
105
+ other.type_caster
106
+ else
107
+ Arel.column_of(other.relation.table_name, other.name.to_s) if other.respond_to?(:relation)
108
+ end
109
+ if !col2 # if the column doesn't exist in the database
107
110
  ArelExtensions::Nodes::DateSub.new [self, other]
108
111
  else
109
112
  arg2 = col2.type
@@ -123,11 +126,11 @@ module ArelExtensions
123
126
  else
124
127
  case other
125
128
  when Integer, Float, BigDecimal
126
- Arel::Nodes::Grouping.new(Arel::Nodes::Subtraction.new(self, Arel.sql(other.to_s)))
129
+ Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.sql(other.to_s)))
127
130
  when String
128
- Arel::Nodes::Grouping.new(Arel::Nodes::Subtraction.new(self, Arel.sql(other)))
131
+ Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.sql(other)))
129
132
  else
130
- Arel::Nodes::Grouping.new(Arel::Nodes::Subtraction.new(self, other))
133
+ Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.quoted(other)))
131
134
  end
132
135
  end
133
136
  end
@@ -15,7 +15,7 @@ module ArelExtensions
15
15
  def * other
16
16
  case other
17
17
  when Float, BigDecimal
18
- super(Arel::Nodes.build_quoted(other))
18
+ super(Arel.quoted(other))
19
19
  else
20
20
  super(other)
21
21
  end
@@ -25,7 +25,7 @@ module ArelExtensions
25
25
  def / other
26
26
  case other
27
27
  when Float, BigDecimal
28
- super(Arel::Nodes.build_quoted(other))
28
+ super(Arel.quoted(other))
29
29
  else
30
30
  super(other)
31
31
  end
@@ -33,32 +33,32 @@ module ArelExtensions
33
33
 
34
34
  # Abs function returns the absolute value of a number passed as argument #
35
35
  def abs
36
- ArelExtensions::Nodes::Abs.new [self]
36
+ ArelExtensions::Nodes::Abs.new [self]
37
37
  end
38
38
 
39
39
  # will rounded up any positive or negative decimal value within the function upwards #
40
40
  def ceil
41
- ArelExtensions::Nodes::Ceil.new [self]
41
+ ArelExtensions::Nodes::Ceil.new [self]
42
42
  end
43
43
 
44
44
  # function rounded up any positive or negative decimal value down to the next least integer
45
45
  def floor
46
- ArelExtensions::Nodes::Floor.new [self]
46
+ ArelExtensions::Nodes::Floor.new [self]
47
47
  end
48
48
 
49
49
  # function gives the base 10 log
50
50
  def log10
51
- ArelExtensions::Nodes::Log10.new [self]
51
+ ArelExtensions::Nodes::Log10.new [self]
52
52
  end
53
53
 
54
54
  # function gives the power of a number
55
55
  def pow exposant = 0
56
- ArelExtensions::Nodes::Power.new [self,exposant]
56
+ ArelExtensions::Nodes::Power.new [self, exposant]
57
57
  end
58
58
 
59
59
  # function gives the power of a number
60
60
  def power exposant = 0
61
- ArelExtensions::Nodes::Power.new [self,exposant]
61
+ ArelExtensions::Nodes::Power.new [self, exposant]
62
62
  end
63
63
 
64
64
  # Aggregate Functions
@@ -71,7 +71,7 @@ module ArelExtensions
71
71
  end
72
72
 
73
73
  def sum opts = {unbiased: true}
74
- if Gem::Version.new(Arel::VERSION) >= Gem::Version.new("9.0.0")
74
+ if Gem::Version.new(Arel::VERSION) >= Gem::Version.new('9.0.0')
75
75
  Arel::Nodes::Sum.new [self]
76
76
  else
77
77
  ArelExtensions::Nodes::Sum.new self, **opts
@@ -86,17 +86,17 @@ module ArelExtensions
86
86
 
87
87
  # function is used to round a numeric field to the number of decimals specified
88
88
  def round precision = nil
89
- if precision
90
- ArelExtensions::Nodes::Round.new [self, precision]
91
- else
92
- ArelExtensions::Nodes::Round.new [self]
93
- end
89
+ if precision
90
+ ArelExtensions::Nodes::Round.new [self, precision]
91
+ else
92
+ ArelExtensions::Nodes::Round.new [self]
93
+ end
94
94
  end
95
95
 
96
96
  # function returning a number at a specific format
97
97
  def format_number format_string, locale = nil
98
98
  begin
99
- sprintf(format_string,0) # this line is to get the right error message if the format_string is not correct
99
+ sprintf(format_string, 0) # this line is to get the right error message if the format_string is not correct
100
100
  m = /^(.*)%([ #+\-0]*)([1-9][0-9]+|[1-9]?)[.]?([0-9]*)([a-zA-Z])(.*)$/.match(format_string)
101
101
  opts = {
102
102
  prefix: m[1],
@@ -108,10 +108,10 @@ module ArelExtensions
108
108
  locale: locale,
109
109
  original_string: format_string
110
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]
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
113
  rescue Exception
114
- Arel::Nodes.build_quoted('Wrong Format')
114
+ Arel.quoted('Wrong Format')
115
115
  end
116
116
  end
117
117
  end
File without changes
File without changes
@@ -16,7 +16,7 @@ module ArelExtensions
16
16
  RETURN_TYPE = :boolean
17
17
 
18
18
  def initialize expr
19
- super expr.first
19
+ super expr.first
20
20
  end
21
21
  end
22
22
  end
@@ -1,6 +1,6 @@
1
1
  module ArelExtensions
2
2
  module Nodes
3
- if Gem::Version.new(Arel::VERSION) < Gem::Version.new("7.1.0")
3
+ if Gem::Version.new(Arel::VERSION) < Gem::Version.new('7.1.0')
4
4
  class Case < Arel::Nodes::Node
5
5
  include Arel::Expressions
6
6
  include Arel::Math
@@ -34,16 +34,18 @@ module ArelExtensions
34
34
  include Arel::Math
35
35
  include Arel::Predications
36
36
  include Arel::OrderPredications
37
- include ArelExtensions::Math
37
+ include ArelExtensions::Aliases
38
38
  include ArelExtensions::Comparators
39
- include ArelExtensions::Predications
39
+ include ArelExtensions::DateDuration
40
+ include ArelExtensions::Math
40
41
  include ArelExtensions::MathFunctions
41
- include ArelExtensions::StringFunctions
42
42
  include ArelExtensions::NullFunctions
43
+ include ArelExtensions::Predications
44
+ include ArelExtensions::StringFunctions
43
45
 
44
46
  def return_type
45
47
  obj = if @conditions.length > 0
46
- @conditions.last.right
48
+ @conditions.last.right
47
49
  elsif @default
48
50
  @default.expr
49
51
  end
@@ -53,14 +55,10 @@ module ArelExtensions
53
55
  case obj
54
56
  when Integer, Float
55
57
  :number
56
- when Date, DateTime,Time
58
+ when Date, DateTime, Time
57
59
  :datetime
58
60
  when Arel::Attributes::Attribute
59
- begin
60
- Arel::Table.engine.connection.schema_cache.columns_hash(obj.relation.table_name)[obj.name.to_s].type
61
- rescue Exception
62
- :string
63
- end
61
+ Arel.column_of(obj.relation.table_name, obj.name.to_s)&.type || :string
64
62
  else
65
63
  :string
66
64
  end
@@ -102,7 +100,7 @@ module ArelExtensions
102
100
  alias :== :eql?
103
101
 
104
102
  def as other
105
- Arel::Nodes::As.new self, Arel::Nodes::SqlLiteral.new(other)
103
+ Arel::Nodes::As.new self, Arel.sql(other)
106
104
  end
107
105
  end
108
106
  end
@@ -19,11 +19,11 @@ module ArelExtensions
19
19
  when 'text', :text, 'ntext', :ntext
20
20
  @as_attr = expr[1].to_sym
21
21
  @return_type = :string
22
- when :datetime, 'datetime','smalldatetime'
22
+ when :datetime, 'datetime', 'smalldatetime'
23
23
  @return_type = :datetime
24
- when :time,'time'
24
+ when :time, 'time'
25
25
  @return_type = :time
26
- when :date,'date'
26
+ when :date, 'date'
27
27
  @return_type = :date
28
28
  when :binary, 'binary', 'varbinary', 'image'
29
29
  @return_type = :binary
@@ -32,17 +32,17 @@ module ArelExtensions
32
32
  @as_attr = :string
33
33
  end
34
34
  tab = [convert_to_node(expr.first)]
35
- return super(tab)
35
+ super(tab)
36
36
  end
37
37
 
38
38
  def +(other)
39
39
  case @return_type
40
40
  when :string
41
- return ArelExtensions::Nodes::Concat.new [self, other]
41
+ ArelExtensions::Nodes::Concat.new [self, other]
42
42
  when :ruby_time
43
43
  ArelExtensions::Nodes::DateAdd.new [self, other]
44
44
  else
45
- Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new self, other)
45
+ Arel.grouping(Arel::Nodes::Addition.new self, other)
46
46
  end
47
47
  end
48
48
 
File without changes
File without changes
@@ -27,7 +27,7 @@ module ArelExtensions
27
27
  when DateTime, Time
28
28
  @left_node_type = :ruby_time
29
29
  end
30
- return super(tab)
30
+ super(tab)
31
31
  end
32
32
  end
33
33
  end
@@ -1,17 +1,17 @@
1
1
  module ArelExtensions
2
2
  module Nodes
3
3
  class Collate < Function
4
- RETURN_TYPE = :string
4
+ RETURN_TYPE = :string
5
5
 
6
- attr_accessor :ai, :ci, :option
6
+ attr_accessor :ai, :ci, :option
7
7
 
8
- def initialize left, option = nil, ai = false, ci = false
9
- @ai = ai
10
- @ci = ci
11
- @option = option
12
- tab = [convert_to_node(left)]
13
- return super(tab)
14
- end
8
+ def initialize left, option = nil, ai = false, ci = false
9
+ @ai = ai
10
+ @ci = ci
11
+ @option = option
12
+ tab = [convert_to_node(left)]
13
+ super(tab)
14
+ end
15
15
  end
16
16
  end
17
17
  end
@@ -13,10 +13,10 @@ module ArelExtensions::Nodes
13
13
  end
14
14
  }.flatten.reduce([]) { |res, b|
15
15
  # concatenate successive literal strings.
16
- if b.is_a?(Arel::Nodes::Quoted) && b.expr == ""
16
+ if b.is_a?(Arel::Nodes::Quoted) && b.expr == ''
17
17
  res
18
18
  elsif res.last && res.last.is_a?(Arel::Nodes::Quoted) && b.is_a?(Arel::Nodes::Quoted)
19
- res[-1] = Arel::Nodes.build_quoted(res.last.expr + b.expr)
19
+ res[-1] = Arel.quoted(res.last.expr.to_s + b.expr.to_s)
20
20
  else
21
21
  res << b
22
22
  end
@@ -19,7 +19,7 @@ module ArelExtensions
19
19
  when DateTime, Time
20
20
  @left_node_type = :ruby_time
21
21
  end
22
- res << ([:date, :ruby_date].include?(@left_node_type) ? convert_to_date_node(col) : convert_to_datetime_node(col))
22
+ res << (%i[date ruby_date].include?(@left_node_type) ? convert_to_date_node(col) : convert_to_datetime_node(col))
23
23
  case expr[1]
24
24
  when Arel::Nodes::Node, Arel::Attributes::Attribute
25
25
  @right_node_type = type_of_attribute(expr[1])
@@ -28,7 +28,7 @@ module ArelExtensions
28
28
  when DateTime, Time
29
29
  @right_node_type = :ruby_time
30
30
  end
31
- res << ([:date, :ruby_date].include?(@left_node_type) ? convert_to_date_node(expr[1]) : convert_to_datetime_node(expr[1]))
31
+ res << (%i[date ruby_date].include?(@left_node_type) ? convert_to_date_node(expr[1]) : convert_to_datetime_node(expr[1]))
32
32
  super res
33
33
  end
34
34
  end
@@ -43,19 +43,19 @@ module ArelExtensions
43
43
  tab = expr.map do |arg|
44
44
  convert(arg)
45
45
  end
46
- return super(tab)
46
+ super(tab)
47
47
  end
48
48
 
49
49
  def sqlite_value
50
50
  v = self.expressions.last
51
51
  if defined?(ActiveSupport::Duration) && ActiveSupport::Duration === v
52
52
  if @date_type == :date
53
- return Arel::Nodes.build_quoted((v.value >= 0 ? '+' : '-') + v.inspect)
53
+ Arel.quoted((v.value >= 0 ? '+' : '-') + v.inspect)
54
54
  elsif @date_type == :datetime
55
- return Arel::Nodes.build_quoted((v.value >= 0 ? '+' : '-') + v.inspect)
55
+ Arel.quoted((v.value >= 0 ? '+' : '-') + v.inspect)
56
56
  end
57
57
  else
58
- return v
58
+ v
59
59
  end
60
60
  end
61
61
 
@@ -115,9 +115,18 @@ module ArelExtensions
115
115
  v ||= self.expressions.last
116
116
  if defined?(ActiveSupport::Duration) && ActiveSupport::Duration === v
117
117
  if @date_type == :date
118
- v.to_i / (24*3600)
118
+ v.to_i / (24 * 3600)
119
119
  elsif @date_type == :datetime
120
- v.to_i
120
+ if v.parts.size == 1
121
+ # first entry in the dict v.parts; one of [:years, :months, :weeks, :days, :hours, :minutes, :seconds]
122
+ # | the value
123
+ # | |
124
+ # | |
125
+ # v v
126
+ v.parts.first.second
127
+ else
128
+ v.to_i
129
+ end
121
130
  end
122
131
  else
123
132
  v
@@ -130,20 +139,30 @@ module ArelExtensions
130
139
  if @date_type == :date
131
140
  Arel.sql('day')
132
141
  elsif @date_type == :datetime
133
- Arel.sql('second')
142
+ res = if v.parts.size == 1
143
+ # first entry in the dict v.parts; one of [:years, :months, :weeks, :days, :hours, :minutes, :seconds]
144
+ # | the key
145
+ # | | convert symbol to string
146
+ # | | | remove the plural suffix `s`
147
+ # v v v v
148
+ v.parts.first.first.to_s[0..-2]
149
+ else
150
+ 'second'
151
+ end
152
+ Arel.sql(res)
134
153
  end
135
154
  else
136
155
  if ArelExtensions::Nodes::Duration === v
137
156
  v.with_interval = true
138
157
  case v.left
139
- when 'd','m','y'
158
+ when 'd', 'm', 'y'
140
159
  Arel.sql('day')
141
- when 'h','mn','s'
160
+ when 'h', 'mn', 's'
142
161
  Arel.sql('second')
143
162
  when /i\z/
144
- Arel.sql(Arel::Visitors::MSSQL::DATE_MAPPING[v.left[0..-2]])
163
+ Arel.sql(ArelExtensions::Visitors::MSSQL::LOADED_VISITOR::DATE_MAPPING[v.left[0..-2]])
145
164
  else
146
- Arel.sql(Arel::Visitors::MSSQL::DATE_MAPPING[v.left])
165
+ Arel.sql(ArelExtensions::Visitors::MSSQL::LOADED_VISITOR::DATE_MAPPING[v.left])
147
166
  end
148
167
  end
149
168
  end
@@ -160,7 +179,7 @@ module ArelExtensions
160
179
  when DateTime, Time, Date
161
180
  raise(ArgumentError, "#{object.class} cannot be converted to Integer")
162
181
  when String
163
- Arel::Nodes.build_quoted(object)
182
+ Arel.quoted(object)
164
183
  else
165
184
  raise(ArgumentError, "#{object.class} cannot be converted to Integer")
166
185
  end
File without changes
File without changes
File without changes
@@ -5,11 +5,12 @@ module ArelExtensions
5
5
  class Format < Function
6
6
  RETURN_TYPE = :string
7
7
 
8
- attr_accessor :col_type, :iso_format
8
+ attr_accessor :col_type, :iso_format, :time_zone
9
9
 
10
10
  def initialize expr
11
- col = expr.first
11
+ col = expr[0]
12
12
  @iso_format = convert_format(expr[1])
13
+ @time_zone = expr[2]
13
14
  @col_type = type_of_attribute(col)
14
15
  super [col, convert_to_string_node(@iso_format)]
15
16
  end
@@ -0,0 +1,42 @@
1
+ require 'strscan'
2
+
3
+ module ArelExtensions
4
+ module Nodes
5
+ class FormattedDate < Function
6
+ RETURN_TYPE = :string
7
+
8
+ attr_accessor :col_type, :iso_format, :time_zone
9
+
10
+ def initialize expr
11
+ col = expr[0]
12
+ @iso_format = convert_format(expr[1])
13
+ @time_zone = expr[2]
14
+ @col_type = type_of_attribute(col)
15
+ super [col, convert_to_string_node(@iso_format)]
16
+ end
17
+
18
+ private
19
+
20
+ # Address portability issues with some of the formats.
21
+ def convert_format(fmt)
22
+ s = StringScanner.new fmt
23
+ res = StringIO.new
24
+ while !s.eos?
25
+ res <<
26
+ case
27
+ when s.scan(/%D/) then '%m/%d/%y'
28
+ when s.scan(/%F/) then '%Y-%m-%d'
29
+ when s.scan(/%R/) then '%H:%M'
30
+ when s.scan(/%r/) then '%I:%M:%S %p'
31
+ when s.scan(/%T/) then '%H:%M:%S'
32
+ when s.scan(/%v/) then '%e-%b-%Y'
33
+
34
+ when s.scan(/[^%]+/) then s.matched
35
+ when s.scan(/./) then s.matched
36
+ end
37
+ end
38
+ res.string
39
+ end
40
+ end
41
+ end
42
+ end
@@ -3,10 +3,10 @@ module ArelExtensions
3
3
  class FormattedNumber < Function
4
4
  RETURN_TYPE = :string
5
5
 
6
- attr_accessor :locale, :prefix, :suffix, :flags, :scientific_notation, :width,:precision, :type, :original_string
6
+ attr_accessor :locale, :prefix, :suffix, :flags, :scientific_notation, :width, :precision, :type, :original_string
7
7
 
8
8
  def initialize expr
9
- # expr[1] = {:locale => 'fr_FR', :type => "e"/"f"/"d", :prefix => "$ ", :suffix => " %", :flags => " +-#0", :width => 5, :precision => 6}
9
+ # expr[1] = {locale: 'fr_FR', type: "e"/"f"/"d", prefix: "$ ", suffix: " %", flags: " +-#0", width: 5, precision: 6}
10
10
  col = expr.first
11
11
  @locale = expr[1][:locale]
12
12
  @prefix = expr[1][:prefix]