Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ DESCRIPTION

ruby-plsql gem provides simple Ruby API for calling Oracle PL/SQL procedures. It could be used both for accessing Oracle PL/SQL API procedures in legacy applications as well as it could be used to create PL/SQL unit tests using Ruby testing libraries.

NUMBER, BINARY_INTEGER, PLS_INTEGER, VARCHAR2, NVARCHAR2, CHAR, NCHAR, DATE, TIMESTAMP, CLOB, BLOB, BOOLEAN, PL/SQL RECORD, TABLE, VARRAY, OBJECT and CURSOR types are supported for input and output parameters and return values of PL/SQL procedures and functions.
NUMBER, BINARY_INTEGER, PLS_INTEGER, NATURAL, NATURALN, POSITIVE, POSITIVEN, SIGNTYPE, SIMPLE_INTEGER, VARCHAR, VARCHAR2, NVARCHAR2, CHAR, NCHAR, DATE, TIMESTAMP, CLOB, BLOB, BOOLEAN, PL/SQL RECORD, TABLE, VARRAY, OBJECT and CURSOR types are supported for input and output parameters and return values of PL/SQL procedures and functions.

ruby-plsql supports Ruby 1.8.7, 1.9.3, 2.1.3 and JRuby 1.6.7, 1.7.16 implementations.

Expand Down
4 changes: 2 additions & 2 deletions lib/plsql/jdbc_connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -342,15 +342,15 @@ def result_set_to_ruby_data_type(column_type, column_type_name)
def plsql_to_ruby_data_type(metadata)
data_type, data_length = metadata[:data_type], metadata[:data_length]
case data_type
when "VARCHAR2", "CHAR", "NVARCHAR2", "NCHAR"
when "VARCHAR", "VARCHAR2", "CHAR", "NVARCHAR2", "NCHAR"
[String, data_length || 32767]
when "CLOB", "NCLOB"
[Java::OracleSql::CLOB, nil]
when "BLOB"
[Java::OracleSql::BLOB, nil]
when "NUMBER"
[BigDecimal, nil]
when "PLS_INTEGER", "BINARY_INTEGER"
when "NATURAL", "NATURALN", "POSITIVE", "POSITIVEN", "SIGNTYPE", "SIMPLE_INTEGER", "PLS_INTEGER", "BINARY_INTEGER"
[Fixnum, nil]
when "DATE"
[DateTime, nil]
Expand Down
4 changes: 2 additions & 2 deletions lib/plsql/oci_connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -147,13 +147,13 @@ def cursor_from_query(sql, bindvars=[], options={})
def plsql_to_ruby_data_type(metadata)
data_type, data_length = metadata[:data_type], metadata[:data_length]
case data_type
when "VARCHAR2", "CHAR", "NVARCHAR2", "NCHAR"
when "VARCHAR", "VARCHAR2", "CHAR", "NVARCHAR2", "NCHAR"
[String, data_length || 32767]
when "CLOB", "NCLOB"
[OCI8::CLOB, nil]
when "BLOB"
[OCI8::BLOB, nil]
when "NUMBER", "PLS_INTEGER", "BINARY_INTEGER"
when "NUMBER", "NATURAL", "NATURALN", "POSITIVE", "POSITIVEN", "SIGNTYPE", "SIMPLE_INTEGER", "PLS_INTEGER", "BINARY_INTEGER"
[OraNumber, nil]
when "DATE"
[DateTime, nil]
Expand Down
2 changes: 1 addition & 1 deletion lib/plsql/procedure.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def self.type_to_sql(metadata) #:nodoc:
when 'NUMBER'
precision, scale = metadata[:data_precision], metadata[:data_scale]
"NUMBER#{precision ? "(#{precision}#{scale ? ",#{scale}": ""})" : ""}"
when 'VARCHAR2', 'CHAR'
when 'VARCHAR', 'VARCHAR2', 'CHAR'
length = case metadata[:char_used]
when 'C' then "#{metadata[:char_length]} CHAR"
when 'B' then "#{metadata[:data_length]} BYTE"
Expand Down
4 changes: 2 additions & 2 deletions lib/plsql/procedure_call.rb
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,9 @@ def get_overload_from_arguments_list(args)
end

MATCHING_TYPES = {
:integer => ['NUMBER', 'PLS_INTEGER', 'BINARY_INTEGER'],
:integer => ['NUMBER', 'NATURAL', 'NATURALN', 'POSITIVE', 'POSITIVEN', 'SIGNTYPE', 'SIMPLE_INTEGER', 'PLS_INTEGER', 'BINARY_INTEGER'],
:decimal => ['NUMBER', 'BINARY_FLOAT', 'BINARY_DOUBLE'],
:string => ['VARCHAR2', 'NVARCHAR2', 'CHAR', 'NCHAR', 'CLOB', 'BLOB'],
:string => ['VARCHAR', 'VARCHAR2', 'NVARCHAR2', 'CHAR', 'NCHAR', 'CLOB', 'BLOB'],
:date => ['DATE'],
:time => ['DATE', 'TIMESTAMP', 'TIMESTAMP WITH TIME ZONE', 'TIMESTAMP WITH LOCAL TIME ZONE'],
:boolean => ['PL/SQL BOOLEAN'],
Expand Down
4 changes: 2 additions & 2 deletions lib/plsql/variable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,10 @@ def value=(new_value)

def metadata(type_string)
case type_string
when /^(VARCHAR2|CHAR|NVARCHAR2|NCHAR)(\((\d+)[\s\w]*\))?$/
when /^(VARCHAR|VARCHAR2|CHAR|NVARCHAR2|NCHAR)(\((\d+)[\s\w]*\))?$/
{:data_type => $1, :data_length => $3.to_i, :in_out => 'IN/OUT'}
when /^(CLOB|NCLOB|BLOB)$/,
/^(NUMBER)(\(.*\))?$/, /^(PLS_INTEGER|BINARY_INTEGER)$/,
/^(NUMBER)(\(.*\))?$/, /^(NATURAL|NATURALN|POSITIVE|POSITIVEN|SIGNTYPE|SIMPLE_INTEGER|PLS_INTEGER|BINARY_INTEGER)$/,
/^(DATE|TIMESTAMP|TIMESTAMP WITH TIME ZONE|TIMESTAMP WITH LOCAL TIME ZONE)$/
{:data_type => $1, :in_out => 'IN/OUT'}
when /^INTEGER$/
Expand Down
9 changes: 9 additions & 0 deletions spec/plsql/connection_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@
# Ruby 1.8 and 1.9
unless defined?(JRuby)
describe "OCI data type conversions" do
it "should translate PL/SQL VARCHAR to Ruby String" do
expect(@conn.plsql_to_ruby_data_type(:data_type => "VARCHAR", :data_length => 100)).to eq [String, 100]
expect(@conn.plsql_to_ruby_data_type(:data_type => "VARCHAR", :data_length => nil)).to eq [String, 32767]
end

it "should translate PL/SQL VARCHAR2 to Ruby String" do
expect(@conn.plsql_to_ruby_data_type(:data_type => "VARCHAR2", :data_length => 100)).to eq [String, 100]
expect(@conn.plsql_to_ruby_data_type(:data_type => "VARCHAR2", :data_length => nil)).to eq [String, 32767]
Expand Down Expand Up @@ -122,6 +127,10 @@
else

describe "JDBC data type conversions" do
it "should translate PL/SQL VARCHAR to Ruby String" do
expect(@conn.plsql_to_ruby_data_type(:data_type => "VARCHAR", :data_length => 100)).to eq [String, 100]
expect(@conn.plsql_to_ruby_data_type(:data_type => "VARCHAR", :data_length => nil)).to eq [String, 32767]
end
it "should translate PL/SQL VARCHAR2 to Ruby String" do
expect(@conn.plsql_to_ruby_data_type(:data_type => "VARCHAR2", :data_length => 100)).to eq [String, 100]
expect(@conn.plsql_to_ruby_data_type(:data_type => "VARCHAR2", :data_length => nil)).to eq [String, 32767]
Expand Down
123 changes: 63 additions & 60 deletions spec/plsql/procedure_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
require 'spec_helper'

describe "Parameter type mapping /" do
describe "Function with string parameters" do

shared_examples "Function with string parameters" do |datatype|
before(:all) do
plsql.connect! CONNECTION_PARAMS
plsql.execute <<-SQL
CREATE OR REPLACE FUNCTION test_uppercase
( p_string VARCHAR2 )
RETURN VARCHAR2
( p_string #{datatype} )
RETURN #{datatype}
IS
BEGIN
RETURN UPPER(p_string);
Expand Down Expand Up @@ -56,83 +57,85 @@

end

describe "Function with numeric parameters" do
['VARCHAR', 'VARCHAR2'].each do |datatype|
describe "Function with #{datatype} parameters" do
it_should_behave_like "Function with string parameters", datatype
end
end

shared_examples "Function with numeric" do |ora_data_type, class_, num1, num2, expected, mandatory|
before(:all) do
plsql.connect! CONNECTION_PARAMS
plsql.execute <<-SQL
CREATE OR REPLACE FUNCTION test_sum
( p_num1 NUMBER, p_num2 NUMBER )
RETURN NUMBER
( p_num1 #{ora_data_type}, p_num2 #{ora_data_type} )
RETURN #{ora_data_type}
IS
BEGIN
RETURN p_num1 + p_num2;
END test_sum;
SQL
plsql.execute <<-SQL
CREATE OR REPLACE FUNCTION test_number_1
( p_num NUMBER )
RETURN VARCHAR2
IS
BEGIN
IF p_num = 1 THEN
RETURN 'Y';
ELSIF p_num = 0 THEN
RETURN 'N';
ELSIF p_num IS NULL THEN
RETURN NULL;
ELSE
RETURN 'UNKNOWN';
END IF;
END test_number_1;
SQL
plsql.execute <<-SQL
CREATE OR REPLACE PROCEDURE test_integers
( p_pls_int PLS_INTEGER, p_bin_int BINARY_INTEGER, x_pls_int OUT PLS_INTEGER, x_bin_int OUT BINARY_INTEGER )
IS
BEGIN
x_pls_int := p_pls_int;
x_bin_int := p_bin_int;
END;
SQL
end

after(:all) do
plsql.execute "DROP FUNCTION test_sum"
plsql.execute "DROP FUNCTION test_number_1"
plsql.execute "DROP PROCEDURE test_integers"
plsql.logoff
end

it "should process integer parameters" do
expect(plsql.test_sum(123,456)).to eq(579)
it "should get #{ora_data_type} variable type mapped to #{class_.to_s}" do
expect(plsql.test_sum(num1, num2)).to be_a class_
end

it "should process big integer parameters" do
expect(plsql.test_sum(123123123123,456456456456)).to eq(579579579579)
it "should process input parameters and return correct result" do
expect(plsql.test_sum(num1, num2)).to eq(expected)
end

it "should process float parameters and return BigDecimal" do
expect(plsql.test_sum(123.123,456.456)).to eq(BigDecimal("579.579"))
end
it "should process nil parameter as NULL" do
expect(plsql.test_sum(num1, nil)).to be_nil
end unless mandatory

end

it "should process BigDecimal parameters and return BigDecimal" do
expect(plsql.test_sum(:p_num1 => BigDecimal("123.123"), :p_num2 => BigDecimal("456.456"))).to eq(BigDecimal("579.579"))
@big_number = ('1234567890' * 3).to_i
[
{:ora_data_type => 'INTEGER', :class => Bignum, :num1 => @big_number, :num2 => @big_number, :expected => @big_number*2},
{:ora_data_type => 'NUMBER', :class => BigDecimal, :num1 => 12345.12345, :num2 => 12345.12345, :expected => 24690.2469 },
{:ora_data_type => 'PLS_INTEGER', :class => Fixnum, :num1 => 123456789, :num2 => 123456789, :expected => 246913578 },
{:ora_data_type => 'BINARY_INTEGER',:class => Fixnum, :num1 => 123456789, :num2 => 123456789, :expected => 246913578 },
{:ora_data_type => 'SIMPLE_INTEGER',:class => Fixnum, :num1 => 123456789, :num2 => 123456789, :expected => 246913578, :mandatory => true },
{:ora_data_type => 'NATURAL', :class => Fixnum, :num1 => 123456789, :num2 => 123456789, :expected => 246913578 },
{:ora_data_type => 'NATURALN', :class => Fixnum, :num1 => 123456789, :num2 => 123456789, :expected => 246913578, :mandatory => true },
{:ora_data_type => 'POSITIVE', :class => Fixnum, :num1 => 123456789, :num2 => 123456789, :expected => 246913578 },
{:ora_data_type => 'POSITIVEN', :class => Fixnum, :num1 => 123456789, :num2 => 123456789, :expected => 246913578, :mandatory => true },
{:ora_data_type => 'SIGNTYPE', :class => Fixnum, :num1 => 1, :num2 => -1, :expected => 0 },
].each do |row|
ora_data_type, class_, num1, num2, expected, mandatory = row.values
describe ora_data_type do
include_examples "Function with numeric", ora_data_type, class_, num1, num2, expected, mandatory
end
end

it "should process nil parameter as NULL" do
expect(plsql.test_sum(123,nil)).to be_nil
describe "Boolean to NUMBER conversion" do
before(:all) do
plsql.connect! CONNECTION_PARAMS
plsql.execute <<-SQL
CREATE OR REPLACE FUNCTION test_num ( p_num NUMBER) RETURN NUMBER
IS
BEGIN
RETURN p_num;
END test_num;
SQL
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have a test now which to cover the "true to 1 conversion"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will get recovered and added as a separate describe block

end

after(:all) do
plsql.execute "DROP FUNCTION test_num"
plsql.logoff
end
it "should convert true value to 1 for NUMBER parameter" do
expect(plsql.test_number_1(true)).to eq('Y')
expect(plsql.test_num(true)).to eq(1)
end

it "should convert false value to 0 for NUMBER parameter" do
expect(plsql.test_number_1(false)).to eq('N')
end

it "should process binary integer parameters" do
expect(plsql.test_integers(123, 456)).to eq({:x_pls_int => 123, :x_bin_int => 456})
expect(plsql.test_num(false)).to eq(0)
end
end

Expand Down Expand Up @@ -609,7 +612,7 @@
CREATE TABLE test_employees (
employee_id NUMBER(15),
first_name VARCHAR2(50),
last_name VARCHAR2(50),
last_name VARCHAR(50),
hire_date DATE
)
SQL
Expand All @@ -626,7 +629,7 @@
TYPE t_employee IS RECORD(
employee_id NUMBER(15),
first_name VARCHAR2(50),
last_name VARCHAR2(50),
last_name VARCHAR(50),
hire_date DATE
);

Expand Down Expand Up @@ -887,7 +890,7 @@ def new_candidate(status)
CREATE OR REPLACE TYPE t_employee AS OBJECT (
employee_id NUMBER(15),
first_name VARCHAR2(50),
last_name VARCHAR2(50),
last_name VARCHAR(50),
hire_date DATE,
address t_address,
phones t_phones
Expand Down Expand Up @@ -1047,7 +1050,7 @@ def new_candidate(status)
TYPE t_employee IS RECORD(
employee_id NUMBER(15),
first_name VARCHAR2(50),
last_name VARCHAR2(50),
last_name VARCHAR(50),
hire_date DATE
);
TYPE t_employees IS TABLE OF t_employee;
Expand All @@ -1057,7 +1060,7 @@ def new_candidate(status)
TYPE t_employee2 IS RECORD(
employee_id NUMBER(15),
first_name VARCHAR2(50),
last_name VARCHAR2(50),
last_name VARCHAR(50),
hire_date DATE,
numbers t_numbers
);
Expand Down Expand Up @@ -1294,7 +1297,7 @@ def new_candidate(status)
CREATE TABLE test_employees (
employee_id NUMBER(15),
first_name VARCHAR2(50),
last_name VARCHAR2(50),
last_name VARCHAR(50),
hire_date DATE
)
SQL
Expand All @@ -1312,7 +1315,7 @@ def new_candidate(status)
TYPE t_employee IS RECORD(
employee_id NUMBER(15),
first_name VARCHAR2(50),
last_name VARCHAR2(50),
last_name VARCHAR(50),
hire_date DATE
);
TYPE t_employees IS TABLE OF t_employee
Expand Down Expand Up @@ -1742,7 +1745,7 @@ def new_candidate(status)
CREATE TABLE test_employees (
employee_id NUMBER(15),
first_name VARCHAR2(50),
last_name VARCHAR2(50),
last_name VARCHAR(50),
hire_date DATE
)
SQL
Expand Down
2 changes: 1 addition & 1 deletion spec/plsql/sql_statements_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
CREATE TABLE test_employees (
employee_id NUMBER(15),
first_name VARCHAR2(50),
last_name VARCHAR2(50),
last_name VARCHAR(50),
hire_date DATE
)
SQL
Expand Down
4 changes: 2 additions & 2 deletions spec/plsql/table_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
CREATE TABLE test_employees (
employee_id NUMBER(15) NOT NULL,
first_name VARCHAR2(50),
last_name VARCHAR2(50),
last_name VARCHAR(50),
hire_date DATE,
created_at TIMESTAMP,
status VARCHAR2(1) DEFAULT 'N'
Expand All @@ -35,7 +35,7 @@
CREATE TABLE test_employees2 (
employee_id NUMBER(15) NOT NULL,
first_name VARCHAR2(50),
last_name VARCHAR2(50),
last_name VARCHAR(50),
hire_date DATE DEFAULT SYSDATE,
address t_address,
phones t_phones
Expand Down
2 changes: 1 addition & 1 deletion spec/plsql/type_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@
CREATE OR REPLACE TYPE t_employee AS OBJECT (
employee_id NUMBER(15),
first_name VARCHAR2(50),
last_name VARCHAR2(50),
last_name VARCHAR(50),
hire_date DATE,
address t_address,
phones t_phones
Expand Down
Loading