ruby-plsql 0.7.1 → 0.9.0
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 +26 -0
- data/README.md +1 -1
- data/VERSION +1 -1
- data/lib/plsql/connection.rb +16 -16
- data/lib/plsql/helpers.rb +3 -3
- data/lib/plsql/jdbc_connection.rb +3 -5
- data/lib/plsql/oci_connection.rb +8 -4
- data/lib/plsql/package.rb +3 -3
- data/lib/plsql/procedure.rb +306 -11
- data/lib/plsql/procedure_call.rb +20 -15
- data/lib/plsql/schema.rb +13 -9
- data/lib/plsql/sequence.rb +2 -2
- data/lib/plsql/table.rb +7 -6
- data/lib/plsql/type.rb +7 -7
- data/lib/plsql/variable.rb +4 -4
- data/lib/plsql/version.rb +1 -1
- data/lib/plsql/view.rb +2 -2
- metadata +13 -91
- data/.codeclimate.yml +0 -30
- data/.github/stale.yml +0 -37
- data/.rubocop.yml +0 -153
- 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 -49
- data/Gemfile +0 -21
- data/Rakefile +0 -53
- data/Vagrantfile +0 -38
- 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/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 -2360
- data/spec/plsql/schema_spec.rb +0 -356
- data/spec/plsql/sequence_spec.rb +0 -67
- data/spec/plsql/sql_statements_spec.rb +0 -91
- data/spec/plsql/table_spec.rb +0 -371
- 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: e240a454b5016fb465baaff47830601ea5f06f9a0f4ed7f2e032e2e8027c8841
|
|
4
|
+
data.tar.gz: 8209b0f8b037838e7be37578a396b8652855540abd6a0c2cbf226adfaf7a598e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: af3ba3c7a782369e6e4f94afe467194f155fc961dc80e946ebbbaec07f48244169d33f1c0c387d6710752b7590f70c9cc5fb84bc21f8687b8c520d32ed09f557
|
|
7
|
+
data.tar.gz: 2fe1c1fa55a48cc547a3f34f371aba37147c4d3c8efc2c34d104b42b8e250251f6d233d65c6fedba42855774ccf559d6aed4164f341823b5c6fbbbb605acb047
|
data/History.txt
CHANGED
|
@@ -1,3 +1,29 @@
|
|
|
1
|
+
This file is no longer being updated. For the latest updates and release information, please see: https://github.com/rsim/ruby-plsql/releases
|
|
2
|
+
|
|
3
|
+
== 0.8.0 2021-08-10
|
|
4
|
+
* Improvements and fixes
|
|
5
|
+
* Support Rails 6.1 [#193]
|
|
6
|
+
* Support Rails 6.0 [#178]
|
|
7
|
+
* Support Oracle Database 18c or higher [#196]
|
|
8
|
+
* case-insensitive table names and proc params [#185]
|
|
9
|
+
* Use OCI driver type for RUBY_ENGINE TruffleRuby [#190]
|
|
10
|
+
* Replace NativeException with Java::JavaSql::SQLException [#192]
|
|
11
|
+
* Fixnum and Bignum are deprecated in Ruby 2.4 [#191]
|
|
12
|
+
|
|
13
|
+
* CI
|
|
14
|
+
* Run CI with GitHub Actions [#198]
|
|
15
|
+
* CI against Rails 6.1 [#193]
|
|
16
|
+
* CI against Rails 6.0 [#178]
|
|
17
|
+
* CI against Ruby 3.0.2, 2.7.4 and 2.6.8 [#197]
|
|
18
|
+
* Exclude jruby-head with Rails main [#194]
|
|
19
|
+
* Exclude jruby-head with Rails main [#194]
|
|
20
|
+
* Bump RuboCop version to 0.81.0 [#186]
|
|
21
|
+
* Run RuboCop using GitHub Actions [#180, #182]
|
|
22
|
+
* Remove .codeclimate.yml [#181]
|
|
23
|
+
* Fallback to bundler 1.7.13 [#171]
|
|
24
|
+
* Terminate CI against Ruby 2.2.x [#172]
|
|
25
|
+
* Use Ubuntu Xenial at Travis CI [#176]
|
|
26
|
+
|
|
1
27
|
== 0.7.1 2018-09-03
|
|
2
28
|
* Fix
|
|
3
29
|
* Address incorrect versions in Gemfile
|
data/README.md
CHANGED
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.9.0
|
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,9 +36,9 @@ module PLSQL
|
|
|
36
36
|
conn
|
|
37
37
|
end
|
|
38
38
|
|
|
39
|
-
def self.driver_type
|
|
40
|
-
# MRI 1.8.6 or YARV 1.9.1
|
|
41
|
-
@driver_type ||= if (!defined?(RUBY_ENGINE) || RUBY_ENGINE == "ruby") && defined?(OCI8)
|
|
39
|
+
def self.driver_type # :nodoc:
|
|
40
|
+
# MRI 1.8.6 or YARV 1.9.1 or TruffleRuby
|
|
41
|
+
@driver_type ||= if (!defined?(RUBY_ENGINE) || RUBY_ENGINE == "ruby" || RUBY_ENGINE == "truffleruby") && defined?(OCI8)
|
|
42
42
|
:oci
|
|
43
43
|
# JRuby
|
|
44
44
|
elsif (defined?(RUBY_ENGINE) && RUBY_ENGINE == "jruby")
|
|
@@ -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
|
|
@@ -46,7 +46,7 @@ rescue LoadError, NameError
|
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
module PLSQL
|
|
49
|
-
class JDBCConnection < Connection
|
|
49
|
+
class JDBCConnection < Connection # :nodoc:
|
|
50
50
|
def self.create_raw(params)
|
|
51
51
|
database = params[:database]
|
|
52
52
|
url = if ENV["TNS_ADMIN"] && database && !params[:host] && !params[:url]
|
|
@@ -98,7 +98,7 @@ module PLSQL
|
|
|
98
98
|
cs.close rescue nil
|
|
99
99
|
end
|
|
100
100
|
|
|
101
|
-
class CallableStatement
|
|
101
|
+
class CallableStatement # :nodoc:
|
|
102
102
|
def initialize(conn, sql)
|
|
103
103
|
@sql = sql
|
|
104
104
|
@connection = conn
|
|
@@ -145,7 +145,7 @@ module PLSQL
|
|
|
145
145
|
end
|
|
146
146
|
end
|
|
147
147
|
|
|
148
|
-
class Cursor
|
|
148
|
+
class Cursor # :nodoc:
|
|
149
149
|
include Connection::CursorCommon
|
|
150
150
|
|
|
151
151
|
attr_reader :result_set
|
|
@@ -223,8 +223,6 @@ module PLSQL
|
|
|
223
223
|
end
|
|
224
224
|
|
|
225
225
|
RUBY_CLASS_TO_SQL_TYPE = {
|
|
226
|
-
Fixnum => java.sql.Types::INTEGER,
|
|
227
|
-
Bignum => java.sql.Types::INTEGER,
|
|
228
226
|
Integer => java.sql.Types::INTEGER,
|
|
229
227
|
Float => java.sql.Types::FLOAT,
|
|
230
228
|
BigDecimal => java.sql.Types::NUMERIC,
|
data/lib/plsql/oci_connection.rb
CHANGED
|
@@ -24,7 +24,7 @@ if (oci8_version_ints <=> required_oci8_version) < 0
|
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
module PLSQL
|
|
27
|
-
class OCIConnection < Connection
|
|
27
|
+
class OCIConnection < Connection # :nodoc:
|
|
28
28
|
def self.create_raw(params)
|
|
29
29
|
connection_string = if params[:host]
|
|
30
30
|
"//#{params[:host]}:#{params[:port] || 1521}/#{params[:database]}"
|
|
@@ -64,7 +64,7 @@ module PLSQL
|
|
|
64
64
|
true
|
|
65
65
|
end
|
|
66
66
|
|
|
67
|
-
class Cursor
|
|
67
|
+
class Cursor # :nodoc:
|
|
68
68
|
include Connection::CursorCommon
|
|
69
69
|
|
|
70
70
|
attr_reader :raw_cursor
|
|
@@ -157,7 +157,7 @@ module PLSQL
|
|
|
157
157
|
[DateTime, nil]
|
|
158
158
|
when "TIMESTAMP", "TIMESTAMP WITH TIME ZONE", "TIMESTAMP WITH LOCAL TIME ZONE"
|
|
159
159
|
[Time, nil]
|
|
160
|
-
when "TABLE", "VARRAY", "OBJECT", "XMLTYPE"
|
|
160
|
+
when "TABLE", "VARRAY", "OBJECT", "XMLTYPE", "OPAQUE/XMLTYPE"
|
|
161
161
|
# create Ruby class for collection
|
|
162
162
|
klass = OCI8::Object::Base.get_class_by_typename(metadata[:sql_type_name])
|
|
163
163
|
unless klass
|
|
@@ -289,7 +289,11 @@ module PLSQL
|
|
|
289
289
|
# ActiveRecord Oracle enhanced adapter puts OCI8EnhancedAutoRecover wrapper around OCI8
|
|
290
290
|
# in this case we need to pass original OCI8 connection
|
|
291
291
|
else
|
|
292
|
-
raw_connection.
|
|
292
|
+
if raw_connection.instance_variable_defined?(:@raw_connection)
|
|
293
|
+
raw_connection.instance_variable_get(:@raw_connection)
|
|
294
|
+
else
|
|
295
|
+
raw_connection.instance_variable_get(:@connection)
|
|
296
|
+
end
|
|
293
297
|
end
|
|
294
298
|
end
|
|
295
299
|
|
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,15 @@ 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
|
+
if (@schema.connection.database_version <=> [18, 0, 0, 0]) >= 0
|
|
87
|
+
get_argument_metadata_from_18c
|
|
88
|
+
else
|
|
89
|
+
get_argument_metadata_below_18c
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def get_argument_metadata_below_18c # :nodoc:
|
|
86
94
|
@arguments = {}
|
|
87
95
|
@argument_list = {}
|
|
88
96
|
@out_list = {}
|
|
@@ -118,6 +126,9 @@ module PLSQL
|
|
|
118
126
|
data_type, in_out, data_length, data_precision, data_scale, char_used,
|
|
119
127
|
char_length, type_owner, type_name, type_subname, defaulted = r
|
|
120
128
|
|
|
129
|
+
# Oracle 23c reports BOOLEAN as "BOOLEAN" instead of "PL/SQL BOOLEAN"
|
|
130
|
+
data_type = "PL/SQL BOOLEAN" if data_type == "BOOLEAN"
|
|
131
|
+
|
|
121
132
|
@overloaded ||= !overload.nil?
|
|
122
133
|
# if not overloaded then store arguments at key 0
|
|
123
134
|
overload ||= 0
|
|
@@ -197,7 +208,103 @@ module PLSQL
|
|
|
197
208
|
construct_argument_list_for_overloads
|
|
198
209
|
end
|
|
199
210
|
|
|
200
|
-
|
|
211
|
+
# get procedure argument metadata from data dictionary
|
|
212
|
+
def get_argument_metadata_from_18c # :nodoc:
|
|
213
|
+
@arguments = {}
|
|
214
|
+
@argument_list = {}
|
|
215
|
+
@out_list = {}
|
|
216
|
+
@return = {}
|
|
217
|
+
@overloaded = false
|
|
218
|
+
|
|
219
|
+
# store tmp tables for each overload for table parameters with types defined inside packages
|
|
220
|
+
@tmp_table_names = {}
|
|
221
|
+
# store if tmp tables are created for specific overload
|
|
222
|
+
@tmp_tables_created = {}
|
|
223
|
+
|
|
224
|
+
@schema.select_all(
|
|
225
|
+
"SELECT subprogram_id, object_name, TO_NUMBER(overload), argument_name, position,
|
|
226
|
+
data_type, in_out, data_length, data_precision, data_scale, char_used,
|
|
227
|
+
char_length, type_owner, nvl(type_subname, type_name),
|
|
228
|
+
decode(type_object_type, 'PACKAGE', type_name, null), type_object_type, defaulted
|
|
229
|
+
FROM all_arguments
|
|
230
|
+
WHERE object_id = :object_id
|
|
231
|
+
AND owner = :owner
|
|
232
|
+
AND object_name = :procedure_name
|
|
233
|
+
ORDER BY overload, sequence",
|
|
234
|
+
@object_id, @schema_name, @procedure
|
|
235
|
+
) do |r|
|
|
236
|
+
|
|
237
|
+
subprogram_id, _object_name, overload, argument_name, position,
|
|
238
|
+
data_type, in_out, data_length, data_precision, data_scale, char_used,
|
|
239
|
+
char_length, type_owner, type_name, type_package, type_object_type, defaulted = r
|
|
240
|
+
|
|
241
|
+
# Oracle 23c reports BOOLEAN as "BOOLEAN" instead of "PL/SQL BOOLEAN"
|
|
242
|
+
data_type = "PL/SQL BOOLEAN" if data_type == "BOOLEAN"
|
|
243
|
+
|
|
244
|
+
@overloaded ||= !overload.nil?
|
|
245
|
+
# if not overloaded then store arguments at key 0
|
|
246
|
+
overload ||= 0
|
|
247
|
+
@arguments[overload] ||= {}
|
|
248
|
+
@return[overload] ||= nil
|
|
249
|
+
@tmp_table_names[overload] ||= []
|
|
250
|
+
|
|
251
|
+
sql_type_name = build_sql_type_name(type_owner, type_package, type_name)
|
|
252
|
+
|
|
253
|
+
tmp_table_name = nil
|
|
254
|
+
# type defined inside package
|
|
255
|
+
if type_package
|
|
256
|
+
if collection_type?(data_type)
|
|
257
|
+
tmp_table_name = "#{Connection::RUBY_TEMP_TABLE_PREFIX}#{@schema.connection.session_id}_#{@object_id}_#{subprogram_id}_#{position}"
|
|
258
|
+
end
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
argument_metadata = {
|
|
262
|
+
position: position && position.to_i,
|
|
263
|
+
data_type: data_type,
|
|
264
|
+
in_out: in_out,
|
|
265
|
+
data_length: data_length && data_length.to_i,
|
|
266
|
+
data_precision: data_precision && data_precision.to_i,
|
|
267
|
+
data_scale: data_scale && data_scale.to_i,
|
|
268
|
+
char_used: char_used,
|
|
269
|
+
char_length: char_length && char_length.to_i,
|
|
270
|
+
type_owner: type_owner,
|
|
271
|
+
type_name: type_name,
|
|
272
|
+
# TODO: should be renamed to type_package, when support for legacy database versions is dropped
|
|
273
|
+
# due to the explicit change declaration of types in oracle plsql_type-catalogs (type_package + type_name),
|
|
274
|
+
# the assignment of type + subtype was switched here for 18c and beyond
|
|
275
|
+
type_subname: type_package,
|
|
276
|
+
sql_type_name: sql_type_name,
|
|
277
|
+
defaulted: defaulted,
|
|
278
|
+
type_object_type: type_object_type
|
|
279
|
+
}
|
|
280
|
+
if tmp_table_name
|
|
281
|
+
@tmp_table_names[overload] << [(argument_metadata[:tmp_table_name] = tmp_table_name), argument_metadata]
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
if composite_type?(data_type)
|
|
285
|
+
case data_type
|
|
286
|
+
when "PL/SQL RECORD", "REF CURSOR"
|
|
287
|
+
argument_metadata[:fields] = get_field_definitions(argument_metadata)
|
|
288
|
+
when "PL/SQL TABLE", "TABLE", "VARRAY"
|
|
289
|
+
argument_metadata[:element] = get_element_definition(argument_metadata)
|
|
290
|
+
end
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
# if function has return value
|
|
294
|
+
if argument_name.nil? && in_out == "OUT"
|
|
295
|
+
@return[overload] = argument_metadata
|
|
296
|
+
else
|
|
297
|
+
# sometime there are empty IN arguments in all_arguments view for procedures without arguments (e.g. for DBMS_OUTPUT.DISABLE)
|
|
298
|
+
@arguments[overload][argument_name.downcase.to_sym] = argument_metadata if argument_name
|
|
299
|
+
end
|
|
300
|
+
end
|
|
301
|
+
# if procedure is without arguments then create default empty argument list for default overload
|
|
302
|
+
@arguments[0] = {} if @arguments.keys.empty?
|
|
303
|
+
|
|
304
|
+
construct_argument_list_for_overloads
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
def construct_argument_list_for_overloads # :nodoc:
|
|
201
308
|
@overloads = @arguments.keys.sort
|
|
202
309
|
@overloads.each do |overload|
|
|
203
310
|
@argument_list[overload] = @arguments[overload].keys.sort { |k1, k2| @arguments[overload][k1][:position] <=> @arguments[overload][k2][:position] }
|
|
@@ -205,10 +312,10 @@ module PLSQL
|
|
|
205
312
|
end
|
|
206
313
|
end
|
|
207
314
|
|
|
208
|
-
def ensure_tmp_tables_created(overload)
|
|
315
|
+
def ensure_tmp_tables_created(overload) # :nodoc:
|
|
209
316
|
return if @tmp_tables_created.nil? || @tmp_tables_created[overload]
|
|
210
317
|
@tmp_table_names[overload] && @tmp_table_names[overload].each do |table_name, argument_metadata|
|
|
211
|
-
sql = "CREATE GLOBAL TEMPORARY TABLE #{table_name} (\n"
|
|
318
|
+
sql = +"CREATE GLOBAL TEMPORARY TABLE #{table_name} (\n"
|
|
212
319
|
element_metadata = argument_metadata[:element]
|
|
213
320
|
case element_metadata[:data_type]
|
|
214
321
|
when "PL/SQL RECORD"
|
|
@@ -229,22 +336,210 @@ module PLSQL
|
|
|
229
336
|
@tmp_tables_created[overload] = true
|
|
230
337
|
end
|
|
231
338
|
|
|
339
|
+
def build_sql_type_name(type_owner, type_package, type_name) # :nodoc:
|
|
340
|
+
if type_owner == nil || type_owner == "PUBLIC"
|
|
341
|
+
type_owner_res = ""
|
|
342
|
+
else
|
|
343
|
+
type_owner_res = "#{type_owner}."
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
if type_package == nil
|
|
347
|
+
type_name_res = type_name
|
|
348
|
+
else
|
|
349
|
+
type_name_res = "#{type_package}.#{type_name}"
|
|
350
|
+
end
|
|
351
|
+
type_name_res && "#{type_owner_res}#{type_name_res}"
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
def get_field_definitions(argument_metadata) # :nodoc:
|
|
355
|
+
fields = {}
|
|
356
|
+
case argument_metadata[:type_object_type]
|
|
357
|
+
when "PACKAGE"
|
|
358
|
+
@schema.select_all(
|
|
359
|
+
"SELECT attr_no, attr_name, attr_type_owner, attr_type_name, attr_type_package, length, precision, scale, char_used
|
|
360
|
+
FROM ALL_PLSQL_TYPES t, ALL_PLSQL_TYPE_ATTRS ta
|
|
361
|
+
WHERE t.OWNER = :owner AND t.type_name = :type_name AND t.package_name = :package_name
|
|
362
|
+
AND ta.OWNER = t.owner AND ta.TYPE_NAME = t.TYPE_NAME AND ta.PACKAGE_NAME = t.PACKAGE_NAME
|
|
363
|
+
ORDER BY attr_no",
|
|
364
|
+
@schema_name, argument_metadata[:type_name], argument_metadata[:type_subname]) do |r|
|
|
365
|
+
|
|
366
|
+
attr_no, attr_name, attr_type_owner, attr_type_name, attr_type_package, attr_length, attr_precision, attr_scale, attr_char_used = r
|
|
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
|
+
|
|
371
|
+
fields[attr_name.downcase.to_sym] = {
|
|
372
|
+
position: attr_no.to_i,
|
|
373
|
+
data_type: attr_type_owner == nil ? attr_type_name : get_composite_type(attr_type_owner, attr_type_name, attr_type_package),
|
|
374
|
+
in_out: argument_metadata[:in_out],
|
|
375
|
+
data_length: attr_length && attr_length.to_i,
|
|
376
|
+
data_precision: attr_precision && attr_precision.to_i,
|
|
377
|
+
data_scale: attr_scale && attr_scale.to_i,
|
|
378
|
+
char_used: attr_char_used == nil ? "0" : attr_char_used,
|
|
379
|
+
char_length: attr_char_used && attr_length && attr_length.to_i,
|
|
380
|
+
type_owner: attr_type_owner,
|
|
381
|
+
type_name: attr_type_owner && attr_type_name,
|
|
382
|
+
type_subname: attr_type_package,
|
|
383
|
+
sql_type_name: attr_type_owner && build_sql_type_name(attr_type_owner, attr_type_package, attr_type_name),
|
|
384
|
+
defaulted: argument_metadata[:defaulted]
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
if fields[attr_name.downcase.to_sym][:data_type] == "TABLE" && fields[attr_name.downcase.to_sym][:type_subname] != nil
|
|
388
|
+
fields[attr_name.downcase.to_sym][:fields] = get_field_definitions(fields[attr_name.downcase.to_sym])
|
|
389
|
+
end
|
|
390
|
+
end
|
|
391
|
+
when "TABLE", "VIEW"
|
|
392
|
+
@schema.select_all(
|
|
393
|
+
"SELECT column_id, column_name, data_type, data_length, data_precision, data_scale, char_length, char_used
|
|
394
|
+
FROM ALL_TAB_COLS WHERE OWNER = :owner AND TABLE_NAME = :type_name
|
|
395
|
+
ORDER BY column_id",
|
|
396
|
+
@schema_name, argument_metadata[:type_name]) do |r|
|
|
397
|
+
|
|
398
|
+
col_no, col_name, col_type_name, col_length, col_precision, col_scale, col_char_length, col_char_used = r
|
|
399
|
+
|
|
400
|
+
fields[col_name.downcase.to_sym] = {
|
|
401
|
+
position: col_no.to_i,
|
|
402
|
+
data_type: col_type_name,
|
|
403
|
+
in_out: argument_metadata[:in_out],
|
|
404
|
+
data_length: col_length && col_length.to_i,
|
|
405
|
+
data_precision: col_precision && col_precision.to_i,
|
|
406
|
+
data_scale: col_scale && col_scale.to_i,
|
|
407
|
+
char_used: col_char_used == nil ? "0" : col_char_used,
|
|
408
|
+
char_length: col_char_length && col_char_length.to_i,
|
|
409
|
+
type_owner: nil,
|
|
410
|
+
type_name: nil,
|
|
411
|
+
type_subname: nil,
|
|
412
|
+
sql_type_name: nil,
|
|
413
|
+
defaulted: argument_metadata[:defaulted]
|
|
414
|
+
}
|
|
415
|
+
end
|
|
416
|
+
end
|
|
417
|
+
fields
|
|
418
|
+
end
|
|
419
|
+
|
|
420
|
+
def get_element_definition(argument_metadata) # :nodoc:
|
|
421
|
+
element_metadata = {}
|
|
422
|
+
if collection_type?(argument_metadata[:data_type])
|
|
423
|
+
case argument_metadata[:type_object_type]
|
|
424
|
+
when "PACKAGE"
|
|
425
|
+
r = @schema.select_first(
|
|
426
|
+
"SELECT elem_type_owner, elem_type_name, elem_type_package, length, precision, scale, char_used, index_by
|
|
427
|
+
FROM ALL_PLSQL_COLL_TYPES t
|
|
428
|
+
WHERE t.OWNER = :owner AND t.TYPE_NAME = :type_name AND t.PACKAGE_NAME = :package_name",
|
|
429
|
+
@schema_name, argument_metadata[:type_name], argument_metadata[:type_subname])
|
|
430
|
+
|
|
431
|
+
elem_type_owner, elem_type_name, elem_type_package, elem_length, elem_precision, elem_scale, elem_char_used, index_by = r
|
|
432
|
+
|
|
433
|
+
# Oracle 23c reports BOOLEAN as "BOOLEAN" instead of "PL/SQL BOOLEAN"
|
|
434
|
+
elem_type_name = "PL/SQL BOOLEAN" if elem_type_name == "BOOLEAN"
|
|
435
|
+
|
|
436
|
+
if index_by == "VARCHAR2"
|
|
437
|
+
raise ArgumentError, "Index-by Varchar-Table (associative array) #{argument_metadata[:type_name]} is not supported"
|
|
438
|
+
end
|
|
439
|
+
|
|
440
|
+
element_metadata = {
|
|
441
|
+
position: 1,
|
|
442
|
+
data_type: if elem_type_owner == nil
|
|
443
|
+
elem_type_name
|
|
444
|
+
else
|
|
445
|
+
elem_type_package != nil ? "PL/SQL RECORD" : "OBJECT"
|
|
446
|
+
end,
|
|
447
|
+
in_out: argument_metadata[:in_out],
|
|
448
|
+
data_length: elem_length && elem_length.to_i,
|
|
449
|
+
data_precision: elem_precision && elem_precision.to_i,
|
|
450
|
+
data_scale: elem_scale && elem_scale.to_i,
|
|
451
|
+
char_used: elem_char_used,
|
|
452
|
+
char_length: elem_char_used && elem_length && elem_length.to_i,
|
|
453
|
+
type_owner: elem_type_owner,
|
|
454
|
+
type_name: elem_type_name,
|
|
455
|
+
type_subname: elem_type_package,
|
|
456
|
+
sql_type_name: elem_type_owner && build_sql_type_name(elem_type_owner, elem_type_package, elem_type_name),
|
|
457
|
+
type_object_type: elem_type_package != nil ? "PACKAGE" : nil,
|
|
458
|
+
defaulted: argument_metadata[:defaulted]
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
if elem_type_package != nil
|
|
462
|
+
element_metadata[:fields] = get_field_definitions(element_metadata)
|
|
463
|
+
end
|
|
464
|
+
when "TYPE"
|
|
465
|
+
r = @schema.select_first(
|
|
466
|
+
"SELECT elem_type_owner, elem_type_name, length, precision, scale, char_used
|
|
467
|
+
FROM ALL_COLL_TYPES t
|
|
468
|
+
WHERE t.owner = :owner AND t.TYPE_NAME = :type_name",
|
|
469
|
+
@schema_name, argument_metadata[:type_name]
|
|
470
|
+
)
|
|
471
|
+
elem_type_owner, elem_type_name, elem_length, elem_precision, elem_scale, elem_char_used = r
|
|
472
|
+
|
|
473
|
+
# Oracle 23c reports BOOLEAN as "BOOLEAN" instead of "PL/SQL BOOLEAN"
|
|
474
|
+
elem_type_name = "PL/SQL BOOLEAN" if elem_type_name == "BOOLEAN"
|
|
475
|
+
|
|
476
|
+
element_metadata = {
|
|
477
|
+
position: 1,
|
|
478
|
+
data_type: elem_type_owner == nil ? elem_type_name : "OBJECT",
|
|
479
|
+
in_out: argument_metadata[:in_out],
|
|
480
|
+
data_length: elem_length && elem_length.to_i,
|
|
481
|
+
data_precision: elem_precision && elem_precision.to_i,
|
|
482
|
+
data_scale: elem_scale && elem_scale.to_i,
|
|
483
|
+
char_used: elem_char_used,
|
|
484
|
+
char_length: elem_char_used && elem_length && elem_length.to_i,
|
|
485
|
+
type_owner: elem_type_owner,
|
|
486
|
+
type_name: elem_type_name,
|
|
487
|
+
type_subname: nil,
|
|
488
|
+
sql_type_name: elem_type_owner && build_sql_type_name(elem_type_owner, nil, elem_type_name),
|
|
489
|
+
defaulted: argument_metadata[:defaulted]
|
|
490
|
+
}
|
|
491
|
+
end
|
|
492
|
+
else
|
|
493
|
+
element_metadata = {
|
|
494
|
+
position: 1,
|
|
495
|
+
data_type: "PL/SQL RECORD",
|
|
496
|
+
in_out: argument_metadata[:in_out],
|
|
497
|
+
data_length: nil,
|
|
498
|
+
data_precision: nil,
|
|
499
|
+
data_scale: nil,
|
|
500
|
+
char_used: "B",
|
|
501
|
+
char_length: 0,
|
|
502
|
+
type_owner: argument_metadata[:type_owner],
|
|
503
|
+
type_name: argument_metadata[:type_name],
|
|
504
|
+
type_subname: argument_metadata[:type_subname],
|
|
505
|
+
sql_type_name: build_sql_type_name(argument_metadata[:type_owner], argument_metadata[:type_subname], argument_metadata[:type_name]),
|
|
506
|
+
defaulted: argument_metadata[:defaulted]
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
if element_metadata[:type_subname] != nil
|
|
510
|
+
element_metadata[:fields] = get_field_definitions(element_metadata)
|
|
511
|
+
end
|
|
512
|
+
end
|
|
513
|
+
element_metadata
|
|
514
|
+
end
|
|
515
|
+
|
|
516
|
+
def get_composite_type(type_owner, type_name, type_package)
|
|
517
|
+
r = @schema.select_first("SELECT typecode FROM all_plsql_types WHERE owner = :owner AND type_name = :type_name AND package_name = :type_package
|
|
518
|
+
UNION ALL
|
|
519
|
+
SELECT typecode FROM all_types WHERE owner = :owner AND type_name = :type_name",
|
|
520
|
+
type_owner, type_name, type_package, type_owner, type_name)
|
|
521
|
+
typecode = r[0]
|
|
522
|
+
raise ArgumentError, "#{type_name} type #{build_sql_type_name(type_owner, type_package, type_name)} definition inside package is not supported as part of other type definition," <<
|
|
523
|
+
" use CREATE TYPE outside package" if typecode == "COLLECTION"
|
|
524
|
+
typecode
|
|
525
|
+
end
|
|
526
|
+
|
|
232
527
|
PLSQL_COMPOSITE_TYPES = ["PL/SQL RECORD", "PL/SQL TABLE", "TABLE", "VARRAY", "REF CURSOR"].freeze
|
|
233
|
-
def composite_type?(data_type)
|
|
528
|
+
def composite_type?(data_type) # :nodoc:
|
|
234
529
|
PLSQL_COMPOSITE_TYPES.include? data_type
|
|
235
530
|
end
|
|
236
531
|
|
|
237
532
|
PLSQL_COLLECTION_TYPES = ["PL/SQL TABLE", "TABLE", "VARRAY"].freeze
|
|
238
|
-
def collection_type?(data_type)
|
|
533
|
+
def collection_type?(data_type) # :nodoc:
|
|
239
534
|
PLSQL_COLLECTION_TYPES.include? data_type
|
|
240
535
|
end
|
|
241
536
|
|
|
242
|
-
def overloaded?
|
|
537
|
+
def overloaded? # :nodoc:
|
|
243
538
|
@overloaded
|
|
244
539
|
end
|
|
245
540
|
end
|
|
246
541
|
|
|
247
|
-
class Procedure
|
|
542
|
+
class Procedure # :nodoc:
|
|
248
543
|
extend ProcedureClassMethods
|
|
249
544
|
include ProcedureCommon
|
|
250
545
|
|