arel_extensions 0.8.4 → 0.8.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4f2ade749fb291100715cf14fb1429423d253532
4
- data.tar.gz: 111e9e06da61b1949ea7c6e8a9d59c8332dfbbec
3
+ metadata.gz: a8e5c240fc0fe59c0b14a9709b6c065276475334
4
+ data.tar.gz: f5caf5d24a636b49f39132e3817ed867dd803374
5
5
  SHA512:
6
- metadata.gz: f805809f0cf68defc693d50f82cc300118f990233c29f81eccc2accef50093f3b447f1ba1b4740072e9d675f646a82f75f9e9eeaaf813e323d1db7230a3cac9e
7
- data.tar.gz: e4bd7faa243ae45fcc604294e662765e25055e13111a1889810327893dc545020c4bd1b465d2eaa4c16262fcdc282fbfd89cd4ceff95be986a9f9694538ecd5a
6
+ metadata.gz: 2c1ffca0a92fb3d704b2f2ed2649cf6a8df2fb90e46602680aa5c894c9ffef0d6af726736da6de97b12d7ce09f88d4d087e4bf0f1e3d64ab4dec89c8a0c03f93
7
+ data.tar.gz: 617784403ff3999277c8c60430294feaacba648366635d768f14347f2373fab2209c7dd097c72b1bb7ad0a9dcc9e7d9aad1c21976495943a20d317a2cee70467
data/.travis.yml CHANGED
@@ -2,9 +2,15 @@ language: ruby
2
2
  sudo: required
3
3
  cache: bundler
4
4
  before_install:
5
+ - chmod +x .travis/oracle/download.sh
6
+ - chmod +x .travis/oracle/install.sh
7
+ - chmod +x .travis/setup_accounts.sh
8
+ install:
9
+ - .travis/oracle/download.sh
10
+ - .travis/oracle/install.sh
11
+ - .travis/setup_accounts.sh
5
12
  - gem install bundler
6
- # - ".travis/oracle/download.sh"
7
- # - ".travis/oracle/install.sh"
13
+ - bundle install
8
14
  gemfile:
9
15
  - gemfiles/rails4.gemfile
10
16
  - gemfiles/rails5.gemfile
@@ -16,19 +22,24 @@ before_script:
16
22
  - psql -c 'create database arext_test;' -U postgres
17
23
  # - $ORACLE_HOME/bin/sqlplus CREATE DB
18
24
  script:
19
- - bundle exec rake test
20
25
  - gem build arel_extensions.gemspec
26
+ - bundle exec rake test
21
27
  - bundle exec rake test:sqlite
22
28
  - bundle exec rake test:mysql
23
29
  - bundle exec rake test:postgresql
24
- # - bundle exec rake test:oracle
30
+ - bundle exec rake test:oracle
25
31
  env:
26
32
  global:
27
33
  - JRUBY_OPTS='--dev -J-Xmx1024M'
28
34
  - ORACLE_COOKIE=sqldev
29
35
  - ORACLE_FILE=oracle11g/xe/oracle-xe-11.2.0-1.0.x86_64.rpm.zip
36
+ - ORACLE_OJDBC_URL=http://download.oracle.com/otn/utilities_drivers/jdbc/11204/ojdbc6.jar
37
+ - TNS_ADMIN=$ORACLE_HOME/network/admin
38
+ - ORACLE_BASE=/u01/app/oracle
30
39
  - ORACLE_HOME=/u01/app/oracle/product/11.2.0/xe
31
40
  - ORACLE_SID=XE
41
+ - DATABASE_NAME=XE
42
+ - NLS_LANG=AMERICAN_AMERICA.AL32UTF8
32
43
  - 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=
33
44
  rvm:
34
45
  - 2.0.0
@@ -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('ojdbc6.jar'),
93
+ '--user-agent', env['USER_AGENT'],
94
+ env['ORACLE_OJDBC_URL']
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,9 @@
1
+ #!/bin/bash
2
+
3
+ set -ev
4
+
5
+ "$ORACLE_HOME/bin/sqlplus" -L -S / AS SYSDBA <<SQL
6
+ @@test/support/alter_system_user_password.sql
7
+ @@test/support/create_oracle_enhanced_users.sql
8
+ exit
9
+ SQL
data/README.md CHANGED
@@ -4,7 +4,14 @@ Arel Extensions adds shortcuts, fixes and new ORM mappings (ruby to SQL) to Arel
4
4
  It aims to ensure pure ruby syntax for the biggest number of usual cases.
5
5
  It allows to use more advanced SQL functions for any supported RDBMS.
6
6
 
7
- Examples:
7
+
8
+ ## Requirements
9
+
10
+ Arel 6 (Rails 4) or Arel 7+ (Rails 5).
11
+
12
+
13
+ ## Examples
14
+
8
15
  t is an Arel::Table for table my_table
9
16
 
10
17
  ## Comparators
@@ -14,6 +21,11 @@ t is an Arel::Table for table my_table
14
21
  # => my_table.nb > 42
15
22
  ```
16
23
 
24
+ ```ruby
25
+ (t[:date1] > t[:date2]).to_sql # (same as (t[:date1].gt(t[:date2])).to_sql)
26
+ # => my_table.date1 > my_table.date2
27
+ ```
28
+
17
29
  ## Maths
18
30
 
19
31
  Currently in Arel:
@@ -34,7 +46,7 @@ With Arel Extensions:
34
46
  # => SUM(my_table.nb) + 42
35
47
  ```
36
48
 
37
- Other functions : ABS, RAND, ROUND, FLOOR, CEIL, MD5, FORMAT
49
+ Other functions : ABS, RAND, ROUND, FLOOR, CEIL, FORMAT
38
50
 
39
51
  ## String operations
40
52
 
@@ -73,7 +85,7 @@ Other functions : SOUNDEX, LENGTH, REPLACE, LOCATE, TRIM
73
85
  ((t[:birthdate] - Date.today) * -1).to_sql
74
86
  # => DATEDIFF(my_table.birthdate, '2017-01-01') * -1
75
87
 
76
- (t[:birthdate].week).to_sql
88
+ t[:birthdate].week.to_sql
77
89
  # => WEEK(my_table.birthdate)
78
90
 
79
91
  t[:birthdate].month.to_sql
@@ -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.4'
7
+ s.version = '0.8.5'
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"]
@@ -3,7 +3,6 @@ source "https://rubygems.org"
3
3
  gem 'arel', '~> 6.0'
4
4
 
5
5
  group :development, :test do
6
-
7
6
  gem 'activesupport', '~> 4.0'
8
7
  gem 'activemodel', '~> 4.0'
9
8
  gem 'activerecord', '~> 4.0'
@@ -13,7 +12,7 @@ group :development, :test do
13
12
  gem "pg", :platform => [:ruby, :mswin, :mingw]
14
13
 
15
14
  gem 'ruby-oci8', :platform => [:ruby, :mswin, :mingw] if ENV.has_key? 'ORACLE_HOME'
16
- gem 'activerecord-oracle_enhanced-adapter', '~> 1.6.0'
15
+ gem 'activerecord-oracle_enhanced-adapter', '~> 1.6.0' if ENV.has_key? 'ORACLE_HOME'
17
16
 
18
17
  # for JRuby
19
18
  gem 'activerecord-jdbc-adapter', platform: :jruby
@@ -10,8 +10,9 @@ group :development, :test do
10
10
  gem "sqlite3", :platform => [:ruby, :mswin, :mingw]
11
11
  gem "mysql2", :platform => [:ruby, :mswin, :mingw]
12
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'
13
+
14
+ gem 'ruby-oci8', :platform => [:ruby, :mswin, :mingw] if ENV.has_key? 'ORACLE_HOME'
15
+ gem 'activerecord-oracle_enhanced-adapter', '~> 1.7.0' if ENV.has_key? 'ORACLE_HOME'
15
16
 
16
17
  # for JRuby
17
18
  gem 'activerecord-jdbc-adapter', platform: :jruby
data/init/postgresql.sql CHANGED
@@ -1,12 +1,14 @@
1
1
  CREATE OR REPLACE FUNCTION public.find_in_set(n INTEGER, s TEXT)
2
- RETURNS BOOLEAN
2
+ RETURNS INT4
3
3
  LANGUAGE sql
4
4
  AS $function$
5
- select bool(int4(z.row_number))
6
- from
7
- (
8
- select row_number() over(), y.x
5
+ SELECT * FROM (
6
+ select int4(z.row_number) from (
7
+ select row_number() over(), y.x
9
8
  from (select unnest(('{' || $2 || '}')::int[]) as x) as y
10
- ) as z
11
- where z.x = $1
12
- $function$
9
+ ) as z
10
+ where z.x = $1
11
+ UNION ALL
12
+ SELECT 0) z
13
+ LIMIT 1
14
+ $function$
@@ -2,26 +2,30 @@ module ArelExtensions
2
2
  module DateDuration
3
3
  #function returns the year (as a number) given a date value.
4
4
  def year
5
- ArelExtensions::Nodes::Duration.new "y",self
5
+ ArelExtensions::Nodes::Duration.new "y", self
6
6
  end
7
7
 
8
8
  #function returns the month (as a number) given a date value.
9
9
  def month
10
- ArelExtensions::Nodes::Duration.new "m",self
10
+ ArelExtensions::Nodes::Duration.new "m", self
11
11
  end
12
12
 
13
13
  #function returns the week (as a number) given a date value.
14
14
  def week
15
- ArelExtensions::Nodes::Duration.new "w",self
15
+ ArelExtensions::Nodes::Duration.new "w", self
16
16
  end
17
17
 
18
18
  #function returns the month (as a number) given a date value.
19
19
  def day
20
- ArelExtensions::Nodes::Duration.new "d",self
20
+ ArelExtensions::Nodes::Duration.new "d", self
21
21
  end
22
22
 
23
23
  def wday
24
- ArelExtensions::Nodes::Wday.new self
24
+ ArelExtensions::Nodes::Duration.new 'wd', self
25
+ end
26
+
27
+ def format(tpl)
28
+ ArelExtensions::Nodes::Format.new [self, tpl]
25
29
  end
26
30
 
27
31
  end
@@ -15,7 +15,7 @@ module ArelExtensions
15
15
  Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new self, other)
16
16
  elsif arg == :datetime || arg == :date
17
17
  ArelExtensions::Nodes::DateAdd.new [self, other]
18
- elsif arg == :string
18
+ elsif arg == :string || arg == :text
19
19
  ArelExtensions::Nodes::Concat.new [self, other]
20
20
  end
21
21
  end
@@ -18,6 +18,7 @@ require 'arel_extensions/nodes/soundex'
18
18
  require 'arel_extensions/nodes/trim'
19
19
  require 'arel_extensions/nodes/ltrim'
20
20
  require 'arel_extensions/nodes/rtrim'
21
+ require 'arel_extensions/nodes/format'
21
22
 
22
23
  # Date functions
23
24
  require 'arel_extensions/nodes/date_diff'
@@ -1,6 +1,8 @@
1
1
  module ArelExtensions
2
2
  module Nodes
3
3
  class Abs < Function
4
+ @@return_type = :number
5
+
4
6
  end
5
7
  end
6
8
  end
@@ -5,6 +5,8 @@ module ArelExtensions
5
5
  class DateDiff < Function #difference entre colonne date et date string/date
6
6
  attr_accessor :date_type
7
7
 
8
+ @@return_type = :integer # by default...
9
+
8
10
  def initialize(expr)
9
11
  col = expr.first
10
12
  case col
@@ -70,6 +72,21 @@ module ArelExtensions
70
72
  end
71
73
  end
72
74
 
75
+ def oracle_value(v = nil)
76
+ v ||= self.expressions.last
77
+ if defined?(ActiveSupport::Duration) && ActiveSupport::Duration === v
78
+ if @date_type == :date
79
+ Arel.sql("INTERVAL '%s' DAY" % v.inspect.to_i)
80
+ elsif @date_type == :datetime
81
+ Arel.sql("INTERVAL '%s' SECOND" % v.to_i)
82
+ end
83
+ # elsif Arel::Attributes::Attribute === v
84
+ # v
85
+ else
86
+ v
87
+ end
88
+ end
89
+
73
90
  private
74
91
  def convert(object)
75
92
  case object
@@ -1,15 +1,7 @@
1
1
  module ArelExtensions
2
2
  module Nodes
3
3
  class FindInSet < Function
4
-
5
- def left
6
- @expressions.first
7
- end
8
-
9
-
10
- def right
11
- @expressions[1]
12
- end
4
+ @@return_type = :integer
13
5
 
14
6
  end
15
7
  end
@@ -0,0 +1,12 @@
1
+ module ArelExtensions
2
+ module Nodes
3
+ class Format < Function
4
+ attr_accessor :col_type
5
+ def initialize expr
6
+ col = expr.first
7
+ @col_type = Arel::Table.engine.connection.schema_cache.columns_hash(col.relation.table_name)[col.name.to_s].type
8
+ super [expr.first, convert_to_string_node(expr[1])]
9
+ end
10
+ end
11
+ end
12
+ end
@@ -4,6 +4,10 @@ module ArelExtensions
4
4
  include Arel::Math
5
5
  include Arel::Expressions
6
6
 
7
+ cattr_accessor :return_type
8
+
9
+ @@return_type = :string # by default...
10
+
7
11
  # overrides as to make new Node like AliasPredication
8
12
  def as other
9
13
  Arel::Nodes::As.new(self, Arel.sql(other))
@@ -21,7 +25,6 @@ module ArelExtensions
21
25
  @expressions[1]
22
26
  end
23
27
 
24
- protected
25
28
  def convert_to_node(object)
26
29
  case object
27
30
  when Arel::Attributes::Attribute, Arel::Nodes::Node, Fixnum, Integer
@@ -31,7 +34,7 @@ module ArelExtensions
31
34
  when String
32
35
  Arel::Nodes.build_quoted(object)
33
36
  when Date
34
- Arel::Nodes.build_quoted(object, self)
37
+ Arel::Nodes.build_quoted(object.to_s, self)
35
38
  when NilClass
36
39
  Arel.sql('NULL')
37
40
  when ActiveSupport::Duration
@@ -41,6 +44,34 @@ module ArelExtensions
41
44
  end
42
45
  end
43
46
 
47
+ def convert_to_string_node(object)
48
+ case object
49
+ when Arel::Nodes::Node
50
+ object
51
+ when Fixnum, Integer
52
+ Arel::Nodes.build_quoted(object.to_s)
53
+ when Arel::Attributes::Attribute
54
+ case Arel::Table.engine.connection.schema_cache.columns_hash(object.relation.table_name)[object.name.to_s].type
55
+ when :date
56
+ ArelExtensions::Nodes::Format.new [object, 'yyyy-mm-dd']
57
+ else
58
+ object
59
+ end
60
+ when DateTime, Time
61
+ Arel::Nodes.build_quoted(Date.new(object.year, object.month, object.day), self)
62
+ when String
63
+ Arel::Nodes.build_quoted(object)
64
+ when Date
65
+ Arel::Nodes.build_quoted(object, self)
66
+ when NilClass
67
+ Arel.sql('NULL')
68
+ when ActiveSupport::Duration
69
+ Arel::Nodes.build_quoted(object.to_i.to_s)
70
+ else
71
+ raise(ArgumentError, "#{object.class} can not be converted to CONCAT arg")
72
+ end
73
+ end
74
+
44
75
  def convert_to_date_node(object)
45
76
  case object
46
77
  when Arel::Attributes::Attribute, Arel::Nodes::Node