ruby-plsql 0.6.0 → 0.7.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 +5 -5
- data/.codeclimate.yml +30 -0
- data/.github/stale.yml +37 -0
- data/.rubocop.yml +153 -0
- data/.travis.yml +20 -6
- data/.travis/oracle/download.sh +9 -10
- data/.travis/oracle/install.sh +6 -6
- data/Gemfile +13 -9
- data/History.txt +26 -0
- data/README.md +9 -5
- data/Rakefile +31 -26
- data/VERSION +1 -1
- data/Vagrantfile +2 -2
- data/gemfiles/Gemfile.activerecord-5.0 +21 -0
- data/gemfiles/Gemfile.activerecord-5.1 +21 -0
- data/gemfiles/Gemfile.activerecord-5.2 +21 -0
- data/lib/plsql/connection.rb +16 -18
- data/lib/plsql/helpers.rb +1 -3
- data/lib/plsql/jdbc_connection.rb +66 -61
- data/lib/plsql/oci8_patches.rb +2 -2
- data/lib/plsql/oci_connection.rb +51 -69
- data/lib/plsql/package.rb +5 -8
- data/lib/plsql/procedure.rb +75 -78
- data/lib/plsql/procedure_call.rb +498 -501
- data/lib/plsql/schema.rb +95 -100
- data/lib/plsql/sequence.rb +10 -13
- data/lib/plsql/sql_statements.rb +9 -11
- data/lib/plsql/table.rb +59 -63
- data/lib/plsql/type.rb +71 -76
- data/lib/plsql/variable.rb +89 -94
- data/lib/plsql/version.rb +1 -1
- data/lib/plsql/view.rb +16 -19
- data/ruby-plsql.gemspec +41 -37
- data/spec/plsql/connection_spec.rb +67 -67
- data/spec/plsql/package_spec.rb +15 -15
- data/spec/plsql/procedure_spec.rb +286 -233
- data/spec/plsql/schema_spec.rb +22 -23
- data/spec/plsql/sequence_spec.rb +2 -2
- data/spec/plsql/sql_statements_spec.rb +5 -5
- data/spec/plsql/table_spec.rb +77 -77
- data/spec/plsql/type_spec.rb +23 -29
- data/spec/plsql/variable_spec.rb +59 -59
- data/spec/plsql/version_spec.rb +4 -4
- data/spec/plsql/view_spec.rb +42 -42
- data/spec/spec_helper.rb +37 -29
- data/spec/support/test_db.rb +12 -13
- metadata +44 -26
- data/.travis/oracle/LICENSE +0 -5
- data/.travis/oracle/README.md +0 -64
- data/.travis/oracle/download.js +0 -100
data/lib/plsql/oci8_patches.rb
CHANGED
data/lib/plsql/oci_connection.rb
CHANGED
@@ -18,17 +18,16 @@ require "plsql/oci8_patches"
|
|
18
18
|
|
19
19
|
# check ruby-oci8 version
|
20
20
|
required_oci8_version = [2, 0, 3]
|
21
|
-
oci8_version_ints = OCI8::VERSION.scan(/\d+/).map{|s| s.to_i}
|
21
|
+
oci8_version_ints = OCI8::VERSION.scan(/\d+/).map { |s| s.to_i }
|
22
22
|
if (oci8_version_ints <=> required_oci8_version) < 0
|
23
23
|
raise LoadError, "ERROR: ruby-oci8 version #{OCI8::VERSION} is too old. Please install ruby-oci8 version #{required_oci8_version.join('.')} or later."
|
24
24
|
end
|
25
25
|
|
26
26
|
module PLSQL
|
27
27
|
class OCIConnection < Connection #:nodoc:
|
28
|
-
|
29
28
|
def self.create_raw(params)
|
30
29
|
connection_string = if params[:host]
|
31
|
-
"//#{params[:host]}:#{params[:port]||1521}/#{params[:database]}"
|
30
|
+
"//#{params[:host]}:#{params[:port] || 1521}/#{params[:database]}"
|
32
31
|
else
|
33
32
|
params[:database]
|
34
33
|
end
|
@@ -47,7 +46,7 @@ module PLSQL
|
|
47
46
|
def rollback
|
48
47
|
raw_connection.rollback
|
49
48
|
end
|
50
|
-
|
49
|
+
|
51
50
|
def autocommit?
|
52
51
|
raw_connection.autocommit?
|
53
52
|
end
|
@@ -86,7 +85,7 @@ module PLSQL
|
|
86
85
|
self.new(conn, raw_cursor)
|
87
86
|
end
|
88
87
|
|
89
|
-
def self.new_from_query(conn, sql, bindvars=[], options={})
|
88
|
+
def self.new_from_query(conn, sql, bindvars = [], options = {})
|
90
89
|
cursor = new_from_parse(conn, sql)
|
91
90
|
if prefetch_rows = options[:prefetch_rows]
|
92
91
|
cursor.prefetch_rows = prefetch_rows
|
@@ -104,7 +103,7 @@ module PLSQL
|
|
104
103
|
ora_value = @connection.ruby_value_to_ora_value(value, type)
|
105
104
|
@raw_cursor.bind_param(arg, ora_value, type, length)
|
106
105
|
end
|
107
|
-
|
106
|
+
|
108
107
|
def exec(*bindvars)
|
109
108
|
@raw_cursor.exec(*bindvars)
|
110
109
|
end
|
@@ -115,11 +114,11 @@ module PLSQL
|
|
115
114
|
|
116
115
|
def fetch
|
117
116
|
row = @raw_cursor.fetch
|
118
|
-
row && row.map{|v| @connection.ora_value_to_ruby_value(v)}
|
117
|
+
row && row.map { |v| @connection.ora_value_to_ruby_value(v) }
|
119
118
|
end
|
120
119
|
|
121
120
|
def fields
|
122
|
-
@fields ||= @raw_cursor.get_col_names.map{|c| c.downcase.to_sym}
|
121
|
+
@fields ||= @raw_cursor.get_col_names.map { |c| c.downcase.to_sym }
|
123
122
|
end
|
124
123
|
|
125
124
|
def close_raw_cursor
|
@@ -133,14 +132,13 @@ module PLSQL
|
|
133
132
|
end
|
134
133
|
close_raw_cursor
|
135
134
|
end
|
136
|
-
|
137
135
|
end
|
138
136
|
|
139
137
|
def parse(sql)
|
140
138
|
Cursor.new_from_parse(self, sql)
|
141
139
|
end
|
142
140
|
|
143
|
-
def cursor_from_query(sql, bindvars=[], options={})
|
141
|
+
def cursor_from_query(sql, bindvars = [], options = {})
|
144
142
|
Cursor.new_from_query(self, sql, bindvars, options)
|
145
143
|
end
|
146
144
|
|
@@ -174,18 +172,16 @@ module PLSQL
|
|
174
172
|
end
|
175
173
|
end
|
176
174
|
|
177
|
-
def ruby_value_to_ora_value(value, type=nil)
|
175
|
+
def ruby_value_to_ora_value(value, type = nil)
|
178
176
|
type ||= value.class
|
179
177
|
case type.to_s.to_sym
|
180
|
-
when :
|
178
|
+
when :Integer, :BigDecimal, :String
|
181
179
|
value
|
182
180
|
when :OraNumber
|
183
181
|
# pass parameters as OraNumber to avoid rounding errors
|
184
182
|
case value
|
185
|
-
when Bignum
|
186
|
-
OraNumber.new(value.to_s)
|
187
183
|
when BigDecimal
|
188
|
-
OraNumber.new(value.to_s(
|
184
|
+
OraNumber.new(value.to_s("F"))
|
189
185
|
when TrueClass
|
190
186
|
OraNumber.new(1)
|
191
187
|
when FalseClass
|
@@ -218,7 +214,7 @@ module PLSQL
|
|
218
214
|
raise ArgumentError, "You should pass Array value for collection type parameter" unless value.is_a?(Array)
|
219
215
|
elem_list = value.map do |elem|
|
220
216
|
if (attr_tdo = tdo.coll_attr.typeinfo)
|
221
|
-
attr_type,
|
217
|
+
attr_type, _ = plsql_to_ruby_data_type(data_type: "OBJECT", sql_type_name: attr_tdo.typename)
|
222
218
|
else
|
223
219
|
attr_type = elem.class
|
224
220
|
end
|
@@ -227,7 +223,7 @@ module PLSQL
|
|
227
223
|
# construct collection value
|
228
224
|
# TODO: change setting instance variable to appropriate ruby-oci8 method call when available
|
229
225
|
collection = type.new(raw_oci_connection)
|
230
|
-
collection.instance_variable_set(
|
226
|
+
collection.instance_variable_set("@attributes", elem_list)
|
231
227
|
collection
|
232
228
|
else # object type
|
233
229
|
raise ArgumentError, "You should pass Hash value for object type parameter" unless value.is_a?(Hash)
|
@@ -237,7 +233,7 @@ module PLSQL
|
|
237
233
|
case attr.datatype
|
238
234
|
when OCI8::TDO::ATTR_NAMED_TYPE, OCI8::TDO::ATTR_NAMED_COLLECTION
|
239
235
|
# nested object type or collection
|
240
|
-
attr_type,
|
236
|
+
attr_type, _ = plsql_to_ruby_data_type(data_type: "OBJECT", sql_type_name: attr.typeinfo.typename)
|
241
237
|
object_attrs[key] = ruby_value_to_ora_value(object_attrs[key], attr_type)
|
242
238
|
end
|
243
239
|
end
|
@@ -266,7 +262,7 @@ module PLSQL
|
|
266
262
|
when OCI8::Object::Base
|
267
263
|
tdo = raw_oci_connection.get_tdo_by_class(value.class)
|
268
264
|
if tdo.is_collection?
|
269
|
-
value.to_ary.map{|e| ora_value_to_ruby_value(e)}
|
265
|
+
value.to_ary.map { |e| ora_value_to_ruby_value(e) }
|
270
266
|
else # object type
|
271
267
|
tdo.attributes.inject({}) do |hash, attr|
|
272
268
|
hash[attr.name] = ora_value_to_ruby_value(value.instance_variable_get(:@attributes)[attr.name])
|
@@ -280,63 +276,49 @@ module PLSQL
|
|
280
276
|
end
|
281
277
|
end
|
282
278
|
|
283
|
-
def describe_synonym(schema_name, synonym_name)
|
284
|
-
if schema_name == 'PUBLIC'
|
285
|
-
full_name = synonym_name.to_s
|
286
|
-
else
|
287
|
-
full_name = "#{schema_name}.#{synonym_name}"
|
288
|
-
end
|
289
|
-
metadata = raw_connection.describe_synonym(full_name)
|
290
|
-
[metadata.schema_name, metadata.name]
|
291
|
-
rescue OCIError
|
292
|
-
nil
|
293
|
-
end
|
294
|
-
|
295
279
|
def database_version
|
296
|
-
@database_version ||= (version = raw_connection.oracle_server_version) &&
|
280
|
+
@database_version ||= (version = raw_connection.oracle_server_version) &&
|
297
281
|
[version.major, version.minor, version.update, version.patch]
|
298
282
|
end
|
299
283
|
|
300
284
|
private
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
end
|
310
|
-
end
|
311
|
-
|
312
|
-
def ora_number_to_ruby_number(num)
|
313
|
-
# return BigDecimal instead of Float to avoid rounding errors
|
314
|
-
num == (num_to_i = num.to_i) ? num_to_i : (num.is_a?(BigDecimal) ? num : BigDecimal.new(num.to_s))
|
315
|
-
end
|
316
|
-
|
317
|
-
def ora_date_to_ruby_date(val)
|
318
|
-
case val
|
319
|
-
when DateTime
|
320
|
-
# similar implementation as in oracle_enhanced adapter
|
321
|
-
begin
|
322
|
-
Time.send(plsql.default_timezone, val.year, val.month, val.day, val.hour, val.min, val.sec)
|
323
|
-
rescue
|
324
|
-
offset = plsql.default_timezone.to_sym == :local ? plsql.local_timezone_offset : 0
|
325
|
-
DateTime.civil(val.year, val.month, val.day, val.hour, val.min, val.sec, offset)
|
326
|
-
end
|
327
|
-
when OraDate
|
328
|
-
# similar implementation as in oracle_enhanced adapter
|
329
|
-
begin
|
330
|
-
Time.send(plsql.default_timezone, val.year, val.month, val.day, val.hour, val.minute, val.second)
|
331
|
-
rescue
|
332
|
-
offset = plsql.default_timezone.to_sym == :local ? plsql.local_timezone_offset : 0
|
333
|
-
DateTime.civil(val.year, val.month, val.day, val.hour, val.minute, val.second, offset)
|
285
|
+
|
286
|
+
def raw_oci_connection
|
287
|
+
if raw_connection.is_a? OCI8
|
288
|
+
raw_connection
|
289
|
+
# ActiveRecord Oracle enhanced adapter puts OCI8EnhancedAutoRecover wrapper around OCI8
|
290
|
+
# in this case we need to pass original OCI8 connection
|
291
|
+
else
|
292
|
+
raw_connection.instance_variable_get(:@connection)
|
334
293
|
end
|
335
|
-
else
|
336
|
-
val
|
337
294
|
end
|
338
|
-
end
|
339
295
|
|
296
|
+
def ora_number_to_ruby_number(num)
|
297
|
+
# return BigDecimal instead of Float to avoid rounding errors
|
298
|
+
num == (num_to_i = num.to_i) ? num_to_i : (num.is_a?(BigDecimal) ? num : BigDecimal(num.to_s))
|
299
|
+
end
|
300
|
+
|
301
|
+
def ora_date_to_ruby_date(val)
|
302
|
+
case val
|
303
|
+
when DateTime
|
304
|
+
# similar implementation as in oracle_enhanced adapter
|
305
|
+
begin
|
306
|
+
Time.send(plsql.default_timezone, val.year, val.month, val.day, val.hour, val.min, val.sec)
|
307
|
+
rescue
|
308
|
+
offset = plsql.default_timezone.to_sym == :local ? plsql.local_timezone_offset : 0
|
309
|
+
DateTime.civil(val.year, val.month, val.day, val.hour, val.min, val.sec, offset)
|
310
|
+
end
|
311
|
+
when OraDate
|
312
|
+
# similar implementation as in oracle_enhanced adapter
|
313
|
+
begin
|
314
|
+
Time.send(plsql.default_timezone, val.year, val.month, val.day, val.hour, val.minute, val.second)
|
315
|
+
rescue
|
316
|
+
offset = plsql.default_timezone.to_sym == :local ? plsql.local_timezone_offset : 0
|
317
|
+
DateTime.civil(val.year, val.month, val.day, val.hour, val.minute, val.second, offset)
|
318
|
+
end
|
319
|
+
else
|
320
|
+
val
|
321
|
+
end
|
322
|
+
end
|
340
323
|
end
|
341
|
-
|
342
324
|
end
|
data/lib/plsql/package.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
module PLSQL
|
2
|
-
|
3
2
|
module PackageClassMethods #:nodoc:
|
4
3
|
def find(schema, package)
|
5
4
|
package_name = package.to_s.upcase
|
@@ -56,11 +55,11 @@ module PLSQL
|
|
56
55
|
|
57
56
|
private
|
58
57
|
|
59
|
-
|
60
|
-
|
61
|
-
|
58
|
+
def method_missing(method, *args, &block)
|
59
|
+
method = method.to_s
|
60
|
+
method.chop! if (assignment = method[/=$/])
|
62
61
|
|
63
|
-
|
62
|
+
case (object = self[method])
|
64
63
|
when Procedure
|
65
64
|
if assignment
|
66
65
|
raise ArgumentError, "Cannot assign value to package procedure '#{method.upcase}'"
|
@@ -82,9 +81,7 @@ module PLSQL
|
|
82
81
|
end
|
83
82
|
else
|
84
83
|
raise ArgumentError, "No PL/SQL procedure or variable '#{method.upcase}' found"
|
84
|
+
end
|
85
85
|
end
|
86
|
-
end
|
87
|
-
|
88
86
|
end
|
89
|
-
|
90
87
|
end
|
data/lib/plsql/procedure.rb
CHANGED
@@ -1,45 +1,44 @@
|
|
1
1
|
module PLSQL
|
2
|
-
|
3
2
|
module ProcedureClassMethods #:nodoc:
|
4
3
|
def find(schema, procedure, package = nil, override_schema_name = nil)
|
5
4
|
if package.nil?
|
6
5
|
if (row = schema.select_first(
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
6
|
+
"SELECT #{procedure_object_id_src(schema)}.object_id
|
7
|
+
FROM all_procedures p, all_objects o
|
8
|
+
WHERE p.owner = :owner
|
9
|
+
AND p.object_name = :object_name
|
10
|
+
AND o.owner = p.owner
|
11
|
+
AND o.object_name = p.object_name
|
12
|
+
AND o.object_type in ('PROCEDURE', 'FUNCTION')",
|
14
13
|
schema.schema_name, procedure.to_s.upcase))
|
15
14
|
new(schema, procedure, nil, nil, row[0])
|
16
15
|
# search for synonym
|
17
16
|
elsif (row = schema.select_first(
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
17
|
+
"SELECT o.owner, o.object_name, #{procedure_object_id_src(schema)}.object_id
|
18
|
+
FROM all_synonyms s, all_objects o, all_procedures p
|
19
|
+
WHERE s.owner IN (:owner, 'PUBLIC')
|
20
|
+
AND s.synonym_name = :synonym_name
|
21
|
+
AND o.owner = s.table_owner
|
22
|
+
AND o.object_name = s.table_name
|
23
|
+
AND o.object_type IN ('PROCEDURE','FUNCTION')
|
24
|
+
AND o.owner = p.owner
|
25
|
+
AND o.object_name = p.object_name
|
26
|
+
ORDER BY DECODE(s.owner, 'PUBLIC', 1, 0)",
|
28
27
|
schema.schema_name, procedure.to_s.upcase))
|
29
28
|
new(schema, row[1], nil, row[0], row[2])
|
30
29
|
else
|
31
30
|
nil
|
32
31
|
end
|
33
32
|
elsif package && (row = schema.select_first(
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
33
|
+
# older Oracle versions do not have object_id column in all_procedures
|
34
|
+
"SELECT #{procedure_object_id_src(schema)}.object_id
|
35
|
+
FROM all_procedures p, all_objects o
|
36
|
+
WHERE p.owner = :owner
|
37
|
+
AND p.object_name = :object_name
|
38
|
+
AND p.procedure_name = :procedure_name
|
39
|
+
AND o.owner = p.owner
|
40
|
+
AND o.object_name = p.object_name
|
41
|
+
AND o.object_type = 'PACKAGE'",
|
43
42
|
override_schema_name || schema.schema_name, package, procedure.to_s.upcase))
|
44
43
|
new(schema, procedure, package, override_schema_name, row[0])
|
45
44
|
else
|
@@ -49,9 +48,9 @@ module PLSQL
|
|
49
48
|
|
50
49
|
private
|
51
50
|
|
52
|
-
|
53
|
-
|
54
|
-
|
51
|
+
def procedure_object_id_src(schema)
|
52
|
+
(schema.connection.database_version <=> [11, 1, 0, 0]) >= 0 ? "p" : "o"
|
53
|
+
end
|
55
54
|
end
|
56
55
|
|
57
56
|
module ProcedureCommon #:nodoc:
|
@@ -61,21 +60,21 @@ module PLSQL
|
|
61
60
|
# return type string from metadata that can be used in DECLARE block or table definition
|
62
61
|
def self.type_to_sql(metadata) #:nodoc:
|
63
62
|
case metadata[:data_type]
|
64
|
-
when
|
63
|
+
when "NUMBER"
|
65
64
|
precision, scale = metadata[:data_precision], metadata[:data_scale]
|
66
|
-
"NUMBER#{precision ? "(#{precision}#{scale ? ",#{scale}": ""})" : ""}"
|
67
|
-
when
|
65
|
+
"NUMBER#{precision ? "(#{precision}#{scale ? ",#{scale}" : ""})" : ""}"
|
66
|
+
when "VARCHAR", "VARCHAR2", "CHAR"
|
68
67
|
length = case metadata[:char_used]
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
68
|
+
when "C" then "#{metadata[:char_length]} CHAR"
|
69
|
+
when "B" then "#{metadata[:data_length]} BYTE"
|
70
|
+
else
|
71
|
+
metadata[:data_length]
|
73
72
|
end
|
74
73
|
"#{metadata[:data_type]}#{length && "(#{length})"}"
|
75
|
-
when
|
74
|
+
when "NVARCHAR2", "NCHAR"
|
76
75
|
length = metadata[:char_length]
|
77
76
|
"#{metadata[:data_type]}#{length && "(#{length})"}"
|
78
|
-
when
|
77
|
+
when "PL/SQL TABLE", "TABLE", "VARRAY", "OBJECT", "XMLTYPE"
|
79
78
|
metadata[:sql_type_name]
|
80
79
|
else
|
81
80
|
metadata[:data_type]
|
@@ -99,9 +98,9 @@ module PLSQL
|
|
99
98
|
@tmp_tables_created = {}
|
100
99
|
|
101
100
|
# subprogram_id column is available just from version 10g
|
102
|
-
subprogram_id_column = (@schema.connection.database_version <=> [10, 2, 0, 2]) >= 0 ?
|
101
|
+
subprogram_id_column = (@schema.connection.database_version <=> [10, 2, 0, 2]) >= 0 ? "subprogram_id" : "NULL"
|
103
102
|
# defaulted is available just from version 11g
|
104
|
-
defaulted_column = (@schema.connection.database_version <=> [11, 0, 0, 0]) >= 0 ?
|
103
|
+
defaulted_column = (@schema.connection.database_version <=> [11, 0, 0, 0]) >= 0 ? "defaulted" : "NULL"
|
105
104
|
|
106
105
|
@schema.select_all(
|
107
106
|
"SELECT #{subprogram_id_column}, object_name, TO_NUMBER(overload), argument_name, position, data_level,
|
@@ -138,7 +137,7 @@ module PLSQL
|
|
138
137
|
# then generate unique ID from object_name and overload
|
139
138
|
subprogram_id ||= "#{object_name.hash % 10000}#{overload}"
|
140
139
|
tmp_table_name = "#{Connection::RUBY_TEMP_TABLE_PREFIX}#{@schema.connection.session_id}_#{@object_id}_#{subprogram_id}_#{position}"
|
141
|
-
elsif data_type !=
|
140
|
+
elsif data_type != "PL/SQL RECORD"
|
142
141
|
# raise exception only when there are no overloaded procedure definitions
|
143
142
|
# (as probably this overload will not be used at all)
|
144
143
|
raise ArgumentError, "Parameter type #{sql_type_name} definition inside package is not supported, use CREATE TYPE outside package" if overload == 0
|
@@ -146,19 +145,19 @@ module PLSQL
|
|
146
145
|
end
|
147
146
|
|
148
147
|
argument_metadata = {
|
149
|
-
:
|
150
|
-
:
|
151
|
-
:
|
152
|
-
:
|
153
|
-
:
|
154
|
-
:
|
155
|
-
:
|
156
|
-
:
|
157
|
-
:
|
158
|
-
:
|
159
|
-
:
|
160
|
-
:
|
161
|
-
:
|
148
|
+
position: position && position.to_i,
|
149
|
+
data_type: data_type,
|
150
|
+
in_out: in_out,
|
151
|
+
data_length: data_length && data_length.to_i,
|
152
|
+
data_precision: data_precision && data_precision.to_i,
|
153
|
+
data_scale: data_scale && data_scale.to_i,
|
154
|
+
char_used: char_used,
|
155
|
+
char_length: char_length && char_length.to_i,
|
156
|
+
type_owner: type_owner,
|
157
|
+
type_name: type_name,
|
158
|
+
type_subname: type_subname,
|
159
|
+
sql_type_name: sql_type_name,
|
160
|
+
defaulted: defaulted
|
162
161
|
}
|
163
162
|
if tmp_table_name
|
164
163
|
@tmp_table_names[overload] << [(argument_metadata[:tmp_table_name] = tmp_table_name), argument_metadata]
|
@@ -166,14 +165,14 @@ module PLSQL
|
|
166
165
|
|
167
166
|
if composite_type?(data_type)
|
168
167
|
case data_type
|
169
|
-
when
|
168
|
+
when "PL/SQL RECORD"
|
170
169
|
argument_metadata[:fields] = {}
|
171
170
|
end
|
172
171
|
previous_level_argument_metadata[data_level] = argument_metadata
|
173
172
|
end
|
174
173
|
|
175
174
|
# if function has return value
|
176
|
-
if argument_name.nil? && data_level == 0 && in_out ==
|
175
|
+
if argument_name.nil? && data_level == 0 && in_out == "OUT"
|
177
176
|
@return[overload] = argument_metadata
|
178
177
|
# if parameter
|
179
178
|
else
|
@@ -184,9 +183,9 @@ module PLSQL
|
|
184
183
|
# or lower level part of composite type
|
185
184
|
else
|
186
185
|
case previous_level_argument_metadata[data_level - 1][:data_type]
|
187
|
-
when
|
186
|
+
when "PL/SQL RECORD"
|
188
187
|
previous_level_argument_metadata[data_level - 1][:fields][argument_name.downcase.to_sym] = argument_metadata
|
189
|
-
when
|
188
|
+
when "PL/SQL TABLE", "TABLE", "VARRAY", "REF CURSOR"
|
190
189
|
previous_level_argument_metadata[data_level - 1][:element] = argument_metadata
|
191
190
|
end
|
192
191
|
end
|
@@ -201,8 +200,8 @@ module PLSQL
|
|
201
200
|
def construct_argument_list_for_overloads #:nodoc:
|
202
201
|
@overloads = @arguments.keys.sort
|
203
202
|
@overloads.each do |overload|
|
204
|
-
@argument_list[overload] = @arguments[overload].keys.sort {|k1, k2| @arguments[overload][k1][:position] <=> @arguments[overload][k2][:position]}
|
205
|
-
@out_list[overload] = @argument_list[overload].select {|k| @arguments[overload][k][:in_out] =~ /OUT/}
|
203
|
+
@argument_list[overload] = @arguments[overload].keys.sort { |k1, k2| @arguments[overload][k1][:position] <=> @arguments[overload][k2][:position] }
|
204
|
+
@out_list[overload] = @argument_list[overload].select { |k| @arguments[overload][k][:in_out] =~ /OUT/ }
|
206
205
|
end
|
207
206
|
end
|
208
207
|
|
@@ -210,19 +209,19 @@ module PLSQL
|
|
210
209
|
return if @tmp_tables_created.nil? || @tmp_tables_created[overload]
|
211
210
|
@tmp_table_names[overload] && @tmp_table_names[overload].each do |table_name, argument_metadata|
|
212
211
|
sql = "CREATE GLOBAL TEMPORARY TABLE #{table_name} (\n"
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
212
|
+
element_metadata = argument_metadata[:element]
|
213
|
+
case element_metadata[:data_type]
|
214
|
+
when "PL/SQL RECORD"
|
215
|
+
fields_metadata = element_metadata[:fields]
|
216
|
+
fields_sorted_by_position = fields_metadata.keys.sort_by { |k| fields_metadata[k][:position] }
|
217
|
+
sql << fields_sorted_by_position.map do |field|
|
218
|
+
metadata = fields_metadata[field]
|
219
|
+
"#{field} #{ProcedureCommon.type_to_sql(metadata)}"
|
220
|
+
end.join(",\n")
|
221
|
+
else
|
222
|
+
sql << "element #{ProcedureCommon.type_to_sql(element_metadata)}"
|
223
|
+
end
|
224
|
+
sql << ",\ni__ NUMBER(38)\n"
|
226
225
|
sql << ") ON COMMIT PRESERVE ROWS\n"
|
227
226
|
sql_block = "DECLARE\nPRAGMA AUTONOMOUS_TRANSACTION;\nBEGIN\nEXECUTE IMMEDIATE :sql;\nEND;\n"
|
228
227
|
@schema.execute sql_block, sql
|
@@ -230,12 +229,12 @@ module PLSQL
|
|
230
229
|
@tmp_tables_created[overload] = true
|
231
230
|
end
|
232
231
|
|
233
|
-
PLSQL_COMPOSITE_TYPES = [
|
232
|
+
PLSQL_COMPOSITE_TYPES = ["PL/SQL RECORD", "PL/SQL TABLE", "TABLE", "VARRAY", "REF CURSOR"].freeze
|
234
233
|
def composite_type?(data_type) #:nodoc:
|
235
234
|
PLSQL_COMPOSITE_TYPES.include? data_type
|
236
235
|
end
|
237
236
|
|
238
|
-
PLSQL_COLLECTION_TYPES = [
|
237
|
+
PLSQL_COLLECTION_TYPES = ["PL/SQL TABLE", "TABLE", "VARRAY"].freeze
|
239
238
|
def collection_type?(data_type) #:nodoc:
|
240
239
|
PLSQL_COLLECTION_TYPES.include? data_type
|
241
240
|
end
|
@@ -266,7 +265,5 @@ module PLSQL
|
|
266
265
|
call = ProcedureCall.new(self, args)
|
267
266
|
call.exec(&block)
|
268
267
|
end
|
269
|
-
|
270
268
|
end
|
271
|
-
|
272
269
|
end
|