Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9fccd1d

Browse files
committed
Wrapping up anydata into cursor
1 parent 7676a9a commit 9fccd1d

12 files changed

Lines changed: 96 additions & 101 deletions

source/api/ut.pkb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ create or replace package body ut is
2828
return ut_runner.version();
2929
end;
3030

31-
function expect(a_actual in anydata, a_message varchar2 := null) return ut_expectation_compound is
31+
function expect(a_actual in anydata, a_message varchar2 := null) return ut_expectation_refcursor is
3232
begin
33-
return ut_expectation_compound(ut_data_value_anydata.get_instance(a_actual), a_message);
33+
return ut_expectation_refcursor(ut_data_value_anydata(a_actual), a_message);
3434
end;
3535

3636
function expect(a_actual in blob, a_message varchar2 := null) return ut_expectation is

source/api/ut.pks

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ create or replace package ut authid current_user as
1919

2020
function version return varchar2;
2121

22-
function expect(a_actual in anydata, a_message varchar2 := null) return ut_expectation_compound;
22+
function expect(a_actual in anydata, a_message varchar2 := null) return ut_expectation_refcursor;
2323

2424
function expect(a_actual in blob, a_message varchar2 := null) return ut_expectation;
2525

source/expectations/data_values/ut_cursor_details.tpb

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,10 @@ create or replace type body ut_cursor_details as
2323
l_element_info ut_metadata.t_anytype_elem_info_rec;
2424
l_is_collection boolean;
2525
begin
26-
2726
l_elements_info := ut_metadata.get_anytype_members_info( a_compound_data );
28-
2927
l_is_collection := ut_metadata.is_collection(l_elements_info.type_code);
30-
3128
if l_elements_info.elements_count is null then
32-
3329
l_element_info := ut_metadata.get_attr_elem_info( a_compound_data );
34-
3530
self.cursor_columns_info.extend;
3631
self.cursor_columns_info(cursor_columns_info.last) :=
3732
ut_cursor_column(
@@ -98,7 +93,7 @@ create or replace type body ut_cursor_details as
9893
begin
9994
self.cursor_columns_info := ut_cursor_column_tab();
10095
dbms_sql.describe_columns3(a_cursor_number, l_columns_count, l_columns_desc);
101-
96+
10297
/**
10398
* Due to a bug with object being part of cursor in ANYDATA scenario
10499
* oracle fails to revert number to cursor. We ar using dbms_sql.close cursor to close it
@@ -121,6 +116,7 @@ create or replace type body ut_cursor_details as
121116
ut_utils.boolean_to_int(l_is_collection),
122117
null
123118
);
119+
124120
if l_columns_desc(pos).col_type = dbms_sql.user_defined_type or l_is_collection then
125121
desc_compound_data(
126122
ut_metadata.get_user_defined_type( l_columns_desc(pos).col_schema_name, l_columns_desc(pos).col_type_name ),
@@ -177,7 +173,7 @@ create or replace type body ut_cursor_details as
177173
bulk collect into l_result.cursor_columns_info
178174
from table(self.cursor_columns_info) x
179175
where exists(
180-
select 1 from included_columns f where regexp_like( x.access_path, '^'||f.col_names||'($|/.*)' )
176+
select 1 from included_columns f where regexp_like( x.access_path, '^/?'||f.col_names||'($|/.*)' )
181177
);
182178
end if;
183179
elsif a_match_options.exclude.items.count > 0 then
@@ -189,7 +185,7 @@ create or replace type body ut_cursor_details as
189185
bulk collect into l_result.cursor_columns_info
190186
from table(self.cursor_columns_info) x
191187
where not exists(
192-
select 1 from excluded_columns f where regexp_like( x.access_path, '^'||f.col_names||'($|/.*)' )
188+
select 1 from excluded_columns f where regexp_like( '/'||x.access_path, '^/?'||f.col_names||'($|/.*)' )
193189
);
194190
end if;
195191
self := l_result;

source/expectations/data_values/ut_data_value_anydata.tpb

Lines changed: 58 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,58 +16,70 @@ create or replace type body ut_data_value_anydata as
1616
limitations under the License.
1717
*/
1818

19-
final member procedure init(self in out nocopy ut_data_value_anydata, a_value anydata, a_data_object_type varchar2, a_extract_path varchar2) is
19+
member procedure init(self in out nocopy ut_data_value_anydata, a_value anydata) is
2020
l_query sys_refcursor;
2121
l_ctx number;
2222
l_ut_owner varchar2(250) := ut_utils.ut_owner;
23+
cursor_not_open exception;
24+
l_cursor_number number;
25+
l_type_name varchar2(100);
26+
l_schema varchar(100);
27+
l_part1 varchar(30);
28+
l_part2 varchar(30);
29+
l_dblink varchar(30);
30+
l_part1_type number;
31+
l_objectid number;
2332
begin
24-
self.data_type := case when a_value is not null then lower(a_value.gettypename) else 'undefined' end;
33+
self.data_type := case when a_value is not null then lower(a_value.gettypename()) else 'undefined' end;
34+
--TODO : Move that to helper ??
2535
self.data_id := sys_guid();
36+
self.self_type := $$plsql_unit;
37+
self.cursor_details := ut_cursor_details();
2638
if a_value is not null then
39+
dbms_utility.name_resolve(self.data_type,7, l_schema, l_part1, l_part2, l_dblink, l_part1_type, l_objectid);
2740
execute immediate '
2841
declare
2942
l_data '||self.data_type||';
3043
l_value anydata := :a_value;
3144
l_status integer;
45+
l_tmp_refcursor sys_refcursor;
46+
l_refcursor sys_refcursor;
3247
begin
33-
l_status := l_value.get'||a_data_object_type||'(l_data);
48+
l_status := l_value.get'||get_instance(a_value)||'(l_data);
3449
:l_data_is_null := case when l_data is null then 1 else 0 end;
35-
end;' using in a_value, out self.is_data_null;
50+
open l_tmp_refcursor for select l_data '||l_part1||' from dual;
51+
:l_refcursor := l_tmp_refcursor;
52+
end;' using in a_value, out self.is_data_null, out l_query;
53+
3654
else
3755
self.is_data_null := 1;
3856
end if;
39-
4057
ut_compound_data_helper.cleanup_diff;
4158
if not self.is_null() then
42-
ut_expectation_processor.set_xml_nls_params();
43-
open l_query for select a_value val from dual;
44-
l_ctx := sys.dbms_xmlgen.newcontext( l_query );
45-
dbms_xmlgen.setrowtag(l_ctx, '');
46-
dbms_xmlgen.setrowsettag(l_ctx, '');
47-
dbms_xmlgen.setnullhandling(l_ctx,2);
48-
execute immediate
49-
'insert into ' || l_ut_owner || '.ut_compound_data_tmp(data_id, item_no, item_data) ' ||
50-
'select :self_guid, rownum, value(a) ' ||
51-
' from table( xmlsequence( extract(:l_xml, :xpath ) ) ) a'
52-
using in self.data_id, dbms_xmlgen.getXMLtype(l_ctx), a_extract_path;
53-
self.elements_count := sql%rowcount;
54-
dbms_xmlgen.closecontext (l_ctx);
55-
ut_expectation_processor.reset_nls_params();
59+
self.elements_count := 0;
60+
if l_query%isopen then
61+
self.extract_cursor(l_query);
62+
l_cursor_number := dbms_sql.to_cursor_number(l_query);
63+
self.cursor_details := ut_cursor_details(l_cursor_number);
64+
dbms_sql.close_cursor(l_cursor_number);
65+
elsif not l_query%isopen then
66+
raise cursor_not_open;
67+
end if;
5668
end if;
5769
end;
5870

59-
static function get_instance(a_data_value anydata) return ut_data_value_anydata is
60-
l_result ut_data_value_anydata := ut_data_value_object(null);
71+
member function get_instance(a_data_value anydata) return varchar2 is
72+
l_result varchar2(30);
6173
l_type anytype;
6274
l_type_code integer;
6375
begin
6476
if a_data_value is not null then
6577
l_type_code := a_data_value.gettype(l_type);
6678
if l_type_code in (dbms_types.typecode_table, dbms_types.typecode_varray, dbms_types.typecode_namedcollection, dbms_types.typecode_object) then
6779
if l_type_code = dbms_types.typecode_object then
68-
l_result := ut_data_value_object(a_data_value);
80+
l_result := 'object';
6981
else
70-
l_result := ut_data_value_collection(a_data_value);
82+
l_result := 'collection';
7183
end if;
7284
else
7385
raise_application_error(-20000, 'Data type '||a_data_value.gettypename||' in ANYDATA is not supported by utPLSQL');
@@ -76,5 +88,28 @@ create or replace type body ut_data_value_anydata as
7688
return l_result;
7789
end;
7890

91+
constructor function ut_data_value_anydata(self in out nocopy ut_data_value_anydata, a_value anydata) return self as result
92+
is
93+
begin
94+
init(a_value);
95+
return;
96+
end;
97+
98+
overriding member function compare_implementation(
99+
a_other ut_data_value,
100+
a_match_options ut_matcher_options,
101+
a_inclusion_compare boolean := false,
102+
a_is_negated boolean := false
103+
) return integer is
104+
l_result integer := 0;
105+
begin
106+
if not a_other is of (ut_data_value_anydata) then
107+
raise value_error;
108+
end if;
109+
110+
l_result := l_result + (self as ut_data_value_refcursor).compare_implementation(a_other,a_match_options,a_inclusion_compare,a_is_negated);
111+
return l_result;
112+
end;
113+
79114
end;
80115
/

source/expectations/data_values/ut_data_value_anydata.tps

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
create or replace type ut_data_value_anydata under ut_compound_data_value(
1+
create or replace type ut_data_value_anydata under ut_data_value_refcursor(
22
/*
33
utPLSQL - Version 3
44
Copyright 2016 - 2018 utPLSQL Project
@@ -16,7 +16,15 @@ create or replace type ut_data_value_anydata under ut_compound_data_value(
1616
limitations under the License.
1717
*/
1818

19-
final member procedure init(self in out nocopy ut_data_value_anydata, a_value anydata, a_data_object_type varchar2, a_extract_path varchar2),
20-
static function get_instance(a_data_value anydata) return ut_data_value_anydata
21-
) not final not instantiable
19+
20+
member procedure init(self in out nocopy ut_data_value_anydata, a_value anydata),
21+
member function get_instance(a_data_value anydata) return varchar2,
22+
constructor function ut_data_value_anydata(self in out nocopy ut_data_value_anydata, a_value anydata) return self as result,
23+
overriding member function compare_implementation(
24+
a_other ut_data_value,
25+
a_match_options ut_matcher_options,
26+
a_inclusion_compare boolean := false,
27+
a_is_negated boolean := false
28+
) return integer
29+
)
2230
/

source/expectations/data_values/ut_data_value_refcursor.tpb

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ create or replace type body ut_data_value_refcursor as
5050
loop
5151
l_xml := dbms_xmlgen.getxmltype(l_ctx);
5252
exit when dbms_xmlgen.getNumRowsProcessed(l_ctx) = 0;
53-
5453
self.elements_count := self.elements_count + dbms_xmlgen.getNumRowsProcessed(l_ctx);
5554
execute immediate
5655
'insert into ' || l_ut_owner || '.ut_compound_data_tmp(data_id, item_no, item_data) ' ||
@@ -345,7 +344,6 @@ create or replace type body ut_data_value_refcursor as
345344
a_inclusion_compare,
346345
a_is_negated
347346
);
348-
-- dbms_output.put_line(substr(l_diff_cursor_text,1,32767));
349347
l_result := l_result + compare_data( l_self, l_other, l_diff_cursor_text );
350348
end if;
351349
return l_result;

source/expectations/data_values/ut_data_value_refcursor.tps

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,5 @@ create or replace type ut_data_value_refcursor under ut_compound_data_value(
4242
a_is_negated boolean := false
4343
) return integer,
4444
overriding member function is_empty return boolean
45-
)
46-
/
45+
) not final
46+
/

source/expectations/matchers/ut_equal.tpb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ create or replace type body ut_equal as
3131

3232
constructor function ut_equal(self in out nocopy ut_equal, a_expected anydata, a_nulls_are_equal boolean := null) return self as result is
3333
begin
34-
init(ut_data_value_anydata.get_instance(a_expected), a_nulls_are_equal);
34+
init(ut_data_value_anydata(a_expected), a_nulls_are_equal);
3535
return;
3636
end;
3737

@@ -42,7 +42,7 @@ create or replace type body ut_equal as
4242
'equal( a_expected anydata, a_exclude varchar2 )',
4343
'equal( a_expected anydata ).exclude( a_exclude varchar2 )'
4444
);
45-
init(ut_data_value_anydata.get_instance(a_expected), a_nulls_are_equal);
45+
init(ut_data_value_anydata(a_expected), a_nulls_are_equal);
4646
self.options.exclude.add_items(a_exclude);
4747
return;
4848
end;
@@ -53,7 +53,7 @@ create or replace type body ut_equal as
5353
'equal( a_expected anydata, a_exclude ut_varchar2_list )',
5454
'equal( a_expected anydata ).exclude( a_exclude ut_varchar2_list )'
5555
);
56-
init(ut_data_value_anydata.get_instance(a_expected), a_nulls_are_equal);
56+
init(ut_data_value_anydata(a_expected), a_nulls_are_equal);
5757
self.options.exclude.add_items(a_exclude);
5858
return;
5959
end;

source/expectations/matchers/ut_have_count.tpb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ create or replace type body ut_have_count as
2626
overriding member function run_matcher(self in out nocopy ut_have_count, a_actual ut_data_value) return boolean is
2727
l_result boolean;
2828
begin
29-
if a_actual is of(ut_data_value_refcursor, ut_data_value_collection) then
29+
if a_actual is of(ut_data_value_refcursor) then
3030
l_result := ( self.expected = treat(a_actual as ut_compound_data_value).elements_count );
3131
else
3232
l_result := (self as ut_matcher).run_matcher(a_actual);

source/install.sql

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -186,16 +186,14 @@ prompt Installing DBMSPLSQL Tables objects into &&ut3_owner schema
186186
@@install_component.sql 'expectations/matchers/ut_matcher_options.tps'
187187
@@install_component.sql 'expectations/data_values/ut_data_value.tps'
188188
@@install_component.sql 'expectations/data_values/ut_compound_data_value.tps'
189-
@@install_component.sql 'expectations/data_values/ut_data_value_anydata.tps'
190-
@@install_component.sql 'expectations/data_values/ut_data_value_collection.tps'
191-
@@install_component.sql 'expectations/data_values/ut_data_value_object.tps'
192189
@@install_component.sql 'expectations/data_values/ut_data_value_blob.tps'
193190
@@install_component.sql 'expectations/data_values/ut_data_value_boolean.tps'
194191
@@install_component.sql 'expectations/data_values/ut_data_value_clob.tps'
195192
@@install_component.sql 'expectations/data_values/ut_data_value_date.tps'
196193
@@install_component.sql 'expectations/data_values/ut_data_value_dsinterval.tps'
197194
@@install_component.sql 'expectations/data_values/ut_data_value_number.tps'
198195
@@install_component.sql 'expectations/data_values/ut_data_value_refcursor.tps'
196+
@@install_component.sql 'expectations/data_values/ut_data_value_anydata.tps'
199197
@@install_component.sql 'expectations/data_values/ut_data_value_timestamp.tps'
200198
@@install_component.sql 'expectations/data_values/ut_data_value_timestamp_tz.tps'
201199
@@install_component.sql 'expectations/data_values/ut_data_value_timestamp_ltz.tps'
@@ -233,16 +231,14 @@ prompt Installing DBMSPLSQL Tables objects into &&ut3_owner schema
233231
@@install_component.sql 'expectations/data_values/ut_data_value.tpb'
234232
@@install_component.sql 'expectations/data_values/ut_compound_data_value.tpb'
235233
@@install_component.sql 'expectations/data_values/ut_compound_data_helper.pkb'
236-
@@install_component.sql 'expectations/data_values/ut_data_value_anydata.tpb'
237-
@@install_component.sql 'expectations/data_values/ut_data_value_object.tpb'
238-
@@install_component.sql 'expectations/data_values/ut_data_value_collection.tpb'
239234
@@install_component.sql 'expectations/data_values/ut_data_value_blob.tpb'
240235
@@install_component.sql 'expectations/data_values/ut_data_value_boolean.tpb'
241236
@@install_component.sql 'expectations/data_values/ut_data_value_clob.tpb'
242237
@@install_component.sql 'expectations/data_values/ut_data_value_date.tpb'
243238
@@install_component.sql 'expectations/data_values/ut_data_value_dsinterval.tpb'
244239
@@install_component.sql 'expectations/data_values/ut_data_value_number.tpb'
245240
@@install_component.sql 'expectations/data_values/ut_data_value_refcursor.tpb'
241+
@@install_component.sql 'expectations/data_values/ut_data_value_anydata.tpb'
246242
@@install_component.sql 'expectations/data_values/ut_data_value_timestamp.tpb'
247243
@@install_component.sql 'expectations/data_values/ut_data_value_timestamp_tz.tpb'
248244
@@install_component.sql 'expectations/data_values/ut_data_value_timestamp_ltz.tpb'

0 commit comments

Comments
 (0)