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
Added missing annotation manager.
Removed unused code from ut_meta_data.
Improved code comments.
  • Loading branch information
jgebal committed Oct 14, 2017
commit ca31e98091c5e82d540d7b0650bb7be38587df4b
199 changes: 199 additions & 0 deletions source/core/annotations/ut_annotation_manager.pkb
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
create or replace package body ut_annotation_manager as
/*
utPLSQL - Version X.X.X.X
Copyright 2016 - 2017 utPLSQL Project

Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

------------------------------
--private definitions

function get_annotated_objects_cursor(a_object_owner varchar2, a_object_type varchar2, a_object_name varchar2) return sys_refcursor is
l_result sys_refcursor;
l_ut_owner varchar2(250) := ut_utils.ut_owner;
l_objects_view varchar2(200) := ut_metadata.get_dba_view('dba_objects');
l_cursor_text long;
begin
l_cursor_text :=
q'[select ]'||l_ut_owner||q'[.ut_annotation_cached_object(
object_owner => o.owner,
object_name => o.object_name,
object_type => o.object_type,
needs_refresh => case when o.last_ddl_time < i.parse_time then 'N' else 'Y' end,
cache_id => i.cache_id
)
from ]'||l_objects_view||q'[ o
left join ut3.ut_annotation_cache_info i
on o.owner = i.object_owner and o.object_name = i.object_name and o.object_type = i.object_type
where o.owner = :a_object_owner
and o.object_type = :a_object_type
and o.status = 'VALID'
and :a_object_name ]'|| case when a_object_name is not null then '= o.object_name' else 'is null' end;
open l_result for l_cursor_text using a_object_owner, a_object_type, a_object_name;
return l_result;
end;

function get_sources_for_annotations(a_object_owner varchar2, a_object_type varchar2, a_object_name varchar2) return sys_refcursor is
l_result sys_refcursor;
l_sources_view varchar2(200) := ut_metadata.get_dba_view('dba_source');
begin
open l_result for
q'[select s.name, s.text
from ]'||l_sources_view||q'[ s
where s.type = :a_object_type
and s.owner = :a_object_owner
and s.name
in (select x.name
from ]'||l_sources_view||q'[ x
where x.type = :a_object_type
and x.owner = :a_object_owner
and x.text like '%--%\%%' escape '\'
and :a_object_name ]'|| case when a_object_name is not null then '= x.name' else 'is null' end || q'[
)
order by name, line]'
using a_object_type, a_object_owner, a_object_type, a_object_owner, a_object_name;

return l_result;
end;

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
l_result sys_refcursor;
l_sources_view varchar2(200) := ut_metadata.get_dba_view('dba_source');
l_card natural;
begin
l_card := ut_utils.scale_cardinality(cardinality(a_objects_to_refresh));
open l_result for
q'[select /*+ cardinality( r ]'||l_card||q'[ )*/
s.name, s.text
from table(:a_objects_to_refresh) r
join ]'||l_sources_view||q'[ s
on s.name = r.object_name
where s.type = :a_object_type
and s.owner = :a_object_owner
and s.name
in (select /*+ cardinality( x ]'||l_card||q'[ )*/
x.name
from table(:a_objects_to_refresh) t
join ]'||l_sources_view||q'[ x
on x.name = t.object_name
where x.type = :a_object_type
and x.owner = :a_object_owner
and x.text like '%--%\%%' escape '\'
)
order by name, line]'
using a_objects_to_refresh, a_object_type, a_object_owner, a_objects_to_refresh, a_object_type, a_object_owner;

return l_result;
end;

------------------------------------------------------------
--public definitions
------------------------------------------------------------
function get_annotated_objects(a_object_owner varchar2, a_object_type varchar2, a_object_name varchar2 := null) return ut_annotated_objects pipelined is
l_info_rows ut_annotation_cached_objects;
l_in_cache ut_annotation_cached_objects;
l_to_parse ut_annotation_cached_objects := ut_annotation_cached_objects();
l_cursor sys_refcursor;
l_results ut_annotated_objects;
l_result ut_annotated_object;
c_object_fetch_limit constant integer := 10;
c_lines_fetch_limit constant integer := 1000;
l_lines dbms_preprocessor.source_lines_t;
l_names dbms_preprocessor.source_lines_t;
l_name varchar2(250) := '''';
l_object_lines dbms_preprocessor.source_lines_t;
begin
--get information about cached objects
l_cursor := get_annotated_objects_cursor(a_object_owner, a_object_type, a_object_name);
fetch l_cursor bulk collect into l_info_rows;
close l_cursor;

--get list of objects in cache
select value(x) bulk collect into l_in_cache from table(l_info_rows) x where x.needs_refresh = 'N';

--if not all in cache, get list of objects to refresh
if l_in_cache.count <= l_info_rows.count then
select value(x) bulk collect into l_to_parse from table(l_info_rows) x where x.needs_refresh = 'Y';
end if;

--pipe annotations from cache
if l_in_cache.count > 0 then
l_cursor := ut_annotation_cache_manager.get_annotations_for_objects(l_in_cache);
loop
fetch l_cursor bulk collect into l_results limit c_object_fetch_limit;
for i in 1 .. l_results.count loop
pipe row (l_results(i));
end loop;
exit when l_cursor%notfound;
end loop;
close l_cursor;
end if;

--if some source needs parsing
if l_to_parse.count > 0 then
--do we need to parse all of sources
if l_in_cache.count = 0 then
l_cursor := get_sources_for_annotations(a_object_owner, a_object_type, a_object_name);
else
-- sources need to be filtered by objects to parse
l_cursor := get_sources_for_annotations(a_object_owner, a_object_type, l_to_parse);
end if;

--remove cached annotations data for objects that will be refreshed
ut_annotation_cache_manager.cleanup_cache(l_to_parse);

loop
fetch l_cursor bulk collect into l_names, l_lines limit c_lines_fetch_limit;

for i in 1 .. l_names.count loop

if l_names(i) != l_name then
l_result := ut_annotated_object(
a_object_owner, l_name, a_object_type,
ut_annotation_parser.parse_object_annotations(l_object_lines)
);
ut_annotation_cache_manager.update_cache(l_result);
if l_result.annotations.count > 0 then
pipe row (l_result);
end if;
l_object_lines.delete;
end if;

l_name := l_names(i);
l_object_lines(l_object_lines.count+1) := l_lines(i);

end loop;
exit when l_cursor%notfound;

end loop;

if l_name is not null then
l_result := ut_annotated_object(
a_object_owner, l_name, a_object_type,
ut_annotation_parser.parse_object_annotations(l_object_lines)
);
ut_annotation_cache_manager.update_cache(l_result);
if l_result.annotations.count > 0 then
pipe row (l_result);
end if;
l_object_lines.delete;
end if;

close l_cursor;
end if;

end;

end ut_annotation_manager;
/
34 changes: 34 additions & 0 deletions source/core/annotations/ut_annotation_manager.pks
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
create or replace package ut_annotation_manager authid current_user as
/*
utPLSQL - Version X.X.X.X
Copyright 2016 - 2017 utPLSQL Project

Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

/**
* Builds annotations out of database source code by reading it from cache
*/

/**
* Parses an object or all objects of a specified type for database schema.
* Results are returned in as a pipelined function.
* @param a_object_owner schema name to be parsed
* @param a_object_type type of object to be parsed
* @param a_object_name name of object to be parsed - optional
* @return array containing annotated objects along with annotations for each object (nested)
*/
function get_annotated_objects(a_object_owner varchar2, a_object_type varchar2, a_object_name varchar2 := null) return ut_annotated_objects pipelined;

end ut_annotation_manager;
/
22 changes: 2 additions & 20 deletions source/core/ut_metadata.pkb
Original file line number Diff line number Diff line change
Expand Up @@ -115,24 +115,6 @@ create or replace package body ut_metadata as
return false;
end;

function get_package_spec_source(a_owner varchar2, a_object_name varchar2) return clob is
l_lines sys.dbms_preprocessor.source_lines_t;
l_cursor sys_refcursor;
l_source clob;
l_view_name varchar2(128) := get_dba_view('dba_source');
begin
open l_cursor for 'select text from '||l_view_name||q'[ s
where s.owner = :a_owner and s.name = :a_object_name and s.type = 'PACKAGE'
order by s.line]' using upper(a_owner), upper(a_object_name);
fetch l_cursor bulk collect into l_lines;
-- we fetch the source explicitly as dbms_preprocessor is very sow on 12.1 and 12.2 when grabbing the sources.
l_lines := sys.dbms_preprocessor.get_post_processed_source(l_lines);
for i in 1..l_lines.count loop
ut_utils.append_to_clob(l_source, replace(l_lines(i), chr(13)||chr(10), chr(10)));
end loop;
return l_source;
end;

function get_source_definition_line(a_owner varchar2, a_object_name varchar2, a_line_no integer) return varchar2 is
l_cursor sys_refcursor;
l_view_name varchar2(128) := get_dba_view('dba_source');
Expand Down Expand Up @@ -165,9 +147,9 @@ create or replace package body ut_metadata as
g_cached_object := null;
end;

function get_dba_view(a_view_name varchar2) return varchar2 is
function get_dba_view(a_dba_view_name varchar2) return varchar2 is
l_invalid_object_name exception;
l_result varchar2(128) := lower(a_view_name);
l_result varchar2(128) := lower(a_dba_view_name);
pragma exception_init(l_invalid_object_name,-44002);
begin
l_result := dbms_assert.sql_object_name(l_result);
Expand Down
92 changes: 36 additions & 56 deletions source/core/ut_metadata.pks
Original file line number Diff line number Diff line change
Expand Up @@ -16,78 +16,58 @@ create or replace package ut_metadata authid current_user as
limitations under the License.
*/

/*
package: ut_metadata

Common place for all code that reads from the system tables.

*/

/*
function: form_name

forms correct object/subprogram name to call as owner.object[.subprogram]

*/
/**
* Common package for all code that reads from the system tables.
*/

/**
* Forms correct object/subprogram name to call as owner.object[.subprogram]
*
*/
function form_name(a_owner_name varchar2, a_object varchar2, a_subprogram varchar2 default null) return varchar2;

/*
function: package_valid

check if package exists and is VALID.

*/
/**
* Check if package exists and is in a VALID state
*
*/
function package_valid(a_owner_name varchar2, a_package_name in varchar2) return boolean;

/*
function: procedure_exists

check if package exists and is VALID and contains the given procedure.

*/
/**
* Check if package exists and is VALID and contains the given procedure.
*
*/
function procedure_exists(a_owner_name varchar2, a_package_name in varchar2, a_procedure_name in varchar2)
return boolean;

/*
procedure: do_resolve

resolves [owner.]object using dbms_utility.name_resolve and returnes resolved parts

*/
/**
* Resolves [owner.]object using dbms_utility.name_resolve and returns resolved parts
*
*/
procedure do_resolve(a_owner in out nocopy varchar2, a_object in out nocopy varchar2);

/*
procedure: do_resolve

resolves [owner.]object[.procedure] using dbms_utility.name_resolve and returnes resolved parts

*/
/**
* Resolves [owner.]object[.procedure] using dbms_utility.name_resolve and returns resolved parts
*
*/
procedure do_resolve(a_owner in out nocopy varchar2, a_object in out nocopy varchar2, a_procedure_name in out nocopy varchar2);

/*
function: get_package_spec_source

return the text of the package specification for a given package
*/
function get_package_spec_source(a_owner varchar2, a_object_name varchar2) return clob;


/*
function: get_source_definition_line

return the text of the source line for a given object, excludes package spec and type spec
*/
/**
* Return the text of the source line for a given object (body). It excludes package spec and type spec
*/
function get_source_definition_line(a_owner varchar2, a_object_name varchar2, a_line_no integer) return varchar2;


/**
* Invalidates package-level cache for source.
* Caching is used to improve performance of function get_source_definition_line
*/
procedure reset_source_definition_cache;

/*
function: get_dba_view

return the dba_xxx view name if it is accessible or all_xxx view otherwise
*/
function get_dba_view(a_view_name varchar2) return varchar2;
/**
* Returns dba_... view name if it is accessible, otherwise it returns all_xxx view
* @param a_dba_view_name the name of dba view requested
*/
function get_dba_view(a_dba_view_name varchar2) return varchar2;

end ut_metadata;
/