arel_extensions 2.1.8 → 2.1.10

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.
@@ -13,11 +13,19 @@ group :development, :test do
13
13
  gem 'pg', '~> 1.1', platforms: [:mri]
14
14
 
15
15
  gem 'tiny_tds', platforms: %i[mri mingw x64_mingw mswin]
16
- gem 'activerecord-sqlserver-adapter', '~> 7.0.0.0', platforms: %i[mri mingw x64_mingw mswin]
16
+ gem 'activerecord-sqlserver-adapter', '~> 7.0.7', platforms: %i[mri mingw x64_mingw mswin]
17
17
  gem 'tzinfo-data', platforms: %i[mingw mswin x64_mingw]
18
18
 
19
19
  gem 'ruby-oci8', platforms: %i[mri mswin mingw] if ENV.has_key? 'ORACLE_HOME'
20
20
  gem 'activerecord-oracle_enhanced-adapter', '~> 6.0.0' if ENV.has_key? 'ORACLE_HOME'
21
+
22
+ # for JRuby
23
+ gem 'jdbc-mssql', platforms: :jruby, require: true
24
+ gem 'jdbc-sqlite3', platform: :jruby
25
+ gem 'activerecord-jdbc-alt-adapter', '~> 70.0', platform: :jruby, require: true
26
+ gem 'activerecord-jdbcmysql-adapter', platforms: :jruby
27
+ gem 'activerecord-jdbcpostgresql-adapter', platforms: :jruby
28
+ gem 'activerecord-jdbcsqlite3-adapter', platforms: :jruby
21
29
  end
22
30
 
23
31
  gemspec path: Dir.pwd
@@ -17,6 +17,14 @@ group :development, :test do
17
17
 
18
18
  gem 'ruby-oci8', platforms: %i[mri mswin mingw] if ENV.has_key? 'ORACLE_HOME'
19
19
  gem 'activerecord-oracle_enhanced-adapter', '~> 7.0.0' if ENV.has_key? 'ORACLE_HOME'
20
+
21
+ # for JRuby
22
+ gem 'jdbc-mssql', platforms: :jruby, require: true
23
+ gem 'jdbc-sqlite3', platform: :jruby
24
+ gem 'activerecord-jdbc-alt-adapter', '~> 71.0.0.alpha1', platform: :jruby, require: true
25
+ gem 'activerecord-jdbcmysql-adapter', platforms: :jruby
26
+ gem 'activerecord-jdbcpostgresql-adapter', platforms: :jruby
27
+ gem 'activerecord-jdbcsqlite3-adapter', platforms: :jruby
20
28
  end
21
29
 
22
30
  gemspec path: Dir.pwd
@@ -1,3 +1,3 @@
1
1
  module ArelExtensions
2
- VERSION = '2.1.8'.freeze
2
+ VERSION = '2.1.10'.freeze
3
3
  end
@@ -2,52 +2,68 @@ module ArelExtensions
2
2
  module Visitors
3
3
  module MSSQL
4
4
 
5
- mssql_class = Arel::Visitors.constants.select { |c|
6
- Arel::Visitors.const_get(c).is_a?(Class) && %i[MSSQL SQLServer].include?(c)
7
- }.first
8
-
9
- LOADED_VISITOR = Arel::Visitors.const_get(mssql_class) || Arel::Visitors.const_get('MSSQL')
10
-
11
- LOADED_VISITOR::DATE_MAPPING = {
12
- 'd' => 'day', 'm' => 'month', 'y' => 'year', 'wd' => 'weekday', 'w' => 'week', 'h' => 'hour', 'mn' => 'minute', 's' => 'second'
13
- }.freeze
14
-
15
- LOADED_VISITOR::DATE_FORMAT_DIRECTIVES = {
16
- '%Y' => 'YYYY', '%C' => '', '%y' => 'YY', '%m' => 'MM', '%B' => 'month', '%^B' => '', '%b' => '', '%^b' => '', # year, month
17
- '%V' => 'iso_week', '%G' => '', # ISO week number and year of week
18
- '%d' => 'DD', '%e' => '' , '%j' => '' , '%w' => 'dw', %'a' => '', '%A' => 'weekday', # day, weekday
19
- '%H' => 'hh', '%k' => '' , '%I' => '' , '%l' => '' , '%P' => '', '%p' => '', # hours
20
- '%M' => 'mi', '%S' => 'ss', '%L' => 'ms', '%N' => 'ns', '%z' => 'tz'
21
- }.freeze
22
-
23
- LOADED_VISITOR::DATE_FORMAT_FORMAT = {
24
- 'YY' => '0#', 'MM' => '0#', 'DD' => '0#', 'hh' => '0#', 'mi' => '0#', 'ss' => '0#', 'iso_week' => '0#'
25
- }
26
-
27
- LOADED_VISITOR::DATE_NAME = [
28
- '%B', '%A'
29
- ]
30
-
31
- LOADED_VISITOR::DATE_FORMAT_REGEX =
32
- Regexp.new(
33
- LOADED_VISITOR::DATE_FORMAT_DIRECTIVES
34
- .keys
35
- .map{|k| Regexp.escape(k)}
36
- .join('|')
37
- ).freeze
38
-
39
- # TODO; all others... http://www.sql-server-helper.com/tips/date-formats.aspx
40
- LOADED_VISITOR::DATE_CONVERT_FORMATS = {
41
- 'YYYY-MM-DD' => 120,
42
- 'YY-MM-DD' => 120,
43
- 'MM/DD/YYYY' => 101,
44
- 'MM-DD-YYYY' => 110,
45
- 'YYYY/MM/DD' => 111,
46
- 'DD-MM-YYYY' => 105,
47
- 'DD-MM-YY' => 5,
48
- 'DD.MM.YYYY' => 104,
49
- 'YYYY-MM-DDTHH:MM:SS:MMM' => 126
50
- }.freeze
5
+ MSSQL_CLASS_NAMES = %i[MSSQL SQLServer].freeze
6
+
7
+ mssql_class =
8
+ Arel::Visitors
9
+ .constants
10
+ .select { |c| Arel::Visitors.const_get(c).is_a?(Class) }
11
+ .find { |c| MSSQL_CLASS_NAMES.include?(c) }
12
+
13
+ # This guard is necessary because:
14
+ #
15
+ # 1. const_get(mssql_class) will fail when mssql_class is nil.
16
+ # 2. mssql_class could be nil under certain conditions:
17
+ # 1. especially on ruby 2.5 (and surprisingly not jruby 9.2) and 3.0+.
18
+ # 2. when not working with mssql itself.
19
+ if mssql_class
20
+ LOADED_VISITOR = Arel::Visitors.const_get(mssql_class)
21
+
22
+ LOADED_VISITOR::DATE_MAPPING = {
23
+ 'd' => 'day', 'm' => 'month', 'y' => 'year',
24
+ 'wd' => 'weekday', 'w' => 'week',
25
+ 'h' => 'hour', 'mn' => 'minute', 's' => 'second'
26
+ }.freeze
27
+
28
+ LOADED_VISITOR::DATE_FORMAT_DIRECTIVES = {
29
+ '%Y' => 'YYYY', '%C' => '', '%y' => 'YY', '%m' => 'MM', '%B' => 'month', '%^B' => '', '%b' => '', '%^b' => '', # year, month
30
+ '%V' => 'iso_week', '%G' => '', # ISO week number and year of week
31
+ '%d' => 'DD', '%e' => '' , '%j' => '' , '%w' => 'dw', %'a' => '', '%A' => 'weekday', # day, weekday
32
+ '%H' => 'hh', '%k' => '' , '%I' => '' , '%l' => '' , '%P' => '', '%p' => '', # hours
33
+ '%M' => 'mi', '%S' => 'ss', '%L' => 'ms', '%N' => 'ns', '%z' => 'tz'
34
+ }.freeze
35
+
36
+ LOADED_VISITOR::DATE_FORMAT_FORMAT = {
37
+ 'YY' => '0#', 'MM' => '0#', 'DD' => '0#',
38
+ 'hh' => '0#', 'mi' => '0#', 'ss' => '0#',
39
+ 'iso_week' => '0#'
40
+ }
41
+
42
+ LOADED_VISITOR::DATE_NAME = [
43
+ '%B', '%A'
44
+ ]
45
+
46
+ LOADED_VISITOR::DATE_FORMAT_REGEX =
47
+ Regexp.new(
48
+ LOADED_VISITOR::DATE_FORMAT_DIRECTIVES
49
+ .keys
50
+ .map{|k| Regexp.escape(k)}
51
+ .join('|')
52
+ ).freeze
53
+
54
+ # TODO; all others... http://www.sql-server-helper.com/tips/date-formats.aspx
55
+ LOADED_VISITOR::DATE_CONVERT_FORMATS = {
56
+ 'YYYY-MM-DD' => 120,
57
+ 'YY-MM-DD' => 120,
58
+ 'MM/DD/YYYY' => 101,
59
+ 'MM-DD-YYYY' => 110,
60
+ 'YYYY/MM/DD' => 111,
61
+ 'DD-MM-YYYY' => 105,
62
+ 'DD-MM-YY' => 5,
63
+ 'DD.MM.YYYY' => 104,
64
+ 'YYYY-MM-DDTHH:MM:SS:MMM' => 126
65
+ }.freeze
66
+ end
51
67
 
52
68
  # Quoting in JRuby + AR < 5 requires special handling for MSSQL.
53
69
  #
@@ -57,9 +73,10 @@ module ArelExtensions
57
73
  # It didn't handle numbers correctly: `quote(1, nil)` translated into
58
74
  # `N'1'` which we don't want.
59
75
  #
60
- # The following is adapted from activerecord/lib/active_record/connection_adapters/abstract/quoting.rb
76
+ # The following is adapted from
77
+ # https://github.com/rails/rails/blob/main/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb
61
78
  #
62
- if RUBY_PLATFORM == 'java' && ActiveRecord::VERSION::MAJOR < 5
79
+ if RUBY_PLATFORM == 'java'
63
80
  def quote_string(s)
64
81
  s.gsub('\\', '\&\&').gsub("'", "''") # ' (for ruby-mode)
65
82
  end
@@ -70,14 +87,15 @@ module ArelExtensions
70
87
 
71
88
  def quoted_date(value)
72
89
  if value.acts_like?(:time)
73
- if ActiveRecord::Base.default_timezone == :utc
90
+ if (ActiveRecord.respond_to?(:default_timezone) && ActiveRecord.default_timezone == :utc) || ActiveRecord::Base.default_timezone == :utc
74
91
  value = value.getutc if value.respond_to?(:getutc) && !value.utc?
75
92
  else
76
93
  value = value.getlocal if value.respond_to?(:getlocal)
77
94
  end
78
95
  end
79
-
80
- result = value.to_s(:db)
96
+ # new versions of AR use `to_fs`, but we want max compatibility, and we're
97
+ # not going to write it over and over, so it's fine like that.
98
+ result = value.to_formatted_s(:db)
81
99
  if value.respond_to?(:usec) && value.usec > 0
82
100
  result << '.' << sprintf('%06d', value.usec)
83
101
  else
@@ -104,17 +122,19 @@ module ArelExtensions
104
122
  value
105
123
  when String, Symbol, ActiveSupport::Multibyte::Chars
106
124
  "'#{quote_string(value.to_s)}'"
107
- when true
125
+ when true
108
126
  quoted_true
109
- when false
127
+ when false
110
128
  quoted_false
111
- when nil
129
+ when nil
112
130
  'NULL'
113
131
  # BigDecimals need to be put in a non-normalized form and quoted.
114
132
  when BigDecimal
115
133
  value.to_s('F')
116
134
  when Numeric, ActiveSupport::Duration
117
135
  value.to_s
136
+ when Arel::VERSION.to_i > 6 && ActiveRecord::Type::Time::Value
137
+ "'#{quoted_time(value)}'"
118
138
  when Date, Time
119
139
  "'#{quoted_date(value)}'"
120
140
  when Class
@@ -125,6 +145,15 @@ module ArelExtensions
125
145
  end
126
146
  end
127
147
 
148
+ alias_method(:old_primary_Key_From_Table, :primary_Key_From_Table) rescue nil
149
+ def primary_Key_From_Table t
150
+ return unless t
151
+
152
+ column_name = @connection.schema_cache.primary_keys(t.name) ||
153
+ @connection.schema_cache.columns_hash(t.name).first.try(:second).try(:name)
154
+ column_name ? t[column_name] : nil
155
+ end
156
+
128
157
  # Math Functions
129
158
  def visit_ArelExtensions_Nodes_Ceil o, collector
130
159
  collector << 'CEILING('
@@ -543,14 +572,21 @@ module ArelExtensions
543
572
  collector = visit o.left, collector
544
573
  end
545
574
  collector << ' AS '
546
-
547
- # sometimes these values are already quoted, if they are, don't double quote it
548
- quote = o.right.is_a?(Arel::Nodes::SqlLiteral) && o.right[0] != '"' && o.right[-1] != '"'
549
-
550
- collector << '"' if quote
575
+ # Sometimes these values are already quoted, if they are, don't double quote it
576
+ lft, rgt =
577
+ if o.right.is_a?(Arel::Nodes::SqlLiteral)
578
+ if Arel::VERSION.to_i >= 6 && o.right[0] != '[' && o.right[-1] != ']'
579
+ # This is a lie, it's not about arel version, but SQL Server's (>= 2000).
580
+ ['[', ']']
581
+ elsif o.right[0] != '"' && o.right[-1] != '"'
582
+ ['"', '"']
583
+ else
584
+ []
585
+ end
586
+ end
587
+ collector << lft if lft
551
588
  collector = visit o.right, collector
552
- collector << '"' if quote
553
-
589
+ collector << rgt if rgt
554
590
  collector
555
591
  end
556
592
 
@@ -158,10 +158,10 @@ module ArelExtensions
158
158
  collector = visit o.expressions.first, collector
159
159
  collector <<
160
160
  if o.ai
161
- " COLLATE #{charset == 'latin1' ? 'latin1_general_ci' : 'utf8_unicode_ci'}"
161
+ " COLLATE #{charset == 'latin1' ? 'latin1_general_ci' : "#{charset}_unicode_ci"}"
162
162
  # doesn't work in latin1
163
163
  elsif o.ci
164
- " COLLATE #{charset == 'latin1' ? 'latin1_general_ci' : 'utf8_unicode_ci'}"
164
+ " COLLATE #{charset == 'latin1' ? 'latin1_general_ci' : "#{charset}_unicode_ci"}"
165
165
  else
166
166
  " COLLATE #{charset}_bin"
167
167
  end
@@ -190,7 +190,7 @@ module ArelExtensions
190
190
  collector << ' AT TIME ZONE '
191
191
  collector = visit Arel.quoted(dst_tz), collector
192
192
  when String
193
- collector << ') AT TIME ZONE '
193
+ collector << ") AT TIME ZONE 'UTC' AT TIME ZONE "
194
194
  collector = visit Arel.quoted(o.time_zone), collector
195
195
  end
196
196
  collector << COMMA
@@ -392,7 +392,7 @@ module ArelExtensions
392
392
  when :number, :decimal, :float
393
393
  'numeric'
394
394
  when :datetime
395
- 'timestamp with time zone'
395
+ 'timestamp without time zone'
396
396
  when :date
397
397
  'date'
398
398
  when :binary
@@ -1,6 +1,21 @@
1
+ # MSSQL visitors for java and rails ≥ 7 are painful to work with:
2
+ # requiring the exact path to the visitor is needed even if the
3
+ # AR adapter was loaded. It's also needed exactly here because:
4
+ # 1. putting it inside the visitor or anywhere else will not
5
+ # guarantee its actual loading.
6
+ # 2. it needs to load before arel_extensions/visitors.
7
+ if RUBY_PLATFORM == 'java' && Gem::Specification.find { |g| g.name == 'jdbc-mssql' }
8
+ begin
9
+ require 'arel/visitors/sqlserver'
10
+ rescue LoadError
11
+ warn 'arel/visitors/sqlserver not found: MSSQL might not work correctly.'
12
+ end
13
+ end
14
+
1
15
  require 'arel_extensions/visitors/convert_format'
2
16
  require 'arel_extensions/visitors/to_sql'
3
17
  require 'arel_extensions/visitors/mysql'
18
+ require 'arel_extensions/visitors/mssql'
4
19
  require 'arel_extensions/visitors/postgresql'
5
20
  require 'arel_extensions/visitors/sqlite'
6
21
 
@@ -9,10 +24,6 @@ if defined?(Arel::Visitors::Oracle)
9
24
  require 'arel_extensions/visitors/oracle12'
10
25
  end
11
26
 
12
- if defined?(Arel::Visitors::SQLServer) || defined?(Arel::Visitors::MSSQL)
13
- require 'arel_extensions/visitors/mssql'
14
- end
15
-
16
27
  if defined?(Arel::Visitors::SQLServer)
17
28
  class Arel::Visitors::SQLServer
18
29
  include ArelExtensions::Visitors::MSSQL
@@ -27,26 +38,20 @@ if defined?(Arel::Visitors::DepthFirst)
27
38
  end
28
39
  end
29
40
 
41
+ # Especially required here, not inside the next if, for Arel < 6.
42
+ if RUBY_PLATFORM != 'java'
43
+ begin
44
+ require 'arel_sqlserver'
45
+ rescue LoadError
46
+ warn 'gem arel_sqlserver not found: SQLServer Visitor might not work correctly.'
47
+ end
48
+ end
49
+
30
50
  if defined?(Arel::Visitors::MSSQL)
31
51
  class Arel::Visitors::MSSQL
32
52
  include ArelExtensions::Visitors::MSSQL
33
53
 
34
- alias_method(:old_visit_Arel_Nodes_As, :visit_Arel_Nodes_As) rescue nil
35
- def visit_Arel_Nodes_As o, collector
36
- if o.left.is_a?(Arel::Nodes::Binary)
37
- collector << '('
38
- collector = visit o.left, collector
39
- collector << ')'
40
- else
41
- collector = visit o.left, collector
42
- end
43
- collector << ' AS ['
44
- collector = visit o.right, collector
45
- collector << ']'
46
- collector
47
- end
48
-
49
- alias_method(:old_visit_Arel_Nodes_SelectStatement, :visit_Arel_Nodes_SelectStatement) rescue nil
54
+ alias_method(:old_visit_Arel_Nodes_SelectStatement, :visit_Arel_Nodes_SelectStatement)
50
55
  def visit_Arel_Nodes_SelectStatement o, collector
51
56
  if !collector.value.blank? && o.limit.blank? && o.offset.blank?
52
57
  o = o.dup
@@ -55,51 +60,41 @@ if defined?(Arel::Visitors::MSSQL)
55
60
  old_visit_Arel_Nodes_SelectStatement(o, collector)
56
61
  end
57
62
  end
63
+ end
58
64
 
59
- begin
60
- require 'arel_sqlserver'
61
- if Arel::VERSION.to_i == 6
62
- if Arel::Visitors::VISITORS['sqlserver'] && Arel::Visitors::VISITORS['sqlserver'] != Arel::Visitors::MSSQL
63
- Arel::Visitors::VISITORS['sqlserver'].class_eval do
64
- include ArelExtensions::Visitors::MSSQL
65
-
66
- alias_method(:old_visit_Arel_Nodes_SelectStatement, :visit_Arel_Nodes_SelectStatement) rescue nil
67
- def visit_Arel_Nodes_SelectStatement o, collector
68
- if !collector.value.blank? && o.limit.blank? && o.offset.blank?
69
- o = o.dup
70
- o.orders = []
71
- end
72
- old_visit_Arel_Nodes_SelectStatement(o, collector)
73
- end
74
-
75
- alias_method(:old_visit_Arel_Nodes_As, :visit_Arel_Nodes_As) rescue nil
76
- def visit_Arel_Nodes_As o, collector
77
- if o.left.is_a?(Arel::Nodes::Binary)
78
- collector << '('
79
- collector = visit o.left, collector
80
- collector << ')'
81
- else
82
- collector = visit o.left, collector
83
- end
84
- collector << ' AS ['
85
- collector = visit o.right, collector
86
- collector << ']'
87
- collector
88
- end
65
+ if defined?(Arel::Visitors::SQLServer)
66
+ class Arel::Visitors::SQLServer
67
+ include ArelExtensions::Visitors::MSSQL
89
68
 
90
- alias_method(:old_primary_Key_From_Table, :primary_Key_From_Table) rescue nil
91
- def primary_Key_From_Table t
92
- return unless t
69
+ # There's a bug when working with jruby 9.4 that prevents us from
70
+ # refactoring this and putting it in the main module, or even in a separate
71
+ # module then including it.
72
+ #
73
+ # Reason: the line in this file that does:
74
+ #
75
+ # require 'arel_extensions/visitors/mssql'
76
+ #
77
+ # The error could be seen by:
78
+ #
79
+ # 1. placing the visit_ inside the visitor, or placing it in a module
80
+ # then including it here.
81
+ # 2. replacing the `rescue nil` from aliasing trick, and printing the
82
+ # error.
83
+ #
84
+ # It complains that the visit_ does not exist in the module, as if it's
85
+ # evaluating the module eagerly, instead of lazily like in other versions
86
+ # of ruby.
87
+ #
88
+ # It might be something different, but this is the first thing we should
89
+ # investigate.
93
90
 
94
- column_name = @connection.schema_cache.primary_keys(t.name) ||
95
- @connection.schema_cache.columns_hash(t.name).first.try(:second).try(:name)
96
- column_name ? t[column_name] : nil
97
- end
98
- end
91
+ alias_method(:old_visit_Arel_Nodes_SelectStatement, :visit_Arel_Nodes_SelectStatement) rescue nil
92
+ def visit_Arel_Nodes_SelectStatement o, collector
93
+ if !collector.value.blank? && o.limit.blank? && o.offset.blank?
94
+ o = o.dup
95
+ o.orders = []
99
96
  end
97
+ old_visit_Arel_Nodes_SelectStatement(o, collector)
100
98
  end
101
- rescue LoadError
102
- rescue => e
103
- e
104
99
  end
105
100
  end
@@ -121,6 +121,26 @@ module Arel
121
121
  )
122
122
  end
123
123
 
124
+ def self.json_true
125
+ res = Arel.grouping(Arel.quoted('true'))
126
+ res.instance_eval {
127
+ def return_type
128
+ :boolean
129
+ end
130
+ }
131
+ res
132
+ end
133
+
134
+ def self.json_false
135
+ res = Arel.grouping(Arel.quoted('false'))
136
+ res.instance_eval {
137
+ def return_type
138
+ :boolean
139
+ end
140
+ }
141
+ res
142
+ end
143
+
124
144
  # The NULL literal.
125
145
  def self.null
126
146
  Arel.quoted(nil)
@@ -12,7 +12,8 @@ end
12
12
 
13
13
  YELLOW = '33'
14
14
 
15
- # Load gems specific to databases
15
+ # Load gems specific to databases.
16
+ #
16
17
  # NOTE:
17
18
  # It's strongly advised to test each database on its own. Loading multiple
18
19
  # backend gems leads to undefined behavior according to tests; the backend
@@ -22,26 +23,32 @@ YELLOW = '33'
22
23
  # The issue also seems to be related to arel version: at some point, arel
23
24
  # dropped its wide support for DBs and kept Postgres, MySQL and SQLite.
24
25
  # Here, we're just trying to load the correct ones.
26
+ #
27
+ # NOTE:
28
+ # As of jruby 9.4 (and maybe 9.3, but I couldn't test it given the state of
29
+ # the alt-adapter), we need to load jdbc/mssql manually.
25
30
  db_and_gem =
26
- if RUBY_ENGINE == 'jruby'
31
+ if RUBY_PLATFORM == 'java'
27
32
  {
28
- 'oracle' => 'activerecord-oracle_enhanced-adapter',
29
- 'mssql' => 'activerecord-jdbcsqlserver-adapter'
33
+ 'oracle' => ['activerecord-oracle_enhanced-adapter'],
34
+ 'mssql' => ['jdbc/mssql', 'activerecord-jdbcsqlserver-adapter'],
30
35
  }
31
36
  else
32
37
  {
33
- 'oracle' => 'activerecord-oracle_enhanced-adapter',
34
- 'mssql' => 'activerecord-sqlserver-adapter'
38
+ 'oracle' => ['activerecord-oracle_enhanced-adapter'],
39
+ 'mssql' => ['activerecord-sqlserver-adapter'],
35
40
  }
36
41
  end
37
42
 
38
- def load_lib(gem)
39
- if gem && (RUBY_ENGINE == 'jruby' || Arel::VERSION.to_i > 9)
40
- begin
41
- Gem::Specification.find_by_name(gem)
42
- require gem
43
- rescue Gem::MissingSpecError
44
- warn "Warning: failed to load gem #{gem}. Are you sure it's installed?"
43
+ def load_lib(gems)
44
+ if gems && (RUBY_PLATFORM == 'java' || Arel::VERSION.to_i > 9)
45
+ gems.each do |gem|
46
+ begin
47
+ require gem
48
+ rescue Exception => e
49
+ warn "Warning: failed to load gem #{gem}. Are you sure it's installed?"
50
+ warn e.message
51
+ end
45
52
  end
46
53
  end
47
54
  end
data/test/real_db_test.rb CHANGED
@@ -40,6 +40,7 @@ def setup_db
40
40
  t.column :created_at, :date
41
41
  t.column :updated_at, :date
42
42
  t.column :score, :decimal
43
+ t.column :updated_at, :datetime
43
44
  end
44
45
  end
45
46
 
@@ -53,11 +54,12 @@ end
53
54
  class ListTest < Minitest::Test
54
55
  def setup
55
56
  d = Date.new(2016, 05, 23)
57
+ dt = Time.new(2016, 05, 23, 12, 34, 56)
56
58
  setup_db
57
59
  User.create age: 5, name: 'Lucas', created_at: d, score: 20.16
58
60
  User.create age: 15, name: 'Sophie', created_at: d, score: 20.16
59
61
  User.create age: 20, name: 'Camille', created_at: d, score: 20.16
60
- User.create age: 21, name: 'Arthur', created_at: d, score: 65.62
62
+ User.create age: 21, name: 'Arthur', created_at: d, score: 65.62, updated_at: dt
61
63
  u = User.create age: 23, name: 'Myung', created_at: d, score: 20.16
62
64
  @myung = User.where(id: u.id)
63
65
  User.create age: 25, name: 'Laure', created_at: d, score: 20.16
@@ -91,7 +93,7 @@ class ListTest < Minitest::Test
91
93
  end
92
94
  end
93
95
 
94
- def test_Comparator
96
+ def test_comparator
95
97
  assert_equal 2, User.where(User.arel_table[:age] < 6).count
96
98
  assert_equal 2, User.where(User.arel_table[:age] <= 10).count
97
99
  assert_equal 3, User.where(User.arel_table[:age] > 20).count
@@ -99,6 +101,18 @@ class ListTest < Minitest::Test
99
101
  assert_equal 1, User.where(User.arel_table[:age] > 5).where(User.arel_table[:age] < 20).count
100
102
  end
101
103
 
104
+ def test_date_date_comparator
105
+ d = Date.new(2016, 05, 24) #after created_at in db
106
+ assert_equal 8, User.where(User.arel_table[:age] < d).count
107
+ assert_equal 0, User.where(User.arel_table[:age] > d).count
108
+ assert_equal 0, User.where(User.arel_table[:age] == d).count
109
+ d = Date.new(2016, 05, 23)
110
+ assert_equal 8, User.where(User.arel_table[:age] == d).count
111
+ dt = Time.new(2016, 05, 23, 12, 35, 00) #after updated_at in db
112
+ assert_equal 1, User.where(User.arel_table[:update_at] < dt).count
113
+ assert_equal 0, User.where(User.arel_table[:update_at] > dt).count
114
+ end
115
+
102
116
  def test_date_duration
103
117
  # Year
104
118
  assert_equal 2016, User.where(User.arel_table[:name].eq('Lucas')).select((User.arel_table[:created_at].year).as('res')).first.res.to_i
@@ -501,7 +501,7 @@ module ArelExtensions
501
501
  #
502
502
  # MySQL is happy to consider that times by default are in UTC.
503
503
  assert_equal '2014/03/03 13:42:00', t(@lucas, @updated_at.send(method, '%Y/%m/%d %H:%M:%S', {tz['utc'] => tz['paris']}))
504
- refute_equal '2014/03/03 13:42:00', t(@lucas, @updated_at.send(method, '%Y/%m/%d %H:%M:%S', tz['paris'])) if !['mysql'].include?(ENV['DB'])
504
+ refute_equal '2014/03/03 13:42:00', t(@lucas, @updated_at.send(method, '%Y/%m/%d %H:%M:%S', tz['paris'])) if !%w[mysql postgresql].include?(ENV['DB'])
505
505
 
506
506
  # Winter/Summer time
507
507
  assert_equal '2014/08/03 14:42:00', t(@lucas, (@updated_at + 5.months).send(method, '%Y/%m/%d %H:%M:%S', {tz['utc'] => tz['paris']}))
data/version_v1.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module ArelExtensions
2
- VERSION = '1.3.8'.freeze
2
+ VERSION = '1.3.10'.freeze
3
3
  end
data/version_v2.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module ArelExtensions
2
- VERSION = '2.1.8'.freeze
2
+ VERSION = '2.1.10'.freeze
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: arel_extensions
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.8
4
+ version: 2.1.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yann Azoury
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2023-11-14 00:00:00.000000000 Z
13
+ date: 2024-07-31 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activerecord
@@ -67,6 +67,8 @@ extra_rdoc_files:
67
67
  - functions.html
68
68
  files:
69
69
  - ".codeclimate.yml"
70
+ - ".github/workflows/publish.yml"
71
+ - ".github/workflows/release.yml"
70
72
  - ".github/workflows/ruby.yml"
71
73
  - ".gitignore"
72
74
  - ".rubocop.yml"
@@ -79,6 +81,8 @@ files:
79
81
  - TODO
80
82
  - appveyor.yml
81
83
  - arel_extensions.gemspec
84
+ - bin/build
85
+ - bin/publish
82
86
  - dev/compose.yaml
83
87
  - functions.html
84
88
  - gemfiles/rails3.gemfile
@@ -210,7 +214,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
210
214
  - !ruby/object:Gem::Version
211
215
  version: '0'
212
216
  requirements: []
213
- rubygems_version: 3.3.5
217
+ rubygems_version: 3.4.19
214
218
  signing_key:
215
219
  specification_version: 4
216
220
  summary: Extending Arel