arel_extensions 0.8.4 → 0.8.5

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