arel_extensions 0.8.3 → 0.8.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/.travis/oracle/download.js +116 -0
  3. data/.travis/oracle/download.sh +16 -0
  4. data/.travis/oracle/install.sh +32 -0
  5. data/.travis.yml +72 -69
  6. data/Rakefile +29 -4
  7. data/arel_extensions.gemspec +1 -1
  8. data/functions.html +21 -12
  9. data/gemfiles/rails4.gemfile +11 -3
  10. data/gemfiles/rails5.gemfile +8 -4
  11. data/lib/arel_extensions/math.rb +2 -2
  12. data/lib/arel_extensions/math_functions.rb +1 -1
  13. data/lib/arel_extensions/nodes/concat.rb +16 -0
  14. data/lib/arel_extensions/nodes/date_diff.rb +37 -25
  15. data/lib/arel_extensions/nodes/function.rb +30 -0
  16. data/lib/arel_extensions/nodes/is_null.rb +6 -0
  17. data/lib/arel_extensions/nodes/replace.rb +8 -26
  18. data/lib/arel_extensions/nodes/round.rb +6 -6
  19. data/lib/arel_extensions/nodes.rb +1 -1
  20. data/lib/arel_extensions/null_functions.rb +2 -2
  21. data/lib/arel_extensions/string_functions.rb +5 -1
  22. data/lib/arel_extensions/version.rb +1 -1
  23. data/lib/arel_extensions/visitors/mysql.rb +89 -113
  24. data/lib/arel_extensions/visitors/oracle.rb +28 -65
  25. data/lib/arel_extensions/visitors/postgresql.rb +82 -121
  26. data/lib/arel_extensions/visitors/sqlite.rb +60 -55
  27. data/lib/arel_extensions/visitors/to_sql.rb +30 -5
  28. data/test/database.yml +15 -3
  29. data/test/real_db_test.rb +0 -1
  30. data/test/visitors/test_bulk_insert_sqlite.rb +2 -1
  31. data/test/visitors/test_oracle.rb +2 -2
  32. data/test/visitors/test_to_sql.rb +3 -4
  33. data/test/with_ar/all_agnostic_test.rb +294 -0
  34. data/test/with_ar/insert_agnostic_test.rb +52 -0
  35. data/test/with_ar/test_bulk_sqlite.rb +3 -2
  36. metadata +10 -5
  37. data/lib/arel_extensions/nodes/isnull.rb +0 -30
  38. data/test/with_ar/test_string_postgresql.rb +0 -81
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cc58508a314b8bc3f5f4eb4aa704c4cba75783f6
4
- data.tar.gz: a347453b0960efb17862dbb15e7433efa81cdc05
3
+ metadata.gz: 4f2ade749fb291100715cf14fb1429423d253532
4
+ data.tar.gz: 111e9e06da61b1949ea7c6e8a9d59c8332dfbbec
5
5
  SHA512:
6
- metadata.gz: 9aab7c24f6cd74293a52b5064764a9cbbffcc5d208140ddfab546ddc985f1435fb6ccbe7418e86e32c03c844670567dc03d16474077d52cd3acea1d5169bcc63
7
- data.tar.gz: c74789a394dabfd3a8061a174a270312a7eacd3e46e0decd8089b2b4043eda970c65406adc22a60f9278345c4a063c58d1e1ef3450113ebac506ecbddac99dc9
6
+ metadata.gz: f805809f0cf68defc693d50f82cc300118f990233c29f81eccc2accef50093f3b447f1ba1b4740072e9d675f646a82f75f9e9eeaaf813e323d1db7230a3cac9e
7
+ data.tar.gz: e4bd7faa243ae45fcc604294e662765e25055e13111a1889810327893dc545020c4bd1b465d2eaa4c16262fcdc282fbfd89cd4ceff95be986a9f9694538ecd5a
@@ -0,0 +1,116 @@
1
+ // vim: set et sw=2 ts=2:
2
+ "use strict";
3
+ var env = process.env;
4
+ var Promise = require('bluebird');
5
+ var Phantom = Promise.promisifyAll(require('node-phantom-simple'));
6
+ var PhantomError = require('node-phantom-simple/headless_error');
7
+
8
+ var credentials = Object.keys(env)
9
+ .filter(function (key) { return key.indexOf('ORACLE_LOGIN_') == 0 })
10
+ .map(function (key) { return [key.substr(13), env[key]] });
11
+
12
+ if (credentials.length <= 0) {
13
+ console.error("Missing ORACLE_LOGIN environment variables!");
14
+ process.exit(1);
15
+ }
16
+
17
+ Phantom.createAsync({ parameters: { 'ssl-protocol': 'tlsv1' } }).then(function (browser) {
18
+ browser = Promise.promisifyAll(browser, { suffix: 'Promise' });
19
+
20
+ // Configure the browser, open a tab
21
+ return browser
22
+ .addCookiePromise({'name': 'oraclelicense', 'value': "accept-" + env['ORACLE_COOKIE'] + "-cookie", 'domain': '.oracle.com' })
23
+ .then(function () {
24
+ return browser.createPagePromise();
25
+ })
26
+ .then(function (page) {
27
+ page = Promise.promisifyAll(page, { suffix: 'Promise' });
28
+
29
+ // Configure the tab
30
+ page.onResourceError = console.error.bind(console);
31
+ return page
32
+ .setPromise('settings.userAgent', env['USER_AGENT']) // PhantomJS configures the UA per tab
33
+
34
+ // Request the file, wait for the login page
35
+ .then(function () {
36
+ return page.openPromise("https://edelivery.oracle.com/akam/otn/linux/" + env['ORACLE_FILE']).then(function (status) {
37
+ if (status != 'success') throw "Unable to connect to oracle.com";
38
+ return page.waitForSelectorPromise('input[type=password]', 5000);
39
+ })
40
+ .catch(PhantomError, function (err) {
41
+ return page.getPromise('plainText').then(function (text) {
42
+ console.error("Unable to load login page. Last response was:\n" + text);
43
+ throw err;
44
+ });
45
+ });
46
+ })
47
+
48
+ // Export cookies for cURL
49
+ .then(function () {
50
+ return page.getPromise('cookies').then(function (cookies) {
51
+ var data = "";
52
+ for (var i = 0; i < cookies.length; ++i) {
53
+ var cookie = cookies[i];
54
+ data += cookie.domain + "\tTRUE\t" + cookie.path + "\t"
55
+ + (cookie.secure ? "TRUE" : "FALSE") + "\t0\t"
56
+ + cookie.name + "\t" + cookie.value + "\n";
57
+ }
58
+ return Promise.promisifyAll(require('fs')).writeFileAsync(env['COOKIES'], data);
59
+ });
60
+ })
61
+
62
+ // Submit the login form using cURL
63
+ .then(function () {
64
+ return page.evaluatePromise(function () {
65
+ var $form = jQuery(document.forms[0]);
66
+ return {
67
+ action: $form.prop('action'),
68
+ data: $form.serialize()
69
+ };
70
+ })
71
+ .then(function (form) {
72
+ return browser.exitPromise().then(function () {
73
+ var unapplied = credentials.filter(function (tuple) {
74
+ var applied = false;
75
+ form.data = form.data.replace(tuple[0] + '=', function (name) {
76
+ applied = true;
77
+ return name + encodeURIComponent(tuple[1]);
78
+ });
79
+ return !applied;
80
+ })
81
+ .map(function (tuple) { return tuple[0] });
82
+
83
+ if (unapplied.length > 0) {
84
+ console.warn("Unable to use all ORACLE_LOGIN environment variables: %j", unapplied);
85
+ }
86
+
87
+ var cmd = ['curl', [
88
+ '--cookie', env['COOKIES'],
89
+ '--cookie-jar', env['COOKIES'],
90
+ '--data', '@-',
91
+ '--location',
92
+ '--output', require('path').basename(env['ORACLE_FILE']),
93
+ '--user-agent', env['USER_AGENT'],
94
+ form.action
95
+ ]];
96
+
97
+ console.info("Executing %j", cmd);
98
+
99
+ var child_process = require('child_process');
100
+ var child = child_process.spawn.apply(child_process, cmd.concat({ stdio: ['pipe', 1, 2] }));
101
+ child.on('exit', process.exit);
102
+ child.stdin.end(form.data);
103
+ });
104
+ });
105
+ })
106
+ .catch(function (err) {
107
+ console.error(err);
108
+ browser.on('exit', function () { process.exit(1); });
109
+ browser.exit();
110
+ });
111
+ });
112
+ })
113
+ .catch(function (err) {
114
+ console.error(err);
115
+ process.exit(1);
116
+ });
@@ -0,0 +1,16 @@
1
+ #!/bin/sh -e
2
+
3
+ [ -n "$ORACLE_COOKIE" ] || { echo "Missing ORACLE_COOKIE environment variable!"; exit 1; }
4
+ [ -n "$ORACLE_FILE" ] || { echo "Missing ORACLE_FILE environment variable!"; exit 1; }
5
+
6
+ cd "$(dirname "$(readlink -f "$0")")"
7
+
8
+ npm install bluebird node-phantom-simple
9
+
10
+ export COOKIES='cookies.txt'
11
+ export USER_AGENT='Mozilla/5.0'
12
+
13
+ echo > "$COOKIES"
14
+ chmod 600 "$COOKIES"
15
+
16
+ exec node download.js
@@ -0,0 +1,32 @@
1
+ #!/bin/sh -e
2
+
3
+ [ -n "$ORACLE_FILE" ] || { echo "Missing ORACLE_FILE environment variable!"; exit 1; }
4
+ [ -n "$ORACLE_HOME" ] || { echo "Missing ORACLE_HOME environment variable!"; exit 1; }
5
+
6
+ ORACLE_RPM="$(basename $ORACLE_FILE .zip)"
7
+
8
+ cd "$(dirname "$(readlink -f "$0")")"
9
+
10
+ dpkg -s bc libaio1 rpm unzip > /dev/null 2>&1 ||
11
+ ( sudo apt-get -qq update && sudo apt-get --no-install-recommends -qq install bc libaio1 rpm unzip )
12
+
13
+ df -B1 /dev/shm | awk 'END { if ($1 != "shmfs" && $1 != "tmpfs" || $2 < 2147483648) exit 1 }' ||
14
+ ( sudo rm -r /dev/shm && sudo mkdir /dev/shm && sudo mount -t tmpfs shmfs -o size=2G /dev/shm )
15
+
16
+ test -f /sbin/chkconfig ||
17
+ ( echo '#!/bin/sh' | sudo tee /sbin/chkconfig > /dev/null && sudo chmod u+x /sbin/chkconfig )
18
+
19
+ test -d /var/lock/subsys || sudo mkdir /var/lock/subsys
20
+
21
+ unzip -j "$(basename $ORACLE_FILE)" "*/$ORACLE_RPM"
22
+ sudo rpm --install --nodeps --nopre "$ORACLE_RPM"
23
+
24
+ echo 'OS_AUTHENT_PREFIX=""' | sudo tee -a "$ORACLE_HOME/config/scripts/init.ora" > /dev/null
25
+ sudo usermod -aG dba $USER
26
+
27
+ ( echo ; echo ; echo travis ; echo travis ; echo n ) | sudo AWK='/usr/bin/awk' /etc/init.d/oracle-xe configure
28
+
29
+ "$ORACLE_HOME/bin/sqlplus" -L -S / AS SYSDBA <<SQL
30
+ CREATE USER $USER IDENTIFIED EXTERNALLY;
31
+ GRANT CONNECT, RESOURCE TO $USER;
32
+ SQL
data/.travis.yml CHANGED
@@ -1,85 +1,88 @@
1
1
  language: ruby
2
- sudo: false
2
+ sudo: required
3
3
  cache: bundler
4
4
  before_install:
5
- - gem install bundler
6
- # - sudo apt-get update -qq
7
- # - sudo apt-get install -qq sqlite3
8
- #addons:
9
- # mariadb: '10.0'
5
+ - gem install bundler
6
+ # - ".travis/oracle/download.sh"
7
+ # - ".travis/oracle/install.sh"
10
8
  gemfile:
11
- - gemfiles/rails4.gemfile
12
- # - gemfiles/rails3.gemfile
13
- - gemfiles/rails5.gemfile
9
+ - gemfiles/rails4.gemfile
10
+ - gemfiles/rails5.gemfile
14
11
  services:
15
- - mysql
16
- - postgresql
12
+ - mysql
13
+ - postgresql
17
14
  before_script:
18
- - mysql -e 'create database arext_test;'
19
- - psql -c 'create database arext_test;' -U postgres
15
+ - mysql -e 'create database arext_test;'
16
+ - psql -c 'create database arext_test;' -U postgres
17
+ # - $ORACLE_HOME/bin/sqlplus CREATE DB
20
18
  script:
21
- - "bundle exec rake test"
22
- # - "bundle exec rake test:sqlite3"
23
- - "gem build arel_extensions.gemspec"
24
- - "bundle exec ruby test/real_db_test.rb"
19
+ - bundle exec rake test
20
+ - gem build arel_extensions.gemspec
21
+ - bundle exec rake test:sqlite
22
+ - bundle exec rake test:mysql
23
+ - bundle exec rake test:postgresql
24
+ # - bundle exec rake test:oracle
25
25
  env:
26
26
  global:
27
- - JRUBY_OPTS='--dev -J-Xmx1024M'
27
+ - JRUBY_OPTS='--dev -J-Xmx1024M'
28
+ - ORACLE_COOKIE=sqldev
29
+ - ORACLE_FILE=oracle11g/xe/oracle-xe-11.2.0-1.0.x86_64.rpm.zip
30
+ - ORACLE_HOME=/u01/app/oracle/product/11.2.0/xe
31
+ - ORACLE_SID=XE
32
+ - 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=
28
33
  rvm:
29
- - 2.0.0
30
- - 2.1
31
- - 2.2.5
32
- - 2.3.1
33
- - rbx-2
34
- - jruby-9.0.5.0
35
- - jruby-head
36
- - ruby-head
34
+ - 2.0.0
35
+ - 2.1
36
+ - 2.2.5
37
+ - 2.3.1
38
+ - rbx-2
39
+ - jruby-9.0.5.0
40
+ - jruby-head
41
+ - ruby-head
37
42
  jdk:
38
- - openjdk7
39
- - oraclejdk7
40
- - oraclejdk8
41
- # - openjdk6
43
+ - openjdk7
44
+ - oraclejdk7
45
+ - oraclejdk8
42
46
  matrix:
43
47
  fast_finish: true
44
48
  exclude:
45
- - rvm: rbx-2
46
- jdk: openjdk7
47
- - rvm: rbx-2
48
- jdk: oraclejdk7
49
- - rvm: 2.0.0
50
- jdk: openjdk7
51
- - rvm: 2.0.0
52
- jdk: oraclejdk7
53
- - rvm: 2.1
54
- jdk: openjdk7
55
- - rvm: 2.1
56
- jdk: oraclejdk7
57
- - rvm: 2.2.5
58
- jdk: openjdk7
59
- - rvm: 2.2.5
60
- jdk: oraclejdk7
61
- - rvm: 2.3.1
62
- jdk: openjdk7
63
- - rvm: 2.3.1
64
- jdk: oraclejdk7
65
- - rvm: ruby-head
66
- jdk: openjdk7
67
- - rvm: ruby-head
68
- jdk: oraclejdk7
69
- - rvm: 2.0.0
70
- gemfile: gemfiles/rails5.gemfile
71
- - rvm: 2.1
72
- gemfile: gemfiles/rails5.gemfile
73
- - rvm: rbx-2
74
- gemfile: gemfiles/rails5.gemfile
49
+ - rvm: rbx-2
50
+ jdk: openjdk7
51
+ - rvm: rbx-2
52
+ jdk: oraclejdk7
53
+ - rvm: 2.0.0
54
+ jdk: openjdk7
55
+ - rvm: 2.0.0
56
+ jdk: oraclejdk7
57
+ - rvm: 2.1
58
+ jdk: openjdk7
59
+ - rvm: 2.1
60
+ jdk: oraclejdk7
61
+ - rvm: 2.2.5
62
+ jdk: openjdk7
63
+ - rvm: 2.2.5
64
+ jdk: oraclejdk7
65
+ - rvm: 2.3.1
66
+ jdk: openjdk7
67
+ - rvm: 2.3.1
68
+ jdk: oraclejdk7
69
+ - rvm: ruby-head
70
+ jdk: openjdk7
71
+ - rvm: ruby-head
72
+ jdk: oraclejdk7
73
+ - rvm: 2.0.0
74
+ gemfile: gemfiles/rails5.gemfile
75
+ - rvm: 2.1
76
+ gemfile: gemfiles/rails5.gemfile
77
+ - rvm: rbx-2
78
+ gemfile: gemfiles/rails5.gemfile
79
+ - rvm: ruby-head
80
+ gemfile: gemfiles/rails4.gemfile
75
81
  allow_failures:
76
- # - rvm: jruby-9.0.5.0
77
- # - rvm: jruby-head
78
- - rvm: ruby-head
79
- gemfile: gemfiles/rails4.gemfile
80
- # - rvm: ruby-head
81
- # gemfile: gemfiles/rails3.gemfile
82
- # - rvm: jruby-head
83
- bundler_args: --jobs 3 --retry 2
82
+ - rvm: jruby-9.0.5.0
83
+ gemfile: gemfiles/rails5.gemfile
84
+ - rvm: jruby-head
85
+ gemfile: gemfiles/rails5.gemfile
86
+ bundler_args: "--jobs 3 --retry 2"
84
87
  notifications:
85
- email: false
88
+ email: false
data/Rakefile CHANGED
@@ -7,8 +7,33 @@ desc "Default Task"
7
7
  task default: [ :test ]
8
8
 
9
9
  Rake::TestTask.new(:test) do |t|
10
- t.libs << 'lib'
11
- t.libs << 'test'
12
- t.pattern = 'test/**/test_*.rb'
13
- t.verbose = true
10
+ t.libs << 'lib'
11
+ t.libs << 'test'
12
+ t.pattern = 'test/**/test_*.rb'
13
+ t.warning = true
14
+ t.verbose = true
14
15
  end
16
+
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}"]
39
+ end
@@ -4,7 +4,7 @@ $:.push File.expand_path("../lib", __FILE__)
4
4
 
5
5
  Gem::Specification.new do |s|
6
6
  s.name = "arel_extensions"
7
- s.version = '0.8.3'
7
+ s.version = '0.8.4'
8
8
  s.platform = Gem::Platform::RUBY
9
9
  s.authors = ["Yann Azoury", "Mathilde Pechdimaldjian", "Félix Bellanger"]
10
10
  s.email = ["yann.azoury@faveod.com", "mathilde.pechdimaldjian@gmail.com", "felix.bellanger@faveod.com"]
data/functions.html CHANGED
@@ -94,7 +94,7 @@
94
94
  <td class="tg-baqh">✔</td>
95
95
  </tr>
96
96
  <tr>
97
- <th class="tg-ffjm" rowspan="11"><br><br><br><br><br><br><br><br><br>String <br>functions</th>
97
+ <th class="tg-ffjm" rowspan="12"><br><br><br><br><br><br><br><br><br>String <br>functions</th>
98
98
  <td class="tg-yw4l">CONCAT<br>column + "string"</td>
99
99
  <td class="tg-baqh">✔</td>
100
100
  <td class="tg-baqh">✔</td>
@@ -153,8 +153,8 @@
153
153
  <td class="tg-baqh">✔</td>
154
154
  <td class="tg-baqh">✔</td>
155
155
  <td class="tg-3oug">require pcre.so</td>
156
- <td class="tg-j6lv">REGEXP_LIKE()</td>
157
- <td class="tg-j6lv">LIKE()<br></td>
156
+ <td class="tg-j6lv">REGEXP_LIKE</td>
157
+ <td class="tg-j6lv">LIKE</td>
158
158
  <td class="tg-baqh">✔</td>
159
159
  </tr>
160
160
  <tr>
@@ -162,10 +162,19 @@
162
162
  <td class="tg-baqh">✔</td>
163
163
  <td class="tg-baqh">✔<br></td>
164
164
  <td class="tg-3oug">require pcre.so</td>
165
- <td class="tg-j6lv">NOT REGEXP_LIKE()</td>
166
- <td class="tg-j6lv">NOT LIKE()</td>
165
+ <td class="tg-j6lv">NOT REGEXP_LIKE </td>
166
+ <td class="tg-j6lv">NOT LIKE</td>
167
167
  <td class="tg-baqh">✔</td>
168
168
  </tr>
169
+ <tr>
170
+ <td class="tg-yw4l">ILIKE (in Arel6)<br/>column.imatches('%pattern')</td>
171
+ <td class="tg-j6lv">LOWER() LIKE LOWER()</td>
172
+ <td class="tg-baqh">✔</td>
173
+ <td class="tg-baqh">✔</td>
174
+ <td class="tg-j6lv">LOWER() LIKE LOWER()</td>
175
+ <td class="tg-j6lv">LOWER() LIKE LOWER()</td>
176
+ <td class="tg-j6lv">LOWER() LIKE LOWER()</td>
177
+ </tr>
169
178
  <tr>
170
179
  <td class="tg-yw4l">TRIM (leading)<br>column.trim("LEADING","M")</td>
171
180
  <td class="tg-baqh">✔</td>
@@ -194,7 +203,7 @@
194
203
  <td class="tg-j6lv">TRIM()</td>
195
204
  </tr>
196
205
  <tr>
197
- <th class="tg-4rp9" rowspan="6"><br><br><br><br><br><br><br>Date <br>functions<br></th>
206
+ <th class="tg-4rp9" rowspan="6"><br><br><br><br><br><br><br>Date <br>functions</th>
198
207
  <td class="tg-yw4l">DATEADD<br>column + 2.year<br></td>
199
208
  <td class="tg-j6lv">DATE_ADD()<br></td>
200
209
  <td class="tg-baqh">✔</td>
@@ -249,7 +258,7 @@
249
258
  <td class="tg-baqh">✔</td>
250
259
  </tr>
251
260
  <tr>
252
- <th class="tg-72dn" rowspan="8"><br><br><br><br><br><br>Comparators<br>functions<br></th>
261
+ <th class="tg-72dn" rowspan="8"><br><br><br><br><br><br>Comparators<br>functions</th>
253
262
  <td class="tg-yw4l">COALESCE<br>column.coalesce(var)</td>
254
263
  <td class="tg-baqh">✔</td>
255
264
  <td class="tg-baqh">✔</td>
@@ -259,8 +268,8 @@
259
268
  <td class="tg-baqh">✔</td>
260
269
  </tr>
261
270
  <tr>
262
- <td class="tg-yw4l">ISNULL<br>column.isnull(var)</td>
263
- <td class="tg-j6lv">IFNULL()<br></td>
271
+ <td class="tg-yw4l">ISNULL<br>column.isnull()</td>
272
+ <td class="tg-j6lv">IFNULL()</td>
264
273
  <td class="tg-baqh">✔</td>
265
274
  <td class="tg-baqh">✔</td>
266
275
  <td class="tg-j6lv">NVC()</td>
@@ -268,7 +277,7 @@
268
277
  <td class="tg-baqh">✔</td>
269
278
  </tr>
270
279
  <tr>
271
- <td class="tg-yw4l">==<br>column == integer<br></td>
280
+ <td class="tg-yw4l">==<br>column == integer</td>
272
281
  <td class="tg-baqh">✔</td>
273
282
  <td class="tg-baqh">✔</td>
274
283
  <td class="tg-baqh">✔</td>
@@ -277,7 +286,7 @@
277
286
  <td class="tg-baqh">✔</td>
278
287
  </tr>
279
288
  <tr>
280
- <td class="tg-yw4l">!=<br>column != integer<br></td>
289
+ <td class="tg-yw4l">!=<br>column != integer</td>
281
290
  <td class="tg-baqh">✔</td>
282
291
  <td class="tg-baqh">✔</td>
283
292
  <td class="tg-baqh">✔</td>
@@ -286,7 +295,7 @@
286
295
  <td class="tg-baqh">✔</td>
287
296
  </tr>
288
297
  <tr>
289
- <td class="tg-yw4l">&gt;<br>column &gt; integer<br></td>
298
+ <td class="tg-yw4l">&gt;<br>column &gt; integer</td>
290
299
  <td class="tg-baqh">✔</td>
291
300
  <td class="tg-baqh">✔</td>
292
301
  <td class="tg-baqh">✔</td>
@@ -3,17 +3,25 @@ source "https://rubygems.org"
3
3
  gem 'arel', '~> 6.0'
4
4
 
5
5
  group :development, :test do
6
+
7
+ gem 'activesupport', '~> 4.0'
8
+ gem 'activemodel', '~> 4.0'
9
+ gem 'activerecord', '~> 4.0'
10
+
6
11
  gem "sqlite3", :platform => [:ruby, :mswin, :mingw]
7
12
  gem "mysql2", :platform => [:ruby, :mswin, :mingw]
8
13
  gem "pg", :platform => [:ruby, :mswin, :mingw]
14
+
15
+ gem 'ruby-oci8', :platform => [:ruby, :mswin, :mingw] if ENV.has_key? 'ORACLE_HOME'
16
+ gem 'activerecord-oracle_enhanced-adapter', '~> 1.6.0'
17
+
9
18
  # for JRuby
19
+ gem 'activerecord-jdbc-adapter', platform: :jruby
10
20
  gem "jdbc-sqlite3", :platform => :jruby
11
21
  gem "activerecord-jdbcsqlite3-adapter", :platform => :jruby
12
22
  gem "activerecord-jdbcmysql-adapter", :platform => :jruby
13
23
  gem "activerecord-jdbcpostgresql-adapter", :platform => :jruby
14
- gem 'activesupport', '~> 4.0'
15
- gem 'activemodel', '~> 4.0'
16
- gem 'activerecord', '~> 4.0'
24
+ gem "activerecord-jdbcmssql-adapter", :platform => :jruby
17
25
  end
18
26
 
19
27
  gemspec :path => "../"
@@ -3,19 +3,23 @@ source "https://rubygems.org"
3
3
  gem 'arel', '~> 7.0'
4
4
 
5
5
  group :development, :test do
6
+ gem 'activesupport', '~> 5'
7
+ gem 'activemodel', '~> 5'
8
+ gem 'activerecord', '~> 5'
9
+
6
10
  gem "sqlite3", :platform => [:ruby, :mswin, :mingw]
7
11
  gem "mysql2", :platform => [:ruby, :mswin, :mingw]
8
12
  gem "pg", :platform => [:ruby, :mswin, :mingw]
13
+ gem 'ruby-oci8', '~> 2.2.0', :platform => [:ruby, :mswin, :mingw] if ENV.has_key? 'ORACLE_HOME'
14
+ gem 'activerecord-oracle_enhanced-adapter', '~> 1.7.0'
9
15
 
10
16
  # for JRuby
17
+ gem 'activerecord-jdbc-adapter', platform: :jruby
11
18
  gem "jdbc-sqlite3", :platform => :jruby
12
19
  gem "activerecord-jdbcsqlite3-adapter", :platform => :jruby
13
20
  gem "activerecord-jdbcmysql-adapter", :platform => :jruby
14
21
  gem "activerecord-jdbcpostgresql-adapter", :platform => :jruby
15
-
16
- gem 'activesupport', '~> 5'
17
- gem 'activemodel', '~> 5'
18
- gem 'activerecord', '~> 5'
22
+ gem "activerecord-jdbcmssql-adapter", :platform => :jruby
19
23
  end
20
24
 
21
25
  gemspec :path => "../"
@@ -29,12 +29,12 @@ module ArelExtensions
29
29
  when Arel::Attributes::Attribute
30
30
  arg2 = Arel::Table.engine.connection.schema_cache.columns_hash(other.relation.table_name)[other.name.to_s].type
31
31
  if arg2 == :date || arg2 == :datetime
32
- ArelExtensions::Nodes::DateDiff.new self, other
32
+ ArelExtensions::Nodes::DateDiff.new [self, other]
33
33
  else
34
34
  ArelExtensions::Nodes::DateSub.new self, other
35
35
  end
36
36
  when Arel::Nodes::Node, DateTime, Time, String, Date
37
- ArelExtensions::Nodes::DateDiff.new self, other
37
+ ArelExtensions::Nodes::DateDiff.new [self, other]
38
38
  when Fixnum
39
39
  ArelExtensions::Nodes::DateSub.new self, other
40
40
  end
@@ -25,7 +25,7 @@ module ArelExtensions
25
25
  #function is used to round a numeric field to the number of decimals specified
26
26
  def round precision = nil
27
27
  if precision
28
- ArelExtensions::Nodes::Round.new [self, Arel::Nodes.build_quoted(precision)]
28
+ ArelExtensions::Nodes::Round.new [self, precision]
29
29
  else
30
30
  ArelExtensions::Nodes::Round.new [self]
31
31
  end
@@ -14,5 +14,21 @@ module ArelExtensions
14
14
  end
15
15
 
16
16
  end
17
+
18
+ class GroupConcat < Function
19
+
20
+ def initialize expr
21
+ tab = expr.map { |arg|
22
+ convert_to_node(arg)
23
+ }
24
+ return super(tab)
25
+ end
26
+
27
+ def +(other)
28
+ return ArelExtensions::Nodes::Concat.new([self, other])
29
+ end
30
+
31
+ end
32
+
17
33
  end
18
34
  end
@@ -2,35 +2,21 @@ require 'date'
2
2
 
3
3
  module ArelExtensions
4
4
  module Nodes
5
- class DateDiff < Arel::Nodes::Node #difference entre colonne date et date string/date
6
- include Arel::Predications
7
- include Arel::WindowPredications
8
- include Arel::OrderPredications
9
- include Arel::AliasPredication
10
-
11
- attr_accessor :left, :right
12
-
13
- def initialize(left, right, aliaz = nil)
14
- super()
15
- @left = convert_date(left)
16
- @right = convert_date(right)
17
- end
5
+ class DateDiff < Function #difference entre colonne date et date string/date
6
+ attr_accessor :date_type
18
7
 
19
- def convert_date(object)
20
- case object
21
- when Arel::Attributes::Attribute, Arel::Nodes::Node
22
- object
23
- when DateTime, Time
24
- Arel::Nodes.build_quoted(Date.new(object.year, object.month, object.day), self)
25
- when String
26
- Arel::Nodes.build_quoted(Date.parse(object), self)
8
+ def initialize(expr)
9
+ col = expr.first
10
+ case col
11
+ when Arel::Nodes::Node
12
+ @date_type = Arel::Table.engine.connection.schema_cache.columns_hash(col.relation.table_name)[col.name.to_s].type
27
13
  when Date
28
- Arel::Nodes.build_quoted(object, self)
29
- else
30
- raise(ArgumentError, "#{object.class} can not be converted to Date")
14
+ @date_type = :date
15
+ when DateTime, Time
16
+ @date_type = :datetime
31
17
  end
18
+ super [convert_to_date_node(col), convert_to_date_node(expr[1])]
32
19
  end
33
-
34
20
  end
35
21
 
36
22
  class DateAdd < Function
@@ -58,6 +44,32 @@ module ArelExtensions
58
44
  end
59
45
  end
60
46
 
47
+ def mysql_value(v = nil)
48
+ v ||= self.expressions.last
49
+ if defined?(ActiveSupport::Duration) && ActiveSupport::Duration === v
50
+ if @date_type == :date
51
+ Arel.sql((v.value >= 0 ? 'INTERVAL ' : 'INTERVAL -') + v.inspect.sub(/s\Z/, ''))
52
+ elsif @date_type == :datetime
53
+ Arel.sql((v.value >= 0 ? 'INTERVAL ' : 'INTERVAL -') + v.inspect.sub(/s\Z/, ''))
54
+ end
55
+ else
56
+ v
57
+ end
58
+ end
59
+
60
+ def postgresql_value(v = nil)
61
+ v ||= self.expressions.last
62
+ if defined?(ActiveSupport::Duration) && ActiveSupport::Duration === v
63
+ if @date_type == :date
64
+ Arel.sql("INTERVAL '%s'" % v.inspect.sub(/s\Z/, '').upcase)
65
+ elsif @date_type == :datetime
66
+ Arel.sql("INTERVAL '%s'" % v.inspect.sub(/s\Z/, '').upcase)
67
+ end
68
+ else
69
+ return v
70
+ end
71
+ end
72
+
61
73
  private
62
74
  def convert(object)
63
75
  case object