arel_extensions 2.0.24 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +153 -72
- data/README.md +42 -0
- data/gemfiles/rails5_2.gemfile +6 -5
- data/gemfiles/rails6.gemfile +6 -6
- data/gemfiles/rails6_1.gemfile +5 -5
- data/gemfiles/rails7.gemfile +30 -0
- data/lib/arel_extensions/aliases.rb +14 -0
- data/lib/arel_extensions/attributes.rb +2 -0
- data/lib/arel_extensions/nodes/case.rb +2 -5
- data/lib/arel_extensions/version.rb +1 -1
- data/lib/arel_extensions/visitors/mysql.rb +9 -2
- data/lib/arel_extensions/visitors/postgresql.rb +8 -2
- data/lib/arel_extensions/visitors/to_sql.rb +13 -8
- data/lib/arel_extensions.rb +16 -6
- data/test/real_db_test.rb +5 -1
- data/test/visitors/test_to_sql.rb +17 -10
- data/test/with_ar/all_agnostic_test.rb +14 -3
- 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 +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e7a9848d43d40c207414003ca84c7719ad94bf2899b0e480768c623d3fe8d3ce
|
4
|
+
data.tar.gz: 9638df9811fbe0220ba6a1ebd123d2f2fa35794e23c303cd7c29709e2147b2b5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2ecc111c143ce298c40ce7e595b0b175589ee4e0cd469e180fd69e245219646422435f145ba774d4271878c23d0b1a04e2af840d250c79d159ab2f227d8605b8
|
7
|
+
data.tar.gz: f25c0cf0f3a155c93aad8f295952f701dfb5d4ed5bc2adfef5984884a27700576331624a5d912b95301c8c2ef55cbde650d951676734d4290dcb6372cbec837a
|
data/.github/workflows/ruby.yml
CHANGED
@@ -1,23 +1,63 @@
|
|
1
|
-
|
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
|
-
|
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
|
-
|
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
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
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
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
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.
|
data/gemfiles/rails5_2.gemfile
CHANGED
@@ -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
|
12
|
-
gem "mysql2", '0.4.10', platforms: [:mri
|
13
|
-
gem "pg",'< 1.0.0', platforms: [:mri
|
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
|
16
|
-
|
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'
|
data/gemfiles/rails6.gemfile
CHANGED
@@ -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
|
12
|
-
|
13
|
-
|
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
|
-
|
16
|
-
|
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: "../"
|
data/gemfiles/rails6_1.gemfile
CHANGED
@@ -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
|
12
|
-
gem "mysql2", '0.5.2', platforms: [:mri
|
13
|
-
gem "pg",'~> 1.1', platforms: [:mri
|
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
|
-
|
16
|
-
|
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: "../"
|
@@ -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
|
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
|
@@ -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(
|
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(
|
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(
|
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(
|
618
|
+
Arel.when(s.is_null).then(make_json_null).else(make_json_string(s))
|
614
619
|
when :nil
|
615
|
-
|
620
|
+
make_json_null
|
616
621
|
else
|
617
|
-
ArelExtensions::Nodes::Cast.new([v, :string]).coalesce(
|
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])
|
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])
|
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
|
data/lib/arel_extensions.rb
CHANGED
@@ -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.
|
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::
|
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
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
.
|
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
|
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
|
@@ -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
|
-
|
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
|
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.0
|
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:
|
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.
|
227
|
+
rubygems_version: 3.2.3
|
226
228
|
signing_key:
|
227
229
|
specification_version: 4
|
228
230
|
summary: Extending Arel
|