arel_extensions 1.3.5 → 2.0.0.rc3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.codeclimate.yml +2 -1
- data/.gitignore +6 -7
- data/.rubocop.yml +3 -67
- data/.travis/oracle/download.js +152 -0
- data/.travis/oracle/download.sh +30 -0
- data/.travis/oracle/download_ojdbc.js +116 -0
- data/.travis/oracle/install.sh +34 -0
- data/.travis/setup_accounts.sh +9 -0
- data/.travis/sqlite3/extension-functions.sh +6 -0
- data/.travis.yml +223 -0
- data/Gemfile +21 -16
- data/README.md +13 -125
- data/Rakefile +30 -41
- data/TODO +1 -0
- data/appveyor.yml +22 -51
- data/arel_extensions.gemspec +14 -14
- data/functions.html +3 -3
- data/gemfiles/rails3.gemfile +10 -10
- data/gemfiles/rails4.gemfile +14 -14
- data/gemfiles/rails5_0.gemfile +14 -14
- data/gemfiles/rails5_1_4.gemfile +14 -14
- data/gemfiles/rails5_2.gemfile +14 -16
- data/init/mssql.sql +4 -4
- data/init/mysql.sql +38 -38
- data/init/oracle.sql +0 -0
- data/init/postgresql.sql +21 -21
- data/init/sqlite.sql +0 -0
- data/lib/arel_extensions/attributes.rb +3 -4
- data/lib/arel_extensions/boolean_functions.rb +14 -53
- data/lib/arel_extensions/common_sql_functions.rb +17 -16
- data/lib/arel_extensions/comparators.rb +28 -27
- data/lib/arel_extensions/date_duration.rb +14 -13
- data/lib/arel_extensions/insert_manager.rb +15 -18
- data/lib/arel_extensions/math.rb +53 -55
- data/lib/arel_extensions/math_functions.rb +39 -46
- data/lib/arel_extensions/nodes/abs.rb +1 -0
- data/lib/arel_extensions/nodes/blank.rb +2 -1
- data/lib/arel_extensions/nodes/case.rb +16 -16
- data/lib/arel_extensions/nodes/cast.rb +8 -10
- data/lib/arel_extensions/nodes/ceil.rb +1 -1
- data/lib/arel_extensions/nodes/coalesce.rb +4 -3
- data/lib/arel_extensions/nodes/collate.rb +10 -9
- data/lib/arel_extensions/nodes/concat.rb +18 -9
- data/lib/arel_extensions/nodes/date_diff.rb +26 -42
- data/lib/arel_extensions/nodes/duration.rb +3 -0
- data/lib/arel_extensions/nodes/find_in_set.rb +1 -0
- data/lib/arel_extensions/nodes/floor.rb +1 -1
- data/lib/arel_extensions/nodes/format.rb +8 -35
- data/lib/arel_extensions/nodes/formatted_number.rb +23 -22
- data/lib/arel_extensions/nodes/function.rb +37 -42
- data/lib/arel_extensions/nodes/is_null.rb +0 -0
- data/lib/arel_extensions/nodes/json.rb +39 -48
- data/lib/arel_extensions/nodes/length.rb +0 -5
- data/lib/arel_extensions/nodes/levenshtein_distance.rb +1 -1
- data/lib/arel_extensions/nodes/locate.rb +2 -1
- data/lib/arel_extensions/nodes/log10.rb +2 -1
- data/lib/arel_extensions/nodes/matches.rb +7 -5
- data/lib/arel_extensions/nodes/md5.rb +1 -0
- data/lib/arel_extensions/nodes/power.rb +5 -5
- data/lib/arel_extensions/nodes/rand.rb +1 -0
- data/lib/arel_extensions/nodes/repeat.rb +5 -3
- data/lib/arel_extensions/nodes/replace.rb +8 -16
- data/lib/arel_extensions/nodes/round.rb +6 -5
- data/lib/arel_extensions/nodes/soundex.rb +15 -15
- data/lib/arel_extensions/nodes/std.rb +21 -18
- data/lib/arel_extensions/nodes/substring.rb +16 -8
- data/lib/arel_extensions/nodes/then.rb +1 -1
- data/lib/arel_extensions/nodes/trim.rb +6 -4
- data/lib/arel_extensions/nodes/union.rb +8 -5
- data/lib/arel_extensions/nodes/union_all.rb +7 -4
- data/lib/arel_extensions/nodes/wday.rb +4 -0
- data/lib/arel_extensions/nodes.rb +1 -1
- data/lib/arel_extensions/null_functions.rb +7 -5
- data/lib/arel_extensions/predications.rb +43 -44
- data/lib/arel_extensions/railtie.rb +5 -5
- data/lib/arel_extensions/set_functions.rb +7 -5
- data/lib/arel_extensions/string_functions.rb +29 -58
- data/lib/arel_extensions/tasks.rb +6 -6
- data/lib/arel_extensions/version.rb +1 -1
- data/lib/arel_extensions/visitors/ibm_db.rb +31 -24
- data/lib/arel_extensions/visitors/mssql.rb +181 -279
- data/lib/arel_extensions/visitors/mysql.rb +210 -280
- data/lib/arel_extensions/visitors/oracle.rb +180 -201
- data/lib/arel_extensions/visitors/oracle12.rb +31 -18
- data/lib/arel_extensions/visitors/postgresql.rb +173 -252
- data/lib/arel_extensions/visitors/sqlite.rb +126 -140
- data/lib/arel_extensions/visitors/to_sql.rb +237 -272
- data/lib/arel_extensions/visitors.rb +59 -75
- data/lib/arel_extensions.rb +31 -159
- data/test/database.yml +7 -15
- data/test/helper.rb +18 -0
- data/test/real_db_test.rb +116 -105
- data/test/support/fake_record.rb +3 -3
- data/test/test_comparators.rb +17 -14
- data/test/visitors/test_bulk_insert_oracle.rb +11 -11
- data/test/visitors/test_bulk_insert_sqlite.rb +13 -12
- data/test/visitors/test_bulk_insert_to_sql.rb +13 -11
- data/test/visitors/test_oracle.rb +55 -55
- data/test/visitors/test_to_sql.rb +226 -419
- data/test/with_ar/all_agnostic_test.rb +361 -578
- data/test/with_ar/insert_agnostic_test.rb +21 -27
- data/test/with_ar/test_bulk_sqlite.rb +16 -17
- data/test/with_ar/test_math_sqlite.rb +26 -26
- data/test/with_ar/test_string_mysql.rb +33 -31
- data/test/with_ar/test_string_sqlite.rb +34 -30
- metadata +22 -29
- data/.github/workflows/ruby.yml +0 -341
- data/gemfiles/rails6.gemfile +0 -30
- data/gemfiles/rails6_1.gemfile +0 -30
- data/gemfiles/rails7.gemfile +0 -23
- data/gemspecs/arel_extensions-v1.gemspec +0 -28
- data/gemspecs/arel_extensions-v2.gemspec +0 -28
- data/generate_gems.sh +0 -15
- data/lib/arel_extensions/aliases.rb +0 -14
- data/lib/arel_extensions/helpers.rb +0 -51
- data/lib/arel_extensions/nodes/aggregate_function.rb +0 -13
- data/lib/arel_extensions/nodes/sum.rb +0 -7
- data/lib/arel_extensions/visitors/convert_format.rb +0 -37
- data/test/arelx_test_helper.rb +0 -71
- data/version_v1.rb +0 -3
- data/version_v2.rb +0 -3
data/.travis.yml
ADDED
@@ -0,0 +1,223 @@
|
|
1
|
+
language: ruby
|
2
|
+
sudo: required
|
3
|
+
cache:
|
4
|
+
bundler: true
|
5
|
+
directories:
|
6
|
+
- $ORACLE_HOME
|
7
|
+
before_install:
|
8
|
+
- chmod +x .travis/sqlite3/extension-functions.sh
|
9
|
+
# - chmod +x .travis/oracle/download.sh
|
10
|
+
# - chmod +x .travis/oracle/install.sh
|
11
|
+
# - chmod +x .travis/setup_accounts.sh
|
12
|
+
- sudo apt-get install -y sqlite3-pcre curl
|
13
|
+
- .travis/sqlite3/extension-functions.sh
|
14
|
+
# - .travis/oracle/download.sh
|
15
|
+
# - sh -ex .travis/oracle/install.sh
|
16
|
+
# - .travis/setup_accounts.sh
|
17
|
+
install:
|
18
|
+
- gem install bundler -v 1.17.3
|
19
|
+
- bundle install
|
20
|
+
gemfile:
|
21
|
+
- gemfiles/rails4.gemfile
|
22
|
+
- gemfiles/rails5_0.gemfile
|
23
|
+
- gemfiles/rails5_1_4.gemfile
|
24
|
+
- gemfiles/rails5_2.gemfile
|
25
|
+
services:
|
26
|
+
- mysql
|
27
|
+
- postgresql
|
28
|
+
before_script:
|
29
|
+
- mysql -e 'create database arext_test;'
|
30
|
+
- psql -c 'create database arext_test;' -U postgres
|
31
|
+
script:
|
32
|
+
- gem build arel_extensions.gemspec
|
33
|
+
- bundle exec rake test
|
34
|
+
- bundle exec rake test:sqlite
|
35
|
+
- bundle exec rake test:mysql
|
36
|
+
- bundle exec rake test:postgresql
|
37
|
+
#- bundle exec rake test:oracle # service unavailable
|
38
|
+
env:
|
39
|
+
global:
|
40
|
+
- JRUBY_OPTS='--dev -J-Xmx1024M'
|
41
|
+
# - ORACLE_COOKIE=sqldev
|
42
|
+
# - ORACLE_FILE=oracle11g/xe/oracle-xe-11.2.0-1.0.x86_64.rpm.zip
|
43
|
+
# - ORACLE_OJDBC_URL=http://download.oracle.com/otn/utilities_drivers/jdbc/11204/ojdbc6.jar
|
44
|
+
- TNS_ADMIN=$ORACLE_HOME/network/admin
|
45
|
+
# - ORACLE_BASE=/u01/app/oracle
|
46
|
+
# - ORACLE_HOME=/u01/app/oracle/product/11.2.0/xe
|
47
|
+
# - ORACLE_SID=XE
|
48
|
+
- DATABASE_NAME=XE
|
49
|
+
- NLS_LANG=AMERICAN_AMERICA.AL32UTF8
|
50
|
+
- secure: 0RUuF4l0e3J8UIIMlgb8x/aYy2pH6Wb+EWylOr2W1EQechivoFw6IEYD1EZWIOZ/uNpkQ2h/urbUqW3/HpKhZn+NYP2sQI41Xyu1TD+6HPWAHpEvLzemhQSJV6eIeLRQoVDLUmqF23nUZDtKQAwOOyJVMeqHMahJi5K7N/cfQmifs2QcBnMxPnANIcrSXxOCBoqCl6BERG9JTeKERG/lWG1I9vRIe9ISNyOPUQVVI6SfTJwhJP5NLkxSJG1q2PLPK7p6zQ684sS4zSnS5oV23yDsQWWIwxk78CVu1jnFBu8Qq3ngWsInlkHrPotjtaxmTxM8JQd4fgE5NMO2Pjnj8w7zg+sbl+3OVtareX+M9+OLdUD5xBQhecPpzflMqib2qZ0fr9tdoT8kAZJTiXtQrptZfaXleZlH74l2dO/PYxkoWMusYQnSbQl0G3AoyYH+l7YpefL4arm0s5IIiOK+ZiCoZ14pl26rYAA1iPUe5AT+hecKi+fwqhyFE7fMX+zC+AvzsQL8jrP0CXL/hmPkoFYxvcDgUoYhvOq+mmQHdOfU7ny4hH5z5d9691qceduHFvF7fNZ4pSofj03eGqfTTk+SDNeZIo6NXNlayayjV2L/DxL6d7vetxkWwipx47PI76gBAqJlxgODJuzoOtyQkPyIVsDlzI1UPoS+UbrU51w=
|
51
|
+
rvm:
|
52
|
+
- 2.0.0
|
53
|
+
- 2.1
|
54
|
+
- 2.2.5
|
55
|
+
- 2.3.1
|
56
|
+
- 2.4.0
|
57
|
+
- 2.5.0
|
58
|
+
- rbx-2
|
59
|
+
- jruby-9.0.5.0
|
60
|
+
- jruby-9.2.0.0
|
61
|
+
- jruby-head
|
62
|
+
- ruby-head
|
63
|
+
jdk:
|
64
|
+
- openjdk7
|
65
|
+
- oraclejdk8
|
66
|
+
- oraclejdk9
|
67
|
+
- openjdk10
|
68
|
+
- oraclejdk10
|
69
|
+
- openjdk11
|
70
|
+
- oraclejdk11
|
71
|
+
matrix:
|
72
|
+
fast_finish: true
|
73
|
+
exclude:
|
74
|
+
- rvm: rbx-2
|
75
|
+
jdk: openjdk7
|
76
|
+
- rvm: 2.0.0
|
77
|
+
jdk: openjdk7
|
78
|
+
- rvm: 2.1
|
79
|
+
jdk: openjdk7
|
80
|
+
- rvm: 2.2.5
|
81
|
+
jdk: openjdk7
|
82
|
+
- rvm: 2.3.1
|
83
|
+
jdk: openjdk7
|
84
|
+
- rvm: 2.4.0
|
85
|
+
jdk: openjdk7
|
86
|
+
- rvm: 2.5.0
|
87
|
+
jdk: openjdk7
|
88
|
+
- rvm: ruby-head
|
89
|
+
jdk: openjdk7
|
90
|
+
- rvm: rbx-2
|
91
|
+
jdk: oraclejdk8
|
92
|
+
- rvm: 2.0.0
|
93
|
+
jdk: oraclejdk8
|
94
|
+
- rvm: 2.1
|
95
|
+
jdk: oraclejdk8
|
96
|
+
- rvm: 2.2.5
|
97
|
+
jdk: oraclejdk8
|
98
|
+
- rvm: 2.3.1
|
99
|
+
jdk: oraclejdk8
|
100
|
+
- rvm: 2.4.0
|
101
|
+
jdk: oraclejdk8
|
102
|
+
- rvm: 2.5.0
|
103
|
+
jdk: oraclejdk8
|
104
|
+
- rvm: ruby-head
|
105
|
+
jdk: oraclejdk8
|
106
|
+
- rvm: rbx-2
|
107
|
+
jdk: oraclejdk10
|
108
|
+
- rvm: 2.0.0
|
109
|
+
jdk: oraclejdk10
|
110
|
+
- rvm: 2.1
|
111
|
+
jdk: oraclejdk10
|
112
|
+
- rvm: 2.2.5
|
113
|
+
jdk: oraclejdk10
|
114
|
+
- rvm: 2.3.1
|
115
|
+
jdk: oraclejdk10
|
116
|
+
- rvm: 2.4.0
|
117
|
+
jdk: oraclejdk10
|
118
|
+
- rvm: 2.5.0
|
119
|
+
jdk: oraclejdk10
|
120
|
+
- rvm: ruby-head
|
121
|
+
jdk: oraclejdk10
|
122
|
+
- rvm: rbx-2
|
123
|
+
jdk: openjdk10
|
124
|
+
- rvm: 2.0.0
|
125
|
+
jdk: openjdk10
|
126
|
+
- rvm: 2.1
|
127
|
+
jdk: openjdk10
|
128
|
+
- rvm: 2.2.5
|
129
|
+
jdk: openjdk10
|
130
|
+
- rvm: 2.3.1
|
131
|
+
jdk: openjdk10
|
132
|
+
- rvm: 2.4.0
|
133
|
+
jdk: openjdk10
|
134
|
+
- rvm: 2.5.0
|
135
|
+
jdk: openjdk10
|
136
|
+
- rvm: ruby-head
|
137
|
+
jdk: openjdk10
|
138
|
+
- rvm: rbx-2
|
139
|
+
jdk: oraclejdk11
|
140
|
+
- rvm: 2.0.0
|
141
|
+
jdk: oraclejdk11
|
142
|
+
- rvm: 2.1
|
143
|
+
jdk: oraclejdk11
|
144
|
+
- rvm: 2.2.5
|
145
|
+
jdk: oraclejdk11
|
146
|
+
- rvm: 2.3.1
|
147
|
+
jdk: oraclejdk11
|
148
|
+
- rvm: 2.4.0
|
149
|
+
jdk: oraclejdk11
|
150
|
+
- rvm: 2.5.0
|
151
|
+
jdk: oraclejdk11
|
152
|
+
- rvm: ruby-head
|
153
|
+
jdk: oraclejdk11
|
154
|
+
- rvm: rbx-2
|
155
|
+
jdk: openjdk11
|
156
|
+
- rvm: 2.0.0
|
157
|
+
jdk: openjdk11
|
158
|
+
- rvm: 2.1
|
159
|
+
jdk: openjdk11
|
160
|
+
- rvm: 2.2.5
|
161
|
+
jdk: openjdk11
|
162
|
+
- rvm: 2.3.1
|
163
|
+
jdk: openjdk11
|
164
|
+
- rvm: 2.4.0
|
165
|
+
jdk: openjdk11
|
166
|
+
- rvm: 2.5.0
|
167
|
+
jdk: openjdk11
|
168
|
+
- rvm: ruby-head
|
169
|
+
jdk: openjdk11
|
170
|
+
- rvm: jruby-9.2.0.0
|
171
|
+
jdk: openjdk7
|
172
|
+
- rvm: jruby-head
|
173
|
+
jdk: openjdk7
|
174
|
+
- rvm: 2.0.0
|
175
|
+
gemfile: gemfiles/rails5_1_4.gemfile
|
176
|
+
- rvm: 2.1
|
177
|
+
gemfile: gemfiles/rails5_1_4.gemfile
|
178
|
+
- rvm: 2.2.5
|
179
|
+
gemfile: gemfiles/rails5_1_4.gemfile
|
180
|
+
- rvm: ruby-head
|
181
|
+
gemfile: gemfiles/rails4.gemfile
|
182
|
+
- rvm: 2.0.0
|
183
|
+
gemfile: gemfiles/rails5_0.gemfile
|
184
|
+
- rvm: 2.1
|
185
|
+
gemfile: gemfiles/rails5_0.gemfile
|
186
|
+
- rvm: jruby-9.0.5.0
|
187
|
+
gemfile: gemfiles/rails5_1_4.gemfile
|
188
|
+
- rvm: 2.0.0
|
189
|
+
gemfile: gemfiles/rails5_2.gemfile
|
190
|
+
- rvm: 2.1
|
191
|
+
gemfile: gemfiles/rails5_2.gemfile
|
192
|
+
allow_failures:
|
193
|
+
- rvm: rbx-2
|
194
|
+
gemfile: gemfiles/rails4.gemfile
|
195
|
+
- rvm: rbx-2
|
196
|
+
gemfile: gemfiles/rails5_0.gemfile
|
197
|
+
- rvm: rbx-2
|
198
|
+
gemfile: gemfiles/rails5_1_4.gemfile
|
199
|
+
- rvm: rbx-2
|
200
|
+
gemfile: gemfiles/rails5_2.gemfile
|
201
|
+
- rvm: rbx-2
|
202
|
+
gemfile: gemfiles/rails5_1_4.gemfile
|
203
|
+
- rvm: jruby-9.0.5.0
|
204
|
+
gemfile: gemfiles/rails5_2.gemfile
|
205
|
+
- rvm: jruby-9.2.0.0
|
206
|
+
jdk: oraclejdk9
|
207
|
+
gemfile: gemfiles/rails5_2.gemfile
|
208
|
+
- jdk: openjdk10
|
209
|
+
- jdk: oraclejdk10
|
210
|
+
- jdk: openjdk11
|
211
|
+
- jdk: oraclejdk11
|
212
|
+
- rvm: ruby-head
|
213
|
+
- rvm: jruby-head
|
214
|
+
- rvm: jruby-9.2.0.0
|
215
|
+
jdk: oraclejdk9
|
216
|
+
- rvm: jruby-9.0.5.0
|
217
|
+
jdk: oraclejdk9
|
218
|
+
bundler_args: "--jobs 3 --retry 2"
|
219
|
+
notifications:
|
220
|
+
email:
|
221
|
+
notifications:
|
222
|
+
- julien.delporte@faveod.com
|
223
|
+
- yann.azoury@faveod.com
|
data/Gemfile
CHANGED
@@ -1,24 +1,29 @@
|
|
1
|
-
source
|
1
|
+
source "https://rubygems.org"
|
2
|
+
|
3
|
+
gem 'rails', '~> 6.0.0.rc2'
|
2
4
|
|
3
|
-
gemspec
|
4
5
|
|
5
6
|
group :development, :test do
|
6
|
-
gem '
|
7
|
-
gem '
|
8
|
-
gem '
|
7
|
+
gem 'activesupport', '~> 6.0.0.rc2'
|
8
|
+
gem 'activemodel', '~> 6.0.0.rc2'
|
9
|
+
gem 'activerecord', '~> 6.0.0.rc2'
|
9
10
|
|
10
|
-
gem
|
11
|
-
gem '
|
12
|
-
gem '
|
13
|
-
gem 'activerecord-jdbcpostgresql-adapter', platforms: :jruby
|
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]
|
14
14
|
|
15
|
-
gem
|
16
|
-
gem
|
15
|
+
gem "tiny_tds", :platforms => [:mri, :mingw] if RUBY_PLATFORM =~ /windows/
|
16
|
+
gem "activerecord-sqlserver-adapter", :platforms => [:mri, :mingw]
|
17
17
|
|
18
|
-
gem 'ruby-oci8', platforms
|
19
|
-
gem 'activerecord-oracle_enhanced-adapter', '~>
|
18
|
+
gem 'ruby-oci8', :platforms => [:mri, :mswin, :mingw] if ENV.has_key? 'ORACLE_HOME'
|
19
|
+
gem 'activerecord-oracle_enhanced-adapter', '~> 6.0.0.rc2' if ENV.has_key? 'ORACLE_HOME'
|
20
20
|
|
21
|
-
|
22
|
-
gem '
|
23
|
-
gem
|
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
|
24
28
|
end
|
29
|
+
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Arel Extensions
|
2
2
|
|
3
|
-
![
|
3
|
+
[![Travis Build Status](https://img.shields.io/travis/Faveod/arel-extensions.svg?label=Travis%20build)](http://travis-ci.org/Faveod/arel-extensions)
|
4
4
|
[![AppVeyor Build Status](https://img.shields.io/appveyor/ci/yazfav/arel-extensions.svg?label=AppVeyor%20build)](https://ci.appveyor.com/project/yazfav/arel-extensions)
|
5
5
|
[![Security](https://hakiri.io/github/Faveod/arel-extensions/master.svg)](https://hakiri.io/github/Faveod/arel-extensions/master)
|
6
6
|
![](http://img.shields.io/badge/license-MIT-brightgreen.svg)
|
@@ -19,11 +19,6 @@ It allows to use more advanced SQL functions for any supported RDBMS.
|
|
19
19
|
Arel 6 (Rails 4) or Arel 7+ (Rails 5).
|
20
20
|
[Arel Repository](http://github.com/rails/arel)
|
21
21
|
|
22
|
-
or
|
23
|
-
|
24
|
-
Rails 6
|
25
|
-
[Rails Repository](http://github.com/rails/rails)
|
26
|
-
|
27
22
|
## Usage
|
28
23
|
|
29
24
|
Most of the features will work just by adding the gem to your Gemfiles. To make sure to get all the features for any dbms, you should execute the next line as soon as you get your connection to your DB:
|
@@ -77,9 +72,9 @@ With Arel Extensions:
|
|
77
72
|
Other functions : ABS, RAND, ROUND, FLOOR, CEIL, FORMAT
|
78
73
|
|
79
74
|
For Example:
|
80
|
-
```ruby
|
75
|
+
```ruby
|
81
76
|
t[:price].format_number("%07.2f €","fr_FR")
|
82
|
-
# equivalent to 'sprintf("%07.2f €",price)' plus locale management
|
77
|
+
# equivalent to 'sprintf("%07.2f €",price)' plus locale management
|
83
78
|
```
|
84
79
|
|
85
80
|
## String operations
|
@@ -130,77 +125,12 @@ t[:birthdate].month.to_sql
|
|
130
125
|
|
131
126
|
t[:birthdate].year.to_sql
|
132
127
|
# => YEAR(my_table.birthdate)
|
133
|
-
```
|
134
|
-
|
135
|
-
### Datetime
|
136
|
-
|
137
|
-
```ruby
|
138
|
-
# datetime difference
|
139
|
-
t[:birthdate] - Time.utc(2014, 3, 3, 12, 41, 18)
|
140
|
-
|
141
|
-
# comparison
|
142
|
-
t[:birthdate] >= '2014-03-03 10:10:10'
|
143
|
-
```
|
144
|
-
|
145
|
-
### Format and Time Zone Conversion
|
146
|
-
|
147
|
-
`format` has two forms:
|
148
128
|
|
149
|
-
```ruby
|
150
129
|
t[:birthdate].format('%Y-%m-%d').to_sql
|
151
130
|
# => DATE_FORMAT(my_table.birthdate, '%Y-%m-%d')
|
152
131
|
```
|
153
132
|
|
154
|
-
|
155
|
-
The second form accepts 2 kinds of values:
|
156
|
-
|
157
|
-
1. String:
|
158
|
-
|
159
|
-
```ruby
|
160
|
-
t[:birthdate].format('%Y/%m/%d %H:%M:%S', 'posix/Pacific/Tahiti')
|
161
|
-
# => DATE_FORMAT(CONVERT_TZ(CAST(my_table.birthdate AS datetime), 'UTC', 'posix/Pacific/Tahiti'), '%Y/%m/%d %H:%i:%S') ## MySQL
|
162
|
-
# => TO_CHAR(CAST(my_table.birthdate AS timestamp with time zone) AT TIME ZONE 'posix/Pacific/Tahiti', 'YYYY/MM/DD HH24:MI:SS') ## PostgreSQL
|
163
|
-
# => CONVERT(datetime, my_table.birthdate) AT TIME ZONE 'UTC' AT TIME ZONE N'posix/Pacific/Tahiti' ## SQL Server (& truncated for clarity)
|
164
|
-
# ^^^^^^^^^^^^^^^^^^^^ 🚨 Invalid timezone for SQL Server. Explanation below.
|
165
|
-
```
|
166
|
-
|
167
|
-
which will convert the datetime field to the supplied time zone. This generally
|
168
|
-
means that you're letting the RDBMS decide or infer what is the timezone of the
|
169
|
-
column before conversion to the supplied timezone.
|
170
|
-
|
171
|
-
1. Hash of the form `{ src_time_zone => dst_time_zone }`:
|
172
|
-
|
173
|
-
```ruby
|
174
|
-
t[:birthdate].format('%Y/%m/%d %H:%M:%S', { 'posix/Europe/Paris' => 'posix/Pacific/Tahiti' })
|
175
|
-
```
|
176
|
-
|
177
|
-
which will explicitly indicate the original timestamp that should be considered
|
178
|
-
by the RDBMS.
|
179
|
-
|
180
|
-
Warning:
|
181
|
-
|
182
|
-
- ⚠️ Time Zone names are specific to each RDBMS. While `PostgreSQL` and `MySQL`
|
183
|
-
have overlaping names (the ones prefixed with `posix`), you should always
|
184
|
-
read your vendor's documentation. `SQL Server` is a black sheep and has its
|
185
|
-
own conventions.
|
186
|
-
- ⚠️ Daylight saving is managed by the RDBMS vendor. Choose the approptiate time
|
187
|
-
zone name that enforces proper daylight saving conversions.
|
188
|
-
- ☣️ Choosing `GMT+offset` will certainly bypass daylight saving computations.
|
189
|
-
- ☣️ Choosing abbreviate forms like `CET`, which stands for `Central European
|
190
|
-
Time` will behave differently on `PostgreSQL` and `MySQL`. Don't assume
|
191
|
-
uniform behavior, or even a _rational_ one.
|
192
|
-
- ⚠️ Pay attention to the type of the `datetime` column you're working with. For
|
193
|
-
example, in Postgres, a `datetime` can be one of the following types:
|
194
|
-
1. `timestamp with time zone`
|
195
|
-
2. `timestamp without time zone`
|
196
|
-
In the first case, you don't need to supply a conversion hash because postgres
|
197
|
-
knows how to convert it to the desired time zone. However, if you do the same
|
198
|
-
for the second case, you might get surprises, especially if your Postgres
|
199
|
-
installation's default timezone is not `UTC`.
|
200
|
-
- ⚠️ SQLite is not supported.
|
201
|
-
- 🚨 Always test against your setup 🚨
|
202
|
-
|
203
|
-
## Unions
|
133
|
+
## Unions
|
204
134
|
|
205
135
|
```ruby
|
206
136
|
(t.where(t[:name].eq('str')) + t.where(t[:name].eq('test'))).to_sql
|
@@ -213,7 +143,7 @@ Arel-extensions allows to use functions on case clause
|
|
213
143
|
|
214
144
|
```ruby
|
215
145
|
t[:name].when("smith").then(1).when("doe").then(2).else(0).sum.to_sql
|
216
|
-
# => SUM(CASE "my_table"."name" WHEN 'smith' THEN 1 WHEN 'doe' THEN 2 ELSE 0 END)
|
146
|
+
# => SUM(CASE "my_table"."name" WHEN 'smith' THEN 1 WHEN 'doe' THEN 2 ELSE 0 END)
|
217
147
|
```
|
218
148
|
|
219
149
|
## Cast Function
|
@@ -230,7 +160,7 @@ t[:id].cast('char').to_sql
|
|
230
160
|
|
231
161
|
To optimize queries, some classical functions are defined in databases missing any alternative native functions.
|
232
162
|
Examples :
|
233
|
-
- FIND_IN_SET
|
163
|
+
- FIND_IN_SET
|
234
164
|
|
235
165
|
## BULK INSERT / UPSERT
|
236
166
|
|
@@ -279,7 +209,7 @@ User.connection.execute(insert_manager.to_sql)
|
|
279
209
|
<td class="tg-yw4l">CEIL<br>column.ceil</td>
|
280
210
|
<td class="ok">✔</td>
|
281
211
|
<td class="ok">✔</td>
|
282
|
-
<td class="tg-j6lv">CASE +
|
212
|
+
<td class="tg-j6lv">CASE + ROUND</td>
|
283
213
|
<td class="ok">✔</td>
|
284
214
|
<td class="tg-j6lv">CEILING()</td>
|
285
215
|
<td class="tg-j6lv">CEILING()</td>
|
@@ -288,7 +218,7 @@ User.connection.execute(insert_manager.to_sql)
|
|
288
218
|
<td class="tg-yw4l">FLOOR<br>column.floor</td>
|
289
219
|
<td class="ok">✔</td>
|
290
220
|
<td class="ok">✔</td>
|
291
|
-
<td class="tg-j6lv">CASE +
|
221
|
+
<td class="tg-j6lv">CASE + ROUND</td>
|
292
222
|
<td class="ok">✔</td>
|
293
223
|
<td class="ok">✔</td>
|
294
224
|
<td class="ok">✔</td>
|
@@ -455,7 +385,7 @@ User.connection.execute(insert_manager.to_sql)
|
|
455
385
|
<td class="ok">✔</td>
|
456
386
|
<td class="tg-j6lv">✔</td>
|
457
387
|
<td class="tg-j6lv">?</td>
|
458
|
-
</tr>
|
388
|
+
</tr>
|
459
389
|
<tr>
|
460
390
|
<td class="tg-yw4l">Matching Accent Insensitive<br>column.ai_matches('blah')</td>
|
461
391
|
<td class="ok">not supported</td>
|
@@ -464,7 +394,7 @@ User.connection.execute(insert_manager.to_sql)
|
|
464
394
|
<td class="ok">not supported</td>
|
465
395
|
<td class="tg-j6lv">✔</td>
|
466
396
|
<td class="tg-j6lv">?</td>
|
467
|
-
</tr>
|
397
|
+
</tr>
|
468
398
|
<tr>
|
469
399
|
<td class="tg-yw4l">Matching Case Insensitive<br>column.imatches('blah')</td>
|
470
400
|
<td class="ok">not supported</td>
|
@@ -473,7 +403,7 @@ User.connection.execute(insert_manager.to_sql)
|
|
473
403
|
<td class="ok">✔</td>
|
474
404
|
<td class="tg-j6lv">✔</td>
|
475
405
|
<td class="tg-j6lv">?</td>
|
476
|
-
</tr>
|
406
|
+
</tr>
|
477
407
|
<tr>
|
478
408
|
<td class="tg-yw4l">Matching Accent/Case Sensitive<br>column.smatches('blah')</td>
|
479
409
|
<td class="ok">✔</td>
|
@@ -482,8 +412,8 @@ User.connection.execute(insert_manager.to_sql)
|
|
482
412
|
<td class="ok">✔</td>
|
483
413
|
<td class="tg-j6lv">✔</td>
|
484
414
|
<td class="tg-j6lv">?</td>
|
485
|
-
</tr>
|
486
|
-
|
415
|
+
</tr>
|
416
|
+
|
487
417
|
<tr>
|
488
418
|
<th class="tg-4rp9" rowspan="6"><div>Date functions</div></th>
|
489
419
|
<td class="tg-yw4l">DATEADD<br>column + 2.year<br></td>
|
@@ -661,45 +591,3 @@ User.connection.execute(insert_manager.to_sql)
|
|
661
591
|
</tr>
|
662
592
|
</tbody>
|
663
593
|
</table>
|
664
|
-
|
665
|
-
## Version Compatibility
|
666
|
-
|
667
|
-
<table>
|
668
|
-
<tr><th>Ruby</th> <th>Rails</th> <th>Arel Extensions</th></tr>
|
669
|
-
<tr><td>3.1</td> <td>6.1</td> <td>2</td></tr>
|
670
|
-
<tr><td>3.0</td> <td>6.1</td> <td>2</td></tr>
|
671
|
-
<tr><td>2.7</td> <td>6.1, 6.0</td> <td>2</td></tr>
|
672
|
-
<tr><td>2.5</td> <td>6.1, 6.0</td> <td>2</td></tr>
|
673
|
-
<tr><td>2.5</td> <td>5.2</td> <td>1</td></tr>
|
674
|
-
</table>
|
675
|
-
|
676
|
-
## Development
|
677
|
-
|
678
|
-
Let's say you want to develop/test for `ruby 2.7.5` and `rails 5.2`.
|
679
|
-
|
680
|
-
You will need to fix your ruby version:
|
681
|
-
|
682
|
-
```bash
|
683
|
-
rbenv install 2.7.5
|
684
|
-
rbenv local 2.7.5
|
685
|
-
```
|
686
|
-
|
687
|
-
Fix your gemfiles:
|
688
|
-
|
689
|
-
```bash
|
690
|
-
bundle config set --local gemfile ./gemfiles/rails6.gemfile
|
691
|
-
```
|
692
|
-
|
693
|
-
Install dependencies:
|
694
|
-
```bash
|
695
|
-
bundle install
|
696
|
-
```
|
697
|
-
|
698
|
-
Develop, then test:
|
699
|
-
|
700
|
-
```bash
|
701
|
-
bundle exec rake test:to_sql
|
702
|
-
```
|
703
|
-
|
704
|
-
Refer to the [Version Compatibility](#version-compatibility) section to correctly
|
705
|
-
set your gemfile.
|
data/Rakefile
CHANGED
@@ -1,50 +1,39 @@
|
|
1
1
|
require 'bundler'
|
2
|
-
Bundler::GemHelper.install_tasks name
|
2
|
+
Bundler::GemHelper.install_tasks :name => "arel_extensions"
|
3
3
|
|
4
4
|
require 'rake/testtask'
|
5
5
|
|
6
|
-
desc
|
7
|
-
task default: [:test]
|
6
|
+
desc "Default Task"
|
7
|
+
task default: [ :test ]
|
8
8
|
|
9
9
|
Rake::TestTask.new(:test) do |t|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
10
|
+
t.libs << 'lib'
|
11
|
+
t.libs << 'test'
|
12
|
+
t.pattern = 'test/**/test_*.rb'
|
13
|
+
t.warning = true
|
14
|
+
t.verbose = true
|
15
15
|
end
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
namespace adapter do
|
41
|
-
task test: "test_#{adapter}"
|
42
|
-
task isolated_test: "isolated_test_#{adapter}"
|
43
|
-
|
44
|
-
# Set the connection environment for the adapter
|
45
|
-
task(:env) { ENV['DB'] = adapter }
|
46
|
-
end
|
47
|
-
|
48
|
-
# Make sure the adapter test evaluates the env setting task
|
49
|
-
task "test_#{adapter}" => ["#{adapter}:env", "test:#{adapter}"]
|
17
|
+
%w(mysql postgresql sqlite ibm_db oracle mssql).each do |adapter|
|
18
|
+
namespace :test do
|
19
|
+
Rake::TestTask.new(adapter => "#{adapter}:env") { |t|
|
20
|
+
t.libs << 'lib'
|
21
|
+
t.libs << 'test'
|
22
|
+
t.pattern = 'test/with_ar/*_agnostic_test.rb'
|
23
|
+
t.warning = true
|
24
|
+
t.verbose = true
|
25
|
+
t.ruby_opts = ["--dev"] if defined?(JRUBY_VERSION)
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
namespace adapter do
|
30
|
+
task :test => "test_#{adapter}"
|
31
|
+
task :isolated_test => "isolated_test_#{adapter}"
|
32
|
+
|
33
|
+
# Set the connection environment for the adapter
|
34
|
+
task(:env) { ENV['DB'] = adapter }
|
35
|
+
end
|
36
|
+
|
37
|
+
# Make sure the adapter test evaluates the env setting task
|
38
|
+
task "test_#{adapter}" => ["#{adapter}:env", "test:#{adapter}"]
|
50
39
|
end
|
data/TODO
CHANGED
data/appveyor.yml
CHANGED
@@ -1,73 +1,44 @@
|
|
1
|
-
image: Visual Studio 2015
|
2
|
-
|
3
1
|
version: "{build}"
|
4
2
|
|
5
3
|
cache:
|
6
4
|
- vendor/bundle
|
7
5
|
|
8
|
-
|
9
|
-
|
10
|
-
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
SQL: MSSQL$SQL2014
|
16
|
-
- RUBY_VERSION: 25-x64
|
17
|
-
RAILS: 5_2
|
18
|
-
SQL: MSSQL$SQL2016
|
19
|
-
- RUBY_VERSION: 25-x64
|
20
|
-
RAILS: 6
|
21
|
-
SQL: MSSQL$SQL2012SP1
|
22
|
-
- RUBY_VERSION: 25-x64
|
23
|
-
RAILS: 6
|
24
|
-
SQL: MSSQL$SQL2014
|
25
|
-
- RUBY_VERSION: 25-x64
|
26
|
-
RAILS: 6
|
27
|
-
SQL: MSSQL$SQL2016
|
28
|
-
- RUBY_VERSION: 25-x64
|
29
|
-
RAILS: 6_1
|
30
|
-
SQL: MSSQL$SQL2012SP1
|
31
|
-
- RUBY_VERSION: 25-x64
|
32
|
-
RAILS: 6_1
|
33
|
-
SQL: MSSQL$SQL2014
|
34
|
-
- RUBY_VERSION: 25-x64
|
35
|
-
RAILS: 6_1
|
36
|
-
SQL: MSSQL$SQL2016
|
6
|
+
branches:
|
7
|
+
only:
|
8
|
+
- master
|
9
|
+
|
10
|
+
services:
|
11
|
+
- mssql2014
|
12
|
+
|
37
13
|
|
38
14
|
install:
|
39
15
|
- set PATH=C:\Ruby%RUBY_VERSION%\bin;%PATH%
|
40
|
-
- gem update --system
|
41
|
-
- gem install rubygems-update && update_rubygems
|
42
16
|
- bundle config --local path vendor/bundle
|
43
|
-
- cp ./gemfiles/rails%RAILS%.gemfile ./Gemfile
|
44
|
-
- bundle config set gemfile ./gemfiles/rails%RAILS%.gemfile
|
45
17
|
- bundle install
|
46
18
|
|
19
|
+
# Disable normal Windows builds in favor of our test script.
|
47
20
|
build: off
|
48
21
|
|
22
|
+
|
49
23
|
before_test:
|
50
24
|
- ruby -v
|
51
25
|
- gem -v
|
52
26
|
- bundle -v
|
53
27
|
|
54
28
|
test_script:
|
55
|
-
-
|
56
|
-
-
|
29
|
+
- ruby --version
|
30
|
+
- gem --version
|
31
|
+
- bundler --version
|
32
|
+
- bundle exec rake test
|
33
|
+
- ps: Start-Service 'MSSQL$SQL2014'
|
34
|
+
- timeout /t 4 /nobreak > NUL
|
57
35
|
- bundle exec rake test:mssql
|
58
36
|
|
59
|
-
|
60
|
-
-
|
37
|
+
environment:
|
61
38
|
matrix:
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
-
|
66
|
-
-
|
67
|
-
|
68
|
-
- cp ./gemfiles/rails%RAILS%.gemfile ./Gemfile
|
69
|
-
- gem update --system
|
70
|
-
- gem install rubygems-update && update_rubygems
|
71
|
-
- bundle config --local path vendor/bundle
|
72
|
-
- bundle config set gemfile ./gemfiles/rails%RAILS%.gemfile
|
73
|
-
- bundle install
|
39
|
+
- RUBY_VERSION: 200
|
40
|
+
- RUBY_VERSION: 21
|
41
|
+
- RUBY_VERSION: 22
|
42
|
+
- RUBY_VERSION: 23
|
43
|
+
- RUBY_VERSION: 23-x64
|
44
|
+
|