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