arel_extensions 2.1.8 → 2.1.10

Sign up to get free protection for your applications and to get access to all the features.
@@ -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