arel_extensions 2.0.24 → 2.1.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bbeb1b141db51f78567bf26939ecb75832dd1c3e524407bf11a56308d8da6d14
4
- data.tar.gz: 543d1893d29e871ebfa9ccdc8e49179cbedf49cd5ccf6b082113925bedffbc81
3
+ metadata.gz: e7a9848d43d40c207414003ca84c7719ad94bf2899b0e480768c623d3fe8d3ce
4
+ data.tar.gz: 9638df9811fbe0220ba6a1ebd123d2f2fa35794e23c303cd7c29709e2147b2b5
5
5
  SHA512:
6
- metadata.gz: e4957e64d63412917884f8cc79b42b81643a7e512f4a0e0ef2331672f34cf625b1cec88dbefdf3e3c65d8fca63e2258dc0ff56d8e96964a392c12a89657756c9
7
- data.tar.gz: 2d090ca797080248a3a44521cdae686e721e627c787fa971e340c2b9dc08b91e51992fd47265aad6ccf0bee2d73c8a2e72ad5681fe09844008f5e21577a2d8ce
6
+ metadata.gz: 2ecc111c143ce298c40ce7e595b0b175589ee4e0cd469e180fd69e245219646422435f145ba774d4271878c23d0b1a04e2af840d250c79d159ab2f227d8605b8
7
+ data.tar.gz: f25c0cf0f3a155c93aad8f295952f701dfb5d4ed5bc2adfef5984884a27700576331624a5d912b95301c8c2ef55cbde650d951676734d4290dcb6372cbec837a
@@ -1,23 +1,63 @@
1
- # This workflow uses actions that are not certified by GitHub.
2
- # They are provided by a third-party and are governed by
3
- # separate terms of service, privacy policy, and support
4
- # documentation.
5
- # This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
6
- # For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
1
+ name: Build and Test
7
2
 
8
- name: Ruby
3
+ # Ruby + Rails Compatibility Matrix from here:
4
+ # https://www.fastruby.io/blog/ruby/rails/versions/compatibility-table.html
9
5
 
10
- on:
11
- push:
12
- branches: [ master ]
13
- pull_request:
14
- branches: [ master ]
6
+ on: [push, pull_request]
15
7
 
16
8
  jobs:
17
- test:
18
-
9
+ job_build_gem:
10
+ name: build
19
11
  runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ ruby: [3.1, 3.0, 2.7, 2.5]
15
+ rails: [7, 6_1, 6, 5_2]
16
+ exclude: [
17
+ {ruby: 3.1, rails: 6 },
18
+ {ruby: 3.1, rails: 5_2},
19
+ {ruby: 3.0, rails: 6 },
20
+ {ruby: 3.0, rails: 5_2},
21
+ {ruby: 2.7, rails: 5_2},
22
+ {ruby: 2.5, rails: 7 },
23
+ ]
24
+ steps:
25
+ - uses: actions/checkout@v2
26
+ - name: Set up Ruby
27
+ uses: ruby/setup-ruby@v1
28
+ with:
29
+ ruby-version: ${{ matrix.ruby }}
30
+ - name: Setup gemspec
31
+ if: ${{ matrix.rails == '6_1' || matrix.rails == '6' }}
32
+ run: |
33
+ cp ./gemspecs/arel_extensions-v2.gemspec ./arel_extensions.gemspec
34
+ cp ./version_v2.rb lib/arel_extensions/version.rb
35
+ cp ./gemfiles/rails${{ matrix.rails }}.gemfile ./Gemfile
36
+ - name: Build source gem
37
+ run: gem build arel_extensions.gemspec
38
+ - name: Upload source gem
39
+ uses: actions/upload-artifact@v2
40
+ with:
41
+ name: ${{ matrix.ruby }}-${{ matrix.rails }}-gem
42
+ path: "*.gem"
20
43
 
44
+ job_test_linux:
45
+ name: test linux
46
+ needs: job_build_gem
47
+ runs-on: ubuntu-latest
48
+ strategy:
49
+ fail-fast: false
50
+ matrix:
51
+ ruby: [3.1, 3.0, 2.7, 2.5]
52
+ rails: [7, 6_1, 6, 5_2]
53
+ exclude: [
54
+ {ruby: 3.1, rails: 6 },
55
+ {ruby: 3.1, rails: 5_2},
56
+ {ruby: 3.0, rails: 6 },
57
+ {ruby: 3.0, rails: 5_2},
58
+ {ruby: 2.7, rails: 5_2},
59
+ {ruby: 2.5, rails: 7 },
60
+ ]
21
61
  services:
22
62
  postgres:
23
63
  image: postgres:11.6-alpine
@@ -28,8 +68,8 @@ jobs:
28
68
  # needed because the postgres container does not provide a healthcheck
29
69
  options: >-
30
70
  --health-cmd "pg_isready -d arext_test -U postgres -p 5432"
31
- --health-interval 10s
32
- --health-timeout 5s
71
+ --health-interval 10s
72
+ --health-timeout 5s
33
73
  --health-retries 5
34
74
  mysql:
35
75
  image: mysql:5.7
@@ -40,63 +80,104 @@ jobs:
40
80
  ports:
41
81
  - 3306:3306
42
82
  options: >-
43
- --health-cmd="mysqladmin ping"
44
- --health-interval=10s
45
- --health-timeout=5s
83
+ --health-cmd="mysqladmin ping"
84
+ --health-interval=10s
85
+ --health-timeout=5s
46
86
  --health-retries=3
47
-
87
+ steps:
88
+ - uses: actions/checkout@v2
89
+ - name: Set up Ruby
90
+ uses: ruby/setup-ruby@v1
91
+ with:
92
+ ruby-version: ${{ matrix.ruby }}
93
+ - name: Install FreeTDS
94
+ run: |
95
+ sudo apt-get update -q
96
+ sudo apt-get install -y freetds-dev
97
+ - name: Install MSSQL 2019
98
+ uses: potatoqualitee/mssqlsuite@v1
99
+ with:
100
+ install: sqlengine, sqlclient, sqlpackage, localdb
101
+ sa-password: Password12!
102
+ - name: Update system-wide gems
103
+ run: gem update --system
104
+ - name: bundle install
105
+ run: |
106
+ bundle config set gemfile ./gemfiles/rails${{ matrix.rails }}.gemfile
107
+ bundle install
108
+ - name: Download gem from build job
109
+ uses: actions/download-artifact@v2
110
+ with:
111
+ name: ${{ matrix.ruby }}-${{ matrix.rails }}-gem
112
+ - name: Install downloaded gem
113
+ run: gem install --local *.gem --verbose
114
+ - name: Run test to_sql
115
+ run: rake test:to_sql
116
+ - name: Run test Postgres
117
+ env:
118
+ PGHOST: localhost
119
+ PGUSER: postgres
120
+ run: rake test:postgresql
121
+ - name: Run test MySql
122
+ env:
123
+ DB_CONNECTION: mysql
124
+ DB_HOST: 127.0.0.1
125
+ DB_PORT: 3306
126
+ DB_DATABASE: arext_test
127
+ DB_USERNAME: travis
128
+ run: |
129
+ mysql --host 127.0.0.1 --port 3306 -uroot -e 'create user travis;'
130
+ mysql --host 127.0.0.1 --port 3306 -uroot -e 'GRANT ALL PRIVILEGES ON arext_test.* TO travis;'
131
+ rake test:mysql
132
+ - name: Run test mssql
133
+ run: rake test:mssql
134
+
135
+
136
+ job_test_windows:
137
+ name: test windows
138
+ needs: job_build_gem
139
+ runs-on: windows-latest
48
140
  strategy:
141
+ fail-fast: false
49
142
  matrix:
50
- ruby-version:
51
- - 3.0.0-preview1
52
- - 2.7
53
- - 2.5
54
- - 2.3
55
- rails-version:
56
- - 6_1
57
- - 6
58
- - 5_2
59
- exclude:
60
- - ruby-version: 2.3
61
- rails-version: 6_1
62
- - ruby-version: 2.3
63
- rails-version: 6
64
- - ruby-version: 3.0.0-preview1
65
- rails-version: 5.2
66
- continue-on-error: ${{ true }}
67
-
143
+ ruby: [3.1, 3.0, 2.7, 2.5]
144
+ rails: [7, 6_1, 6, 5_2]
145
+ exclude: [
146
+ {ruby: 3.1, rails: 6 },
147
+ {ruby: 3.1, rails: 5_2},
148
+ {ruby: 3.0, rails: 6 },
149
+ {ruby: 3.0, rails: 5_2},
150
+ {ruby: 2.7, rails: 5_2},
151
+ {ruby: 2.5, rails: 7 },
152
+ ]
68
153
  steps:
69
- - uses: actions/checkout@v2
70
- - name: Set up Ruby
71
- # To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
72
- # change this to (see https://github.com/ruby/setup-ruby#versioning):
73
- # uses: ruby/setup-ruby@v1
74
- uses: ruby/setup-ruby@21351ecc0a7c196081abca5dc55b08f085efe09a
75
- with:
76
- ruby-version: ${{ matrix.ruby-version }}
77
- - name: Setup gemspec
78
- if: ${{ matrix.rails-version == '6_1' || matrix.rails-version == '6' }}
79
- run: cp ./gemspecs/arel_extensions-v2.gemspec ./arel_extensions.gemspec
80
- - name: Install dependencies
81
- run: |
82
- export BUNDLE_GEMFILE=gemfiles/rails${{ matrix.rails-version }}.gemfile
83
- bundle install
84
- - name: Run test to_sql
85
- run: rake test:to_sql
86
- - name: Run test Postgres
87
- env:
88
- PGHOST: localhost
89
- PGUSER: postgres
90
- run: rake test:postgresql
91
- - name: Run test MySql
92
- env:
93
- DB_CONNECTION: mysql
94
- DB_HOST: 127.0.0.1
95
- DB_PORT: 3306
96
- DB_DATABASE: arext_test
97
- DB_USERNAME: travis
98
- run: |
99
- sudo apt-get install -y mysql-client
100
- mysql --host 127.0.0.1 --port 3306 -uroot -e 'create user travis;'
101
- mysql --host 127.0.0.1 --port 3306 -uroot -e 'GRANT ALL PRIVILEGES ON arext_test.* TO travis;'
102
- rake test:mysql
154
+ - uses: actions/checkout@v2
155
+ - name: Install mssql
156
+ uses: potatoqualitee/mssqlsuite@v1
157
+ with:
158
+ install: sqlengine, sqlclient, sqlpackage, localdb
159
+ sa-password: Password12!
160
+ - name: Set up Ruby
161
+ uses: MSP-Greg/ruby-setup-ruby@win-ucrt-1
162
+ with:
163
+ ruby-version: ${{ matrix.ruby }}
164
+ - name: Install required packages on Windows
165
+ shell: cmd
166
+ run: |
167
+ ridk exec sh -c "pacman --sync --needed --noconfirm ${MINGW_PACKAGE_PREFIX}-gcc"
168
+ - name: Update system-wide gems
169
+ run: gem update --system
170
+ - name: bundle install
171
+ run: |
172
+ bundle config set gemfile .\gemfiles\rails${{ matrix.rails }}.gemfile
173
+ bundle install --verbose
174
+ - name: Download gem from build job
175
+ uses: actions/download-artifact@v2
176
+ with:
177
+ name: ${{ matrix.ruby }}-${{ matrix.rails }}-gem
178
+ - name: Install downloaded gem
179
+ run: gem install --local *.gem --verbose
180
+ - name: Run test to_sql
181
+ run: rake test:to_sql
182
+ - name: Run test mssql
183
+ run: rake test:mssql
data/README.md CHANGED
@@ -596,3 +596,45 @@ User.connection.execute(insert_manager.to_sql)
596
596
  </tr>
597
597
  </tbody>
598
598
  </table>
599
+
600
+ ## Version Compatibility
601
+
602
+ <table>
603
+ <tr><th>Ruby</th> <th>Rails</th> <th>Arel Extensions</th></tr>
604
+ <tr><td>3.1</td> <td>6.1</td> <td>2</td></tr>
605
+ <tr><td>3.0</td> <td>6.1</td> <td>2</td></tr>
606
+ <tr><td>2.7</td> <td>6.1, 6.0</td> <td>2</td></tr>
607
+ <tr><td>2.5</td> <td>6.1, 6.0</td> <td>2</td></tr>
608
+ <tr><td>2.5</td> <td>5.2</td> <td>1</td></tr>
609
+ </table>
610
+
611
+ ## Development
612
+
613
+ Let's say you want to develop/test for `ruby 2.7.5` and `rails 5.2`.
614
+
615
+ You will need to fix your ruby version:
616
+
617
+ ```bash
618
+ rbenv install 2.7.5
619
+ rbenv local 2.7.5
620
+ ```
621
+
622
+ Fix your gemfiles:
623
+
624
+ ```bash
625
+ bundle config set --local gemfile ./gemfiles/rails6.gemfile
626
+ ```
627
+
628
+ Install dependencies:
629
+ ```bash
630
+ bundle install
631
+ ```
632
+
633
+ Develop, then test:
634
+
635
+ ```bash
636
+ bundle exec rake test:to_sql
637
+ ```
638
+
639
+ Refer to the [Version Compatibility](#version-compatibility) section to correctly
640
+ set your gemfile.
@@ -4,16 +4,17 @@ gem 'rails', '~> 5.2.0'
4
4
  gem 'arel', '~> 9'
5
5
 
6
6
  group :development, :test do
7
+ gem 'bigdecimal', '1.3.5'
7
8
  gem 'activesupport', '~> 5.2.0'
8
9
  gem 'activemodel', '~> 5.2.0'
9
10
  gem 'activerecord', '~> 5.2.0'
10
11
 
11
- gem "sqlite3", '<= 1.3.13', platforms: [:mri, :mswin, :mingw]
12
- gem "mysql2", '0.4.10', platforms: [:mri, :mswin, :mingw]
13
- gem "pg",'< 1.0.0', platforms: [:mri, :mingw]
12
+ gem "sqlite3", '<= 1.3.13', platforms: [:mri]
13
+ gem "mysql2", '0.4.10', platforms: [:mri]
14
+ gem "pg",'< 1.0.0', platforms: [:mri]
14
15
 
15
- gem "tiny_tds", platforms: [:mri, :mingw] if RUBY_PLATFORM =~ /windows/
16
- # gem "activerecord-sqlserver-adapter", :platforms => [:mri, :mingw]
16
+ gem "tiny_tds", platforms: [:mri, :mingw, :x64_mingw, :mswin]
17
+ gem "activerecord-sqlserver-adapter", '~> 5.2', :platforms => [:mri, :mingw, :x64_mingw, :mswin]
17
18
 
18
19
  gem 'ruby-oci8', platforms: [:mri, :mswin, :mingw] if ENV.has_key? 'ORACLE_HOME'
19
20
  gem 'activerecord-oracle_enhanced-adapter', '~> 5.2.0' if ENV.has_key? 'ORACLE_HOME'
@@ -8,12 +8,12 @@ group :development, :test do
8
8
  gem 'activemodel', '~> 6.0.0'
9
9
  gem 'activerecord', '~> 6.0.0'
10
10
 
11
- gem "sqlite3", '~> 1.4', platforms: [:mri, :mswin, :mingw]
12
- gem "mysql2", '0.5.2', platforms: [:mri, :mswin, :mingw]
13
- gem "pg",'< 1.0.0', platforms: [:mri, :mingw]
11
+ gem "sqlite3", '~> 1.4', platforms: [:mri]
12
+ gem "mysql2", '0.5.2', platforms: [:mri]
13
+ gem "pg",'< 1.0.0', platforms: [:mri]
14
14
 
15
- #gem "tiny_tds", platforms: [:mri, :mingw] if RUBY_PLATFORM =~ /windows/
16
- #gem "activerecord-sqlserver-adapter", platforms: [:mri, :mingw]
15
+ gem "tiny_tds", platforms: [:mri, :mingw, :x64_mingw, :mswin]
16
+ gem "activerecord-sqlserver-adapter", '~> 6.0', platforms: [:mri, :mingw, :x64_mingw, :mswin]
17
17
 
18
18
  gem 'ruby-oci8', platforms: [:mri, :mswin, :mingw] if ENV.has_key? 'ORACLE_HOME'
19
19
  gem 'activerecord-oracle_enhanced-adapter', '~> 6.0.0' if ENV.has_key? 'ORACLE_HOME'
@@ -27,4 +27,4 @@ group :development, :test do
27
27
  gem "activerecord-jdbcmssql-adapter", platforms: :jruby
28
28
  end
29
29
 
30
- gemspec path: "../"
30
+ gemspec path: "../"
@@ -8,12 +8,12 @@ group :development, :test do
8
8
  gem 'activemodel', '~> 6.1.0'
9
9
  gem 'activerecord', '~> 6.1.0'
10
10
 
11
- gem "sqlite3", '~> 1.4', platforms: [:mri, :mswin, :mingw]
12
- gem "mysql2", '0.5.2', platforms: [:mri, :mswin, :mingw]
13
- gem "pg",'~> 1.1', platforms: [:mri, :mingw]
11
+ gem "sqlite3", '~> 1.4', platforms: [:mri]
12
+ gem "mysql2", '0.5.2', platforms: [:mri]
13
+ gem "pg",'~> 1.1', platforms: [:mri]
14
14
 
15
- #gem "tiny_tds", platforms: [:mri, :mingw] if RUBY_PLATFORM =~ /windows/
16
- #gem "activerecord-sqlserver-adapter", platforms: [:mri, :mingw]
15
+ gem "tiny_tds", platforms: [:mri, :mingw, :x64_mingw, :mswin]
16
+ gem "activerecord-sqlserver-adapter", '~> 6.1.0', platforms: [:mri, :mingw, :x64_mingw, :mswin]
17
17
 
18
18
  gem 'ruby-oci8', platforms: [:mri, :mswin, :mingw] if ENV.has_key? 'ORACLE_HOME'
19
19
  gem 'activerecord-oracle_enhanced-adapter', '~> 6.0.0' if ENV.has_key? 'ORACLE_HOME'
@@ -0,0 +1,30 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem 'rails', '~> 7.0.1'
4
+
5
+
6
+ group :development, :test do
7
+ gem 'activesupport', '~> 7.0.1'
8
+ gem 'activemodel', '~> 7.0.1'
9
+ gem 'activerecord', '~> 7.0.1'
10
+
11
+ gem "sqlite3", '~> 1.4', platforms: [:mri, :mswin, :mingw]
12
+ gem "mysql2", '0.5.2', platforms: [:mri, :mswin, :mingw]
13
+ gem "pg",'~> 1.1', platforms: [:mri, :mingw]
14
+
15
+ #gem "tiny_tds", platforms: [:mri, :mingw] if RUBY_PLATFORM =~ /windows/
16
+ #gem "activerecord-sqlserver-adapter", platforms: [:mri, :mingw]
17
+
18
+ gem 'ruby-oci8', platforms: [:mri, :mswin, :mingw] if ENV.has_key? 'ORACLE_HOME'
19
+ gem 'activerecord-oracle_enhanced-adapter', '~> 6.0.0' if ENV.has_key? 'ORACLE_HOME'
20
+
21
+ # for JRuby
22
+ gem 'activerecord-jdbc-adapter', platforms: :jruby
23
+ gem "jdbc-sqlite3", platforms: :jruby
24
+ gem "activerecord-jdbcsqlite3-adapter", platforms: :jruby
25
+ gem "activerecord-jdbcmysql-adapter", platforms: :jruby
26
+ gem "activerecord-jdbcpostgresql-adapter", platforms: :jruby
27
+ gem "activerecord-jdbcmssql-adapter", platforms: :jruby
28
+ end
29
+
30
+ gemspec path: "../"
@@ -0,0 +1,14 @@
1
+ module ArelExtensions
2
+ module Aliases
3
+
4
+ # Install an alias, if present.
5
+ def xas other
6
+ if other.present?
7
+ Arel::Nodes::As.new(self, Arel.sql(other))
8
+ else
9
+ self
10
+ end
11
+ end
12
+
13
+ end
14
+ end
@@ -1,3 +1,4 @@
1
+ require 'arel_extensions/aliases'
1
2
  require 'arel_extensions/math'
2
3
  require 'arel_extensions/comparators'
3
4
  require 'arel_extensions/date_duration'
@@ -8,6 +9,7 @@ require 'arel_extensions/predications'
8
9
 
9
10
  module ArelExtensions
10
11
  module Attributes
12
+ include ArelExtensions::Aliases
11
13
  include ArelExtensions::Math
12
14
  include ArelExtensions::Comparators
13
15
  include ArelExtensions::DateDuration
@@ -34,6 +34,7 @@ module ArelExtensions
34
34
  include Arel::Math
35
35
  include Arel::Predications
36
36
  include Arel::OrderPredications
37
+ include ArelExtensions::Aliases
37
38
  include ArelExtensions::Math
38
39
  include ArelExtensions::Comparators
39
40
  include ArelExtensions::Predications
@@ -102,11 +103,7 @@ module ArelExtensions
102
103
  alias :== :eql?
103
104
 
104
105
  def as other
105
- Arel::Nodes::As.new self, Arel::Nodes::SqlLiteral.new(other)
106
- end
107
-
108
- def xas other
109
- Arel::Nodes::As.new self, Arel::Nodes::SqlLiteral.new(other)
106
+ Arel::Nodes::As.new self, Arel.sql(other)
110
107
  end
111
108
  end
112
109
  end
@@ -1,3 +1,3 @@
1
1
  module ArelExtensions
2
- VERSION = "2.0.24".freeze
2
+ VERSION = "2.1.0".freeze
3
3
  end
@@ -354,9 +354,16 @@ module ArelExtensions
354
354
  else
355
355
  collector = visit o.left, collector
356
356
  end
357
- collector << " AS `"
357
+ collector << " AS "
358
+
359
+ # sometimes these values are already quoted, if they are, don't double quote it
360
+ quote = o.right.is_a?(Arel::Nodes::SqlLiteral) && o.right[0] != '`' && o.right[-1] != '`'
361
+
362
+ collector << '`' if quote
358
363
  collector = visit o.right, collector
359
- collector << "`"
364
+ collector << '`' if quote
365
+
366
+ collector
360
367
  collector
361
368
  end
362
369
 
@@ -86,9 +86,15 @@ module ArelExtensions
86
86
  else
87
87
  collector = visit o.left, collector
88
88
  end
89
- collector << " AS \""
89
+ collector << " AS "
90
+
91
+ # sometimes these values are already quoted, if they are, don't double quote it
92
+ quote = o.right.is_a?(Arel::Nodes::SqlLiteral) && o.right[0] != '"' && o.right[-1] != '"'
93
+
94
+ collector << '"' if quote
90
95
  collector = visit o.right, collector
91
- collector << "\""
96
+ collector << '"' if quote
97
+
92
98
  collector
93
99
  end
94
100
 
@@ -8,10 +8,15 @@ module ArelExtensions
8
8
  def make_json_string expr
9
9
  Arel::Nodes.build_quoted('"') \
10
10
  + expr
11
+ .coalesce('')
11
12
  .replace('\\','\\\\').replace('"','\"').replace("\n", '\n') \
12
13
  + '"'
13
14
  end
14
15
 
16
+ def make_json_null
17
+ Arel::Nodes.build_quoted("null")
18
+ end
19
+
15
20
  # Math Functions
16
21
  def visit_ArelExtensions_Nodes_Abs o, collector
17
22
  collector << "ABS("
@@ -601,20 +606,20 @@ module ArelExtensions
601
606
  def json_value(o,v)
602
607
  case o.type_of_node(v)
603
608
  when :string
604
- Arel.when(v.is_null).then(Arel.null).else(make_json_string(v))
609
+ Arel.when(v.is_null).then(make_json_null).else(make_json_string(v))
605
610
  when :date
606
611
  s = v.format('%Y-%m-%d')
607
- Arel.when(s.is_null).then(Arel.null).else(make_json_string(s))
612
+ Arel.when(s.is_null).then(make_json_null).else(make_json_string(s))
608
613
  when :datetime
609
614
  s = v.format('%Y-%m-%dT%H:%M:%S')
610
- Arel.when(s.is_null).then(Arel.null).else(make_json_string(s))
615
+ Arel.when(s.is_null).then(make_json_null).else(make_json_string(s))
611
616
  when :time
612
617
  s = v.format('%H:%M:%S')
613
- Arel.when(s.is_null).then(Arel.null).else(make_json_string(s))
618
+ Arel.when(s.is_null).then(make_json_null).else(make_json_string(s))
614
619
  when :nil
615
- Arel.null
620
+ make_json_null
616
621
  else
617
- ArelExtensions::Nodes::Cast.new([v, :string]).coalesce(Arel.null)
622
+ ArelExtensions::Nodes::Cast.new([v, :string]).coalesce(make_json_null)
618
623
  end
619
624
  end
620
625
 
@@ -636,7 +641,7 @@ module ArelExtensions
636
641
  if i != 0
637
642
  res += ', '
638
643
  end
639
- res += make_json_string(ArelExtensions::Nodes::Cast.new([k, :string]).coalesce("")) + ': '
644
+ res += make_json_string(ArelExtensions::Nodes::Cast.new([k, :string])) + ': '
640
645
  res += json_value(o,v)
641
646
  end
642
647
  res += '}'
@@ -658,7 +663,7 @@ module ArelExtensions
658
663
  if i != 0
659
664
  res = res + ', '
660
665
  end
661
- kv = make_json_string(ArelExtensions::Nodes::Cast.new([k, :string]).coalesce("")) + ': '
666
+ kv = make_json_string(ArelExtensions::Nodes::Cast.new([k, :string])) + ': '
662
667
  kv += json_value(o,v)
663
668
  res = res + kv.group_concat(', ', order: Array(orders)).coalesce('')
664
669
  end
@@ -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'
@@ -136,6 +137,7 @@ class Arel::Attributes::Attribute
136
137
  end
137
138
 
138
139
  class Arel::Nodes::Function
140
+ include ArelExtensions::Aliases
139
141
  include ArelExtensions::Math
140
142
  include ArelExtensions::Comparators
141
143
  include ArelExtensions::DateDuration
@@ -153,11 +155,6 @@ class Arel::Nodes::Function
153
155
  end
154
156
  res
155
157
  end
156
-
157
- def xas other
158
- Arel::Nodes::As.new(self, Arel.sql(other))
159
- end
160
-
161
158
  end
162
159
 
163
160
  class Arel::Nodes::Grouping
@@ -211,6 +208,15 @@ class Arel::SelectManager
211
208
  def as table_name
212
209
  Arel::Nodes::TableAlias.new(self, table_name)
213
210
  end
211
+
212
+ # Install an alias, if present.
213
+ def xas table_name
214
+ if table_name.present?
215
+ as table_name
216
+ else
217
+ self
218
+ end
219
+ end
214
220
  end
215
221
 
216
222
  class Arel::Nodes::As
@@ -220,7 +226,11 @@ end
220
226
  class Arel::Table
221
227
  alias_method(:old_alias, :alias) rescue nil
222
228
  def alias(name = "#{self.name}_2")
223
- name.blank? ? self : Arel::Nodes::TableAlias.new(self,name)
229
+ if name.present?
230
+ Arel::Nodes::TableAlias.new(self, name)
231
+ else
232
+ self
233
+ end
224
234
  end
225
235
  end
226
236
 
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::Base.default_timezone = :utc
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
@@ -282,16 +282,23 @@ module ArelExtensions
282
282
  .must_be_like %{CASE "users"."name" WHEN 'smith' THEN 'cool' ELSE 'uncool' END ILIKE 'value'}
283
283
  end
284
284
 
285
- it "should be possible to use as on anything" do
286
- _(compile(@table[:name].as('alias'))).must_be_like %{"users"."name" AS alias}
287
- _(compile(@table[:name].concat(' test').as('alias'))).must_be_like %{CONCAT("users"."name", ' test') AS alias}
288
- _(compile((@table[:name] + ' test').as('alias'))).must_be_like %{CONCAT("users"."name", ' test') AS alias}
289
- _(compile((@table[:age] + 42).as('alias'))).must_be_like %{("users"."age" + 42) AS alias}
290
- _(compile(@table[:name].coalesce('').as('alias'))).must_be_like %{COALESCE("users"."name", '') AS alias}
291
- _(compile(Arel::Nodes.build_quoted('test').as('alias'))).must_be_like %{'test' AS alias}
292
- _(compile(@table.project(@table[:name]).as('alias'))).must_be_like %{(SELECT "users"."name" FROM "users") "alias"}
293
- _(compile(@table[:name].when("smith").then("cool").else("uncool").as('alias')))
294
- .must_be_like %{CASE "users"."name" WHEN 'smith' THEN 'cool' ELSE 'uncool' END AS alias}
285
+ it "should be possible to use as/xas on anything" do
286
+ {
287
+ @table[:name] => %{"users"."name" AS alias},
288
+ @table[:name].concat(' test') => %{CONCAT("users"."name", ' test') AS alias},
289
+ (@table[:name] + ' test') => %{CONCAT("users"."name", ' test') AS alias},
290
+ (@table[:age] + 42) => %{("users"."age" + 42) AS alias},
291
+ @table[:name].coalesce('') => %{COALESCE("users"."name", '') AS alias},
292
+ Arel::Nodes.build_quoted('test') => %{'test' AS alias},
293
+ @table.project(@table[:name]) => %{(SELECT "users"."name" FROM "users") "alias"},
294
+ @table[:name].when("smith").then("cool").else("uncool") => %{CASE "users"."name" WHEN 'smith' THEN 'cool' ELSE 'uncool' END AS alias},
295
+ }.each do |exp, res|
296
+ _(compile(exp.as('alias'))).must_be_like res
297
+ _(compile(exp.xas('alias'))).must_be_like res
298
+
299
+ res_no_alias = res.gsub(/\s*(?:AS alias|"alias")\s*\z/, '')
300
+ _(compile(exp.xas(nil))).must_be_like res_no_alias
301
+ end
295
302
  end
296
303
 
297
304
  it "should accept comparators on functions" do
@@ -2,7 +2,7 @@ require 'arelx_test_helper'
2
2
  require 'date'
3
3
 
4
4
  module ArelExtensions
5
- module WthAr
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::Base.default_timezone = :utc
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
@@ -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
@@ -499,7 +509,8 @@ module ArelExtensions
499
509
  assert_equal Time, t(@lucas,@updated_at.cast(:string).cast(:datetime)).class
500
510
  assert_equal Time, t(@lucas,@updated_at.cast(:time)).class
501
511
 
502
- assert_equal "2014-03-03 12:42:00", t(@lucas,@updated_at.cast(:string)) unless @env_db == 'mssql' # locale dependent
512
+ # mysql adapter in rails7 adds some infos we just squeeze here
513
+ assert_equal "2014-03-03 12:42:00", t(@lucas,@updated_at.cast(:string)).split('.').first unless @env_db == 'mssql' # locale dependent
503
514
  assert_equal Date.parse("2014-03-03"), t(@lucas,Arel::Nodes.build_quoted('2014-03-03').cast(:date))
504
515
  assert_equal Date.parse("5014-03-03"), t(@lucas,(@age.cast(:string) + '014-03-03').cast(:date))
505
516
  assert_equal Time.parse("2014-03-03 12:42:00 UTC"), t(@lucas,@updated_at.cast(:string).cast(:datetime))
@@ -2,7 +2,7 @@ require 'arelx_test_helper'
2
2
  require 'date'
3
3
 
4
4
  module ArelExtensions
5
- module WthAr
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::Base.default_timezone = :utc
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 WthAr
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::Base.default_timezone = :utc
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 WthAr
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::Base.default_timezone = :utc
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 WthAr
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::Base.default_timezone = :utc
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 WthAr
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::Base.default_timezone = :utc
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
@@ -1,3 +1,3 @@
1
1
  module ArelExtensions
2
- VERSION = "1.2.27".freeze
2
+ VERSION = "1.3.0".freeze
3
3
  end
data/version_v2.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module ArelExtensions
2
- VERSION = "2.0.24".freeze
2
+ VERSION = "2.1.0".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.0.24
4
+ version: 2.1.0
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: 2021-12-01 00:00:00.000000000 Z
13
+ date: 2022-02-04 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activerecord
@@ -107,6 +107,7 @@ files:
107
107
  - gemfiles/rails5_2.gemfile
108
108
  - gemfiles/rails6.gemfile
109
109
  - gemfiles/rails6_1.gemfile
110
+ - gemfiles/rails7.gemfile
110
111
  - gemspecs/arel_extensions-v1.gemspec
111
112
  - gemspecs/arel_extensions-v2.gemspec
112
113
  - generate_gems.sh
@@ -116,6 +117,7 @@ files:
116
117
  - init/postgresql.sql
117
118
  - init/sqlite.sql
118
119
  - lib/arel_extensions.rb
120
+ - lib/arel_extensions/aliases.rb
119
121
  - lib/arel_extensions/attributes.rb
120
122
  - lib/arel_extensions/boolean_functions.rb
121
123
  - lib/arel_extensions/common_sql_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.0.8
227
+ rubygems_version: 3.2.3
226
228
  signing_key:
227
229
  specification_version: 4
228
230
  summary: Extending Arel