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

Skip to content

Commit 7837eb4

Browse files
committed
Anydata refactoring.
1 parent 1c0582b commit 7837eb4

7 files changed

Lines changed: 96 additions & 93 deletions

File tree

source/expectations/data_values/ut_compound_data_helper.pkb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,7 @@ create or replace package body ut_compound_data_helper is
623623
l_sql varchar2(32767) := get_cursor_vs_list_sql;
624624
l_result ut_cursor_column_tab := ut_cursor_column_tab();
625625
begin
626-
l_sql := l_sql || q'[select ut_cursor_column(i.column_name,i.column_schema,i.column_type_name, i.column_prec,i.column_scale,i.column_len, i.parent_name,
626+
l_sql := l_sql || q'[select ut_cursor_column(i.column_name,i.column_schema,i.column_type_name,i.column_len, i.parent_name,
627627
i.hierarchy_level,i.column_position, i.column_type, i.is_collection)
628628
from t1 join table(:a_cursor_info) i on ( nvl(t1.parent_name,1) = nvl(i.parent_name,1) and t1.column_name = i.column_name)]';
629629
if a_include then
@@ -735,7 +735,7 @@ create or replace package body ut_compound_data_helper is
735735
function remove_incomparable_cols( a_cursor_details ut_cursor_column_tab,a_incomparable_cols ut_varchar2_list) return ut_cursor_column_tab is
736736
l_result ut_cursor_column_tab;
737737
begin
738-
select ut_cursor_column(i.column_name,i.column_schema,i.column_type_name, i.column_prec,i.column_scale,i.column_len, i.parent_name,
738+
select ut_cursor_column(i.column_name,i.column_schema,i.column_type_name,i.column_len, i.parent_name,
739739
i.hierarchy_level,i.column_position, i.column_type, i.is_collection)
740740
bulk collect into l_result
741741
from table(a_cursor_details) i

source/expectations/data_values/ut_cursor_column.tpb

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,13 @@ create or replace type body ut_cursor_column as
22

33
member procedure init(self in out nocopy ut_cursor_column,
44
a_col_name varchar2, a_col_schema_name varchar2,
5-
a_col_type_name varchar2, a_col_prec integer, a_col_scale integer,
6-
a_col_max_len integer, a_parent_name varchar2 := null, a_hierarchy_level integer := 1,
5+
a_col_type_name varchar2, a_col_max_len integer, a_parent_name varchar2 := null, a_hierarchy_level integer := 1,
76
a_col_position integer, a_col_type varchar2, a_collection integer) is
87
begin
98
self.parent_name := a_parent_name;
109
self.hierarchy_level := a_hierarchy_level;
1110
self.column_position := a_col_position;
12-
self.column_prec := a_col_prec;
1311
self.column_len := a_col_max_len;
14-
self.column_scale := a_col_scale;
1512
self.column_name := TRIM( BOTH '''' FROM a_col_name);
1613
self.column_type_name := a_col_type_name;
1714
self.access_path := case when self.parent_name is null then self.column_name else self.parent_name||'/'||self.column_name end;
@@ -41,12 +38,10 @@ create or replace type body ut_cursor_column as
4138

4239
constructor function ut_cursor_column( self in out nocopy ut_cursor_column,
4340
a_col_name varchar2, a_col_schema_name varchar2,
44-
a_col_type_name varchar2, a_col_prec integer, a_col_scale integer,
45-
a_col_max_len integer, a_parent_name varchar2 := null, a_hierarchy_level integer := 1,
41+
a_col_type_name varchar2, a_col_max_len integer, a_parent_name varchar2 := null, a_hierarchy_level integer := 1,
4642
a_col_position integer, a_col_type in varchar2, a_collection integer) return self as result is
4743
begin
48-
init(a_col_name, a_col_schema_name, a_col_type_name, a_col_prec,
49-
a_col_scale, a_col_max_len, a_parent_name,a_hierarchy_level, a_col_position, a_col_type, a_collection);
44+
init(a_col_name, a_col_schema_name, a_col_type_name, a_col_max_len, a_parent_name,a_hierarchy_level, a_col_position, a_col_type, a_collection);
5045
return;
5146
end;
5247
end;

source/expectations/data_values/ut_cursor_column.tps

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,18 @@ create or replace type ut_cursor_column force authid current_user as object
1111
column_type varchar2(100),
1212
column_type_name varchar2(100),
1313
column_schema varchar2(100),
14-
column_prec integer,
1514
column_len integer,
16-
column_scale integer,
1715
is_sql_diffable number(1, 0),
1816
is_collection number(1, 0),
1917

2018
member procedure init(self in out nocopy ut_cursor_column,
2119
a_col_name varchar2, a_col_schema_name varchar2,
22-
a_col_type_name varchar2, a_col_prec integer, a_col_scale integer,
23-
a_col_max_len integer, a_parent_name varchar2 := null, a_hierarchy_level integer := 1,
20+
a_col_type_name varchar2, a_col_max_len integer, a_parent_name varchar2 := null, a_hierarchy_level integer := 1,
2421
a_col_position integer, a_col_type in varchar2, a_collection integer),
2522

2623
constructor function ut_cursor_column( self in out nocopy ut_cursor_column,
2724
a_col_name varchar2, a_col_schema_name varchar2,
28-
a_col_type_name varchar2, a_col_prec integer, a_col_scale integer,
29-
a_col_max_len integer, a_parent_name varchar2 := null, a_hierarchy_level integer := 1,
25+
a_col_type_name varchar2, a_col_max_len integer, a_parent_name varchar2 := null, a_hierarchy_level integer := 1,
3026
a_col_position integer, a_col_type in varchar2, a_collection integer)
3127
return self as result
3228
)

source/expectations/data_values/ut_cursor_details.tpb

Lines changed: 39 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -13,31 +13,45 @@ create or replace type body ut_cursor_details as
1313

1414
return l_diffs;
1515
end;
16-
17-
member function get_anytype_attribute_count(a_anytype anytype) return pls_integer is
18-
l_attribute_typecode pls_integer;
19-
l_schema_name varchar2(32767);
16+
17+
member procedure get_anytype_members_info(a_anytype anytype, a_attribute_typecode out pls_integer,
18+
a_schema_name out varchar2, a_type_name out varchar2, a_len out pls_integer,a_elements_count out pls_integer) is
2019
l_version varchar2(32767);
21-
l_type_name varchar2(32767);
22-
l_attributes pls_integer;
2320
l_prec pls_integer;
2421
l_scale pls_integer;
25-
l_len pls_integer;
2622
l_csid pls_integer;
2723
l_csfrm pls_integer;
2824
begin
29-
l_attribute_typecode := a_anytype.getinfo(prec => l_prec,
25+
a_attribute_typecode := a_anytype.getinfo(prec => l_prec,
3026
scale => l_scale,
31-
len => l_len,
27+
len => a_len,
3228
csid => l_csid,
3329
csfrm => l_csfrm,
34-
schema_name => l_schema_name,
35-
type_name => l_type_name,
30+
schema_name => a_schema_name,
31+
type_name => a_type_name,
3632
version => l_version,
37-
numelems => l_attributes);
38-
return l_attributes;
33+
numelems => a_elements_count);
3934
end;
4035

36+
member procedure getattreleminfo(a_anytype anytype,a_pos pls_integer, a_attribute_typecode out pls_integer,
37+
a_type_name out varchar2, a_len out pls_integer) is
38+
l_version varchar2(32767);
39+
l_prec pls_integer;
40+
l_scale pls_integer;
41+
l_csid pls_integer;
42+
l_csfrm pls_integer;
43+
l_attr_elt_type anytype;
44+
begin
45+
a_attribute_typecode := a_anytype.getattreleminfo(pos => a_pos, --First attribute
46+
prec => l_prec,
47+
scale => l_scale,
48+
len => a_len,
49+
csid => l_csid,
50+
csfrm => l_csfrm,
51+
attr_elt_type => l_attr_elt_type,
52+
aname => a_type_name);
53+
end;
54+
4155
member function get_user_defined_type(a_owner varchar2, a_type_name varchar2)
4256
return anytype is
4357
l_anydata anydata;
@@ -65,14 +79,12 @@ create or replace type body ut_cursor_details as
6579
l_columns_desc dbms_sql.desc_tab3;
6680
l_attribute_typecode pls_integer;
6781
l_aname varchar2(32767);
68-
l_prec pls_integer;
69-
l_scale pls_integer;
7082
l_len pls_integer;
71-
l_csid pls_integer;
72-
l_csfrm pls_integer;
73-
l_attr_elt_type anytype;
7483
l_anytype anytype;
7584
l_is_collection boolean;
85+
l_elements_count pls_integer;
86+
l_schema_name varchar2(100);
87+
l_type_name varchar2(100);
7688
begin
7789
self.cursor_info := ut_cursor_column_tab();
7890
l_cursor_number := dbms_sql.to_cursor_number(a_cursor);
@@ -87,34 +99,26 @@ create or replace type body ut_cursor_details as
8799
self.cursor_info(cursor_info.last) := ut_cursor_column( l_columns_desc(cur).col_name,
88100
l_columns_desc(cur).col_schema_name,
89101
l_columns_desc(cur).col_type_name,
90-
l_columns_desc(cur).col_precision,
91-
l_columns_desc(cur).col_scale,
92102
l_columns_desc(cur).col_max_len,
93103
null,
94104
1,
95105
cur,
96106
ut_compound_data_helper.get_column_type_desc(l_columns_desc(cur).col_type,true),
97107
ut_utils.boolean_to_int(l_is_collection)
98108
);
109+
99110
if l_columns_desc(cur).col_type = dbms_sql.user_defined_type and not l_is_collection then
100111
l_anytype := get_user_defined_type(l_columns_desc(cur).col_schema_name , l_columns_desc(cur).col_type_name );
101-
for i in 1 .. get_anytype_attribute_count(l_anytype) loop
102-
l_attribute_typecode := l_anytype.getattreleminfo(pos => i, --First attribute
103-
prec => l_prec,
104-
scale => l_scale,
105-
len => l_len,
106-
csid => l_csid,
107-
csfrm => l_csfrm,
108-
attr_elt_type => l_attr_elt_type,
109-
aname => l_aname);
110-
111-
l_is_collection := ut_compound_data_helper.is_collection(l_columns_desc(cur).col_schema_name,l_columns_desc(cur).col_type_name,l_attribute_typecode);
112-
self.cursor_info.extend;
113-
self.cursor_info(cursor_info.last) := ut_cursor_column( l_aname,
112+
113+
get_anytype_members_info(l_anytype,l_attribute_typecode,l_schema_name,l_type_name,l_len,l_elements_count);
114+
115+
for i in 1 .. l_elements_count loop
116+
getattreleminfo(l_anytype,i,l_attribute_typecode,l_aname,l_len);
117+
l_is_collection := ut_compound_data_helper.is_collection(l_columns_desc(cur).col_schema_name,l_columns_desc(cur).col_type_name,l_attribute_typecode);
118+
self.cursor_info.extend;
119+
self.cursor_info(cursor_info.last) := ut_cursor_column( l_aname,
114120
l_columns_desc(cur).col_schema_name,
115121
null,
116-
l_prec,
117-
l_scale,
118122
l_len,
119123
l_columns_desc(cur).col_name,
120124
2,

source/expectations/data_values/ut_cursor_details.tps

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ create or replace type ut_cursor_details force authid current_user as object
22
(
33
cursor_info ut_cursor_column_tab,
44
order member function compare(a_other ut_cursor_details) return integer,
5-
member function get_anytype_attribute_count(a_anytype anytype) return pls_integer,
5+
member procedure get_anytype_members_info(a_anytype anytype, a_attribute_typecode out pls_integer,
6+
a_schema_name out varchar2, a_type_name out varchar2, a_len out pls_integer,a_elements_count out pls_integer),
7+
member procedure getattreleminfo(a_anytype anytype,a_pos pls_integer, a_attribute_typecode out pls_integer,
8+
a_type_name out varchar2, a_len out pls_integer),
69
member function get_user_defined_type(a_owner varchar2, a_type_name varchar2) return anytype,
710
constructor function ut_cursor_details(self in out nocopy ut_cursor_details,a_cursor in out nocopy sys_refcursor)
811
return self as result

source/expectations/data_values/ut_data_value_refcursor.tpb

Lines changed: 45 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,55 @@ create or replace type body ut_data_value_refcursor as
2222
return;
2323
end;
2424

25-
member procedure init(self in out nocopy ut_data_value_refcursor, a_value sys_refcursor) is
25+
member procedure extract_cursor(self in out nocopy ut_data_value_refcursor, a_value sys_refcursor) is
2626
c_bulk_rows constant integer := 10000;
2727
l_cursor sys_refcursor := a_value;
2828
l_ctx number;
2929
l_xml xmltype;
30-
l_current_date_format varchar2(4000);
31-
cursor_not_open exception;
3230
l_ut_owner varchar2(250) := ut_utils.ut_owner;
3331
l_set_id integer := 0;
32+
begin
33+
-- We use DBMS_XMLGEN in order to:
34+
-- 1) be able to process data in bulks (set of rows)
35+
-- 2) be able to influence the ROWSET/ROW tags
36+
-- 3) be able to influence the way NULL values are handled (empty TAG)
37+
-- 4) be able to influence the way TIMESTAMP is formatted.
38+
-- Due to Oracle feature/bug, it is not possible to change the DATE formatting of cursor data
39+
-- AFTER the cursor was opened.
40+
-- The only solution for this is to change NLS settings before opening the cursor.
41+
--
42+
-- This would work fine if we could use DBMS_XMLGEN.restartQuery.
43+
-- The restartQuery fails however if PLSQL variables of TIMESTAMP/INTERVAL or CLOB/BLOB are used.
44+
ut_expectation_processor.set_xml_nls_params();
45+
l_ctx := dbms_xmlgen.newContext(l_cursor);
46+
dbms_xmlgen.setNullHandling(l_ctx, dbms_xmlgen.empty_tag);
47+
dbms_xmlgen.setMaxRows(l_ctx, c_bulk_rows);
48+
49+
loop
50+
l_xml := dbms_xmlgen.getxmltype(l_ctx);
51+
exit when dbms_xmlgen.getNumRowsProcessed(l_ctx) = 0;
52+
53+
self.elements_count := self.elements_count + dbms_xmlgen.getNumRowsProcessed(l_ctx);
54+
execute immediate
55+
'insert into ' || l_ut_owner || '.ut_compound_data_tmp(data_id, item_no, item_data) ' ||
56+
'values (:self_guid, :self_row_count, :l_xml)'
57+
using in self.data_id, l_set_id, l_xml;
58+
59+
l_set_id := l_set_id + c_bulk_rows;
60+
end loop;
61+
62+
ut_expectation_processor.reset_nls_params();
63+
dbms_xmlgen.closeContext(l_ctx);
64+
exception
65+
when others then
66+
ut_expectation_processor.reset_nls_params();
67+
dbms_xmlgen.closeContext(l_ctx);
68+
raise;
69+
end;
3470

71+
member procedure init(self in out nocopy ut_data_value_refcursor, a_value sys_refcursor) is
72+
l_cursor sys_refcursor := a_value;
73+
cursor_not_open exception;
3574
begin
3675
self.is_data_null := ut_utils.boolean_to_int(a_value is null);
3776
self.self_type := $$plsql_unit;
@@ -41,46 +80,13 @@ create or replace type body ut_data_value_refcursor as
4180

4281
if l_cursor is not null then
4382
if l_cursor%isopen then
44-
--Get some more info regarding cursor, including if it containts collection columns and what is their name
45-
83+
--Get some more info regarding cursor, including if it containts collection columns and what is their name
4684
self.elements_count := 0;
4785
self.cursor_details := ut_cursor_details(l_cursor);
48-
-- We use DBMS_XMLGEN in order to:
49-
-- 1) be able to process data in bulks (set of rows)
50-
-- 2) be able to influence the ROWSET/ROW tags
51-
-- 3) be able to influence the way NULL values are handled (empty TAG)
52-
-- 4) be able to influence the way TIMESTAMP is formatted.
53-
-- Due to Oracle feature/bug, it is not possible to change the DATE formatting of cursor data
54-
-- AFTER the cursor was opened.
55-
-- The only solution for this is to change NLS settings before opening the cursor.
56-
--
57-
-- This would work fine if we could use DBMS_XMLGEN.restartQuery.
58-
-- The restartQuery fails however if PLSQL variables of TIMESTAMP/INTERVAL or CLOB/BLOB are used.
59-
60-
ut_expectation_processor.set_xml_nls_params();
61-
l_ctx := dbms_xmlgen.newContext(l_cursor);
62-
dbms_xmlgen.setNullHandling(l_ctx, dbms_xmlgen.empty_tag);
63-
dbms_xmlgen.setMaxRows(l_ctx, c_bulk_rows);
64-
65-
loop
66-
l_xml := dbms_xmlgen.getxmltype(l_ctx);
67-
exit when dbms_xmlgen.getNumRowsProcessed(l_ctx) = 0;
68-
69-
self.elements_count := self.elements_count + dbms_xmlgen.getNumRowsProcessed(l_ctx);
70-
execute immediate
71-
'insert into ' || l_ut_owner || '.ut_compound_data_tmp(data_id, item_no, item_data) ' ||
72-
'values (:self_guid, :self_row_count, :l_xml)'
73-
using in self.data_id, l_set_id, l_xml;
74-
75-
l_set_id := l_set_id + c_bulk_rows;
76-
end loop;
77-
78-
ut_expectation_processor.reset_nls_params();
86+
extract_cursor(l_cursor);
7987
if l_cursor%isopen then
8088
close l_cursor;
81-
end if;
82-
dbms_xmlgen.closeContext(l_ctx);
83-
89+
end if;
8490
elsif not l_cursor%isopen then
8591
raise cursor_not_open;
8692
end if;
@@ -89,11 +95,9 @@ create or replace type body ut_data_value_refcursor as
8995
when cursor_not_open then
9096
raise_application_error(-20155, 'Cursor is not open');
9197
when others then
92-
ut_expectation_processor.reset_nls_params();
9398
if l_cursor%isopen then
9499
close l_cursor;
95100
end if;
96-
dbms_xmlgen.closeContext(l_ctx);
97101
raise;
98102
end;
99103

source/expectations/data_values/ut_data_value_refcursor.tps

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ create or replace type ut_data_value_refcursor under ut_compound_data_value(
3131
cursor_details ut_cursor_details,
3232

3333
constructor function ut_data_value_refcursor(self in out nocopy ut_data_value_refcursor, a_value sys_refcursor) return self as result,
34+
member procedure extract_cursor(self in out nocopy ut_data_value_refcursor, a_value sys_refcursor),
3435
member procedure init(self in out nocopy ut_data_value_refcursor, a_value sys_refcursor),
3536
overriding member function to_string return varchar2,
3637
member function diff( a_other ut_data_value, a_unordered boolean := false, a_join_by_list ut_varchar2_list:=ut_varchar2_list() ) return varchar2,

0 commit comments

Comments
 (0)