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

Skip to content

Commit dbf2538

Browse files
committed
Fixed failing test and test for Wrapped package.
To test wrapped package we need to have an annotation-like text in it. This way the exception handler `when ex_package_is_wrapped` gets tested after adding source filters
1 parent 4ec9eb5 commit dbf2538

9 files changed

Lines changed: 126 additions & 306 deletions

File tree

examples/developer_examples/RunExampleTestAnnotationsParsingTimeHugePackage.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ set echo off
88
declare
99
l_suites ut_suite_items;
1010
begin
11-
l_suites := ut_suite_manager.configure_execution_by_path(USER||'.TST_PKG_HUGE');
11+
l_suites := ut_suite_manager.configure_execution_by_path(ut_varchar2_list(USER||'.TST_PKG_HUGE'));
1212
end;
1313
/
1414

old_tests/RunAll.sql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,8 @@ begin
326326
'source/api/ut_runner.pks',
327327
'source/core/coverage',
328328
'source/core/types',
329+
'source/core/annotations/ut_annotation_manager.pkb',
330+
'source/core/annotations/ut_annotation_manager.pks',
329331
'source/core/annotations/ut_annotation_parser.pkb',
330332
'source/core/annotations/ut_annotation_parser.pks',
331333
'source/core/annotations/ut_annotation_cache_manager.pkb',

source/core/annotations/ut_annotation_parser.pkb

Lines changed: 24 additions & 189 deletions
Original file line numberDiff line numberDiff line change
@@ -194,113 +194,6 @@ create or replace package body ut_annotation_parser as
194194
return l_comments;
195195
end extract_and_replace_comments;
196196

197-
function parse_object_annotations(a_source_lines in out nocopy dbms_preprocessor.source_lines_t) return ut_annotations is
198-
l_processed_lines dbms_preprocessor.source_lines_t;
199-
l_source clob;
200-
l_annotations ut_annotations := ut_annotations();
201-
ex_package_is_wrapped exception;
202-
pragma exception_init(ex_package_is_wrapped, -24241);
203-
204-
begin
205-
if a_source_lines.count > 0 then
206-
--convert to post-processed source clob
207-
begin
208-
--get post-processed source
209-
l_processed_lines := sys.dbms_preprocessor.get_post_processed_source(a_source_lines);
210-
--convert to clob
211-
for i in 1..l_processed_lines.count loop
212-
ut_utils.append_to_clob(l_source, replace(l_processed_lines(i), chr(13)||chr(10), chr(10)));
213-
end loop;
214-
--parse annotations
215-
l_annotations := parse_object_annotations(l_source);
216-
dbms_lob.freetemporary(l_source);
217-
exception
218-
when ex_package_is_wrapped then
219-
null;
220-
end;
221-
end if;
222-
a_source_lines.delete;
223-
return l_annotations;
224-
end;
225-
226-
function get_annotated_objects_cursor(a_object_owner varchar2, a_object_type varchar2, a_object_name varchar2) return sys_refcursor is
227-
l_result sys_refcursor;
228-
l_ut_owner varchar2(250) := ut_utils.ut_owner;
229-
l_objects_view varchar2(200) := ut_metadata.get_dba_view('dba_objects');
230-
l_cursor_text long;
231-
begin
232-
l_cursor_text :=
233-
q'[select ]'||l_ut_owner||q'[.ut_annotation_cached_object(
234-
object_owner => o.owner,
235-
object_name => o.object_name,
236-
object_type => o.object_type,
237-
needs_refresh => case when o.last_ddl_time < i.parse_time then 'N' else 'Y' end,
238-
cache_id => i.cache_id
239-
)
240-
from ]'||l_objects_view||q'[ o
241-
left join ut3.ut_annotation_cache_info i
242-
on o.owner = i.object_owner and o.object_name = i.object_name and o.object_type = i.object_type
243-
where o.owner = :a_object_owner
244-
and o.object_type = :a_object_type
245-
and o.status = 'VALID'
246-
and :a_object_name ]'|| case when a_object_name is not null then '= o.object_name' else 'is null' end;
247-
open l_result for l_cursor_text using a_object_owner, a_object_type, a_object_name;
248-
return l_result;
249-
end;
250-
251-
function get_sources_for_annotations(a_object_owner varchar2, a_object_type varchar2, a_object_name varchar2) return sys_refcursor is
252-
l_result sys_refcursor;
253-
l_sources_view varchar2(200) := ut_metadata.get_dba_view('dba_source');
254-
begin
255-
open l_result for
256-
q'[select s.name, s.text
257-
from ]'||l_sources_view||q'[ s
258-
where s.type = :a_object_type
259-
and s.owner = :a_object_owner
260-
and s.name
261-
in (select x.name
262-
from ]'||l_sources_view||q'[ x
263-
where x.type = :a_object_type
264-
and x.owner = :a_object_owner
265-
and x.text like '%--%\%%' escape '\'
266-
and :a_object_name ]'|| case when a_object_name is not null then '= x.name' else 'is null' end || q'[
267-
)
268-
order by name, line]'
269-
using a_object_type, a_object_owner, a_object_type, a_object_owner, a_object_name;
270-
271-
return l_result;
272-
end;
273-
274-
function get_sources_for_annotations(a_object_owner varchar2, a_object_type varchar2, a_objects_to_refresh ut_annotation_cached_objects) return sys_refcursor is
275-
l_result sys_refcursor;
276-
l_sources_view varchar2(200) := ut_metadata.get_dba_view('dba_source');
277-
l_card natural;
278-
begin
279-
l_card := ut_utils.scale_cardinality(cardinality(a_objects_to_refresh));
280-
open l_result for
281-
q'[select /*+ cardinality( r ]'||l_card||q'[ )*/
282-
s.name, s.text
283-
from table(:a_objects_to_refresh) r
284-
join ]'||l_sources_view||q'[ s
285-
on s.name = r.object_name
286-
where s.type = :a_object_type
287-
and s.owner = :a_object_owner
288-
and s.name
289-
in (select /*+ cardinality( x ]'||l_card||q'[ )*/
290-
x.name
291-
from table(:a_objects_to_refresh) t
292-
join ]'||l_sources_view||q'[ x
293-
on x.name = t.object_name
294-
where x.type = :a_object_type
295-
and x.owner = :a_object_owner
296-
and x.text like '%--%\%%' escape '\'
297-
)
298-
order by name, line]'
299-
using a_objects_to_refresh, a_object_type, a_object_owner, a_objects_to_refresh, a_object_type, a_object_owner;
300-
301-
return l_result;
302-
end;
303-
304197
------------------------------------------------------------
305198
--public definitions
306199
------------------------------------------------------------
@@ -339,91 +232,33 @@ create or replace package body ut_annotation_parser as
339232
return l_result;
340233
end parse_object_annotations;
341234

342-
function get_annotated_objects(a_object_owner varchar2, a_object_type varchar2, a_object_name varchar2 := null) return ut_annotated_objects pipelined is
343-
l_info_rows ut_annotation_cached_objects;
344-
l_in_cache ut_annotation_cached_objects;
345-
l_to_parse ut_annotation_cached_objects := ut_annotation_cached_objects();
346-
l_cursor sys_refcursor;
347-
l_results ut_annotated_objects;
348-
l_result ut_annotated_object;
349-
c_object_fetch_limit constant integer := 10;
350-
c_lines_fetch_limit constant integer := 1000;
351-
l_lines dbms_preprocessor.source_lines_t;
352-
l_names dbms_preprocessor.source_lines_t;
353-
l_name varchar2(250) := '''';
354-
l_object_lines dbms_preprocessor.source_lines_t;
355-
begin
356-
--get information about cached objects
357-
l_cursor := get_annotated_objects_cursor(a_object_owner, a_object_type, a_object_name);
358-
fetch l_cursor bulk collect into l_info_rows;
359-
close l_cursor;
360-
361-
--get list of objects in cache
362-
select value(x) bulk collect into l_in_cache from table(l_info_rows) x where x.needs_refresh = 'N';
363-
364-
--if not all in cache, get list of objects to refresh
365-
if l_in_cache.count <= l_info_rows.count then
366-
select value(x) bulk collect into l_to_parse from table(l_info_rows) x where x.needs_refresh = 'Y';
367-
end if;
368-
369-
--pipe annotations from cache
370-
if l_in_cache.count > 0 then
371-
l_cursor := ut_annotation_cache_manager.get_annotations_for_objects(l_in_cache);
372-
loop
373-
fetch l_cursor bulk collect into l_results limit c_object_fetch_limit;
374-
for i in 1 .. l_results.count loop
375-
pipe row (l_results(i));
376-
end loop;
377-
exit when l_cursor%notfound;
378-
end loop;
379-
close l_cursor;
380-
end if;
381-
382-
--if some source needs parsing
383-
if l_to_parse.count > 0 then
384-
--do we need to parse all of sources
385-
if l_in_cache.count = 0 then
386-
l_cursor := get_sources_for_annotations(a_object_owner, a_object_type, a_object_name);
387-
else
388-
-- sources need to be filtered by objects to parse
389-
l_cursor := get_sources_for_annotations(a_object_owner, a_object_type, l_to_parse);
390-
end if;
391-
392-
--remove cached annotations data for objects that will be refreshed
393-
ut_annotation_cache_manager.cleanup_cache(l_to_parse);
394-
395-
loop
396-
fetch l_cursor bulk collect into l_names, l_lines limit c_lines_fetch_limit;
397-
398-
for i in 1 .. l_names.count loop
399-
400-
if l_names(i) != l_name then
401-
l_result := ut_annotated_object(a_object_owner, l_name, a_object_type, parse_object_annotations(l_object_lines));
402-
ut_annotation_cache_manager.update_cache(l_result);
403-
if l_result.annotations.count > 0 then
404-
pipe row (l_result);
405-
end if;
406-
end if;
407-
408-
l_name := l_names(i);
409-
l_object_lines(l_object_lines.count+1) := l_lines(i);
235+
function parse_object_annotations(a_source_lines dbms_preprocessor.source_lines_t) return ut_annotations is
236+
l_processed_lines dbms_preprocessor.source_lines_t;
237+
l_source clob;
238+
l_annotations ut_annotations := ut_annotations();
239+
ex_package_is_wrapped exception;
240+
pragma exception_init(ex_package_is_wrapped, -24241);
410241

242+
begin
243+
if a_source_lines.count > 0 then
244+
--convert to post-processed source clob
245+
begin
246+
--get post-processed source
247+
l_processed_lines := sys.dbms_preprocessor.get_post_processed_source(a_source_lines);
248+
--convert to clob
249+
for i in 1..l_processed_lines.count loop
250+
ut_utils.append_to_clob(l_source, replace(l_processed_lines(i), chr(13)||chr(10), chr(10)));
411251
end loop;
412-
exit when l_cursor%notfound;
413-
414-
end loop;
415-
416-
if l_name is not null then
417-
l_result := ut_annotated_object(a_object_owner, l_name, a_object_type, parse_object_annotations(l_object_lines));
418-
ut_annotation_cache_manager.update_cache(l_result);
419-
if l_result.annotations.count > 0 then
420-
pipe row (l_result);
421-
end if;
422-
end if;
423-
424-
close l_cursor;
252+
dbms_output.put_line(l_source);
253+
--parse annotations
254+
l_annotations := parse_object_annotations(l_source);
255+
dbms_lob.freetemporary(l_source);
256+
exception
257+
when ex_package_is_wrapped then
258+
null;
259+
end;
425260
end if;
426-
261+
return l_annotations;
427262
end;
428263

429264
end ut_annotation_parser;

source/core/annotations/ut_annotation_parser.pks

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,26 +17,28 @@ create or replace package ut_annotation_parser authid current_user as
1717
*/
1818

1919
/**
20-
* Reads database source code, parses it and returns annotations
20+
* Parses the source passed as input parameter and returns annotations
2121
*/
2222

2323
/**
24-
* Parses source code and converts it to annotations
24+
* Runs the source lines through dbms_preprocessor to remove lines that were not compiled (conditional compilation)
25+
* Parses the processed source code and converts it to annotations
2526
*
26-
* @param a_source clob containing source code to be parsed
27+
* @param a_source_lines ordered lines of source code to be parsed
2728
* @return array containing annotations
2829
*/
29-
function parse_object_annotations(a_source clob) return ut_annotations;
30+
function parse_object_annotations(a_source_lines dbms_preprocessor.source_lines_t) return ut_annotations;
31+
3032

3133
/**
32-
* Parses an object or all objects of a specified type for database schema.
33-
* Pesults are returned in a form of a pipelined function.
34-
* @param a_object_owner schema name to be parsed
35-
* @param a_object_type type of object to be parsed
36-
* @param a_object_name name of object to be parsed - optional
37-
* @return array containing annotated objects along with annotations for each object (nested)
34+
*
35+
* @private
36+
* Parses source code and converts it to annotations
37+
*
38+
* @param a_source_lines ordered lines of source code to be parsed
39+
* @return array containing annotations
3840
*/
39-
function get_annotated_objects(a_object_owner varchar2, a_object_type varchar2, a_object_name varchar2 := null) return ut_annotated_objects pipelined;
41+
function parse_object_annotations(a_source clob) return ut_annotations;
4042

4143
end ut_annotation_parser;
4244
/

source/core/ut_suite_manager.pkb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ create or replace package body ut_suite_manager is
280280
execute immediate
281281
q'[select value(x)
282282
from table(
283-
]'||ut_utils.ut_owner||q'[.ut_annotation_parser.get_annotated_objects(:a_owner_name, 'PACKAGE')
283+
]'||ut_utils.ut_owner||q'[.ut_annotation_manager.get_annotated_objects(:a_owner_name, 'PACKAGE')
284284
)x ]'
285285
bulk collect into l_annotated_objects using a_owner_name;
286286
for i in 1 .. l_annotated_objects.count loop

source/install.sql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ alter session set plsql_warnings = 'ENABLE:ALL', 'DISABLE:(5004,5018,6000,6001,6
8888
@@install_component.sql 'core/annotations/ut_annotation_cache_manager.pkb'
8989
@@install_component.sql 'core/annotations/ut_annotation_parser.pks'
9090
@@install_component.sql 'core/annotations/ut_annotation_parser.pkb'
91+
@@install_component.sql 'core/annotations/ut_annotation_manager.pks'
92+
@@install_component.sql 'core/annotations/ut_annotation_manager.pkb'
9193

9294
--suite manager
9395
@@install_component.sql 'core/ut_suite_manager.pks'

source/uninstall.sql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,8 @@ drop type ut_data_value force;
172172

173173
drop table ut_cursor_data;
174174

175+
drop package ut_annotation_manager;
176+
175177
drop package ut_annotation_parser;
176178

177179
drop package ut_annotation_cache_manager;

0 commit comments

Comments
 (0)