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 +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
|