arel_extensions 2.0.22 → 2.1.1
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/ruby.yml +358 -71
- data/Gemfile +8 -8
- data/README.md +86 -0
- data/arel_extensions.gemspec +1 -1
- data/gemfiles/rails5_2.gemfile +8 -7
- data/gemfiles/rails6.gemfile +7 -8
- data/gemfiles/rails6_1.gemfile +6 -7
- data/gemfiles/rails7.gemfile +22 -0
- data/gemspecs/arel_extensions-v1.gemspec +1 -1
- data/gemspecs/arel_extensions-v2.gemspec +1 -1
- data/lib/arel_extensions/aliases.rb +14 -0
- data/lib/arel_extensions/attributes.rb +2 -0
- data/lib/arel_extensions/date_duration.rb +2 -2
- data/lib/arel_extensions/helpers.rb +48 -0
- data/lib/arel_extensions/insert_manager.rb +19 -17
- data/lib/arel_extensions/math.rb +22 -32
- data/lib/arel_extensions/nodes/case.rb +5 -6
- data/lib/arel_extensions/nodes/cast.rb +1 -1
- data/lib/arel_extensions/nodes/date_diff.rb +23 -4
- data/lib/arel_extensions/nodes/format.rb +3 -2
- data/lib/arel_extensions/nodes/function.rb +2 -6
- data/lib/arel_extensions/nodes/json.rb +3 -1
- data/lib/arel_extensions/nodes/replace.rb +0 -8
- data/lib/arel_extensions/nodes/union.rb +1 -1
- data/lib/arel_extensions/nodes/union_all.rb +1 -1
- data/lib/arel_extensions/version.rb +1 -1
- data/lib/arel_extensions/visitors/mssql.rb +109 -51
- data/lib/arel_extensions/visitors/mysql.rb +15 -2
- data/lib/arel_extensions/visitors/oracle.rb +6 -1
- data/lib/arel_extensions/visitors/postgresql.rb +20 -10
- data/lib/arel_extensions/visitors/sqlite.rb +6 -3
- data/lib/arel_extensions/visitors/to_sql.rb +13 -8
- data/lib/arel_extensions/visitors.rb +9 -1
- data/lib/arel_extensions.rb +57 -15
- data/test/arelx_test_helper.rb +45 -0
- data/test/database.yml +8 -2
- data/test/real_db_test.rb +5 -1
- data/test/support/fake_record.rb +1 -1
- data/test/visitors/test_to_sql.rb +39 -11
- data/test/with_ar/all_agnostic_test.rb +79 -6
- data/test/with_ar/insert_agnostic_test.rb +6 -2
- data/test/with_ar/test_bulk_sqlite.rb +6 -2
- data/test/with_ar/test_math_sqlite.rb +6 -2
- data/test/with_ar/test_string_mysql.rb +6 -2
- data/test/with_ar/test_string_sqlite.rb +6 -2
- data/version_v1.rb +1 -1
- data/version_v2.rb +1 -1
- metadata +10 -8
- data/appveyor.yml +0 -44
data/lib/arel_extensions.rb
CHANGED
@@ -34,9 +34,9 @@ class Arel::Nodes::Grouping
|
|
34
34
|
end
|
35
35
|
|
36
36
|
class Arel::Nodes::Ordering
|
37
|
-
|
38
|
-
|
39
|
-
|
37
|
+
def eql? other
|
38
|
+
self.hash.eql? other.hash
|
39
|
+
end
|
40
40
|
end
|
41
41
|
|
42
42
|
class Arel::Nodes::Function
|
@@ -52,6 +52,7 @@ if Gem::Version.new(Arel::VERSION) >= Gem::Version.new("7.1.0")
|
|
52
52
|
end
|
53
53
|
|
54
54
|
require 'arel_extensions/version'
|
55
|
+
require 'arel_extensions/aliases'
|
55
56
|
require 'arel_extensions/attributes'
|
56
57
|
require 'arel_extensions/visitors'
|
57
58
|
require 'arel_extensions/nodes'
|
@@ -76,7 +77,17 @@ require 'arel_extensions/nodes/soundex'
|
|
76
77
|
require 'arel_extensions/nodes/cast'
|
77
78
|
require 'arel_extensions/nodes/json'
|
78
79
|
|
79
|
-
|
80
|
+
# It seems like the code in lib/arel_extensions/visitors.rb that is supposed
|
81
|
+
# to inject ArelExtension is not enough. Different versions of the sqlserver
|
82
|
+
# adapter behave differently. It doesn't always proc, so we added this for
|
83
|
+
# coverage.
|
84
|
+
if defined?(Arel::Visitors::SQLServer)
|
85
|
+
Arel::Visitors.const_set('MSSQL', Arel::Visitors::SQLServer)
|
86
|
+
require 'arel_extensions/visitors/mssql'
|
87
|
+
class Arel::Visitors::SQLServer
|
88
|
+
include ArelExtensions::Visitors::MSSQL
|
89
|
+
end
|
90
|
+
end
|
80
91
|
|
81
92
|
module Arel
|
82
93
|
def self.rand
|
@@ -88,11 +99,13 @@ module Arel
|
|
88
99
|
end
|
89
100
|
|
90
101
|
def self.json *expr
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
102
|
+
ArelExtensions::Nodes::Json.new(
|
103
|
+
if expr.length == 1
|
104
|
+
expr.first
|
105
|
+
else
|
106
|
+
expr
|
107
|
+
end
|
108
|
+
)
|
96
109
|
end
|
97
110
|
|
98
111
|
def self.when condition
|
@@ -100,20 +113,31 @@ module Arel
|
|
100
113
|
end
|
101
114
|
|
102
115
|
def self.duration s, expr
|
103
|
-
ArelExtensions::Nodes::Duration.new(s
|
116
|
+
ArelExtensions::Nodes::Duration.new("#{s}i", expr)
|
104
117
|
end
|
105
118
|
|
119
|
+
def self.grouping *v
|
120
|
+
Arel::Nodes::Grouping.new(*v)
|
121
|
+
end
|
122
|
+
|
123
|
+
# The TRUE pseudo literal.
|
106
124
|
def self.true
|
107
|
-
Arel::Nodes::Equality.new(1,1)
|
125
|
+
Arel::Nodes::Equality.new(1, 1)
|
108
126
|
end
|
109
127
|
|
128
|
+
# The FALSE pseudo literal.
|
110
129
|
def self.false
|
111
|
-
Arel::Nodes::Equality.new(1,0)
|
130
|
+
Arel::Nodes::Equality.new(1, 0)
|
131
|
+
end
|
132
|
+
|
133
|
+
# The NULL literal.
|
134
|
+
def self.null
|
135
|
+
Arel::Nodes.build_quoted(nil)
|
112
136
|
end
|
113
137
|
|
114
138
|
def self.tuple *v
|
115
|
-
tmp = Arel
|
116
|
-
Arel
|
139
|
+
tmp = Arel.grouping(nil)
|
140
|
+
Arel.grouping v.map{|e| tmp.convert_to_node(e)}
|
117
141
|
end
|
118
142
|
end
|
119
143
|
|
@@ -123,6 +147,7 @@ class Arel::Attributes::Attribute
|
|
123
147
|
end
|
124
148
|
|
125
149
|
class Arel::Nodes::Function
|
150
|
+
include ArelExtensions::Aliases
|
126
151
|
include ArelExtensions::Math
|
127
152
|
include ArelExtensions::Comparators
|
128
153
|
include ArelExtensions::DateDuration
|
@@ -189,6 +214,19 @@ end
|
|
189
214
|
class Arel::SelectManager
|
190
215
|
include ArelExtensions::SetFunctions
|
191
216
|
include ArelExtensions::Nodes
|
217
|
+
|
218
|
+
def as table_name
|
219
|
+
Arel::Nodes::TableAlias.new(self, table_name)
|
220
|
+
end
|
221
|
+
|
222
|
+
# Install an alias, if present.
|
223
|
+
def xas table_name
|
224
|
+
if table_name.present?
|
225
|
+
as table_name
|
226
|
+
else
|
227
|
+
self
|
228
|
+
end
|
229
|
+
end
|
192
230
|
end
|
193
231
|
|
194
232
|
class Arel::Nodes::As
|
@@ -198,7 +236,11 @@ end
|
|
198
236
|
class Arel::Table
|
199
237
|
alias_method(:old_alias, :alias) rescue nil
|
200
238
|
def alias(name = "#{self.name}_2")
|
201
|
-
name.
|
239
|
+
if name.present?
|
240
|
+
Arel::Nodes::TableAlias.new(self, name)
|
241
|
+
else
|
242
|
+
self
|
243
|
+
end
|
202
244
|
end
|
203
245
|
end
|
204
246
|
|
data/test/arelx_test_helper.rb
CHANGED
@@ -6,6 +6,51 @@ require 'active_record'
|
|
6
6
|
|
7
7
|
require 'support/fake_record'
|
8
8
|
|
9
|
+
def colored(color, msg)
|
10
|
+
ENV["TERM"] =~ /^xterm|-256color$/ ? "\x1b[#{color}m#{msg}\x1b[89m\x1b[0m" : "#{msg}"
|
11
|
+
end
|
12
|
+
|
13
|
+
YELLOW = "33"
|
14
|
+
|
15
|
+
def warn(msg)
|
16
|
+
$stderr.puts(colored(YELLOW, msg))
|
17
|
+
end
|
18
|
+
|
19
|
+
# Load gems specific to databases
|
20
|
+
# NOTE:
|
21
|
+
# It's strongly advised to test each database on its own. Loading multiple
|
22
|
+
# backend gems leads to undefined behavior according to tests; the backend
|
23
|
+
# might not recognize the correct DB visitor and will fallback to `ToSQL`
|
24
|
+
# and screw all tests.
|
25
|
+
#
|
26
|
+
# The issue also seems to be related to arel version: at some point, arel
|
27
|
+
# dropped its wide support for DBs and kept Postgres, MySQL and SQLite.
|
28
|
+
# Here, we're just trying to load the correct ones.
|
29
|
+
db_and_gem = if RUBY_ENGINE == 'jruby'
|
30
|
+
{
|
31
|
+
'oracle' => 'activerecord-oracle_enhanced-adapter',
|
32
|
+
'mssql' => 'activerecord-jdbcsqlserver-adapter'
|
33
|
+
}
|
34
|
+
else
|
35
|
+
{
|
36
|
+
'oracle' => 'activerecord-oracle_enhanced-adapter',
|
37
|
+
'mssql' => 'activerecord-sqlserver-adapter'
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
41
|
+
def load_lib(gem)
|
42
|
+
if gem && (RUBY_ENGINE == 'jruby' || Arel::VERSION.to_i > 9)
|
43
|
+
begin
|
44
|
+
Gem::Specification.find_by_name(gem)
|
45
|
+
require gem
|
46
|
+
rescue Gem::MissingSpecError
|
47
|
+
warn "Warning: failed to load gem #{gem}. Are you sure it's installed?"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
load_lib(db_and_gem[ENV['DB']])
|
53
|
+
|
9
54
|
require 'arel_extensions'
|
10
55
|
Arel::Table.engine = FakeRecord::Base.new
|
11
56
|
|
data/test/database.yml
CHANGED
@@ -9,23 +9,29 @@ jdbc-sqlite:
|
|
9
9
|
mysql:
|
10
10
|
adapter: mysql2
|
11
11
|
database: arext_test
|
12
|
-
username:
|
12
|
+
username: root
|
13
13
|
host: 127.0.0.1
|
14
14
|
port: 3306
|
15
15
|
encoding: utf8
|
16
16
|
jdbc-mysql:
|
17
17
|
adapter: jdbcmysql
|
18
18
|
database: arext_test
|
19
|
-
username:
|
19
|
+
username: root
|
20
20
|
encoding: utf8
|
21
21
|
postgresql:
|
22
22
|
adapter: postgresql
|
23
23
|
database: arext_test
|
24
24
|
username: postgres
|
25
|
+
password: secret
|
26
|
+
host: 127.0.0.1
|
27
|
+
port: 5432
|
25
28
|
jdbc-postgresql:
|
26
29
|
adapter: jdbcpostgresql
|
27
30
|
database: arext_test
|
28
31
|
username: postgres
|
32
|
+
password: secret
|
33
|
+
host: 127.0.0.1
|
34
|
+
port: 5432
|
29
35
|
oracle:
|
30
36
|
adapter: oracle_enhanced
|
31
37
|
database: xe
|
data/test/real_db_test.rb
CHANGED
@@ -8,7 +8,11 @@ require 'arel_extensions'
|
|
8
8
|
def setup_db
|
9
9
|
ActiveRecord::Base.configurations = YAML.load_file('test/database.yml')
|
10
10
|
ActiveRecord::Base.establish_connection(ENV['DB'].try(:to_sym) || (RUBY_PLATFORM == 'java' ? :"jdbc-sqlite" : :sqlite))
|
11
|
-
ActiveRecord::
|
11
|
+
if ActiveRecord::VERSION::MAJOR >= 7
|
12
|
+
ActiveRecord.default_timezone = :utc
|
13
|
+
else
|
14
|
+
ActiveRecord::Base.default_timezone = :utc
|
15
|
+
end
|
12
16
|
@cnx = ActiveRecord::Base.connection
|
13
17
|
if ActiveRecord::Base.connection.adapter_name =~ /sqlite/i
|
14
18
|
$sqlite = true
|
data/test/support/fake_record.rb
CHANGED
@@ -105,7 +105,7 @@ module FakeRecord
|
|
105
105
|
attr_reader :spec, :connection
|
106
106
|
|
107
107
|
def initialize
|
108
|
-
@spec = Spec.new(:adapter => 'america')
|
108
|
+
@spec = Spec.new({:adapter => 'america'})
|
109
109
|
@connection = Connection.new
|
110
110
|
@connection.visitor = Arel::Visitors::ToSql.new(connection)
|
111
111
|
end
|
@@ -5,6 +5,27 @@ module ArelExtensions
|
|
5
5
|
module VisitorToSql
|
6
6
|
describe 'the to_sql visitor' do
|
7
7
|
before do
|
8
|
+
if Arel::Table.engine.is_a?(ActiveRecord::Base)
|
9
|
+
puts "This is a hack."
|
10
|
+
# As a matter of fact, if the whole if-block is removed, the to_sql
|
11
|
+
# test become flaky.
|
12
|
+
#
|
13
|
+
# The first time `Arel::Table.engine` is called
|
14
|
+
# from `ArelExtenstions::column_of_via_arel_table(table_name, column_name)`
|
15
|
+
# in `lib/arel_extensions/helpers.rb`
|
16
|
+
# will almost always fail. It's important to note that when the test
|
17
|
+
# fails, it's always on 1 test case, and every subsequent test that
|
18
|
+
# calls to these methods passes.
|
19
|
+
#
|
20
|
+
# After investigation, it turned out that `Arel::Table.engine` will be
|
21
|
+
# of type `ActiveRecord::Base` instead of the expected `FakeRecord::Base`
|
22
|
+
# as set in this `before` block, in the `@conn` instance variable.
|
23
|
+
# Subsequent calls to `column_of_via_arel_table` will have
|
24
|
+
# `Arel::Table.engine` of the expected type.
|
25
|
+
#
|
26
|
+
# It is still unclear why the call in the condition of this if-block
|
27
|
+
# fixes this behavior.
|
28
|
+
end
|
8
29
|
@conn = FakeRecord::Base.new
|
9
30
|
Arel::Table.engine = @conn
|
10
31
|
@visitor = Arel::Visitors::ToSql.new @conn.connection
|
@@ -282,16 +303,23 @@ module ArelExtensions
|
|
282
303
|
.must_be_like %{CASE "users"."name" WHEN 'smith' THEN 'cool' ELSE 'uncool' END ILIKE 'value'}
|
283
304
|
end
|
284
305
|
|
285
|
-
it "should be possible to use as on anything" do
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
.
|
306
|
+
it "should be possible to use as/xas on anything" do
|
307
|
+
{
|
308
|
+
@table[:name] => %{"users"."name" AS alias},
|
309
|
+
@table[:name].concat(' test') => %{CONCAT("users"."name", ' test') AS alias},
|
310
|
+
(@table[:name] + ' test') => %{CONCAT("users"."name", ' test') AS alias},
|
311
|
+
(@table[:age] + 42) => %{("users"."age" + 42) AS alias},
|
312
|
+
@table[:name].coalesce('') => %{COALESCE("users"."name", '') AS alias},
|
313
|
+
Arel::Nodes.build_quoted('test') => %{'test' AS alias},
|
314
|
+
@table.project(@table[:name]) => %{(SELECT "users"."name" FROM "users") "alias"},
|
315
|
+
@table[:name].when("smith").then("cool").else("uncool") => %{CASE "users"."name" WHEN 'smith' THEN 'cool' ELSE 'uncool' END AS alias},
|
316
|
+
}.each do |exp, res|
|
317
|
+
_(compile(exp.as('alias'))).must_be_like res
|
318
|
+
_(compile(exp.xas('alias'))).must_be_like res
|
319
|
+
|
320
|
+
res_no_alias = res.gsub(/\s*(?:AS alias|"alias")\s*\z/, '')
|
321
|
+
_(compile(exp.xas(nil))).must_be_like res_no_alias
|
322
|
+
end
|
295
323
|
end
|
296
324
|
|
297
325
|
it "should accept comparators on functions" do
|
@@ -373,7 +401,7 @@ module ArelExtensions
|
|
373
401
|
end
|
374
402
|
|
375
403
|
it "should respecting Grouping" do
|
376
|
-
g = ->(*v) { Arel
|
404
|
+
g = ->(*v) { Arel.grouping(v) }
|
377
405
|
_(compile(g[@table[:id], @table[:age]].in [g[1, 42]]))
|
378
406
|
.must_be_like %{("users"."id", "users"."age") IN ((1, 42))}
|
379
407
|
_(compile(g[@table[:id], @table[:age]].in [g[1, 42], g[2, 51]]))
|
@@ -2,7 +2,7 @@ require 'arelx_test_helper'
|
|
2
2
|
require 'date'
|
3
3
|
|
4
4
|
module ArelExtensions
|
5
|
-
module
|
5
|
+
module WithAr
|
6
6
|
class ListTest < Minitest::Test
|
7
7
|
require 'minitest/pride'
|
8
8
|
def connect_db
|
@@ -14,7 +14,11 @@ module ArelExtensions
|
|
14
14
|
@env_db = ENV['DB']
|
15
15
|
end
|
16
16
|
ActiveRecord::Base.establish_connection(@env_db.try(:to_sym) || (RUBY_PLATFORM == 'java' ? :"jdbc-sqlite" : :sqlite))
|
17
|
-
ActiveRecord::
|
17
|
+
if ActiveRecord::VERSION::MAJOR >= 7
|
18
|
+
ActiveRecord.default_timezone = :utc
|
19
|
+
else
|
20
|
+
ActiveRecord::Base.default_timezone = :utc
|
21
|
+
end
|
18
22
|
@cnx = ActiveRecord::Base.connection
|
19
23
|
$sqlite = @cnx.adapter_name =~ /sqlite/i
|
20
24
|
$load_extension_disabled ||= false
|
@@ -29,7 +33,7 @@ module ArelExtensions
|
|
29
33
|
t.column :name, :string
|
30
34
|
t.column :comments, :text
|
31
35
|
t.column :created_at, :date
|
32
|
-
t.column :updated_at, :datetime
|
36
|
+
t.column :updated_at, :datetime, precision: nil
|
33
37
|
t.column :duration, :time
|
34
38
|
t.column :other, :string
|
35
39
|
t.column :score, :decimal, :precision => 20, :scale => 10
|
@@ -166,6 +170,12 @@ module ArelExtensions
|
|
166
170
|
# Since Arel10 (Rails6.1), some unwanted behaviors on aggregated calculation were present.
|
167
171
|
# This should works no matter which version of rails is used
|
168
172
|
assert User.group(:score).average(:id).values.all?{|e| !e.nil?}
|
173
|
+
|
174
|
+
# Since Rails 7, a patch to calculations.rb has tirggered a double
|
175
|
+
# quoting of the alias name. See https://github.com/rails/rails/commit/7e6e9091e55c3357b0162d44b6ab955ed0c718d5
|
176
|
+
# Before the patch that fixed this the following error would occur:
|
177
|
+
# ActiveRecord::StatementInvalid: PG::SyntaxError: ERROR: zero-length delimited identifier at or near """"
|
178
|
+
assert User.group(:score).count(:id).values.all?{|e| !e.nil?}
|
169
179
|
end
|
170
180
|
|
171
181
|
# String Functions
|
@@ -358,9 +368,70 @@ module ArelExtensions
|
|
358
368
|
|
359
369
|
def test_format
|
360
370
|
assert_equal '2016-05-23', t(@lucas, @created_at.format('%Y-%m-%d'))
|
361
|
-
skip "SQL Server does not accept any format" if @env_db == 'mssql'
|
362
371
|
assert_equal '2014/03/03 12:42:00', t(@lucas, @updated_at.format('%Y/%m/%d %H:%M:%S'))
|
363
372
|
assert_equal '12:42%', t(@lucas, @updated_at.format('%R%%'))
|
373
|
+
|
374
|
+
# The following tests will ensure proper conversion of timestamps to
|
375
|
+
# requested timezones.
|
376
|
+
#
|
377
|
+
# The names of the timezones is highly dependant on the underlying
|
378
|
+
# operating system, and this is why we need to handle each database
|
379
|
+
# separately: the images we're using to test these databases are
|
380
|
+
# different. So don't rely on the provided examples. Your setup is your
|
381
|
+
# reference.
|
382
|
+
#
|
383
|
+
# One could always have portable code if s/he uses standard
|
384
|
+
# abbreviations, like:
|
385
|
+
#
|
386
|
+
# 1. CET => Central European Time
|
387
|
+
# 2. CEST => Central European Summer Time
|
388
|
+
#
|
389
|
+
# Which implies that the caller should handle daylight saving detection.
|
390
|
+
# In fact, CET will handle daylight saving in MySQL but not Postgres.
|
391
|
+
#
|
392
|
+
# It looks like the posix convention is supported by mysql and
|
393
|
+
# postgresql, e.g.:
|
394
|
+
#
|
395
|
+
# posix/Europe/Paris
|
396
|
+
# posix/America/Nipigon
|
397
|
+
#
|
398
|
+
# so it looks like a more reliably portable way of specifying it.
|
399
|
+
time_zones = {
|
400
|
+
'mssql' => {
|
401
|
+
'utc' => 'UTC',
|
402
|
+
'sao_paulo' => 'Argentina Standard Time',
|
403
|
+
'tahiti' => 'Hawaiian Standard Time',
|
404
|
+
'paris' => 'Central European Standard Time'
|
405
|
+
},
|
406
|
+
'mysql' => {
|
407
|
+
'utc' => 'UTC',
|
408
|
+
'sao_paulo' => 'America/Sao_Paulo',
|
409
|
+
'tahiti' => 'Pacific/Tahiti',
|
410
|
+
'paris' => 'Europe/Paris'
|
411
|
+
},
|
412
|
+
'oracle' => {
|
413
|
+
'utc' => 'UTC',
|
414
|
+
'sao_paulo' => 'America/Sao_Paulo',
|
415
|
+
'tahiti' => 'Pacific/Tahiti',
|
416
|
+
'paris' => 'Europe/Paris'
|
417
|
+
},
|
418
|
+
'postgresql' => {
|
419
|
+
'utc' => 'UTC',
|
420
|
+
'sao_paulo' => 'America/Sao Paulo (-03)',
|
421
|
+
'tahiti' => 'Pacific/Tahiti (-10)',
|
422
|
+
'paris' => 'Europe/Paris'
|
423
|
+
},
|
424
|
+
}
|
425
|
+
|
426
|
+
tz = time_zones[ENV['DB']]
|
427
|
+
skip "Unsupported timezone conversion for DB=#{ENV['DB']}" if tz.nil?
|
428
|
+
assert_equal '2014/03/03 12:42:00', t(@lucas, @updated_at.format('%Y/%m/%d %H:%M:%S', tz['utc']))
|
429
|
+
assert_equal '2014/03/03 09:42:00', t(@lucas, @updated_at.format('%Y/%m/%d %H:%M:%S', tz['sao_paulo']))
|
430
|
+
assert_equal '2014/03/03 02:42:00', t(@lucas, @updated_at.format('%Y/%m/%d %H:%M:%S', tz['tahiti']))
|
431
|
+
|
432
|
+
# Winter/Summer time
|
433
|
+
assert_equal '2022/02/01 11:42:00', t(@lucas, Arel::Nodes.build_quoted('2022-02-01 10:42:00').cast(:datetime).format('%Y/%m/%d %H:%M:%S', tz['paris']))
|
434
|
+
assert_equal '2022/08/01 12:42:00', t(@lucas, Arel::Nodes.build_quoted('2022-08-01 10:42:00').cast(:datetime).format('%Y/%m/%d %H:%M:%S', tz['paris']))
|
364
435
|
end
|
365
436
|
|
366
437
|
def test_coalesce
|
@@ -500,7 +571,8 @@ module ArelExtensions
|
|
500
571
|
assert_equal Time, t(@lucas,@updated_at.cast(:string).cast(:datetime)).class
|
501
572
|
assert_equal Time, t(@lucas,@updated_at.cast(:time)).class
|
502
573
|
|
503
|
-
|
574
|
+
# mysql adapter in rails7 adds some infos we just squeeze here
|
575
|
+
assert_equal "2014-03-03 12:42:00", t(@lucas,@updated_at.cast(:string)).split('.').first unless @env_db == 'mssql' # locale dependent
|
504
576
|
assert_equal Date.parse("2014-03-03"), t(@lucas,Arel::Nodes.build_quoted('2014-03-03').cast(:date))
|
505
577
|
assert_equal Date.parse("5014-03-03"), t(@lucas,(@age.cast(:string) + '014-03-03').cast(:date))
|
506
578
|
assert_equal Time.parse("2014-03-03 12:42:00 UTC"), t(@lucas,@updated_at.cast(:string).cast(:datetime))
|
@@ -515,7 +587,7 @@ module ArelExtensions
|
|
515
587
|
# puts @age.is_null.inspect
|
516
588
|
# puts @age.is_null.to_sql
|
517
589
|
# puts @age=='34'
|
518
|
-
assert_equal "Test", User.select(@name).where(@age.is_null
|
590
|
+
assert_equal "Test", User.select(@name).where(@age.is_null).first.name
|
519
591
|
end
|
520
592
|
|
521
593
|
def test_math_plus
|
@@ -663,6 +735,7 @@ module ArelExtensions
|
|
663
735
|
end
|
664
736
|
|
665
737
|
def test_subquery_with_order
|
738
|
+
skip if ['mssql'].include?(@env_db) && Arel::VERSION.to_i < 10
|
666
739
|
assert_equal 9, User.where(:name => User.select(:name).order(:name)).count
|
667
740
|
assert_equal 9, User.where(@ut[:name].in(@ut.project(@ut[:name]).order(@ut[:name]))).count
|
668
741
|
if !['mysql'].include?(@env_db) # MySql can't have limit in IN subquery
|
@@ -2,7 +2,7 @@ require 'arelx_test_helper'
|
|
2
2
|
require 'date'
|
3
3
|
|
4
4
|
module ArelExtensions
|
5
|
-
module
|
5
|
+
module WithAr
|
6
6
|
class InsertManagerTest < Minitest::Test
|
7
7
|
def setup_db
|
8
8
|
ActiveRecord::Base.configurations = YAML.load_file('test/database.yml')
|
@@ -13,7 +13,11 @@ module ArelExtensions
|
|
13
13
|
@env_db = ENV['DB']
|
14
14
|
end
|
15
15
|
ActiveRecord::Base.establish_connection(@env_db.try(:to_sym) || (RUBY_PLATFORM == 'java' ? :"jdbc-sqlite" : :sqlite))
|
16
|
-
ActiveRecord::
|
16
|
+
if ActiveRecord::VERSION::MAJOR >= 7
|
17
|
+
ActiveRecord.default_timezone = :utc
|
18
|
+
else
|
19
|
+
ActiveRecord::Base.default_timezone = :utc
|
20
|
+
end
|
17
21
|
@cnx = ActiveRecord::Base.connection
|
18
22
|
Arel::Table.engine = ActiveRecord::Base
|
19
23
|
if File.exist?("init/#{@env_db}.sql")
|
@@ -1,12 +1,16 @@
|
|
1
1
|
require 'arelx_test_helper'
|
2
2
|
|
3
3
|
module ArelExtensions
|
4
|
-
module
|
4
|
+
module WithAr
|
5
5
|
describe 'the sqlite visitor' do
|
6
6
|
before do
|
7
7
|
ActiveRecord::Base.configurations = YAML.load_file('test/database.yml')
|
8
8
|
ActiveRecord::Base.establish_connection(ENV['DB'] || (RUBY_PLATFORM == 'java' ? :"jdbc-sqlite" : :sqlite))
|
9
|
-
ActiveRecord::
|
9
|
+
if ActiveRecord::VERSION::MAJOR >= 7
|
10
|
+
ActiveRecord.default_timezone = :utc
|
11
|
+
else
|
12
|
+
ActiveRecord::Base.default_timezone = :utc
|
13
|
+
end
|
10
14
|
@cnx = ActiveRecord::Base.connection
|
11
15
|
Arel::Table.engine = ActiveRecord::Base
|
12
16
|
@cnx.drop_table(:users) rescue nil
|
@@ -1,12 +1,16 @@
|
|
1
1
|
require 'arelx_test_helper'
|
2
2
|
|
3
3
|
module ArelExtensions
|
4
|
-
module
|
4
|
+
module WithAr
|
5
5
|
describe 'the sqlite visitor can do maths' do
|
6
6
|
before do
|
7
7
|
ActiveRecord::Base.configurations = YAML.load_file('test/database.yml')
|
8
8
|
ActiveRecord::Base.establish_connection(ENV['DB'] || (RUBY_PLATFORM == 'java' ? :"jdbc-sqlite" : :sqlite))
|
9
|
-
ActiveRecord::
|
9
|
+
if ActiveRecord::VERSION::MAJOR >= 7
|
10
|
+
ActiveRecord.default_timezone = :utc
|
11
|
+
else
|
12
|
+
ActiveRecord::Base.default_timezone = :utc
|
13
|
+
end
|
10
14
|
Arel::Table.engine = ActiveRecord::Base
|
11
15
|
@cnx = ActiveRecord::Base.connection
|
12
16
|
@cnx.drop_table(:users) rescue nil
|
@@ -2,12 +2,16 @@ require 'arelx_test_helper'
|
|
2
2
|
require 'date'
|
3
3
|
|
4
4
|
module ArelExtensions
|
5
|
-
module
|
5
|
+
module WithAr
|
6
6
|
describe 'the mysql visitor can do string operations' do
|
7
7
|
before do
|
8
8
|
ActiveRecord::Base.configurations = YAML.load_file('test/database.yml')
|
9
9
|
ActiveRecord::Base.establish_connection(ENV['DB'] || (RUBY_PLATFORM == 'java' ? :"jdbc-mysql" : :mysql))
|
10
|
-
ActiveRecord::
|
10
|
+
if ActiveRecord::VERSION::MAJOR >= 7
|
11
|
+
ActiveRecord.default_timezone = :utc
|
12
|
+
else
|
13
|
+
ActiveRecord::Base.default_timezone = :utc
|
14
|
+
end
|
11
15
|
begin
|
12
16
|
@cnx = ActiveRecord::Base.connection
|
13
17
|
rescue => e
|
@@ -2,12 +2,16 @@ require 'arelx_test_helper'
|
|
2
2
|
require 'date'
|
3
3
|
|
4
4
|
module ArelExtensions
|
5
|
-
module
|
5
|
+
module WithAr
|
6
6
|
describe 'the sqlite visitor can do string operations' do
|
7
7
|
before do
|
8
8
|
ActiveRecord::Base.configurations = YAML.load_file('test/database.yml')
|
9
9
|
ActiveRecord::Base.establish_connection(ENV['DB'] || (RUBY_PLATFORM == 'java' ? :"jdbc-sqlite" : :sqlite))
|
10
|
-
ActiveRecord::
|
10
|
+
if ActiveRecord::VERSION::MAJOR >= 7
|
11
|
+
ActiveRecord.default_timezone = :utc
|
12
|
+
else
|
13
|
+
ActiveRecord::Base.default_timezone = :utc
|
14
|
+
end
|
11
15
|
@cnx = ActiveRecord::Base.connection
|
12
16
|
Arel::Table.engine = ActiveRecord::Base
|
13
17
|
@cnx.drop_table(:users) rescue nil
|
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.
|
4
|
+
version: 2.1.1
|
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: 2022-03-03 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activerecord
|
@@ -44,16 +44,16 @@ dependencies:
|
|
44
44
|
name: rdoc
|
45
45
|
requirement: !ruby/object:Gem::Requirement
|
46
46
|
requirements:
|
47
|
-
- - "
|
47
|
+
- - ">="
|
48
48
|
- !ruby/object:Gem::Version
|
49
|
-
version:
|
49
|
+
version: 6.3.1
|
50
50
|
type: :development
|
51
51
|
prerelease: false
|
52
52
|
version_requirements: !ruby/object:Gem::Requirement
|
53
53
|
requirements:
|
54
|
-
- - "
|
54
|
+
- - ">="
|
55
55
|
- !ruby/object:Gem::Version
|
56
|
-
version:
|
56
|
+
version: 6.3.1
|
57
57
|
- !ruby/object:Gem::Dependency
|
58
58
|
name: rake
|
59
59
|
requirement: !ruby/object:Gem::Requirement
|
@@ -97,7 +97,6 @@ files:
|
|
97
97
|
- Rakefile
|
98
98
|
- SQL_Challenges.md
|
99
99
|
- TODO
|
100
|
-
- appveyor.yml
|
101
100
|
- arel_extensions.gemspec
|
102
101
|
- functions.html
|
103
102
|
- gemfiles/rails3.gemfile
|
@@ -107,6 +106,7 @@ files:
|
|
107
106
|
- gemfiles/rails5_2.gemfile
|
108
107
|
- gemfiles/rails6.gemfile
|
109
108
|
- gemfiles/rails6_1.gemfile
|
109
|
+
- gemfiles/rails7.gemfile
|
110
110
|
- gemspecs/arel_extensions-v1.gemspec
|
111
111
|
- gemspecs/arel_extensions-v2.gemspec
|
112
112
|
- generate_gems.sh
|
@@ -116,11 +116,13 @@ files:
|
|
116
116
|
- init/postgresql.sql
|
117
117
|
- init/sqlite.sql
|
118
118
|
- lib/arel_extensions.rb
|
119
|
+
- lib/arel_extensions/aliases.rb
|
119
120
|
- lib/arel_extensions/attributes.rb
|
120
121
|
- lib/arel_extensions/boolean_functions.rb
|
121
122
|
- lib/arel_extensions/common_sql_functions.rb
|
122
123
|
- lib/arel_extensions/comparators.rb
|
123
124
|
- lib/arel_extensions/date_duration.rb
|
125
|
+
- lib/arel_extensions/helpers.rb
|
124
126
|
- lib/arel_extensions/insert_manager.rb
|
125
127
|
- lib/arel_extensions/math.rb
|
126
128
|
- lib/arel_extensions/math_functions.rb
|
@@ -222,7 +224,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
222
224
|
- !ruby/object:Gem::Version
|
223
225
|
version: '0'
|
224
226
|
requirements: []
|
225
|
-
rubygems_version: 3.
|
227
|
+
rubygems_version: 3.2.3
|
226
228
|
signing_key:
|
227
229
|
specification_version: 4
|
228
230
|
summary: Extending Arel
|