ruby-plsql 0.8.0 → 0.9.9
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/History.txt +2 -0
- data/README.md +19 -3
- data/VERSION +1 -1
- data/lib/plsql/connection.rb +14 -14
- data/lib/plsql/helpers.rb +3 -3
- data/lib/plsql/jdbc_connection.rb +62 -22
- data/lib/plsql/oci_connection.rb +10 -10
- data/lib/plsql/package.rb +3 -3
- data/lib/plsql/procedure.rb +57 -22
- data/lib/plsql/procedure_call.rb +15 -15
- data/lib/plsql/schema.rb +17 -10
- data/lib/plsql/sequence.rb +2 -2
- data/lib/plsql/table.rb +6 -6
- data/lib/plsql/type.rb +7 -7
- data/lib/plsql/variable.rb +6 -5
- data/lib/plsql/version.rb +1 -1
- data/lib/plsql/view.rb +2 -2
- metadata +14 -140
- data/.github/stale.yml +0 -37
- data/.github/workflows/rubocop.yml +0 -37
- data/.github/workflows/test.yml +0 -69
- data/.rubocop.yml +0 -147
- data/.travis/oracle/download.sh +0 -15
- data/.travis/oracle/install.sh +0 -32
- data/.travis/setup_accounts.sh +0 -9
- data/.travis.yml +0 -88
- data/Gemfile +0 -24
- data/Rakefile +0 -53
- data/Vagrantfile +0 -38
- data/ci/network/admin/tnsnames.ora +0 -7
- data/ci/setup_accounts.sh +0 -9
- data/gemfiles/Gemfile.activerecord-5.0 +0 -21
- data/gemfiles/Gemfile.activerecord-5.1 +0 -21
- data/gemfiles/Gemfile.activerecord-5.2 +0 -21
- data/gemfiles/Gemfile.activerecord-6.0 +0 -21
- data/gemfiles/Gemfile.activerecord-6.1 +0 -21
- data/gemfiles/Gemfile.activerecord-main +0 -21
- data/lib/plsql/oci8_patches.rb +0 -25
- data/ruby-plsql.gemspec +0 -114
- data/spec/plsql/connection_spec.rb +0 -505
- data/spec/plsql/package_spec.rb +0 -172
- data/spec/plsql/procedure_spec.rb +0 -2390
- data/spec/plsql/schema_spec.rb +0 -364
- data/spec/plsql/sequence_spec.rb +0 -67
- data/spec/plsql/sql_statements_spec.rb +0 -91
- data/spec/plsql/table_spec.rb +0 -376
- data/spec/plsql/type_spec.rb +0 -299
- data/spec/plsql/variable_spec.rb +0 -497
- data/spec/plsql/version_spec.rb +0 -8
- data/spec/plsql/view_spec.rb +0 -264
- data/spec/spec.opts +0 -6
- data/spec/spec_helper.rb +0 -121
- data/spec/support/create_arunit_user.sql +0 -2
- data/spec/support/custom_config.rb.sample +0 -14
- data/spec/support/file_check_script.sh +0 -9
- data/spec/support/test_db.rb +0 -149
- data/spec/support/unlock_and_setup_hr_user.sql +0 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8ce42b7f40a83d55130a51e1acae222dbb1361a7d4a43b712873e2cddae24571
|
|
4
|
+
data.tar.gz: 7cd295463301ff322ed0312cabd73f08337068a8b3b3c57e724a5dae8efb51a0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: '08dabe0856244a3b1e487df17664d996a204f026ce6c19c50dec721bcc42be7936ce41b90ddecfc7d2b798351e624df068602d8da4c1e091e1096f534d8b96c6'
|
|
7
|
+
data.tar.gz: 5b25be049a7575a74911028db9b82986a692af4aa895d1561e1de3600bcfd418429c969bb45832536782ef84c70cf60bb8549207470d0cac962203666f7c035d
|
data/History.txt
CHANGED
data/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
[](https://github.com/rsim/ruby-plsql/actions/workflows/test.yml)
|
|
2
2
|
|
|
3
3
|
ruby-plsql
|
|
4
4
|
==========
|
|
@@ -120,6 +120,22 @@ plsql.activerecord_class = ActiveRecord::Base
|
|
|
120
120
|
and then you do not need to specify plsql.connection (this is also safer when ActiveRecord reestablishes connection to database).
|
|
121
121
|
|
|
122
122
|
|
|
123
|
+
### JRuby JDBC connection:
|
|
124
|
+
|
|
125
|
+
When using JRuby, the `connect!` method with `:host` and `:database` options uses the thin-style service name syntax by default:
|
|
126
|
+
|
|
127
|
+
```ruby
|
|
128
|
+
# Connects using service name syntax: jdbc:oracle:thin:@//localhost:1521/MYSERVICENAME
|
|
129
|
+
plsql.connect! username: "hr", password: "hr", host: "localhost", database: "MYSERVICENAME"
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
If you need to connect using the legacy SID syntax (for Oracle databases older than 12c), prefix the database name with a colon:
|
|
133
|
+
|
|
134
|
+
```ruby
|
|
135
|
+
# Connects using SID syntax: jdbc:oracle:thin:@localhost:1521:MYSID
|
|
136
|
+
plsql.connect! username: "hr", password: "hr", host: "localhost", database: ":MYSID"
|
|
137
|
+
```
|
|
138
|
+
|
|
123
139
|
### Cheat Sheet:
|
|
124
140
|
|
|
125
141
|
You may have a look at this [Cheat Sheet](http://cheatography.com/jgebal/cheat-sheets/ruby-plsql-cheat-sheet/) for instructions on how to use ruby-plsql
|
|
@@ -135,10 +151,10 @@ or include gem in Gemfile if using bundler.
|
|
|
135
151
|
|
|
136
152
|
In addition install either ruby-oci8 (for MRI/YARV) or copy Oracle JDBC driver to $JRUBY_HOME/lib (for JRuby).
|
|
137
153
|
|
|
138
|
-
If you are using MRI Ruby implementation then you need to install ruby-oci8 gem (version 2.
|
|
154
|
+
If you are using MRI Ruby implementation then you need to install ruby-oci8 gem (version 2.1 or higher)
|
|
139
155
|
as well as Oracle client, e.g. [Oracle Instant Client](http://www.oracle.com/technetwork/database/features/instant-client/index-097480.html).
|
|
140
156
|
|
|
141
|
-
If you are using JRuby then you need to download
|
|
157
|
+
If you are using JRuby then you need to download the appropriate [Oracle JDBC driver](https://www.oracle.com/database/technologies/appdev/jdbc-downloads.html) for your Java version - ojdbc17.jar for Java 17+, ojdbc11.jar for Java 11+, ojdbc8.jar for Java 8+, ojdbc7.jar for Java 7, ojdbc6.jar for Java 6, or ojdbc5.jar for Java 5.
|
|
142
158
|
|
|
143
159
|
And copy this file to one of these locations. JDBC driver will be searched in this order:
|
|
144
160
|
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.9.9
|
data/lib/plsql/connection.rb
CHANGED
|
@@ -3,13 +3,13 @@ module PLSQL
|
|
|
3
3
|
attr_reader :raw_driver
|
|
4
4
|
attr_reader :activerecord_class
|
|
5
5
|
|
|
6
|
-
def initialize(raw_conn, ar_class = nil)
|
|
6
|
+
def initialize(raw_conn, ar_class = nil) # :nodoc:
|
|
7
7
|
@raw_driver = self.class.driver_type
|
|
8
8
|
@raw_connection = raw_conn
|
|
9
9
|
@activerecord_class = ar_class
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
def self.create(raw_conn, ar_class = nil)
|
|
12
|
+
def self.create(raw_conn, ar_class = nil) # :nodoc:
|
|
13
13
|
if ar_class && !(defined?(::ActiveRecord) && ar_class.ancestors.include?(::ActiveRecord::Base))
|
|
14
14
|
raise ArgumentError, "Wrong ActiveRecord class"
|
|
15
15
|
end
|
|
@@ -23,7 +23,7 @@ module PLSQL
|
|
|
23
23
|
end
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
def self.create_new(params)
|
|
26
|
+
def self.create_new(params) # :nodoc:
|
|
27
27
|
conn = case driver_type
|
|
28
28
|
when :oci
|
|
29
29
|
OCIConnection.create_raw(params)
|
|
@@ -36,7 +36,7 @@ module PLSQL
|
|
|
36
36
|
conn
|
|
37
37
|
end
|
|
38
38
|
|
|
39
|
-
def self.driver_type
|
|
39
|
+
def self.driver_type # :nodoc:
|
|
40
40
|
# MRI 1.8.6 or YARV 1.9.1 or TruffleRuby
|
|
41
41
|
@driver_type ||= if (!defined?(RUBY_ENGINE) || RUBY_ENGINE == "ruby" || RUBY_ENGINE == "truffleruby") && defined?(OCI8)
|
|
42
42
|
:oci
|
|
@@ -67,18 +67,18 @@ module PLSQL
|
|
|
67
67
|
@raw_driver == :jdbc
|
|
68
68
|
end
|
|
69
69
|
|
|
70
|
-
def logoff
|
|
70
|
+
def logoff # :nodoc:
|
|
71
71
|
# Rollback any uncommited transactions
|
|
72
72
|
rollback
|
|
73
73
|
# Common cleanup activities before logoff, should be called from particular driver method
|
|
74
74
|
drop_session_ruby_temporary_tables
|
|
75
75
|
end
|
|
76
76
|
|
|
77
|
-
def commit
|
|
77
|
+
def commit # :nodoc:
|
|
78
78
|
raise NoMethodError, "Not implemented for this raw driver"
|
|
79
79
|
end
|
|
80
80
|
|
|
81
|
-
def rollback
|
|
81
|
+
def rollback # :nodoc:
|
|
82
82
|
raise NoMethodError, "Not implemented for this raw driver"
|
|
83
83
|
end
|
|
84
84
|
|
|
@@ -98,21 +98,21 @@ module PLSQL
|
|
|
98
98
|
raise NoMethodError, "Not implemented for this raw driver"
|
|
99
99
|
end
|
|
100
100
|
|
|
101
|
-
def select_first(sql, *bindvars)
|
|
101
|
+
def select_first(sql, *bindvars) # :nodoc:
|
|
102
102
|
cursor = cursor_from_query(sql, bindvars, prefetch_rows: 1)
|
|
103
103
|
cursor.fetch
|
|
104
104
|
ensure
|
|
105
105
|
cursor.close rescue nil
|
|
106
106
|
end
|
|
107
107
|
|
|
108
|
-
def select_hash_first(sql, *bindvars)
|
|
108
|
+
def select_hash_first(sql, *bindvars) # :nodoc:
|
|
109
109
|
cursor = cursor_from_query(sql, bindvars, prefetch_rows: 1)
|
|
110
110
|
cursor.fetch_hash
|
|
111
111
|
ensure
|
|
112
112
|
cursor.close rescue nil
|
|
113
113
|
end
|
|
114
114
|
|
|
115
|
-
def select_all(sql, *bindvars, &block)
|
|
115
|
+
def select_all(sql, *bindvars, &block) # :nodoc:
|
|
116
116
|
cursor = cursor_from_query(sql, bindvars)
|
|
117
117
|
results = []
|
|
118
118
|
row_count = 0
|
|
@@ -129,7 +129,7 @@ module PLSQL
|
|
|
129
129
|
cursor.close rescue nil
|
|
130
130
|
end
|
|
131
131
|
|
|
132
|
-
def select_hash_all(sql, *bindvars, &block)
|
|
132
|
+
def select_hash_all(sql, *bindvars, &block) # :nodoc:
|
|
133
133
|
cursor = cursor_from_query(sql, bindvars)
|
|
134
134
|
results = []
|
|
135
135
|
row_count = 0
|
|
@@ -146,11 +146,11 @@ module PLSQL
|
|
|
146
146
|
cursor.close rescue nil
|
|
147
147
|
end
|
|
148
148
|
|
|
149
|
-
def exec(sql, *bindvars)
|
|
149
|
+
def exec(sql, *bindvars) # :nodoc:
|
|
150
150
|
raise NoMethodError, "Not implemented for this raw driver"
|
|
151
151
|
end
|
|
152
152
|
|
|
153
|
-
def parse(sql)
|
|
153
|
+
def parse(sql) # :nodoc:
|
|
154
154
|
raise NoMethodError, "Not implemented for this raw driver"
|
|
155
155
|
end
|
|
156
156
|
|
|
@@ -181,7 +181,7 @@ module PLSQL
|
|
|
181
181
|
|
|
182
182
|
# all_synonyms view is quite slow therefore
|
|
183
183
|
# this implementation is overriden in OCI connection with faster native OCI method
|
|
184
|
-
def describe_synonym(schema_name, synonym_name)
|
|
184
|
+
def describe_synonym(schema_name, synonym_name) # :nodoc:
|
|
185
185
|
select_first(
|
|
186
186
|
"SELECT table_owner, table_name FROM all_synonyms WHERE owner = :owner AND synonym_name = :synonym_name",
|
|
187
187
|
schema_name.to_s.upcase, synonym_name.to_s.upcase)
|
data/lib/plsql/helpers.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
module PLSQL
|
|
2
|
-
module ArrayHelpers
|
|
3
|
-
def self.to_hash(keys, values)
|
|
1
|
+
module PLSQL # :nodoc:
|
|
2
|
+
module ArrayHelpers # :nodoc:
|
|
3
|
+
def self.to_hash(keys, values) # :nodoc:
|
|
4
4
|
(0...keys.size).inject({}) { |hash, i| hash[keys[i]] = values[i]; hash }
|
|
5
5
|
end
|
|
6
6
|
end
|
|
@@ -1,23 +1,26 @@
|
|
|
1
|
+
ojdbc_jars = []
|
|
2
|
+
|
|
1
3
|
begin
|
|
2
4
|
require "java"
|
|
3
5
|
require "jruby"
|
|
4
6
|
|
|
5
|
-
#
|
|
7
|
+
# Oracle JDBC driver jar should be in JRUBY_HOME/lib or should be in ENV['PATH'] or load path
|
|
6
8
|
|
|
7
9
|
java_version = java.lang.System.getProperty("java.version")
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
elsif java_version =~ /^1.6/
|
|
11
|
-
%w(ojdbc6.jar)
|
|
12
|
-
elsif java_version >= "1.7"
|
|
13
|
-
# Oracle 11g client ojdbc6.jar is also compatible with Java 1.7
|
|
14
|
-
# Oracle 12c client provides new ojdbc7.jar
|
|
15
|
-
%w(ojdbc7.jar ojdbc6.jar)
|
|
10
|
+
java_major = if java_version =~ /^1\.(\d+)/
|
|
11
|
+
$1.to_i
|
|
16
12
|
else
|
|
17
|
-
|
|
13
|
+
java_version.to_i
|
|
18
14
|
end
|
|
19
15
|
|
|
20
|
-
|
|
16
|
+
ojdbc_jars << "ojdbc17.jar" if java_major >= 17
|
|
17
|
+
ojdbc_jars << "ojdbc11.jar" if java_major >= 11
|
|
18
|
+
ojdbc_jars << "ojdbc8.jar" if java_major >= 8
|
|
19
|
+
ojdbc_jars << "ojdbc7.jar" if java_major >= 7
|
|
20
|
+
ojdbc_jars << "ojdbc6.jar" if java_major >= 6
|
|
21
|
+
ojdbc_jars << "ojdbc5.jar" if java_major == 5
|
|
22
|
+
|
|
23
|
+
if ENV_JAVA["java.class.path"] !~ Regexp.union(ojdbc_jars)
|
|
21
24
|
# On Unix environment variable should be PATH, on Windows it is sometimes Path
|
|
22
25
|
env_path = (ENV["PATH"] || ENV["Path"] || "").split(File::PATH_SEPARATOR)
|
|
23
26
|
# Look for JDBC driver at first in lib subdirectory (application specific JDBC file version)
|
|
@@ -25,7 +28,7 @@ begin
|
|
|
25
28
|
["./lib"].concat($LOAD_PATH).concat(env_path).detect do |dir|
|
|
26
29
|
# check any compatible JDBC driver in the priority order
|
|
27
30
|
ojdbc_jars.any? do |ojdbc_jar|
|
|
28
|
-
if File.
|
|
31
|
+
if File.exist?(file_path = File.join(dir, ojdbc_jar))
|
|
29
32
|
require file_path
|
|
30
33
|
true
|
|
31
34
|
end
|
|
@@ -33,29 +36,66 @@ begin
|
|
|
33
36
|
end
|
|
34
37
|
end
|
|
35
38
|
|
|
36
|
-
java.sql.DriverManager.registerDriver Java::oracle.jdbc.OracleDriver.new
|
|
37
|
-
|
|
38
39
|
# set tns_admin property from TNS_ADMIN environment variable
|
|
39
40
|
if !java.lang.System.get_property("oracle.net.tns_admin") && ENV["TNS_ADMIN"]
|
|
40
41
|
java.lang.System.set_property("oracle.net.tns_admin", ENV["TNS_ADMIN"])
|
|
41
42
|
end
|
|
42
43
|
|
|
43
|
-
rescue LoadError
|
|
44
|
+
rescue LoadError
|
|
44
45
|
# JDBC driver is unavailable.
|
|
45
46
|
raise LoadError, "ERROR: ruby-plsql could not load Oracle JDBC driver. Please install #{ojdbc_jars.empty? ? "Oracle JDBC" : ojdbc_jars.join(' or ') } library."
|
|
46
47
|
end
|
|
47
48
|
|
|
48
49
|
module PLSQL
|
|
49
|
-
class JDBCConnection < Connection
|
|
50
|
+
class JDBCConnection < Connection # :nodoc:
|
|
51
|
+
begin
|
|
52
|
+
ORACLE_DRIVER = Java::oracle.jdbc.OracleDriver.new
|
|
53
|
+
java.sql.DriverManager.registerDriver ORACLE_DRIVER
|
|
54
|
+
rescue NameError
|
|
55
|
+
raise LoadError, "ERROR: ruby-plsql could not load Oracle JDBC driver. " \
|
|
56
|
+
"Please install the appropriate Oracle JDBC driver. " \
|
|
57
|
+
"See https://www.oracle.com/database/technologies/appdev/jdbc-downloads.html"
|
|
58
|
+
end
|
|
59
|
+
|
|
50
60
|
def self.create_raw(params)
|
|
61
|
+
url = jdbc_connection_url(params)
|
|
62
|
+
conn = begin
|
|
63
|
+
java.sql.DriverManager.getConnection(url, params[:username], params[:password])
|
|
64
|
+
rescue Java::JavaSql::SQLException => e
|
|
65
|
+
raise unless e.message =~ /no suitable driver/i
|
|
66
|
+
# bypass DriverManager to work in cases where ojdbc*.jar
|
|
67
|
+
# is added to the load path at runtime and not on the
|
|
68
|
+
# system classpath
|
|
69
|
+
ORACLE_DRIVER.connect(url, java.util.Properties.new.tap do |props|
|
|
70
|
+
props.setProperty("user", params[:username])
|
|
71
|
+
props.setProperty("password", params[:password])
|
|
72
|
+
end)
|
|
73
|
+
end
|
|
74
|
+
conn.setAutoCommit(false)
|
|
75
|
+
new(conn)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def self.jdbc_connection_url(params)
|
|
51
79
|
database = params[:database]
|
|
52
|
-
|
|
80
|
+
if ENV["TNS_ADMIN"] && database && database !~ %r{\A[:/]} && !params[:host] && !params[:url]
|
|
53
81
|
"jdbc:oracle:thin:@#{database}"
|
|
54
82
|
else
|
|
55
|
-
|
|
56
|
-
|
|
83
|
+
return params[:url] if params[:url]
|
|
84
|
+
|
|
85
|
+
raise ArgumentError, "database or url option is required" if database.nil? || database.empty?
|
|
86
|
+
|
|
87
|
+
host = params[:host] || "localhost"
|
|
88
|
+
port = params[:port] || 1521
|
|
89
|
+
|
|
90
|
+
if database =~ /^:/
|
|
91
|
+
# SID syntax: jdbc:oracle:thin:@host:port:SID
|
|
92
|
+
"jdbc:oracle:thin:@#{host}:#{port}#{database}"
|
|
93
|
+
else
|
|
94
|
+
# service name syntax: jdbc:oracle:thin:@//host:port/service_name
|
|
95
|
+
database = "/#{database}" unless database =~ /^\//
|
|
96
|
+
"jdbc:oracle:thin:@//#{host}:#{port}#{database}"
|
|
97
|
+
end
|
|
57
98
|
end
|
|
58
|
-
new(java.sql.DriverManager.getConnection(url, params[:username], params[:password]))
|
|
59
99
|
end
|
|
60
100
|
|
|
61
101
|
def set_time_zone(time_zone = nil)
|
|
@@ -98,7 +138,7 @@ module PLSQL
|
|
|
98
138
|
cs.close rescue nil
|
|
99
139
|
end
|
|
100
140
|
|
|
101
|
-
class CallableStatement
|
|
141
|
+
class CallableStatement # :nodoc:
|
|
102
142
|
def initialize(conn, sql)
|
|
103
143
|
@sql = sql
|
|
104
144
|
@connection = conn
|
|
@@ -145,7 +185,7 @@ module PLSQL
|
|
|
145
185
|
end
|
|
146
186
|
end
|
|
147
187
|
|
|
148
|
-
class Cursor
|
|
188
|
+
class Cursor # :nodoc:
|
|
149
189
|
include Connection::CursorCommon
|
|
150
190
|
|
|
151
191
|
attr_reader :result_set
|
data/lib/plsql/oci_connection.rb
CHANGED
|
@@ -14,17 +14,13 @@ rescue LoadError
|
|
|
14
14
|
raise LoadError, "ERROR: ruby-plsql could not load ruby-oci8 library. #{msg}"
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
-
require "plsql/oci8_patches"
|
|
18
|
-
|
|
19
17
|
# check ruby-oci8 version
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
if (oci8_version_ints <=> required_oci8_version) < 0
|
|
23
|
-
raise LoadError, "ERROR: ruby-oci8 version #{OCI8::VERSION} is too old. Please install ruby-oci8 version #{required_oci8_version.join('.')} or later."
|
|
18
|
+
if Gem::Version.new(OCI8::VERSION) < Gem::Version.new("2.1.0")
|
|
19
|
+
raise LoadError, "ERROR: ruby-oci8 version #{OCI8::VERSION} is too old. Please install ruby-oci8 version 2.1.0 or later."
|
|
24
20
|
end
|
|
25
21
|
|
|
26
22
|
module PLSQL
|
|
27
|
-
class OCIConnection < Connection
|
|
23
|
+
class OCIConnection < Connection # :nodoc:
|
|
28
24
|
def self.create_raw(params)
|
|
29
25
|
connection_string = if params[:host]
|
|
30
26
|
"//#{params[:host]}:#{params[:port] || 1521}/#{params[:database]}"
|
|
@@ -64,7 +60,7 @@ module PLSQL
|
|
|
64
60
|
true
|
|
65
61
|
end
|
|
66
62
|
|
|
67
|
-
class Cursor
|
|
63
|
+
class Cursor # :nodoc:
|
|
68
64
|
include Connection::CursorCommon
|
|
69
65
|
|
|
70
66
|
attr_reader :raw_cursor
|
|
@@ -157,7 +153,7 @@ module PLSQL
|
|
|
157
153
|
[DateTime, nil]
|
|
158
154
|
when "TIMESTAMP", "TIMESTAMP WITH TIME ZONE", "TIMESTAMP WITH LOCAL TIME ZONE"
|
|
159
155
|
[Time, nil]
|
|
160
|
-
when "TABLE", "VARRAY", "OBJECT", "XMLTYPE"
|
|
156
|
+
when "TABLE", "VARRAY", "OBJECT", "XMLTYPE", "OPAQUE/XMLTYPE"
|
|
161
157
|
# create Ruby class for collection
|
|
162
158
|
klass = OCI8::Object::Base.get_class_by_typename(metadata[:sql_type_name])
|
|
163
159
|
unless klass
|
|
@@ -289,7 +285,11 @@ module PLSQL
|
|
|
289
285
|
# ActiveRecord Oracle enhanced adapter puts OCI8EnhancedAutoRecover wrapper around OCI8
|
|
290
286
|
# in this case we need to pass original OCI8 connection
|
|
291
287
|
else
|
|
292
|
-
raw_connection.
|
|
288
|
+
if raw_connection.instance_variable_defined?(:@raw_connection)
|
|
289
|
+
raw_connection.instance_variable_get(:@raw_connection)
|
|
290
|
+
else
|
|
291
|
+
raw_connection.instance_variable_get(:@connection)
|
|
292
|
+
end
|
|
293
293
|
end
|
|
294
294
|
end
|
|
295
295
|
|
data/lib/plsql/package.rb
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
module PLSQL
|
|
2
|
-
module PackageClassMethods
|
|
2
|
+
module PackageClassMethods # :nodoc:
|
|
3
3
|
def find(schema, package)
|
|
4
4
|
package_name = package.to_s.upcase
|
|
5
5
|
find_in_schema(schema, package_name) || find_by_synonym(schema, package_name)
|
|
@@ -32,7 +32,7 @@ module PLSQL
|
|
|
32
32
|
end
|
|
33
33
|
end
|
|
34
34
|
|
|
35
|
-
class Package
|
|
35
|
+
class Package # :nodoc:
|
|
36
36
|
extend PackageClassMethods
|
|
37
37
|
|
|
38
38
|
def initialize(schema, package, override_schema_name = nil)
|
|
@@ -56,7 +56,7 @@ module PLSQL
|
|
|
56
56
|
private
|
|
57
57
|
|
|
58
58
|
def method_missing(method, *args, &block)
|
|
59
|
-
method = method.to_s
|
|
59
|
+
method = +method.to_s
|
|
60
60
|
method.chop! if (assignment = method[/=$/])
|
|
61
61
|
|
|
62
62
|
case (object = self[method])
|
data/lib/plsql/procedure.rb
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
module PLSQL
|
|
2
|
-
module ProcedureClassMethods
|
|
2
|
+
module ProcedureClassMethods # :nodoc:
|
|
3
3
|
def find(schema, procedure, package = nil, override_schema_name = nil)
|
|
4
4
|
if package.nil?
|
|
5
5
|
if (row = schema.select_first(
|
|
@@ -53,12 +53,12 @@ module PLSQL
|
|
|
53
53
|
end
|
|
54
54
|
end
|
|
55
55
|
|
|
56
|
-
module ProcedureCommon
|
|
56
|
+
module ProcedureCommon # :nodoc:
|
|
57
57
|
attr_reader :arguments, :argument_list, :out_list, :return
|
|
58
58
|
attr_reader :schema, :schema_name, :package, :procedure
|
|
59
59
|
|
|
60
60
|
# return type string from metadata that can be used in DECLARE block or table definition
|
|
61
|
-
def self.type_to_sql(metadata)
|
|
61
|
+
def self.type_to_sql(metadata) # :nodoc:
|
|
62
62
|
case metadata[:data_type]
|
|
63
63
|
when "NUMBER"
|
|
64
64
|
precision, scale = metadata[:data_precision], metadata[:data_scale]
|
|
@@ -82,7 +82,7 @@ module PLSQL
|
|
|
82
82
|
end
|
|
83
83
|
|
|
84
84
|
# get procedure argument metadata from data dictionary
|
|
85
|
-
def get_argument_metadata
|
|
85
|
+
def get_argument_metadata # :nodoc:
|
|
86
86
|
if (@schema.connection.database_version <=> [18, 0, 0, 0]) >= 0
|
|
87
87
|
get_argument_metadata_from_18c
|
|
88
88
|
else
|
|
@@ -90,7 +90,7 @@ module PLSQL
|
|
|
90
90
|
end
|
|
91
91
|
end
|
|
92
92
|
|
|
93
|
-
def get_argument_metadata_below_18c
|
|
93
|
+
def get_argument_metadata_below_18c # :nodoc:
|
|
94
94
|
@arguments = {}
|
|
95
95
|
@argument_list = {}
|
|
96
96
|
@out_list = {}
|
|
@@ -126,6 +126,9 @@ module PLSQL
|
|
|
126
126
|
data_type, in_out, data_length, data_precision, data_scale, char_used,
|
|
127
127
|
char_length, type_owner, type_name, type_subname, defaulted = r
|
|
128
128
|
|
|
129
|
+
# Oracle 23c reports BOOLEAN as "BOOLEAN" instead of "PL/SQL BOOLEAN"
|
|
130
|
+
data_type = "PL/SQL BOOLEAN" if data_type == "BOOLEAN"
|
|
131
|
+
|
|
129
132
|
@overloaded ||= !overload.nil?
|
|
130
133
|
# if not overloaded then store arguments at key 0
|
|
131
134
|
overload ||= 0
|
|
@@ -206,7 +209,7 @@ module PLSQL
|
|
|
206
209
|
end
|
|
207
210
|
|
|
208
211
|
# get procedure argument metadata from data dictionary
|
|
209
|
-
def get_argument_metadata_from_18c
|
|
212
|
+
def get_argument_metadata_from_18c # :nodoc:
|
|
210
213
|
@arguments = {}
|
|
211
214
|
@argument_list = {}
|
|
212
215
|
@out_list = {}
|
|
@@ -231,10 +234,13 @@ module PLSQL
|
|
|
231
234
|
@object_id, @schema_name, @procedure
|
|
232
235
|
) do |r|
|
|
233
236
|
|
|
234
|
-
subprogram_id,
|
|
237
|
+
subprogram_id, _object_name, overload, argument_name, position,
|
|
235
238
|
data_type, in_out, data_length, data_precision, data_scale, char_used,
|
|
236
239
|
char_length, type_owner, type_name, type_package, type_object_type, defaulted = r
|
|
237
240
|
|
|
241
|
+
# Oracle 23c reports BOOLEAN as "BOOLEAN" instead of "PL/SQL BOOLEAN"
|
|
242
|
+
data_type = "PL/SQL BOOLEAN" if data_type == "BOOLEAN"
|
|
243
|
+
|
|
238
244
|
@overloaded ||= !overload.nil?
|
|
239
245
|
# if not overloaded then store arguments at key 0
|
|
240
246
|
overload ||= 0
|
|
@@ -298,7 +304,7 @@ module PLSQL
|
|
|
298
304
|
construct_argument_list_for_overloads
|
|
299
305
|
end
|
|
300
306
|
|
|
301
|
-
def construct_argument_list_for_overloads
|
|
307
|
+
def construct_argument_list_for_overloads # :nodoc:
|
|
302
308
|
@overloads = @arguments.keys.sort
|
|
303
309
|
@overloads.each do |overload|
|
|
304
310
|
@argument_list[overload] = @arguments[overload].keys.sort { |k1, k2| @arguments[overload][k1][:position] <=> @arguments[overload][k2][:position] }
|
|
@@ -306,10 +312,10 @@ module PLSQL
|
|
|
306
312
|
end
|
|
307
313
|
end
|
|
308
314
|
|
|
309
|
-
def ensure_tmp_tables_created(overload)
|
|
315
|
+
def ensure_tmp_tables_created(overload) # :nodoc:
|
|
310
316
|
return if @tmp_tables_created.nil? || @tmp_tables_created[overload]
|
|
311
317
|
@tmp_table_names[overload] && @tmp_table_names[overload].each do |table_name, argument_metadata|
|
|
312
|
-
sql = "CREATE GLOBAL TEMPORARY TABLE #{table_name} (\n"
|
|
318
|
+
sql = +"CREATE GLOBAL TEMPORARY TABLE #{table_name} (\n"
|
|
313
319
|
element_metadata = argument_metadata[:element]
|
|
314
320
|
case element_metadata[:data_type]
|
|
315
321
|
when "PL/SQL RECORD"
|
|
@@ -330,7 +336,7 @@ module PLSQL
|
|
|
330
336
|
@tmp_tables_created[overload] = true
|
|
331
337
|
end
|
|
332
338
|
|
|
333
|
-
def build_sql_type_name(type_owner, type_package, type_name)
|
|
339
|
+
def build_sql_type_name(type_owner, type_package, type_name) # :nodoc:
|
|
334
340
|
if type_owner == nil || type_owner == "PUBLIC"
|
|
335
341
|
type_owner_res = ""
|
|
336
342
|
else
|
|
@@ -345,7 +351,7 @@ module PLSQL
|
|
|
345
351
|
type_name_res && "#{type_owner_res}#{type_name_res}"
|
|
346
352
|
end
|
|
347
353
|
|
|
348
|
-
def get_field_definitions(argument_metadata)
|
|
354
|
+
def get_field_definitions(argument_metadata) # :nodoc:
|
|
349
355
|
fields = {}
|
|
350
356
|
case argument_metadata[:type_object_type]
|
|
351
357
|
when "PACKAGE"
|
|
@@ -355,10 +361,13 @@ module PLSQL
|
|
|
355
361
|
WHERE t.OWNER = :owner AND t.type_name = :type_name AND t.package_name = :package_name
|
|
356
362
|
AND ta.OWNER = t.owner AND ta.TYPE_NAME = t.TYPE_NAME AND ta.PACKAGE_NAME = t.PACKAGE_NAME
|
|
357
363
|
ORDER BY attr_no",
|
|
358
|
-
|
|
364
|
+
argument_metadata[:type_owner], argument_metadata[:type_name], argument_metadata[:type_subname]) do |r|
|
|
359
365
|
|
|
360
366
|
attr_no, attr_name, attr_type_owner, attr_type_name, attr_type_package, attr_length, attr_precision, attr_scale, attr_char_used = r
|
|
361
367
|
|
|
368
|
+
# Oracle 23c reports BOOLEAN as "BOOLEAN" instead of "PL/SQL BOOLEAN"
|
|
369
|
+
attr_type_name = "PL/SQL BOOLEAN" if attr_type_name == "BOOLEAN"
|
|
370
|
+
|
|
362
371
|
fields[attr_name.downcase.to_sym] = {
|
|
363
372
|
position: attr_no.to_i,
|
|
364
373
|
data_type: attr_type_owner == nil ? attr_type_name : get_composite_type(attr_type_owner, attr_type_name, attr_type_package),
|
|
@@ -382,12 +391,15 @@ module PLSQL
|
|
|
382
391
|
when "TABLE", "VIEW"
|
|
383
392
|
@schema.select_all(
|
|
384
393
|
"SELECT column_id, column_name, data_type, data_length, data_precision, data_scale, char_length, char_used
|
|
385
|
-
FROM
|
|
394
|
+
FROM ALL_TAB_COLUMNS WHERE OWNER = :owner AND TABLE_NAME = :type_name
|
|
386
395
|
ORDER BY column_id",
|
|
387
|
-
|
|
396
|
+
argument_metadata[:type_owner], argument_metadata[:type_name]) do |r|
|
|
388
397
|
|
|
389
398
|
col_no, col_name, col_type_name, col_length, col_precision, col_scale, col_char_length, col_char_used = r
|
|
390
399
|
|
|
400
|
+
# remove precision (n) from data_type (returned for TIMESTAMPs and INTERVALs)
|
|
401
|
+
col_type_name = col_type_name.sub(/\(\d+\)/, "")
|
|
402
|
+
|
|
391
403
|
fields[col_name.downcase.to_sym] = {
|
|
392
404
|
position: col_no.to_i,
|
|
393
405
|
data_type: col_type_name,
|
|
@@ -408,7 +420,7 @@ module PLSQL
|
|
|
408
420
|
fields
|
|
409
421
|
end
|
|
410
422
|
|
|
411
|
-
def get_element_definition(argument_metadata)
|
|
423
|
+
def get_element_definition(argument_metadata) # :nodoc:
|
|
412
424
|
element_metadata = {}
|
|
413
425
|
if collection_type?(argument_metadata[:data_type])
|
|
414
426
|
case argument_metadata[:type_object_type]
|
|
@@ -417,10 +429,13 @@ module PLSQL
|
|
|
417
429
|
"SELECT elem_type_owner, elem_type_name, elem_type_package, length, precision, scale, char_used, index_by
|
|
418
430
|
FROM ALL_PLSQL_COLL_TYPES t
|
|
419
431
|
WHERE t.OWNER = :owner AND t.TYPE_NAME = :type_name AND t.PACKAGE_NAME = :package_name",
|
|
420
|
-
|
|
432
|
+
argument_metadata[:type_owner], argument_metadata[:type_name], argument_metadata[:type_subname])
|
|
421
433
|
|
|
422
434
|
elem_type_owner, elem_type_name, elem_type_package, elem_length, elem_precision, elem_scale, elem_char_used, index_by = r
|
|
423
435
|
|
|
436
|
+
# Oracle 23c reports BOOLEAN as "BOOLEAN" instead of "PL/SQL BOOLEAN"
|
|
437
|
+
elem_type_name = "PL/SQL BOOLEAN" if elem_type_name == "BOOLEAN"
|
|
438
|
+
|
|
424
439
|
if index_by == "VARCHAR2"
|
|
425
440
|
raise ArgumentError, "Index-by Varchar-Table (associative array) #{argument_metadata[:type_name]} is not supported"
|
|
426
441
|
end
|
|
@@ -448,16 +463,36 @@ module PLSQL
|
|
|
448
463
|
|
|
449
464
|
if elem_type_package != nil
|
|
450
465
|
element_metadata[:fields] = get_field_definitions(element_metadata)
|
|
466
|
+
elsif elem_type_name && elem_type_name =~ /\A(.+)%ROWTYPE\z/
|
|
467
|
+
# TABLE OF table%ROWTYPE: Oracle stores elem_type_name as "TABLE_NAME%ROWTYPE"
|
|
468
|
+
rowtype_table_name = $1
|
|
469
|
+
check_owner = elem_type_owner || @schema_name
|
|
470
|
+
object_type_row = @schema.select_first(
|
|
471
|
+
"SELECT object_type FROM ALL_OBJECTS WHERE owner = :owner AND object_name = :name AND object_type IN ('TABLE', 'VIEW')",
|
|
472
|
+
check_owner, rowtype_table_name)
|
|
473
|
+
if object_type_row
|
|
474
|
+
element_metadata[:type_owner] ||= check_owner
|
|
475
|
+
element_metadata[:type_name] = rowtype_table_name
|
|
476
|
+
element_metadata[:sql_type_name] = build_sql_type_name(check_owner, nil, rowtype_table_name)
|
|
477
|
+
element_metadata[:data_type] = "PL/SQL RECORD"
|
|
478
|
+
element_metadata[:type_object_type] = object_type_row[0]
|
|
479
|
+
element_metadata[:fields] = get_field_definitions(element_metadata)
|
|
480
|
+
else
|
|
481
|
+
raise ArgumentError, "Could not resolve #{check_owner}.#{rowtype_table_name} to a table or view for #{elem_type_name}"
|
|
482
|
+
end
|
|
451
483
|
end
|
|
452
484
|
when "TYPE"
|
|
453
485
|
r = @schema.select_first(
|
|
454
486
|
"SELECT elem_type_owner, elem_type_name, length, precision, scale, char_used
|
|
455
487
|
FROM ALL_COLL_TYPES t
|
|
456
488
|
WHERE t.owner = :owner AND t.TYPE_NAME = :type_name",
|
|
457
|
-
|
|
489
|
+
argument_metadata[:type_owner], argument_metadata[:type_name]
|
|
458
490
|
)
|
|
459
491
|
elem_type_owner, elem_type_name, elem_length, elem_precision, elem_scale, elem_char_used = r
|
|
460
492
|
|
|
493
|
+
# Oracle 23c reports BOOLEAN as "BOOLEAN" instead of "PL/SQL BOOLEAN"
|
|
494
|
+
elem_type_name = "PL/SQL BOOLEAN" if elem_type_name == "BOOLEAN"
|
|
495
|
+
|
|
461
496
|
element_metadata = {
|
|
462
497
|
position: 1,
|
|
463
498
|
data_type: elem_type_owner == nil ? elem_type_name : "OBJECT",
|
|
@@ -510,21 +545,21 @@ module PLSQL
|
|
|
510
545
|
end
|
|
511
546
|
|
|
512
547
|
PLSQL_COMPOSITE_TYPES = ["PL/SQL RECORD", "PL/SQL TABLE", "TABLE", "VARRAY", "REF CURSOR"].freeze
|
|
513
|
-
def composite_type?(data_type)
|
|
548
|
+
def composite_type?(data_type) # :nodoc:
|
|
514
549
|
PLSQL_COMPOSITE_TYPES.include? data_type
|
|
515
550
|
end
|
|
516
551
|
|
|
517
552
|
PLSQL_COLLECTION_TYPES = ["PL/SQL TABLE", "TABLE", "VARRAY"].freeze
|
|
518
|
-
def collection_type?(data_type)
|
|
553
|
+
def collection_type?(data_type) # :nodoc:
|
|
519
554
|
PLSQL_COLLECTION_TYPES.include? data_type
|
|
520
555
|
end
|
|
521
556
|
|
|
522
|
-
def overloaded?
|
|
557
|
+
def overloaded? # :nodoc:
|
|
523
558
|
@overloaded
|
|
524
559
|
end
|
|
525
560
|
end
|
|
526
561
|
|
|
527
|
-
class Procedure
|
|
562
|
+
class Procedure # :nodoc:
|
|
528
563
|
extend ProcedureClassMethods
|
|
529
564
|
include ProcedureCommon
|
|
530
565
|
|