arel_extensions 2.1.0 → 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.
@@ -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: travis
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: travis
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
@@ -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
@@ -33,7 +33,7 @@ module ArelExtensions
33
33
  t.column :name, :string
34
34
  t.column :comments, :text
35
35
  t.column :created_at, :date
36
- t.column :updated_at, :datetime
36
+ t.column :updated_at, :datetime, precision: nil
37
37
  t.column :duration, :time
38
38
  t.column :other, :string
39
39
  t.column :score, :decimal, :precision => 20, :scale => 10
@@ -171,7 +171,7 @@ module ArelExtensions
171
171
  # This should works no matter which version of rails is used
172
172
  assert User.group(:score).average(:id).values.all?{|e| !e.nil?}
173
173
 
174
- # Since Rails 7, a patch to calculations.rb has tirggered a double
174
+ # Since Rails 7, a patch to calculations.rb has tirggered a double
175
175
  # quoting of the alias name. See https://github.com/rails/rails/commit/7e6e9091e55c3357b0162d44b6ab955ed0c718d5
176
176
  # Before the patch that fixed this the following error would occur:
177
177
  # ActiveRecord::StatementInvalid: PG::SyntaxError: ERROR: zero-length delimited identifier at or near """"
@@ -370,6 +370,68 @@ module ArelExtensions
370
370
  assert_equal '2016-05-23', t(@lucas, @created_at.format('%Y-%m-%d'))
371
371
  assert_equal '2014/03/03 12:42:00', t(@lucas, @updated_at.format('%Y/%m/%d %H:%M:%S'))
372
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']))
373
435
  end
374
436
 
375
437
  def test_coalesce
@@ -525,7 +587,7 @@ module ArelExtensions
525
587
  # puts @age.is_null.inspect
526
588
  # puts @age.is_null.to_sql
527
589
  # puts @age=='34'
528
- assert_equal "Test", User.select(@name).where(@age.is_null.to_sql).first.name
590
+ assert_equal "Test", User.select(@name).where(@age.is_null).first.name
529
591
  end
530
592
 
531
593
  def test_math_plus
@@ -673,6 +735,7 @@ module ArelExtensions
673
735
  end
674
736
 
675
737
  def test_subquery_with_order
738
+ skip if ['mssql'].include?(@env_db) && Arel::VERSION.to_i < 10
676
739
  assert_equal 9, User.where(:name => User.select(:name).order(:name)).count
677
740
  assert_equal 9, User.where(@ut[:name].in(@ut.project(@ut[:name]).order(@ut[:name]))).count
678
741
  if !['mysql'].include?(@env_db) # MySql can't have limit in IN subquery
data/version_v1.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module ArelExtensions
2
- VERSION = "1.3.0".freeze
2
+ VERSION = "1.3.1".freeze
3
3
  end
data/version_v2.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module ArelExtensions
2
- VERSION = "2.1.0".freeze
2
+ VERSION = "2.1.1".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.0
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: 2022-02-04 00:00:00.000000000 Z
13
+ date: 2022-03-03 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activerecord
@@ -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
@@ -123,6 +122,7 @@ files:
123
122
  - lib/arel_extensions/common_sql_functions.rb
124
123
  - lib/arel_extensions/comparators.rb
125
124
  - lib/arel_extensions/date_duration.rb
125
+ - lib/arel_extensions/helpers.rb
126
126
  - lib/arel_extensions/insert_manager.rb
127
127
  - lib/arel_extensions/math.rb
128
128
  - lib/arel_extensions/math_functions.rb
data/appveyor.yml DELETED
@@ -1,44 +0,0 @@
1
- version: "{build}"
2
-
3
- cache:
4
- - vendor/bundle
5
-
6
- branches:
7
- only:
8
- - master
9
-
10
- services:
11
- - mssql2014
12
-
13
-
14
- install:
15
- - set PATH=C:\Ruby%RUBY_VERSION%\bin;%PATH%
16
- - bundle config --local path vendor/bundle
17
- - bundle install
18
-
19
- # Disable normal Windows builds in favor of our test script.
20
- build: off
21
-
22
-
23
- before_test:
24
- - ruby -v
25
- - gem -v
26
- - bundle -v
27
-
28
- test_script:
29
- - ruby --version
30
- - gem --version
31
- - bundler --version
32
- - bundle exec rake test
33
- - ps: Start-Service 'MSSQL$SQL2014'
34
- - timeout /t 4 /nobreak > NUL
35
- - bundle exec rake test:mssql
36
-
37
- environment:
38
- matrix:
39
- - RUBY_VERSION: 200
40
- - RUBY_VERSION: 21
41
- - RUBY_VERSION: 22
42
- - RUBY_VERSION: 23
43
- - RUBY_VERSION: 23-x64
44
-