ruby-plsql 0.5.2 → 0.5.3
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 +4 -4
- data/Gemfile +1 -1
- data/History.txt +12 -0
- data/README.md +23 -4
- data/VERSION +1 -1
- data/Vagrantfile +38 -0
- data/lib/plsql/jdbc_connection.rb +12 -10
- data/lib/plsql/package.rb +4 -0
- data/lib/plsql/procedure_call.rb +27 -33
- data/ruby-plsql.gemspec +11 -8
- data/spec/plsql/connection_spec.rb +17 -13
- data/spec/plsql/package_spec.rb +8 -0
- data/spec/plsql/schema_spec.rb +9 -1
- data/spec/spec_helper.rb +24 -1
- data/spec/support/file_check_script.sh +9 -0
- data/spec/support/test_db.rb +150 -0
- metadata +8 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f9c79fd3f97babd3bfa0f5a54b0830a12a6510c9
|
|
4
|
+
data.tar.gz: b3ec4ad1f9db5aa761fc751b1db9a1263c2dd6f1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 88a0bf576dd829b0cbd7102a72a7a9d8bdfe3aee2e8771353756887f292c5c364ea9b24004c41e4cb14882cfd82c4d8ef7a9cd3709e04ab4693236dd163011c7
|
|
7
|
+
data.tar.gz: ac9bde40f6690697c63acb443a8a9f02afa9fc1bb1670e477c09b21f6c4aa368c61326047ae8733860d337dd862efe4432fba81f3eee35d9a9affc72c60e32ff
|
data/Gemfile
CHANGED
|
@@ -5,7 +5,7 @@ group :development do
|
|
|
5
5
|
gem 'rspec', '~> 3.1'
|
|
6
6
|
|
|
7
7
|
unless ENV['NO_ACTIVERECORD']
|
|
8
|
-
gem 'activerecord', '>= 3.2.3', '< 4.
|
|
8
|
+
gem 'activerecord', '>= 3.2.3', '< 4.3.0'
|
|
9
9
|
gem 'activerecord-oracle_enhanced-adapter', '>= 1.4.1', '< 1.6.0'
|
|
10
10
|
gem 'simplecov', '>= 0'
|
|
11
11
|
end
|
data/History.txt
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
== 0.5.3 2015-05-07
|
|
2
|
+
|
|
3
|
+
* Improvements
|
|
4
|
+
* Support for ActiveRecord 4.2
|
|
5
|
+
* Docs
|
|
6
|
+
* README formatting fixed (Usage with Rails section)
|
|
7
|
+
* Bug fixes
|
|
8
|
+
* Force to convert String type value as real string to avoid error when used JRuby and for VARCHAR2 parameter is assigned non String value
|
|
9
|
+
* Fix dbms_output functionality in case when database exception is raised
|
|
10
|
+
* Internal (development) improvements
|
|
11
|
+
* Vagrant box provisioning added
|
|
12
|
+
|
|
1
13
|
== 0.5.2 2014-10-23
|
|
2
14
|
|
|
3
15
|
* Bug fixes
|
data/README.md
CHANGED
|
@@ -59,6 +59,7 @@ plsql.logoff
|
|
|
59
59
|
|
|
60
60
|
Look at RSpec tests under spec directory for more usage examples.
|
|
61
61
|
|
|
62
|
+
Note: named arguments in procedures calls should be in lower case.
|
|
62
63
|
|
|
63
64
|
### Table operations:
|
|
64
65
|
|
|
@@ -69,7 +70,7 @@ ruby-plsql also provides simple API for select/insert/update/delete table operat
|
|
|
69
70
|
employee = { :employee_id => 1, :first_name => 'First', :last_name => 'Last', :hire_date => Time.local(2000,01,31) }
|
|
70
71
|
plsql.employees.insert employee # INSERT INTO employees VALUES (1, 'First', 'Last', ...)
|
|
71
72
|
|
|
72
|
-
# insert many records
|
|
73
|
+
# insert many records
|
|
73
74
|
employees = [employee1, employee2, ... ] # array of many Hashes
|
|
74
75
|
plsql.employees.insert employees
|
|
75
76
|
|
|
@@ -104,7 +105,7 @@ plsql.employees.delete(:employee_id => 1) # DELETE FROM employees WHERE employee
|
|
|
104
105
|
# select from sequences
|
|
105
106
|
plsql.employees_seq.nextval # SELECT employees_seq.NEXTVAL FROM dual
|
|
106
107
|
plsql.employees_seq.currval # SELECT employees_seq.CURRVAL FROM dual
|
|
107
|
-
|
|
108
|
+
```
|
|
108
109
|
|
|
109
110
|
### Usage with Rails:
|
|
110
111
|
|
|
@@ -140,7 +141,17 @@ If you are using JRuby then you need to download latest [Oracle JDBC driver](htt
|
|
|
140
141
|
TESTS
|
|
141
142
|
-----
|
|
142
143
|
|
|
143
|
-
|
|
144
|
+
Review `spec/spec_helper.rb` to see default schema/user names and database names (use environment variables to override defaults)
|
|
145
|
+
|
|
146
|
+
##### Prepare database
|
|
147
|
+
|
|
148
|
+
* With local [Vagrant](https://www.vagrantup.com) based Oracle XE database.
|
|
149
|
+
|
|
150
|
+
Download Oracle XE database ```oracle-xe-11.2.0-1.0.x86_64.rpm.zip``` from [Oracle Home page](http://www.oracle.com/technetwork/database/database-technologies/express-edition/downloads/index.html) and put it into project home directory.
|
|
151
|
+
|
|
152
|
+
From project home directory run ```vagrant up``` command to build fully functioning **Centos 6.6** virtual machine with installed Oracle XE database.
|
|
153
|
+
|
|
154
|
+
* Within other Oracle Database create Oracle database schema for test purposes.
|
|
144
155
|
|
|
145
156
|
SQL> CREATE USER hr IDENTIFIED BY hr;
|
|
146
157
|
SQL> GRANT unlimited tablespace, create session, create table, create sequence, create procedure, create type, create view, create synonym TO hr;
|
|
@@ -148,6 +159,8 @@ TESTS
|
|
|
148
159
|
SQL> CREATE USER arunit IDENTIFIED BY arunit;
|
|
149
160
|
SQL> GRANT create session TO arunit;
|
|
150
161
|
|
|
162
|
+
##### Prepare dependencies
|
|
163
|
+
|
|
151
164
|
* Install bundler with
|
|
152
165
|
|
|
153
166
|
gem install bundler
|
|
@@ -156,7 +169,13 @@ TESTS
|
|
|
156
169
|
|
|
157
170
|
bundle install
|
|
158
171
|
|
|
159
|
-
|
|
172
|
+
##### Run tests
|
|
173
|
+
|
|
174
|
+
* Run tests with local Vagrant based Oracle XE database
|
|
175
|
+
|
|
176
|
+
USE_VM_DATABASE=Y rake spec
|
|
177
|
+
|
|
178
|
+
* Run tests with other Oracle database
|
|
160
179
|
|
|
161
180
|
rake spec
|
|
162
181
|
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.5.
|
|
1
|
+
0.5.3
|
data/Vagrantfile
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
|
|
2
|
+
VAGRANTFILE_API_VERSION = "2"
|
|
3
|
+
|
|
4
|
+
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
|
5
|
+
|
|
6
|
+
# Every Vagrant virtual environment requires a box to build off of.
|
|
7
|
+
config.vm.box = "chef/centos-6.6"
|
|
8
|
+
config.vm.hostname = "vagrant.oracle"
|
|
9
|
+
config.vm.network :forwarded_port, guest: 1521, host: 1521
|
|
10
|
+
|
|
11
|
+
config.vm.provider :virtualbox do |vb|
|
|
12
|
+
vb.name = "Ruby-PLSQL Oracle XE box"
|
|
13
|
+
# Speed up network
|
|
14
|
+
# http://serverfault.com/a/453260/105586
|
|
15
|
+
# http://serverfault.com/a/595010/105586
|
|
16
|
+
vb.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
|
|
17
|
+
vb.customize ["modifyvm", :id, "--natdnsproxy1", "on"]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Check for Oracle XE installation file
|
|
21
|
+
config.vm.provision :shell, path: "./spec/support/file_check_script.sh"
|
|
22
|
+
|
|
23
|
+
config.vm.provision :shell, inline: "yum update -y"
|
|
24
|
+
config.vm.provision :shell, inline: "yum install -y libaio bc flex unzip"
|
|
25
|
+
config.vm.provision :shell, inline: "mkdir -p /opt/oracle"
|
|
26
|
+
config.vm.provision :shell, inline: "unzip -q -d /opt/oracle /vagrant/oracle-xe-11.2.0-1.0.x86_64.rpm.zip"
|
|
27
|
+
config.vm.provision :shell, inline: "cd /opt/oracle/Disk1 && rpm -ivh oracle-xe-11.2.0-1.0.x86_64.rpm"
|
|
28
|
+
config.vm.provision :shell, inline: %q{sed -i -E "s/<value required>/oracle/" /opt/oracle/Disk1/response/xe.rsp}
|
|
29
|
+
config.vm.provision :shell, inline: "/etc/init.d/oracle-xe configure responseFile=/opt/oracle/Disk1/response/xe.rsp >> /opt/oracle/XEsilentinstall.log"
|
|
30
|
+
config.vm.provision :shell, inline: ". /u01/app/oracle/product/11.2.0/xe/bin/oracle_env.sh"
|
|
31
|
+
config.vm.provision :shell, inline: "touch /etc/profile.d/oracle_profile.sh && cat /u01/app/oracle/product/11.2.0/xe/bin/oracle_env.sh >> /etc/profile.d/oracle_profile.sh"
|
|
32
|
+
config.vm.provision :shell, inline: %q{sed -i -E "s/HOST = [^)]+/HOST = $HOSTNAME/g" /u01/app/oracle/product/11.2.0/xe/network/admin/listener.ora}
|
|
33
|
+
config.vm.provision :shell, inline: %q{sed -i -E "s/<ORACLE_BASE>/\/u01\/app\/oracle/" /u01/app/oracle/product/11.2.0/xe/dbs/init.ora}
|
|
34
|
+
|
|
35
|
+
# Change password for Oracle user
|
|
36
|
+
config.vm.provision :shell, inline: "echo -e \"oracle\noracle\" | passwd oracle"
|
|
37
|
+
|
|
38
|
+
end
|
|
@@ -109,14 +109,14 @@ module PLSQL
|
|
|
109
109
|
@out_types[arg] = type || ora_value.class
|
|
110
110
|
@out_index[arg] = bind_param_index(arg)
|
|
111
111
|
if ['TABLE','VARRAY','OBJECT'].include?(metadata[:data_type])
|
|
112
|
-
@statement.registerOutParameter(@out_index[arg], @connection.get_java_sql_type(ora_value,type),
|
|
112
|
+
@statement.registerOutParameter(@out_index[arg], @connection.get_java_sql_type(ora_value,type),
|
|
113
113
|
metadata[:sql_type_name])
|
|
114
114
|
else
|
|
115
115
|
@statement.registerOutParameter(@out_index[arg],@connection.get_java_sql_type(ora_value,type))
|
|
116
116
|
end
|
|
117
117
|
end
|
|
118
118
|
end
|
|
119
|
-
|
|
119
|
+
|
|
120
120
|
def exec
|
|
121
121
|
@statement.execute
|
|
122
122
|
end
|
|
@@ -128,9 +128,9 @@ module PLSQL
|
|
|
128
128
|
def close
|
|
129
129
|
@statement.close
|
|
130
130
|
end
|
|
131
|
-
|
|
131
|
+
|
|
132
132
|
private
|
|
133
|
-
|
|
133
|
+
|
|
134
134
|
def bind_param_index(key)
|
|
135
135
|
return key if key.kind_of? Integer
|
|
136
136
|
key = ":#{key.to_s}" unless key.to_s =~ /^:/
|
|
@@ -301,7 +301,7 @@ module PLSQL
|
|
|
301
301
|
raise ArgumentError, "Don't know how to bind variable with type #{type_symbol}"
|
|
302
302
|
end
|
|
303
303
|
end
|
|
304
|
-
|
|
304
|
+
|
|
305
305
|
def get_bind_variable(stmt, i, type)
|
|
306
306
|
case type.to_s.to_sym
|
|
307
307
|
when :Fixnum, :Bignum, :Integer
|
|
@@ -337,7 +337,7 @@ module PLSQL
|
|
|
337
337
|
end
|
|
338
338
|
|
|
339
339
|
def result_set_to_ruby_data_type(column_type, column_type_name)
|
|
340
|
-
|
|
340
|
+
|
|
341
341
|
end
|
|
342
342
|
|
|
343
343
|
def plsql_to_ruby_data_type(metadata)
|
|
@@ -371,8 +371,10 @@ module PLSQL
|
|
|
371
371
|
def ruby_value_to_ora_value(value, type=nil, metadata={})
|
|
372
372
|
type ||= value.class
|
|
373
373
|
case type.to_s.to_sym
|
|
374
|
-
when :Fixnum
|
|
374
|
+
when :Fixnum
|
|
375
375
|
value
|
|
376
|
+
when :String
|
|
377
|
+
value.to_s
|
|
376
378
|
when :BigDecimal
|
|
377
379
|
case value
|
|
378
380
|
when TrueClass
|
|
@@ -521,7 +523,7 @@ module PLSQL
|
|
|
521
523
|
end
|
|
522
524
|
|
|
523
525
|
private
|
|
524
|
-
|
|
526
|
+
|
|
525
527
|
def java_date(value)
|
|
526
528
|
value && Java::oracle.sql.DATE.new(value.strftime("%Y-%m-%d %H:%M:%S"))
|
|
527
529
|
end
|
|
@@ -538,7 +540,7 @@ module PLSQL
|
|
|
538
540
|
# return BigDecimal instead of Float to avoid rounding errors
|
|
539
541
|
num == (num_to_i = num.to_i) ? num_to_i : (num.is_a?(BigDecimal) ? num : BigDecimal.new(num.to_s))
|
|
540
542
|
end
|
|
541
|
-
|
|
543
|
+
|
|
542
544
|
end
|
|
543
|
-
|
|
545
|
+
|
|
544
546
|
end
|
data/lib/plsql/package.rb
CHANGED
data/lib/plsql/procedure_call.rb
CHANGED
|
@@ -26,8 +26,6 @@ module PLSQL
|
|
|
26
26
|
|
|
27
27
|
@cursor.exec
|
|
28
28
|
|
|
29
|
-
dbms_output_log
|
|
30
|
-
|
|
31
29
|
if block_given?
|
|
32
30
|
yield get_return_value
|
|
33
31
|
nil
|
|
@@ -36,6 +34,7 @@ module PLSQL
|
|
|
36
34
|
end
|
|
37
35
|
ensure
|
|
38
36
|
@cursor.close if @cursor
|
|
37
|
+
dbms_output_log
|
|
39
38
|
end
|
|
40
39
|
|
|
41
40
|
private
|
|
@@ -215,10 +214,8 @@ module PLSQL
|
|
|
215
214
|
end
|
|
216
215
|
add_out_variables
|
|
217
216
|
|
|
218
|
-
dbms_output_enable_sql, dbms_output_get_sql = dbms_output_sql
|
|
219
|
-
|
|
220
217
|
@sql = @declare_sql.empty? ? "" : "DECLARE\n" << @declare_sql
|
|
221
|
-
@sql << "BEGIN\n" << @assignment_sql << dbms_output_enable_sql << @call_sql <<
|
|
218
|
+
@sql << "BEGIN\n" << @assignment_sql << dbms_output_enable_sql << @call_sql << @return_sql << "END;\n"
|
|
222
219
|
end
|
|
223
220
|
|
|
224
221
|
def add_argument(argument, value, argument_metadata=nil)
|
|
@@ -539,34 +536,24 @@ module PLSQL
|
|
|
539
536
|
@procedure_name ||= @procedure.procedure
|
|
540
537
|
end
|
|
541
538
|
|
|
542
|
-
def
|
|
543
|
-
|
|
544
|
-
dbms_output_enable_sql = "DBMS_OUTPUT.ENABLE(#{@schema.dbms_output_buffer_size});\n"
|
|
545
|
-
# if database version is at least 10.2 then use DBMS_OUTPUT.GET_LINES with SYS.DBMSOUTPUT_LINESARRAY
|
|
546
|
-
if (@schema.connection.database_version <=> [10, 2, 0, 0]) >= 0
|
|
547
|
-
@declare_sql << "l_dbms_output_numlines INTEGER := #{Schema::DBMS_OUTPUT_MAX_LINES};\n"
|
|
548
|
-
dbms_output_get_sql = "DBMS_OUTPUT.GET_LINES(:dbms_output_lines, l_dbms_output_numlines);\n"
|
|
549
|
-
@bind_values[:dbms_output_lines] = nil
|
|
550
|
-
@bind_metadata[:dbms_output_lines] = {:data_type => 'TABLE', :data_length => nil,
|
|
551
|
-
:sql_type_name => "SYS.DBMSOUTPUT_LINESARRAY", :in_out => 'OUT'}
|
|
552
|
-
# if database version is less than 10.2 then use individual DBMS_OUTPUT.GET_LINE calls
|
|
553
|
-
else
|
|
554
|
-
dbms_output_get_sql = ""
|
|
555
|
-
end
|
|
556
|
-
[dbms_output_enable_sql, dbms_output_get_sql]
|
|
557
|
-
else
|
|
558
|
-
["", ""]
|
|
559
|
-
end
|
|
539
|
+
def dbms_output_enable_sql
|
|
540
|
+
@dbms_output_stream ? "DBMS_OUTPUT.ENABLE(#{@schema.dbms_output_buffer_size});\n" : ""
|
|
560
541
|
end
|
|
561
542
|
|
|
562
|
-
def
|
|
543
|
+
def dbms_output_lines
|
|
544
|
+
lines = []
|
|
563
545
|
if @dbms_output_stream
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
546
|
+
if (@schema.connection.database_version <=> [10, 2, 0, 0]) >= 0
|
|
547
|
+
cursor = @schema.connection.parse("BEGIN DBMS_OUTPUT.GET_LINES(:dbms_output_lines, :dbms_output_numlines); END;\n")
|
|
548
|
+
cursor.bind_param(':dbms_output_lines', nil,
|
|
549
|
+
:data_type => 'TABLE',
|
|
550
|
+
:data_length => nil,
|
|
551
|
+
:sql_type_name => "SYS.DBMSOUTPUT_LINESARRAY",
|
|
552
|
+
:in_out => 'OUT')
|
|
553
|
+
cursor.bind_param(':dbms_output_numlines', Schema::DBMS_OUTPUT_MAX_LINES, :data_type => 'NUMBER', :in_out => 'IN/OUT')
|
|
554
|
+
cursor.exec
|
|
555
|
+
lines = cursor[':dbms_output_lines']
|
|
556
|
+
cursor.close
|
|
570
557
|
else
|
|
571
558
|
cursor = @schema.connection.parse("BEGIN sys.dbms_output.get_line(:line, :status); END;")
|
|
572
559
|
while true do
|
|
@@ -574,14 +561,21 @@ module PLSQL
|
|
|
574
561
|
cursor.bind_param(':status', nil, :data_type => 'NUMBER', :in_out => 'OUT')
|
|
575
562
|
cursor.exec
|
|
576
563
|
break unless cursor[':status'] == 0
|
|
577
|
-
|
|
564
|
+
lines << cursor[':line']
|
|
578
565
|
end
|
|
579
566
|
cursor.close
|
|
580
567
|
end
|
|
581
|
-
@dbms_output_stream.flush
|
|
582
568
|
end
|
|
569
|
+
lines
|
|
570
|
+
end
|
|
571
|
+
|
|
572
|
+
def dbms_output_log
|
|
573
|
+
dbms_output_lines.each do |line|
|
|
574
|
+
@dbms_output_stream.puts "DBMS_OUTPUT: #{line}" if line
|
|
575
|
+
end
|
|
576
|
+
@dbms_output_stream.flush if @dbms_output_stream
|
|
583
577
|
end
|
|
584
578
|
|
|
585
579
|
end
|
|
586
580
|
|
|
587
|
-
end
|
|
581
|
+
end
|
data/ruby-plsql.gemspec
CHANGED
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
|
4
4
|
# -*- encoding: utf-8 -*-
|
|
5
|
-
# stub: ruby-plsql 0.5.
|
|
5
|
+
# stub: ruby-plsql 0.5.3 ruby lib
|
|
6
6
|
|
|
7
7
|
Gem::Specification.new do |s|
|
|
8
8
|
s.name = "ruby-plsql"
|
|
9
|
-
s.version = "0.5.
|
|
9
|
+
s.version = "0.5.3"
|
|
10
10
|
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
|
12
12
|
s.require_paths = ["lib"]
|
|
13
13
|
s.authors = ["Raimonds Simanovskis"]
|
|
14
|
-
s.date = "
|
|
14
|
+
s.date = "2015-05-07"
|
|
15
15
|
s.description = "ruby-plsql gem provides simple Ruby API for calling Oracle PL/SQL procedures.\nIt could be used both for accessing Oracle PL/SQL API procedures in legacy applications\nas well as it could be used to create PL/SQL unit tests using Ruby testing libraries.\n"
|
|
16
16
|
s.email = "raimonds.simanovskis@gmail.com"
|
|
17
17
|
s.extra_rdoc_files = [
|
|
@@ -24,6 +24,7 @@ Gem::Specification.new do |s|
|
|
|
24
24
|
"README.md",
|
|
25
25
|
"Rakefile",
|
|
26
26
|
"VERSION",
|
|
27
|
+
"Vagrantfile",
|
|
27
28
|
"lib/plsql/connection.rb",
|
|
28
29
|
"lib/plsql/helpers.rb",
|
|
29
30
|
"lib/plsql/jdbc_connection.rb",
|
|
@@ -55,10 +56,12 @@ Gem::Specification.new do |s|
|
|
|
55
56
|
"spec/plsql/version_spec.rb",
|
|
56
57
|
"spec/plsql/view_spec.rb",
|
|
57
58
|
"spec/spec.opts",
|
|
58
|
-
"spec/spec_helper.rb"
|
|
59
|
+
"spec/spec_helper.rb",
|
|
60
|
+
"spec/support/file_check_script.sh",
|
|
61
|
+
"spec/support/test_db.rb"
|
|
59
62
|
]
|
|
60
63
|
s.homepage = "http://github.com/rsim/ruby-plsql"
|
|
61
|
-
s.rubygems_version = "2.
|
|
64
|
+
s.rubygems_version = "2.4.6"
|
|
62
65
|
s.summary = "Ruby API for calling Oracle PL/SQL procedures."
|
|
63
66
|
|
|
64
67
|
if s.respond_to? :specification_version then
|
|
@@ -67,14 +70,14 @@ Gem::Specification.new do |s|
|
|
|
67
70
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
|
68
71
|
s.add_development_dependency(%q<jeweler>, ["~> 2.0.1"])
|
|
69
72
|
s.add_development_dependency(%q<rspec>, ["~> 3.1"])
|
|
70
|
-
s.add_development_dependency(%q<activerecord>, ["< 4.
|
|
73
|
+
s.add_development_dependency(%q<activerecord>, ["< 4.3.0", ">= 3.2.3"])
|
|
71
74
|
s.add_development_dependency(%q<activerecord-oracle_enhanced-adapter>, ["< 1.6.0", ">= 1.4.1"])
|
|
72
75
|
s.add_development_dependency(%q<simplecov>, [">= 0"])
|
|
73
76
|
s.add_development_dependency(%q<ruby-oci8>, ["~> 2.1.2"])
|
|
74
77
|
else
|
|
75
78
|
s.add_dependency(%q<jeweler>, ["~> 2.0.1"])
|
|
76
79
|
s.add_dependency(%q<rspec>, ["~> 3.1"])
|
|
77
|
-
s.add_dependency(%q<activerecord>, ["< 4.
|
|
80
|
+
s.add_dependency(%q<activerecord>, ["< 4.3.0", ">= 3.2.3"])
|
|
78
81
|
s.add_dependency(%q<activerecord-oracle_enhanced-adapter>, ["< 1.6.0", ">= 1.4.1"])
|
|
79
82
|
s.add_dependency(%q<simplecov>, [">= 0"])
|
|
80
83
|
s.add_dependency(%q<ruby-oci8>, ["~> 2.1.2"])
|
|
@@ -82,7 +85,7 @@ Gem::Specification.new do |s|
|
|
|
82
85
|
else
|
|
83
86
|
s.add_dependency(%q<jeweler>, ["~> 2.0.1"])
|
|
84
87
|
s.add_dependency(%q<rspec>, ["~> 3.1"])
|
|
85
|
-
s.add_dependency(%q<activerecord>, ["< 4.
|
|
88
|
+
s.add_dependency(%q<activerecord>, ["< 4.3.0", ">= 3.2.3"])
|
|
86
89
|
s.add_dependency(%q<activerecord-oracle_enhanced-adapter>, ["< 1.6.0", ">= 1.4.1"])
|
|
87
90
|
s.add_dependency(%q<simplecov>, [">= 0"])
|
|
88
91
|
s.add_dependency(%q<ruby-oci8>, ["~> 2.1.2"])
|
|
@@ -117,7 +117,7 @@ describe "Connection" do
|
|
|
117
117
|
clob = OCI8::CLOB.new(@raw_conn, large_text)
|
|
118
118
|
expect(@conn.ora_value_to_ruby_value(clob)).to eq large_text
|
|
119
119
|
end
|
|
120
|
-
|
|
120
|
+
|
|
121
121
|
end
|
|
122
122
|
|
|
123
123
|
# JRuby
|
|
@@ -132,19 +132,23 @@ describe "Connection" do
|
|
|
132
132
|
it "should translate PL/SQL NUMBER to Ruby BigDecimal" do
|
|
133
133
|
expect(@conn.plsql_to_ruby_data_type(:data_type => "NUMBER", :data_length => 15)).to eq [BigDecimal, nil]
|
|
134
134
|
end
|
|
135
|
-
|
|
135
|
+
|
|
136
136
|
it "should translate PL/SQL DATE to Ruby DateTime" do
|
|
137
137
|
expect(@conn.plsql_to_ruby_data_type(:data_type => "DATE", :data_length => nil)).to eq [DateTime, nil]
|
|
138
138
|
end
|
|
139
|
-
|
|
139
|
+
|
|
140
140
|
it "should translate PL/SQL TIMESTAMP to Ruby Time" do
|
|
141
141
|
expect(@conn.plsql_to_ruby_data_type(:data_type => "TIMESTAMP", :data_length => nil)).to eq [Time, nil]
|
|
142
142
|
end
|
|
143
|
-
|
|
143
|
+
|
|
144
144
|
it "should not translate Ruby Fixnum when BigDecimal type specified" do
|
|
145
145
|
expect(@conn.ruby_value_to_ora_value(100, BigDecimal)).to eq java.math.BigDecimal.new(100)
|
|
146
146
|
end
|
|
147
|
-
|
|
147
|
+
|
|
148
|
+
it "should translate Ruby String to string value" do
|
|
149
|
+
expect(@conn.ruby_value_to_ora_value(1.1, String)).to eq '1.1'
|
|
150
|
+
end
|
|
151
|
+
|
|
148
152
|
it "should translate Ruby Bignum value to BigDecimal when BigDecimal type specified" do
|
|
149
153
|
big_decimal = @conn.ruby_value_to_ora_value(12345678901234567890, BigDecimal)
|
|
150
154
|
expect(big_decimal).to eq java.math.BigDecimal.new("12345678901234567890")
|
|
@@ -167,7 +171,7 @@ describe "Connection" do
|
|
|
167
171
|
it "should translate Oracle BigDecimal integer value to Fixnum" do
|
|
168
172
|
expect(@conn.ora_value_to_ruby_value(BigDecimal("100"))).to eql(100)
|
|
169
173
|
end
|
|
170
|
-
|
|
174
|
+
|
|
171
175
|
it "should translate Oracle BigDecimal float value to BigDecimal" do
|
|
172
176
|
expect(@conn.ora_value_to_ruby_value(BigDecimal("100.11"))).to eql(BigDecimal("100.11"))
|
|
173
177
|
end
|
|
@@ -210,7 +214,7 @@ describe "Connection" do
|
|
|
210
214
|
expect(@conn.select_first("SELECT :1,:2,:3,:4,:5 FROM dual",
|
|
211
215
|
'abc',123,123.456,@now,@today)).to eq ["abc",123,123.456,@now,Time.parse(@today.to_s)]
|
|
212
216
|
end
|
|
213
|
-
|
|
217
|
+
|
|
214
218
|
it "should execute SQL statement with NULL values and return first result" do
|
|
215
219
|
@now = Time.local(2008,05,31,23,22,11)
|
|
216
220
|
expect(@conn.select_first("SELECT NULL,123,123.456,
|
|
@@ -226,7 +230,7 @@ describe "Connection" do
|
|
|
226
230
|
expect(@conn.select_first("SELECT :1,:2,:3,:4,:5 FROM dual",
|
|
227
231
|
nil,123,123.456,@now,@today)).to eq [nil,123,123.456,@now,Time.parse(@today.to_s)]
|
|
228
232
|
end
|
|
229
|
-
|
|
233
|
+
|
|
230
234
|
end
|
|
231
235
|
|
|
232
236
|
it "should execute SQL statement and return all results" do
|
|
@@ -254,7 +258,7 @@ describe "Connection" do
|
|
|
254
258
|
expect(@conn.select_all("SELECT :1,:2,:3,:4 FROM dual UNION ALL SELECT :1,:2,:3,:4 FROM dual",
|
|
255
259
|
'abc',123,123.456,@now,'abc',123,123.456,@now)).to eq [["abc",123,123.456,@now],["abc",123,123.456,@now]]
|
|
256
260
|
end
|
|
257
|
-
|
|
261
|
+
|
|
258
262
|
it "should execute SQL statement and yield all results in block" do
|
|
259
263
|
@now = Time.local(2008,05,31,23,22,11)
|
|
260
264
|
expect(@conn.select_all("SELECT 'abc',123,123.456,
|
|
@@ -266,7 +270,7 @@ describe "Connection" do
|
|
|
266
270
|
expect(r).to eq ["abc",123,123.456,@now]
|
|
267
271
|
end).to eq 2
|
|
268
272
|
end
|
|
269
|
-
|
|
273
|
+
|
|
270
274
|
it "should execute SQL statement with bind parameters and yield all results in block" do
|
|
271
275
|
@now = Time.local(2008,05,31,23,22,11)
|
|
272
276
|
expect(@conn.select_all("SELECT :1,:2,:3,:4 FROM dual UNION ALL SELECT :1,:2,:3,:4 FROM dual",
|
|
@@ -276,7 +280,7 @@ describe "Connection" do
|
|
|
276
280
|
end
|
|
277
281
|
|
|
278
282
|
end
|
|
279
|
-
|
|
283
|
+
|
|
280
284
|
describe "PL/SQL procedures" do
|
|
281
285
|
before(:all) do
|
|
282
286
|
@random = rand(1000)
|
|
@@ -313,9 +317,9 @@ describe "Connection" do
|
|
|
313
317
|
expect(cursor[":p_date"]).to eq @now
|
|
314
318
|
expect(cursor.close).to be_nil
|
|
315
319
|
end
|
|
316
|
-
|
|
320
|
+
|
|
317
321
|
end
|
|
318
|
-
|
|
322
|
+
|
|
319
323
|
describe "commit and rollback" do
|
|
320
324
|
before(:all) do
|
|
321
325
|
expect(@conn.exec("CREATE TABLE test_commit (dummy VARCHAR2(100))")).to be true
|
data/spec/plsql/package_spec.rb
CHANGED
|
@@ -47,6 +47,14 @@ describe "Package" do
|
|
|
47
47
|
expect(plsql.test_package.test_procedure('xxx')).to eq('XXX')
|
|
48
48
|
end
|
|
49
49
|
|
|
50
|
+
it "should report an existing procedure as existing" do
|
|
51
|
+
expect(plsql.test_package.procedure_defined?(:test_procedure)).to be_truthy
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it "should report an inexistent procedure as not existing" do
|
|
55
|
+
expect(plsql.test_package.procedure_defined?(:inexistent_procedure)).to be_falsey
|
|
56
|
+
end
|
|
57
|
+
|
|
50
58
|
describe "variables" do
|
|
51
59
|
it "should set and get package variable value" do
|
|
52
60
|
plsql.test_package.test_variable = 1
|
data/spec/plsql/schema_spec.rb
CHANGED
|
@@ -227,10 +227,13 @@ describe "DBMS_OUTPUT logging" do
|
|
|
227
227
|
before(:all) do
|
|
228
228
|
plsql.connection = get_connection
|
|
229
229
|
plsql.execute <<-SQL
|
|
230
|
-
CREATE OR REPLACE PROCEDURE test_dbms_output(p_string VARCHAR2)
|
|
230
|
+
CREATE OR REPLACE PROCEDURE test_dbms_output(p_string VARCHAR2, p_raise_error BOOLEAN := false)
|
|
231
231
|
IS
|
|
232
232
|
BEGIN
|
|
233
233
|
DBMS_OUTPUT.PUT_LINE(p_string);
|
|
234
|
+
IF p_raise_error THEN
|
|
235
|
+
RAISE_APPLICATION_ERROR(-20000 - 12, 'Test Error');
|
|
236
|
+
END IF;
|
|
234
237
|
END;
|
|
235
238
|
SQL
|
|
236
239
|
plsql.execute <<-SQL
|
|
@@ -272,6 +275,11 @@ describe "DBMS_OUTPUT logging" do
|
|
|
272
275
|
expect(@buffer.string).to eq("DBMS_OUTPUT: test_dbms_output\n")
|
|
273
276
|
end
|
|
274
277
|
|
|
278
|
+
it "should log output to specified stream in case of exception" do
|
|
279
|
+
expect { plsql.test_dbms_output("test_dbms_output", true) }.to raise_error /Test Error/
|
|
280
|
+
expect(@buffer.string).to eq("DBMS_OUTPUT: test_dbms_output\n")
|
|
281
|
+
end
|
|
282
|
+
|
|
275
283
|
it "should not log output to stream when output is disabled" do
|
|
276
284
|
plsql.test_dbms_output("enabled")
|
|
277
285
|
plsql.dbms_output_stream = nil
|
data/spec/spec_helper.rb
CHANGED
|
@@ -23,7 +23,16 @@ end
|
|
|
23
23
|
|
|
24
24
|
require 'ruby-plsql'
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
# Requires supporting ruby files with custom matchers and macros, etc,
|
|
27
|
+
# in spec/support/ and its subdirectories.
|
|
28
|
+
Dir[File.join(File.dirname(__FILE__), 'support/**/*.rb')].each {|f| require f}
|
|
29
|
+
|
|
30
|
+
if ENV['USE_VM_DATABASE'] == 'Y'
|
|
31
|
+
DATABASE_NAME = 'XE'
|
|
32
|
+
else
|
|
33
|
+
DATABASE_NAME = ENV['DATABASE_NAME'] || 'orcl'
|
|
34
|
+
end
|
|
35
|
+
|
|
27
36
|
DATABASE_SERVICE_NAME = (defined?(JRUBY_VERSION) ? "/" : "") +
|
|
28
37
|
(ENV['DATABASE_SERVICE_NAME'] || DATABASE_NAME)
|
|
29
38
|
DATABASE_HOST = ENV['DATABASE_HOST'] || 'localhost'
|
|
@@ -35,6 +44,20 @@ DATABASE_USERS_AND_PASSWORDS = [
|
|
|
35
44
|
# specify which database version is used (will be verified in one test)
|
|
36
45
|
DATABASE_VERSION = ENV['DATABASE_VERSION'] || '10.2.0.4'
|
|
37
46
|
|
|
47
|
+
if ENV['USE_VM_DATABASE'] == 'Y'
|
|
48
|
+
RSpec.configure do |config|
|
|
49
|
+
config.before(:suite) do
|
|
50
|
+
TestDb.build
|
|
51
|
+
|
|
52
|
+
# Set Verbose off to hide warning: already initialized constant DATABASE_VERSION
|
|
53
|
+
original_verbosity = $VERBOSE
|
|
54
|
+
$VERBOSE = nil
|
|
55
|
+
DATABASE_VERSION = TestDb.database_version
|
|
56
|
+
$VERBOSE = original_verbosity
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
38
61
|
def get_eazy_connect_url(svc_separator = "")
|
|
39
62
|
"#{DATABASE_HOST}:#{DATABASE_PORT}#{svc_separator}#{DATABASE_SERVICE_NAME}"
|
|
40
63
|
end
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
set -e
|
|
3
|
+
|
|
4
|
+
FILE=/vagrant/oracle-xe-11.2.0-1.0.x86_64.rpm.zip
|
|
5
|
+
|
|
6
|
+
if [ ! -f "$FILE" ] ; then
|
|
7
|
+
echo "Oracle XE database installation (oracle-xe-11.2.0-1.0.x86_64.rpm.zip) can not be found. Please download from Oracle homepage and put it into project home directory."
|
|
8
|
+
exit 1
|
|
9
|
+
fi
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
class TestDb
|
|
2
|
+
|
|
3
|
+
DATABASE_USERS = %w{hr arunit}
|
|
4
|
+
|
|
5
|
+
def self.build
|
|
6
|
+
db = self.new
|
|
7
|
+
db.cleanup_database_users
|
|
8
|
+
db.create_user_tablespace
|
|
9
|
+
db.setup_database_users
|
|
10
|
+
db.connection.logoff
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.database_version
|
|
14
|
+
db = self.new
|
|
15
|
+
db.database_version
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def connection
|
|
19
|
+
unless defined?(@connection)
|
|
20
|
+
begin
|
|
21
|
+
Timeout::timeout(5) {
|
|
22
|
+
if defined?(JRUBY_VERSION)
|
|
23
|
+
@connection = java.sql.DriverManager.get_connection(
|
|
24
|
+
'jdbc:oracle:thin:@127.0.0.1:1521/XE',
|
|
25
|
+
'system',
|
|
26
|
+
'oracle'
|
|
27
|
+
);
|
|
28
|
+
else
|
|
29
|
+
@connection = OCI8.new(
|
|
30
|
+
'system',
|
|
31
|
+
'oracle',
|
|
32
|
+
'(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=127.0.0.1)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=XE)))'
|
|
33
|
+
)
|
|
34
|
+
end
|
|
35
|
+
}
|
|
36
|
+
rescue Timeout::Error
|
|
37
|
+
raise "Cannot establish connection with Oracle database as SYSTEM user. Seams you need to start local Oracle database"
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
@connection
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def create_user_tablespace
|
|
44
|
+
return unless connection
|
|
45
|
+
execute_statement(<<-STATEMENT
|
|
46
|
+
DECLARE
|
|
47
|
+
v_exists number;
|
|
48
|
+
BEGIN
|
|
49
|
+
SELECT count(1)
|
|
50
|
+
INTO v_exists
|
|
51
|
+
FROM dba_tablespaces
|
|
52
|
+
WHERE tablespace_name = 'TBS_USERS';
|
|
53
|
+
|
|
54
|
+
IF v_exists = 0 THEN
|
|
55
|
+
EXECUTE IMMEDIATE 'ALTER SYSTEM SET DB_CREATE_FILE_DEST = ''/u01/app/oracle/oradata/XE''';
|
|
56
|
+
EXECUTE IMMEDIATE 'CREATE TABLESPACE TBS_USERS DATAFILE ''tbs_users.dat'' SIZE 10M REUSE AUTOEXTEND ON NEXT 10M MAXSIZE 200M';
|
|
57
|
+
END IF;
|
|
58
|
+
END;
|
|
59
|
+
STATEMENT
|
|
60
|
+
)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def database_users
|
|
64
|
+
DATABASE_USERS.inject([]){|array, user| array << [user.upcase, user]}
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def cleanup_database_users
|
|
68
|
+
return unless connection
|
|
69
|
+
database_users.each do | db, _ |
|
|
70
|
+
execute_statement(<<-STATEMENT
|
|
71
|
+
DECLARE
|
|
72
|
+
v_count INTEGER := 0;
|
|
73
|
+
l_cnt INTEGER;
|
|
74
|
+
BEGIN
|
|
75
|
+
|
|
76
|
+
SELECT COUNT (1)
|
|
77
|
+
INTO v_count
|
|
78
|
+
FROM dba_users
|
|
79
|
+
WHERE username = '#{db}';
|
|
80
|
+
|
|
81
|
+
IF v_count != 0 THEN
|
|
82
|
+
FOR x IN (SELECT *
|
|
83
|
+
FROM v$session
|
|
84
|
+
WHERE username = '#{db}')
|
|
85
|
+
LOOP
|
|
86
|
+
EXECUTE IMMEDIATE 'ALTER SYSTEM DISCONNECT SESSION ''' || x.sid || ',' || x.serial# || ''' IMMEDIATE';
|
|
87
|
+
END LOOP;
|
|
88
|
+
|
|
89
|
+
EXECUTE IMMEDIATE ('DROP USER #{db} CASCADE');
|
|
90
|
+
END IF;
|
|
91
|
+
END;
|
|
92
|
+
STATEMENT
|
|
93
|
+
)
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def setup_database_users
|
|
98
|
+
return unless connection
|
|
99
|
+
database_users.each do | db, passwd |
|
|
100
|
+
execute_statement(<<-STATEMENT
|
|
101
|
+
DECLARE
|
|
102
|
+
v_count INTEGER := 0;
|
|
103
|
+
BEGIN
|
|
104
|
+
|
|
105
|
+
SELECT COUNT (1)
|
|
106
|
+
INTO v_count
|
|
107
|
+
FROM dba_users
|
|
108
|
+
WHERE username = '#{db}';
|
|
109
|
+
|
|
110
|
+
IF v_count = 0 THEN
|
|
111
|
+
EXECUTE IMMEDIATE ('CREATE USER #{db} IDENTIFIED BY #{passwd} DEFAULT TABLESPACE TBS_USERS QUOTA 10m ON TBS_USERS');
|
|
112
|
+
EXECUTE IMMEDIATE ('GRANT create session, create table, create sequence, create procedure, create type, create view, create synonym TO #{db}');
|
|
113
|
+
END IF;
|
|
114
|
+
END;
|
|
115
|
+
STATEMENT
|
|
116
|
+
)
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def database_version
|
|
121
|
+
query = 'SELECT version FROM V$INSTANCE'
|
|
122
|
+
|
|
123
|
+
if defined?(JRUBY_VERSION)
|
|
124
|
+
statement = connection.create_statement
|
|
125
|
+
resource = statement.execute_query(query)
|
|
126
|
+
|
|
127
|
+
resource.next
|
|
128
|
+
value = resource.get_string('VERSION')
|
|
129
|
+
|
|
130
|
+
resource.close
|
|
131
|
+
statement.close
|
|
132
|
+
else
|
|
133
|
+
cursor = execute_statement(query)
|
|
134
|
+
value = cursor.fetch()[0]
|
|
135
|
+
cursor.close
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
value.match(/(.*)\.\d$/)[1]
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def execute_statement(statement)
|
|
142
|
+
if defined?(JRUBY_VERSION)
|
|
143
|
+
statement = connection.prepare_call(statement)
|
|
144
|
+
statement.execute
|
|
145
|
+
statement.close
|
|
146
|
+
else
|
|
147
|
+
connection.exec(statement)
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ruby-plsql
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.5.
|
|
4
|
+
version: 0.5.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Raimonds Simanovskis
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2015-05-07 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: jeweler
|
|
@@ -44,7 +44,7 @@ dependencies:
|
|
|
44
44
|
requirements:
|
|
45
45
|
- - "<"
|
|
46
46
|
- !ruby/object:Gem::Version
|
|
47
|
-
version: 4.
|
|
47
|
+
version: 4.3.0
|
|
48
48
|
- - ">="
|
|
49
49
|
- !ruby/object:Gem::Version
|
|
50
50
|
version: 3.2.3
|
|
@@ -54,7 +54,7 @@ dependencies:
|
|
|
54
54
|
requirements:
|
|
55
55
|
- - "<"
|
|
56
56
|
- !ruby/object:Gem::Version
|
|
57
|
-
version: 4.
|
|
57
|
+
version: 4.3.0
|
|
58
58
|
- - ">="
|
|
59
59
|
- !ruby/object:Gem::Version
|
|
60
60
|
version: 3.2.3
|
|
@@ -122,6 +122,7 @@ files:
|
|
|
122
122
|
- README.md
|
|
123
123
|
- Rakefile
|
|
124
124
|
- VERSION
|
|
125
|
+
- Vagrantfile
|
|
125
126
|
- lib/plsql/connection.rb
|
|
126
127
|
- lib/plsql/helpers.rb
|
|
127
128
|
- lib/plsql/jdbc_connection.rb
|
|
@@ -154,6 +155,8 @@ files:
|
|
|
154
155
|
- spec/plsql/view_spec.rb
|
|
155
156
|
- spec/spec.opts
|
|
156
157
|
- spec/spec_helper.rb
|
|
158
|
+
- spec/support/file_check_script.sh
|
|
159
|
+
- spec/support/test_db.rb
|
|
157
160
|
homepage: http://github.com/rsim/ruby-plsql
|
|
158
161
|
licenses: []
|
|
159
162
|
metadata: {}
|
|
@@ -173,7 +176,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
173
176
|
version: '0'
|
|
174
177
|
requirements: []
|
|
175
178
|
rubyforge_project:
|
|
176
|
-
rubygems_version: 2.
|
|
179
|
+
rubygems_version: 2.4.6
|
|
177
180
|
signing_key:
|
|
178
181
|
specification_version: 4
|
|
179
182
|
summary: Ruby API for calling Oracle PL/SQL procedures.
|