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

Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
36a061c
Removed parsing of annotation text (params) from ut_annotations as an…
jgebal Oct 6, 2017
a29cabe
Removed duplicate `old_tests` for ut_annotations - the functionality …
jgebal Oct 6, 2017
58c6293
Renamed `ut_annotations` to `ut_annotation_parser` and moved to annot…
jgebal Oct 7, 2017
375a7ff
Removed ``ut_annotations` from uninstall script.
jgebal Oct 7, 2017
13703fa
Fixed failing old tests after refactoring.
jgebal Oct 7, 2017
ac23f15
Refactored ut_annotation_parser API to use `ut_annotations` collectio…
jgebal Oct 7, 2017
df2c763
Added cache mechanism to `ut_annotation_parser`.
jgebal Oct 8, 2017
6088c81
Added ability to get annotations for single object.
jgebal Oct 9, 2017
4ec9eb5
Reworking annotation cache - not to use cast(Collect()) on dba_source.
jgebal Oct 13, 2017
dbf2538
Fixed failing test and test for Wrapped package.
jgebal Oct 14, 2017
ca31e98
Added missing annotation manager.
jgebal Oct 14, 2017
289f006
Removed dbms_output from code.
jgebal Oct 14, 2017
8e26ed0
Merge remote-tracking branch 'upstream/develop' into feature/annotati…
jgebal Oct 14, 2017
239abde
Add grant ut_annotation_manager to public
pesse Oct 16, 2017
6acd2ad
Add grant ut_annotation_manager to ut3_user
pesse Oct 16, 2017
e114aae
Merge branch 'develop' into feature/annotations_restructuring
jgebal Oct 17, 2017
b83e142
Fixed hardcoded schema-name
jgebal Oct 18, 2017
6dcaae9
Merge remote-tracking branch 'upstream/develop' into feature/annotati…
jgebal Oct 18, 2017
aafca84
Refactored annotation cache.
jgebal Oct 22, 2017
cd394c7
Fixed test execution on 12.1.
jgebal Oct 23, 2017
73c15a2
Merge remote-tracking branch 'upstream/develop' into feature/annotati…
jgebal Oct 23, 2017
5967a3a
Fixed test execution on 12.1.
jgebal Oct 23, 2017
1438753
Merge branch 'develop' into feature/annotations_restructuring
jgebal Oct 24, 2017
4f5d870
Merge conflicts cleanup
jgebal Oct 24, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Refactored ut_annotation_parser API to use ut_annotations collectio…
…n as output results.

Reworked `ut_suite_manager` to operate on sorted collection for building ut_suite and it's tests.
Adjusted `test_annotation_parser` to cover the refactoring.
  • Loading branch information
jgebal committed Oct 7, 2017
commit ac23f152e17ef68706dee81bf3c0abae8de2db0e
8 changes: 8 additions & 0 deletions source/core/annotations/ut_annotation.tps
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
create type ut_annotation as object(
position number(5,0),
name varchar2(1000),
text varchar2(4000),
subobject_name varchar2(250)
)
/

173 changes: 57 additions & 116 deletions source/core/annotations/ut_annotation_parser.pkb
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,14 @@ create or replace package body ut_annotation_parser as
,modifier => 'n');
end;

function get_annotations(a_source varchar2, a_comments tt_comment_list) return tt_annotations is
l_loop_index pls_integer := 1;
l_comment_index pls_integer;
l_comment varchar2(32767);
l_annotation_str varchar2(32767);
l_annotation_text varchar2(32767);
l_annotation_name varchar2(1000);
l_annotation t_annotation;
l_annotations_list tt_annotations;
function get_annotations(a_source varchar2, a_comments tt_comment_list, a_subobject_name varchar2 := null) return ut_annotations is
l_loop_index pls_integer := 1;
l_annotation_index pls_integer;
l_comment varchar2(32767);
l_annotation_str varchar2(32767);
l_annotation_text varchar2(32767);
l_annotation_name varchar2(1000);
l_annotations ut_annotations := ut_annotations();
begin
-- loop while there are unprocessed comment blocks
while 0 != nvl(regexp_instr(srcstr => a_source
Expand All @@ -57,13 +56,13 @@ create or replace package body ut_annotation_parser as
,0) loop

-- define index of the comment block and get it's content from cache
l_comment_index := to_number(regexp_substr(a_source
l_annotation_index := to_number(regexp_substr(a_source
,c_comment_replacer_regex_ptrn
,1
,l_loop_index
,subexpression => 1));

l_comment := a_comments(l_comment_index);
l_comment := a_comments( l_annotation_index );

-- strip everything except the annotation itself (spaces and others)
l_annotation_str := regexp_substr(l_comment, c_annotation_pattern, 1, 1, modifier => 'i');
Expand All @@ -76,38 +75,39 @@ create or replace package body ut_annotation_parser as
,subexpression => 1));
l_annotation_text := trim(regexp_substr(l_annotation_str, '\((.*?)\)\s*$', subexpression => 1));

l_annotation.text := l_annotation_text;
l_annotations_list(l_annotation_name) := l_annotation;
l_annotations.extend;
l_annotations( l_annotations.last) :=
ut_annotation(l_annotation_index, l_annotation_name, l_annotation_text, a_subobject_name);
end if;
l_loop_index := l_loop_index + 1;
end loop;

return l_annotations_list;
return l_annotations;

end get_annotations;

function get_package_annotations(a_source clob, a_comments tt_comment_list) return tt_annotations is
function get_package_annotations(a_source clob, a_comments tt_comment_list) return ut_annotations is
l_package_comments varchar2(32767);
l_annotations ut_annotations := ut_annotations();
begin
l_package_comments := regexp_substr(srcstr => a_source
,pattern => '^\s*(CREATE\s+(OR\s+REPLACE)?(\s+(NON)?EDITIONABLE)?\s+)?PACKAGE\s[^;]*?(\s+(AS|IS)\s+)((.*?{COMMENT#\d+}\s?)+)'
,modifier => 'i'
,subexpression => 7);

-- parsing for package annotations
return
case when l_package_comments is not null then
get_annotations(l_package_comments, a_comments)
end;
if l_package_comments is not null then
l_annotations := get_annotations(l_package_comments, a_comments);
end if;

return l_annotations;
end;

function get_procedure_list(a_source clob, a_comments tt_comment_list) return tt_procedure_list is
function get_procedure_list(a_source clob, a_comments tt_comment_list) return ut_annotations is
l_proc_comments varchar2(32767);
l_proc_name t_annotation_name;
l_annot_proc_ind number;
l_annot_proc_block varchar2(32767);
l_procedure_annotations tt_procedure_annotations;
l_procedure_list tt_procedure_list;
l_annotations ut_annotations := ut_annotations();
begin
-- loop through procedures and functions of the package and get all the comment blocks just before it's declaration
l_annot_proc_ind := 1;
Expand Down Expand Up @@ -139,18 +139,16 @@ create or replace package body ut_annotation_parser as
,subexpression => 5));

-- parse the comment block for the syntactically correct annotations and store them as an array
l_procedure_annotations.name := l_proc_name;
l_procedure_annotations.annotations := get_annotations(l_proc_comments, a_comments);

l_procedure_list(l_procedure_list.count+1) := l_procedure_annotations;
l_annotations := l_annotations multiset union all get_annotations(l_proc_comments, a_comments, l_proc_name);

--l_annot_proc_ind := l_annot_proc_ind + length(l_annot_proc_block);
l_annot_proc_ind := regexp_instr(srcstr => a_source
,pattern => ';'
,occurrence => 1
,position => l_annot_proc_ind + length(l_annot_proc_block));
end loop;
return l_procedure_list;

return l_annotations;
end;

function extract_and_replace_comments(a_source in out nocopy clob) return tt_comment_list is
Expand Down Expand Up @@ -199,62 +197,21 @@ create or replace package body ut_annotation_parser as
return l_comments;
end extract_and_replace_comments;

-- $if $$ut_trace $then
-- procedure print_parse_results(a_annotated_pkg typ_annotated_package) is
-- l_name t_annotation_name := a_annotated_pkg.package_annotations.first;
-- l_proc_name t_annotation_name;
-- begin
-- dbms_output.put_line('Annotations count: ' || a_annotated_pkg.package_annotations.count);
--
-- while l_name is not null loop
-- dbms_output.put_line(' @' || l_name);
-- if a_annotated_pkg.package_annotations(l_name).count > 0 then
-- dbms_output.put_line(' Parameters:');
--
-- for j in 1 .. a_annotated_pkg.package_annotations(l_name).count loop
-- dbms_output.put_line(' ' || nvl(a_annotated_pkg.package_annotations(l_name)(j).key, '<Anonymous>') || ' = ' ||
-- nvl(a_annotated_pkg.package_annotations(l_name)(j).val, 'NULL'));
-- end loop;
-- else
-- dbms_output.put_line(' No parameters.');
-- end if;
--
-- l_name := a_annotated_pkg.package_annotations.next(l_name);
--
-- end loop;
--
-- dbms_output.put_line('Procedures count: ' || a_annotated_pkg.procedure_annotations.count);
--
-- for i in 1 .. a_annotated_pkg.procedure_annotations.count loop
-- l_proc_name := a_annotated_pkg.procedure_annotations(i).name;
-- dbms_output.put_line(rpad('-', 80, '-'));
-- dbms_output.put_line(' Procedure: ' || l_proc_name);
-- dbms_output.put_line(' Annotations count: ' || a_annotated_pkg.procedure_annotations(i).annotations.count);
-- l_name := a_annotated_pkg.procedure_annotations(i).annotations.first;
-- while l_name is not null loop
-- dbms_output.put_line(' @' || l_name);
-- if a_annotated_pkg.procedure_annotations(i).annotations(l_name).count > 0 then
-- dbms_output.put_line(' Parameters:');
-- for j in 1 .. a_annotated_pkg.procedure_annotations(i).annotations(l_name).count loop
-- dbms_output.put_line(' ' ||
-- nvl(a_annotated_pkg.procedure_annotations(i).annotations(l_name)(j).key, '<Anonymous>') ||
-- ' = ' || nvl(a_annotated_pkg.procedure_annotations(i).annotations(l_name)(j).val, 'NULL'));
-- end loop;
-- else
-- dbms_output.put_line(' No parameters.');
-- end if;
--
-- l_name := a_annotated_pkg.procedure_annotations(i).annotations.next(l_name);
-- end loop;
-- end loop;
--
-- end print_parse_results;
-- $end

function parse_package_annotations(a_source clob) return typ_annotated_package is
$if $$ut_trace $then
procedure print_parse_results(a_annotations ut_annotations) is
begin
dbms_output.put_line('Annotations count: ' || a_annotations.count);
for i in 1 .. a_annotations.count loop
dbms_output.put_line(xmltype(a_annotations(i)).getclobval());
end loop;
end print_parse_results;
$end

function parse_package_annotations(a_source clob) return ut_annotations is
l_source clob := a_source;
l_comments tt_comment_list;
l_annotated_pkg typ_annotated_package;
l_annotations ut_annotations;
l_result ut_annotations;
begin

l_source := delete_multiline_comments(l_source);
Expand All @@ -263,53 +220,37 @@ create or replace package body ut_annotation_parser as
-- this call modifies l_source
l_comments := extract_and_replace_comments(l_source);

l_annotated_pkg.package_annotations := get_package_annotations(l_source, l_comments);

l_annotated_pkg.procedure_annotations := get_procedure_list(l_source, l_comments);

-- -- printing out parsed structure for debugging
-- $if $$ut_trace $then
-- print_parse_results(l_annotated_pkg);
-- $end
l_annotations :=
get_package_annotations(l_source, l_comments)
multiset union all get_procedure_list(l_source, l_comments);

dbms_lob.freetemporary(l_source);
return l_annotated_pkg;
select value(x)
bulk collect into l_result
from table(l_annotations) x
order by x.position;

-- printing out parsed structure for debugging
$if $$ut_trace $then
print_parse_results(l_result);
$end
return l_result;
end parse_package_annotations;

------------------------------
--public definitions

function get_package_annotations(a_owner_name varchar2, a_name varchar2) return typ_annotated_package is
function get_package_annotations(a_owner_name varchar2, a_name varchar2) return ut_annotations is
l_source clob;
ex_package_is_wrapped exception;
pragma exception_init(ex_package_is_wrapped, -24241);
begin

-- TODO: Add cache of annotations. Cache invalidation should be based on DDL timestamp.
-- Cache garbage collection should be executed once in a while to remove annotations cache for packages that were dropped.

begin
l_source := ut_metadata.get_package_spec_source(a_owner_name, a_name);
exception
when ex_package_is_wrapped then
null;
end;

if l_source is null or sys.dbms_lob.getlength(l_source)=0 then
return null;
else
return parse_package_annotations(l_source);
end if;
return parse_package_annotations(ut_metadata.get_package_spec_source(a_owner_name, a_name));
exception
when ex_package_is_wrapped then
return ut_annotations();
end;

-- function get_annotation_param(a_param_list tt_annotation_params, a_def_index pls_integer) return varchar2 is
-- l_result varchar2(32767);
-- begin
-- if a_param_list.exists(a_def_index) then
-- l_result := a_param_list(a_def_index).val;
-- end if;
-- return l_result;
-- end get_annotation_param;

-- parse the annotation parameters and return as key-value pair array
function parse_annotation_params(a_annotation_text varchar2) return tt_annotation_params is
Expand Down
38 changes: 2 additions & 36 deletions source/core/annotations/ut_annotation_parser.pks
Original file line number Diff line number Diff line change
Expand Up @@ -46,53 +46,19 @@ create or replace package ut_annotation_parser authid current_user as
*/
type tt_annotation_params is table of typ_annotation_param index by pls_integer;

type t_annotation is record(
text varchar2(4000)
);

/*
type: tt_annotations
a list of tt_annotation_params index by the annotation name
*/
type tt_annotations is table of t_annotation index by t_annotation_name;

/*
type: tt_procedure_annotations
a list of tt_annotations index by the procedure name
*/
type tt_procedure_annotations is record(name t_procedure_name, annotations tt_annotations);

type tt_procedure_list is table of tt_procedure_annotations index by pls_integer;

/*
type: typ_annotated_package
a structure containing a list of package level annotations and a list of procedure level annotations

*/
type typ_annotated_package is record(
procedure_annotations tt_procedure_list
,package_annotations tt_annotations);

/*
INTERNAL USE ONLY
*/
function parse_package_annotations(a_source clob) return typ_annotated_package;
function parse_package_annotations(a_source clob) return ut_annotations;

/*
function: get_package_annotations

get annotations for specified package specification and return its annotated schema
*/
function get_package_annotations(a_owner_name varchar2, a_name varchar2) return typ_annotated_package;
function get_package_annotations(a_owner_name varchar2, a_name varchar2) return ut_annotations;


/*
function: get_annotation_param

get annotation parameter on a specified index position
*/
-- function get_annotation_param(a_param_list tt_annotation_params, a_def_index pls_integer) return varchar2;

/*
function: parse_annotation_params

Expand Down
2 changes: 2 additions & 0 deletions source/core/annotations/ut_annotations.tps
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
create type ut_annotations as table of ut_annotation
/
8 changes: 8 additions & 0 deletions source/core/types/ut_test.tpb
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ create or replace type body ut_test as
return;
end;

member procedure set_beforeeach(self in out nocopy ut_test, a_before_each_proc_name varchar2) is
begin
self.before_each := ut_executable(self, a_before_each_proc_name, ut_utils.gc_before_each);
end;
member procedure set_aftereach(self in out nocopy ut_test, a_after_each_proc_name varchar2) is
begin
self.after_each := ut_executable(self, a_after_each_proc_name, ut_utils.gc_after_each);
end;
member function is_valid(self in out nocopy ut_test) return boolean is
l_is_valid boolean;
begin
Expand Down
2 changes: 2 additions & 0 deletions source/core/types/ut_test.tps
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ create or replace type ut_test under ut_suite_item (
a_after_test_proc_name varchar2 := null, a_after_each_proc_name varchar2 := null
) return self as result,
member function is_valid(self in out nocopy ut_test) return boolean,
member procedure set_beforeeach(self in out nocopy ut_test, a_before_each_proc_name varchar2),
member procedure set_aftereach(self in out nocopy ut_test, a_after_each_proc_name varchar2),
overriding member function do_execute(self in out nocopy ut_test, a_listener in out nocopy ut_event_listener_base) return boolean,
overriding member procedure calc_execution_result(self in out nocopy ut_test),
overriding member procedure mark_as_errored(self in out nocopy ut_test, a_listener in out nocopy ut_event_listener_base, a_error_stack_trace varchar2),
Expand Down
Loading