@@ -19,32 +19,30 @@ create or replace package body ut_annotation_manager as
1919 ------------------------------
2020 --private definitions
2121
22- function get_annotated_objects_cursor (a_object_owner varchar2, a_object_type varchar2, a_object_name varchar2) return sys_refcursor is
22+ function get_annotation_objs_info_cur (a_object_owner varchar2, a_object_type varchar2) return sys_refcursor is
2323 l_result sys_refcursor;
2424 l_ut_owner varchar2(250) := ut_utils.ut_owner;
2525 l_objects_view varchar2(200) := ut_metadata.get_dba_view('dba_objects');
2626 l_cursor_text long;
2727 begin
2828 l_cursor_text :=
29- q'[select ]'||l_ut_owner||q'[.ut_annotation_cached_object (
29+ q'[select ]'||l_ut_owner||q'[.ut_annotation_obj_cache_info (
3030 object_owner => o.owner,
3131 object_name => o.object_name,
3232 object_type => o.object_type,
33- needs_refresh => case when o.last_ddl_time < i.parse_time then 'N' else 'Y' end,
34- cache_id => i.cache_id
33+ needs_refresh => case when o.last_ddl_time < i.parse_time then 'N' else 'Y' end
3534 )
3635 from ]'||l_objects_view||q'[ o
3736 left join ]'||l_ut_owner||q'[.ut_annotation_cache_info i
3837 on o.owner = i.object_owner and o.object_name = i.object_name and o.object_type = i.object_type
3938 where o.owner = :a_object_owner
4039 and o.object_type = :a_object_type
41- and o.status = 'VALID'
42- and :a_object_name ]'|| case when a_object_name is not null then '= o.object_name' else 'is null' end;
43- open l_result for l_cursor_text using a_object_owner, a_object_type, a_object_name;
40+ and o.status = 'VALID' ]';
41+ open l_result for l_cursor_text using a_object_owner, a_object_type;
4442 return l_result;
4543 end;
4644
47- function get_sources_for_annotations (a_object_owner varchar2, a_object_type varchar2, a_object_name varchar2) return sys_refcursor is
45+ function get_sources_to_annotate (a_object_owner varchar2, a_object_type varchar2) return sys_refcursor is
4846 l_result sys_refcursor;
4947 l_sources_view varchar2(200) := ut_metadata.get_dba_view('dba_source');
5048 begin
@@ -59,15 +57,14 @@ create or replace package body ut_annotation_manager as
5957 where x.type = :a_object_type
6058 and x.owner = :a_object_owner
6159 and x.text like '%--%\%%' escape '\'
62- and :a_object_name ]'|| case when a_object_name is not null then '= x.name' else 'is null' end || q'[
6360 )
6461 order by name, line]'
65- using a_object_type, a_object_owner, a_object_type, a_object_owner, a_object_name ;
62+ using a_object_type, a_object_owner, a_object_type, a_object_owner;
6663
6764 return l_result;
6865 end;
6966
70- 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
67+ function get_sources_to_annotate (a_object_owner varchar2, a_object_type varchar2, a_objects_to_refresh ut_annotation_objs_cache_info ) return sys_refcursor is
7168 l_result sys_refcursor;
7269 l_sources_view varchar2(200) := ut_metadata.get_dba_view('dba_source');
7370 l_card natural;
@@ -97,101 +94,117 @@ create or replace package body ut_annotation_manager as
9794 return l_result;
9895 end;
9996
100- ------------------------------------------------------------
101- --public definitions
102- ------------------------------------------------------------
103- function get_annotated_objects(a_object_owner varchar2, a_object_type varchar2, a_object_name varchar2 := null) return ut_annotated_objects pipelined is
104- l_info_rows ut_annotation_cached_objects;
105- l_in_cache ut_annotation_cached_objects;
106- l_to_parse ut_annotation_cached_objects := ut_annotation_cached_objects();
107- l_cursor sys_refcursor;
108- l_results ut_annotated_objects;
109- l_result ut_annotated_object;
110- c_object_fetch_limit constant integer := 10;
97+ procedure build_annot_cache_for_sources(
98+ a_object_owner varchar2, a_object_type varchar2, a_sources_cursor sys_refcursor,
99+ a_schema_objects ut_annotation_objs_cache_info
100+ ) is
101+ l_annotations ut_annotations;
111102 c_lines_fetch_limit constant integer := 1000;
112103 l_lines dbms_preprocessor.source_lines_t;
113104 l_names dbms_preprocessor.source_lines_t;
114- l_name varchar2(250) := '''' ;
105+ l_name varchar2(250);
115106 l_object_lines dbms_preprocessor.source_lines_t;
107+ pragma autonomous_transaction;
116108 begin
117- --get information about cached objects
118- l_cursor := get_annotated_objects_cursor(a_object_owner, a_object_type, a_object_name);
119- fetch l_cursor bulk collect into l_info_rows;
120- close l_cursor;
121-
122- --get list of objects in cache
123- select value(x) bulk collect into l_in_cache from table(l_info_rows) x where x.needs_refresh = 'N';
124-
125- --if not all in cache, get list of objects to refresh
126- if l_in_cache.count <= l_info_rows.count then
127- select value(x) bulk collect into l_to_parse from table(l_info_rows) x where x.needs_refresh = 'Y';
128- end if;
109+ ut_annotation_cache_manager.cleanup_cache(a_schema_objects);
110+ loop
111+ fetch a_sources_cursor bulk collect into l_names, l_lines limit c_lines_fetch_limit;
112+ for i in 1 .. l_names.count loop
113+ if l_names(i) != l_name then
114+ l_annotations := ut_annotation_parser.parse_object_annotations(l_object_lines);
115+ ut_annotation_cache_manager.update_cache(
116+ ut_annotated_object(a_object_owner, l_name, a_object_type, l_annotations)
117+ );
118+ l_object_lines.delete;
119+ end if;
129120
130- --pipe annotations from cache
131- if l_in_cache.count > 0 then
132- l_cursor := ut_annotation_cache_manager.get_annotations_for_objects(l_in_cache);
133- loop
134- fetch l_cursor bulk collect into l_results limit c_object_fetch_limit;
135- for i in 1 .. l_results.count loop
136- pipe row (l_results(i));
137- end loop;
138- exit when l_cursor%notfound;
121+ l_name := l_names(i);
122+ l_object_lines(l_object_lines.count+1) := l_lines(i);
139123 end loop;
140- close l_cursor;
124+ exit when a_sources_cursor%notfound;
125+
126+ end loop;
127+ if a_sources_cursor%rowcount > 0 then
128+ l_annotations := ut_annotation_parser.parse_object_annotations(l_object_lines);
129+ ut_annotation_cache_manager.update_cache(
130+ ut_annotated_object(a_object_owner, l_name, a_object_type, l_annotations)
131+ );
132+ l_object_lines.delete;
141133 end if;
134+ close a_sources_cursor;
135+ commit;
136+ end;
142137
143- --if some source needs parsing
144- if l_to_parse.count > 0 then
145- --do we need to parse all of sources
146- if l_in_cache.count = 0 then
147- l_cursor := get_sources_for_annotations(a_object_owner, a_object_type, a_object_name);
148- else
149- -- sources need to be filtered by objects to parse
150- l_cursor := get_sources_for_annotations(a_object_owner, a_object_type, l_to_parse);
151- end if;
152-
153- --remove cached annotations data for objects that will be refreshed
154- ut_annotation_cache_manager.cleanup_cache(l_to_parse);
155138
156- loop
157- fetch l_cursor bulk collect into l_names, l_lines limit c_lines_fetch_limit;
139+ procedure rebuild_annotation_cache( a_object_owner varchar2, a_object_type varchar2, a_info_rows ut_annotation_objs_cache_info) is
140+ l_objects_in_cache_count integer;
141+ l_objects_to_parse ut_annotation_objs_cache_info := ut_annotation_objs_cache_info();
142+ begin
143+ --get list of objects in cache
144+ select count( 1)into l_objects_in_cache_count from table(a_info_rows) x where x.needs_refresh = 'N';
158145
159- for i in 1 .. l_names.count loop
146+ --if cache is empty and there are objects to parse
147+ if l_objects_in_cache_count = 0 and a_info_rows.count > 0 then
160148
161- if l_names(i) != l_name then
162- l_result := ut_annotated_object(
163- a_object_owner, l_name, a_object_type,
164- ut_annotation_parser.parse_object_annotations(l_object_lines)
165- );
166- ut_annotation_cache_manager.update_cache(l_result);
167- if l_result.annotations.count > 0 then
168- pipe row (l_result);
169- end if;
170- l_object_lines.delete;
171- end if;
149+ build_annot_cache_for_sources(
150+ a_object_owner, a_object_type,
151+ --all schema objects
152+ get_sources_to_annotate(a_object_owner, a_object_type),
153+ a_info_rows
154+ );
172155
173- l_name := l_names(i);
174- l_object_lines(l_object_lines .count+1) := l_lines(i);
156+ --if not all in cache, get list of objects to rebuild cache for
157+ elsif l_objects_in_cache_count < a_info_rows .count then
175158
176- end loop;
177- exit when l_cursor%notfound;
159+ select value(x)bulk collect into l_objects_to_parse from table(a_info_rows) x where x.needs_refresh = 'Y';
178160
179- end loop;
180-
181- if l_name is not null then
182- l_result := ut_annotated_object(
183- a_object_owner, l_name, a_object_type ,
184- ut_annotation_parser.parse_object_annotations(l_object_lines)
161+ --if some source needs parsing and putting into cache
162+ if l_objects_to_parse.count > 0 then
163+ build_annot_cache_for_sources(
164+ a_object_owner, a_object_type,
165+ get_sources_to_annotate( a_object_owner, a_object_type, l_objects_to_parse) ,
166+ l_objects_to_parse
185167 );
186- ut_annotation_cache_manager.update_cache(l_result);
187- if l_result.annotations.count > 0 then
188- pipe row (l_result);
189- end if;
190- l_object_lines.delete;
191168 end if;
192169
193- close l_cursor;
194170 end if;
171+ end;
172+
173+ ------------------------------------------------------------
174+ --public definitions
175+ ------------------------------------------------------------
176+ procedure rebuild_annotation_cache(a_object_owner varchar2, a_object_type varchar2) is
177+ l_info_cursor sys_refcursor;
178+ l_info_rows ut_annotation_objs_cache_info;
179+ begin
180+ l_info_cursor := get_annotation_objs_info_cur(a_object_owner, a_object_type);
181+ fetch l_info_cursor bulk collect into l_info_rows;
182+ close l_info_cursor;
183+ rebuild_annotation_cache(a_object_owner, a_object_type, l_info_rows);
184+ end;
185+
186+ function get_annotated_objects(a_object_owner varchar2, a_object_type varchar2) return ut_annotated_objects pipelined is
187+ l_info_cursor sys_refcursor;
188+ l_info_rows ut_annotation_objs_cache_info;
189+ l_cursor sys_refcursor;
190+ l_results ut_annotated_objects;
191+ c_object_fetch_limit constant integer := 10;
192+ begin
193+ l_info_cursor := get_annotation_objs_info_cur(a_object_owner, a_object_type);
194+ fetch l_info_cursor bulk collect into l_info_rows;
195+ close l_info_cursor;
196+ rebuild_annotation_cache(a_object_owner, a_object_type, l_info_rows);
197+
198+ --pipe annotations from cache
199+ l_cursor := ut_annotation_cache_manager.get_annotations_for_objects(l_info_rows);
200+ loop
201+ fetch l_cursor bulk collect into l_results limit c_object_fetch_limit;
202+ for i in 1 .. l_results.count loop
203+ pipe row (l_results(i));
204+ end loop;
205+ exit when l_cursor%notfound;
206+ end loop;
207+ close l_cursor;
195208
196209 end;
197210
0 commit comments