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.
- checksums.yaml +4 -4
- data/.github/workflows/publish.yml +29 -0
- data/.github/workflows/release.yml +30 -0
- data/.github/workflows/ruby.yml +173 -147
- data/NEWS.md +37 -3
- data/README.md +4 -4
- data/bin/build +15 -0
- data/bin/publish +8 -0
- data/dev/compose.yaml +8 -0
- data/gemfiles/rails6.gemfile +4 -3
- data/gemfiles/rails6_1.gemfile +4 -3
- data/gemfiles/rails7.gemfile +9 -1
- data/gemfiles/rails7_1.gemfile +8 -0
- data/lib/arel_extensions/version.rb +1 -1
- data/lib/arel_extensions/visitors/mssql.rb +97 -61
- data/lib/arel_extensions/visitors/mysql.rb +2 -2
- data/lib/arel_extensions/visitors/postgresql.rb +2 -2
- data/lib/arel_extensions/visitors.rb +56 -61
- data/lib/arel_extensions.rb +20 -0
- data/test/arelx_test_helper.rb +20 -13
- data/test/real_db_test.rb +16 -2
- data/test/with_ar/all_agnostic_test.rb +1 -1
- data/version_v1.rb +1 -1
- data/version_v2.rb +1 -1
- metadata +7 -3
data/gemfiles/rails7.gemfile
CHANGED
@@ -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.
|
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
|
data/gemfiles/rails7_1.gemfile
CHANGED
@@ -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
|
@@ -2,52 +2,68 @@ module ArelExtensions
|
|
2
2
|
module Visitors
|
3
3
|
module MSSQL
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
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
|
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'
|
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
|
-
|
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
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
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 <<
|
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' :
|
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' :
|
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 <<
|
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
|
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(:
|
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
|
-
|
60
|
-
|
61
|
-
|
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
|
-
|
91
|
-
|
92
|
-
|
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
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
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
|
data/lib/arel_extensions.rb
CHANGED
@@ -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)
|
data/test/arelx_test_helper.rb
CHANGED
@@ -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
|
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(
|
39
|
-
if
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
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
|
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
|
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
data/version_v2.rb
CHANGED
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.
|
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:
|
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.
|
217
|
+
rubygems_version: 3.4.19
|
214
218
|
signing_key:
|
215
219
|
specification_version: 4
|
216
220
|
summary: Extending Arel
|