@@ -17,12 +17,118 @@ create or replace package body ut_coverage is
1717 */
1818
1919 g_skipped_objects ut_object_names;
20+ g_schema_names ut_varchar2_list;
21+ g_include_list ut_object_names;
22+ g_exclude_list ut_object_names;
23+ g_file_mappings ut_coverage_file_mappings;
24+
25+
26+ /**
27+ * Private functions
28+ */
29+ function to_ut_object_list( a_names ut_varchar2_list) return ut_object_names is
30+ l_result ut_object_names;
31+ begin
32+ if a_names is not null then
33+ l_result := ut_object_names();
34+ for i in 1 .. a_names.count loop
35+ l_result.extend;
36+ l_result(l_result.last) := ut_object_name(a_names(i));
37+ end loop;
38+ end if;
39+ return l_result;
40+ end;
41+
42+ /**
43+ * Public functions
44+ */
45+ function default_file_to_obj_type_map return ut_key_value_pairs is
46+ begin
47+ return ut_key_value_pairs(
48+ ut_key_value_pair('tpb', 'TYPE BODY'),
49+ ut_key_value_pair('pkb', 'PACKAGE BODY'),
50+ ut_key_value_pair('trg', 'TRIGGER')
51+ );
52+ end;
53+
54+ function build_file_mappings(
55+ a_file_paths ut_varchar2_list, a_file_to_object_type_mapping ut_key_value_pairs,
56+ a_regex_pattern varchar2, a_object_owner_subexpression positive, a_object_name_subexpression positive, a_object_type_subexpression positive
57+ ) return ut_coverage_file_mappings is
58+ type tt_key_values is table of varchar2(4000) index by varchar2(4000);
59+ l_key_values tt_key_values;
60+ l_mappings ut_coverage_file_mappings;
61+ l_mapping ut_coverage_file_mapping;
62+ l_object_type_key varchar2(4000);
63+ l_object_type varchar2(4000);
64+ l_file_to_object_type_mapping ut_key_value_pairs;
65+ begin
66+ l_file_to_object_type_mapping := nvl(a_file_to_object_type_mapping, default_file_to_obj_type_map());
67+ for i in 1 .. l_file_to_object_type_mapping.count loop
68+ l_key_values(upper(l_file_to_object_type_mapping(i).key)) := l_file_to_object_type_mapping(i).value;
69+ end loop;
70+ if a_file_paths is not null then
71+ l_mappings := ut_coverage_file_mappings();
72+ for i in 1 .. a_file_paths.count loop
73+ l_object_type_key := upper(regexp_substr(a_file_paths(i), a_regex_pattern,1,1,'i',a_object_type_subexpression));
74+ if l_key_values.exists(l_object_type_key) then
75+ l_object_type := l_key_values(l_object_type_key);
76+ else
77+ l_object_type := null;
78+ end if;
79+ l_mapping := ut_coverage_file_mapping(
80+ file_name => a_file_paths(i),
81+ object_owner => nvl(
82+ upper(regexp_substr(a_file_paths(i), a_regex_pattern, 1, 1, 'i', a_object_owner_subexpression))
83+ , sys_context('USERENV', 'CURRENT_SCHEMA')
84+ ),
85+ object_name => upper(regexp_substr(a_file_paths(i), a_regex_pattern, 1, 1, 'i', a_object_name_subexpression)),
86+ object_type => l_object_type
87+ );
88+ l_mappings.extend();
89+ l_mappings(l_mappings.last) := l_mapping;
90+ end loop;
91+ end if;
92+ return l_mappings;
93+ end;
2094
2195 function get_coverage_id return integer is
2296 begin
2397 return ut_coverage_helper.get_coverage_id;
2498 end;
2599
100+ function get_include_schema_names return ut_varchar2_list is
101+ begin
102+ return g_schema_names;
103+ end;
104+
105+ procedure set_include_schema_names(a_schema_names ut_varchar2_list) is
106+ begin
107+ g_schema_names := a_schema_names;
108+ end;
109+
110+ procedure init(
111+ a_schema_names ut_varchar2_list,
112+ a_include_object_list ut_varchar2_list,
113+ a_exclude_object_list ut_varchar2_list
114+ ) is
115+ begin
116+ g_schema_names := a_schema_names;
117+ g_include_list := to_ut_object_list(a_include_object_list);
118+ g_exclude_list := to_ut_object_list(a_exclude_object_list);
119+ end;
120+
121+ procedure init(
122+ a_file_mappings ut_coverage_file_mappings,
123+ a_include_object_list ut_varchar2_list,
124+ a_exclude_object_list ut_varchar2_list
125+ ) is
126+ begin
127+ g_include_list := to_ut_object_list(a_include_object_list);
128+ g_exclude_list := to_ut_object_list(a_exclude_object_list);
129+ g_file_mappings := a_file_mappings;
130+ end;
131+
26132 function coverage_start return integer is
27133 begin
28134 g_skipped_objects := ut_object_names();
@@ -32,7 +138,7 @@ create or replace package body ut_coverage is
32138 procedure coverage_start is
33139 l_coverage_id integer;
34140 begin
35- l_coverage_id := coverage_start;
141+ l_coverage_id := coverage_start() ;
36142 end;
37143
38144 procedure coverage_start_develop is
@@ -61,16 +167,16 @@ create or replace package body ut_coverage is
61167 ut_coverage_helper.coverage_stop();
62168 end;
63169
64- procedure skip_coverage_for(a_object ut_object_name ) is
170+ procedure skip_coverage_for(a_owner varchar2, a_name varchar2 ) is
65171 begin
66172 if g_skipped_objects is null then
67173 g_skipped_objects := ut_object_names();
68174 end if;
69- g_skipped_objects.extend;
70- g_skipped_objects(g_skipped_objects.last) := a_object ;
175+ g_skipped_objects.extend;
176+ g_skipped_objects(g_skipped_objects.last) := ut_object_name(a_owner, a_name) ;
71177 end;
72178
73- function get_coverage_data(a_schema_names ut_varchar2_list) return t_coverage is
179+ function get_coverage_data return t_coverage is
74180
75181 pragma autonomous_transaction;
76182
@@ -88,6 +194,7 @@ create or replace package body ut_coverage is
88194 type t_source_lines is table of binary_integer;
89195 l_source_lines t_source_lines;
90196 line_no binary_integer;
197+ l_schema_names ut_varchar2_list := coalesce(g_schema_names,ut_varchar2_list(sys_context('USERENV','CURRENT_SCHEMA')));
91198 begin
92199
93200 if not ut_coverage_helper.is_develop_mode() then
@@ -97,37 +204,70 @@ create or replace package body ut_coverage is
97204 --prepare global temp table with sources
98205 delete from ut_coverage_sources_tmp;
99206
100- insert into ut_coverage_sources_tmp(owner,name,line,text, to_be_skipped)
101- select s.owner,s.name,s.line,s.text,
102- case
103- when
104- -- to avoid execution of regexp_like on every line
105- -- first do a rough check for existence of search pattern keyword
106- (lower(s.text) like '%procedure%'
107- or lower(s.text) like '%function%'
108- or lower(s.text) like '%begin%'
109- or lower(s.text) like '%end%'
110- or lower(s.text) like '%package%'
111- ) and
112- regexp_like(
113- s.text,
114- '^\s*(((not)?\s*(overriding|final|instantiable)\s*)*(constructor|member)?\s*(procedure|function)|package(\s+body)|begin|end(\s+\S+)?\s*;)', 'i'
115- )
116- then 'Y'
117- end as to_be_skipped
118- from all_source s
119- where s.type not in ('PACKAGE', 'TYPE')
120- and s.owner in (select t.column_value from table(a_schema_names) t)
121- --Exclude calls to utPLSQL framework and Unit Test packages
122- and not exists(select 1 from table(l_skipped_objects) l where s.owner = l.owner AND s.name = l.name);
207+ if g_file_mappings is not null then
208+ insert into ut_coverage_sources_tmp(full_name,owner,name,line,text, to_be_skipped)
209+ select f.file_name, s.owner,s.name,s.line,s.text,
210+ case
211+ when
212+ -- to avoid execution of regexp_like on every line
213+ -- first do a rough check for existence of search pattern keyword
214+ (lower(s.text) like '%procedure%'
215+ or lower(s.text) like '%function%'
216+ or lower(s.text) like '%begin%'
217+ or lower(s.text) like '%end%'
218+ or lower(s.text) like '%package%'
219+ ) and
220+ regexp_like(
221+ s.text,
222+ '^\s*(((not)?\s*(overriding|final|instantiable)\s*)*(static|constructor|member)?\s*(procedure|function)|package(\s+body)|begin|end(\s+\S+)?\s*;)', 'i'
223+ )
224+ then 'Y'
225+ end as to_be_skipped
226+ from all_source s
227+ join table(g_file_mappings) f
228+ on s.name = f.object_name
229+ and s.type = f.object_type
230+ and s.owner = f.object_owner
231+ where s.type not in ('PACKAGE', 'TYPE')
232+ and (g_include_list is null or (s.owner, s.name) in (select il.owner, il.name from table(g_include_list) il))
233+ and (s.owner, s.name) not in (select el.owner, el.name from table(g_exclude_list) el)
234+ --Exclude calls to utPLSQL framework and Unit Test packages
235+ and (s.owner, s.name) not in (select so.owner, so.name from table(l_skipped_objects) so);
236+ else
237+ insert into ut_coverage_sources_tmp(full_name,owner,name,line,text, to_be_skipped)
238+ select lower(s.owner||'.'||s.name), s.owner,s.name,s.line,s.text,
239+ case
240+ when
241+ -- to avoid execution of regexp_like on every line
242+ -- first do a rough check for existence of search pattern keyword
243+ (lower(s.text) like '%procedure%'
244+ or lower(s.text) like '%function%'
245+ or lower(s.text) like '%begin%'
246+ or lower(s.text) like '%end%'
247+ or lower(s.text) like '%package%'
248+ ) and
249+ regexp_like(
250+ s.text,
251+ '^\s*(((not)?\s*(overriding|final|instantiable)\s*)*(static|constructor|member)?\s*(procedure|function)|package(\s+body)|begin|end(\s+\S+)?\s*;)', 'i'
252+ )
253+ then 'Y'
254+ end as to_be_skipped
255+ from all_source s
256+ where s.type not in ('PACKAGE', 'TYPE')
257+ and s.owner in (select t.column_value from table(l_schema_names) t)
258+ and (g_include_list is null or (s.owner, s.name) in (select il.owner, il.name from table(g_include_list) il ) )
259+ and (s.owner, s.name) not in (select el.owner, el.name from table(g_exclude_list) el)
260+ --Exclude calls to utPLSQL framework and Unit Test packages
261+ and (s.owner, s.name) not in (select so.owner, so.name from table(l_skipped_objects) so);
262+ end if;
123263
124264 for src_object in (
125- select o.owner, o.name, lower(o.owner||'.'||o.name) full_name, max(o.line) lines_count,
265+ select o.owner, o.name, o. full_name, max(o.line) lines_count,
126266 cast(
127267 collect(decode(to_be_skipped, 'Y', to_char(line))) as ut_varchar2_list
128268 ) to_be_skipped_list
129269 from ut_coverage_sources_tmp o
130- group by o.owner, o.name
270+ group by o.owner, o.name, o.full_name
131271 ) loop
132272
133273 --get coverage data
@@ -145,6 +285,8 @@ create or replace package body ut_coverage is
145285
146286 if not l_result.objects.exists(src_object.full_name) then
147287 l_result.objects(src_object.full_name) := l_new_unit;
288+ l_result.objects(src_object.full_name).owner := src_object.owner;
289+ l_result.objects(src_object.full_name).name := src_object.name;
148290 end if;
149291 l_result.total_lines := l_result.total_lines + src_object.lines_count;
150292 l_result.objects(src_object.full_name).total_lines := src_object.lines_count;
@@ -179,45 +321,5 @@ create or replace package body ut_coverage is
179321 return l_result;
180322 end get_coverage_data;
181323
182- function get_schema_names_from_run(a_run ut_run) return ut_varchar2_list is
183- type t_schema_names is table of boolean index by varchar2(500);
184- l_schema_names t_schema_names;
185- l_result ut_varchar2_list;
186-
187- l_schema_name varchar2(500);
188-
189- procedure get_suite_item_schema_names(a_suite_item ut_logical_suite, a_schema_names in out nocopy t_schema_names) is
190- begin
191- if a_suite_item is of (ut_suite) then
192- a_schema_names(a_suite_item.object_owner) := true;
193- elsif a_suite_item.items is not null then
194- for i in 1 .. a_suite_item.items.count loop
195- if a_suite_item is of (ut_logical_suite) then
196- get_suite_item_schema_names(treat( a_suite_item.items(i) as ut_logical_suite), a_schema_names);
197- end if;
198- end loop;
199- end if;
200- end;
201-
202- begin
203- if a_run is not null and a_run.items is not null then
204- for i in 1 .. a_run.items.count loop
205- if a_run.items(i) is of (ut_logical_suite) then
206- get_suite_item_schema_names(treat( a_run.items(i) as ut_logical_suite), l_schema_names);
207- end if;
208- end loop;
209- end if;
210- if l_schema_names.count > 0 then
211- l_result := ut_varchar2_list();
212- l_schema_name := l_schema_names.first;
213- loop
214- exit when l_schema_name is null;
215- l_result.extend;
216- l_result(l_result.last) := l_schema_name;
217- l_schema_name := l_schema_names.next(l_schema_name);
218- end loop;
219- end if;
220- return l_result;
221- end;
222324end;
223325/
0 commit comments