11create or replace package body ut_metadata as
22
3+ g_source_view varchar2(32);
4+
5+ function get_source_cursor(a_source_view varchar2, a_owner varchar2, a_object varchar2) return sys_refcursor is
6+ c_query_str constant varchar2(1000) := 'select t.text from ' || a_source_view ||
7+ ' t where t.owner = :a_owner and t.name = :a_object_name and t.type = ''PACKAGE'' order by t.line';
8+ l_cur sys_refcursor;
9+
10+ begin
11+ open l_cur for c_query_str
12+ using a_owner, a_object;
13+ return l_cur;
14+ end;
15+
316 procedure do_resolve(a_owner in out varchar2, a_object in out varchar2, a_procedure_name in out varchar2) is
417 l_name varchar2(200);
518 l_context integer;
@@ -183,6 +196,31 @@ create or replace package body ut_metadata as
183196 end print_parse_results;
184197 $end
185198
199+ function get_source(a_owner varchar2, a_object_name varchar2) return clob is
200+ l_source clob;
201+ l_txt varchar2(4000);
202+ l_cur sys_refcursor;
203+ begin
204+
205+ dbms_lob.createtemporary(l_source, true);
206+
207+ l_cur := get_source_cursor(g_source_view, a_owner, a_object_name);
208+
209+ loop
210+ fetch l_cur
211+ into l_txt;
212+ exit when l_cur%notfound;
213+ dbms_lob.writeappend(l_source, length(l_txt), l_txt);
214+ end loop;
215+
216+ close l_cur;
217+
218+ return l_source;
219+
220+ --l_source := dbms_metadata.get_ddl(object_type => 'PACKAGE_SPEC', name => a_object_name, schema => a_owner);
221+ --return l_source;
222+ end get_source;
223+
186224 function get_annotations(a_source varchar2) return tt_annotations is
187225 l_loop_index pls_integer := 1;
188226 l_comment_index pls_integer;
@@ -257,7 +295,11 @@ create or replace package body ut_metadata as
257295
258296 end;
259297 begin
260- l_pkg_spec := dbms_metadata.get_ddl(object_type => 'PACKAGE_SPEC', name => a_name, schema => a_owner_name);
298+ l_pkg_spec := get_source(a_owner_name, a_name);
299+
300+ if l_pkg_spec is null then
301+ return;
302+ end if;
261303
262304 -- delete multiline comments
263305 l_pkg_spec := regexp_replace(srcstr => l_pkg_spec, pattern => c_multiline_comment_pattern, modifier => 'n');
@@ -271,30 +313,31 @@ create or replace package body ut_metadata as
271313 -- replace all single line comments with {COMMENT#12} element and store it's content for easier processing
272314 l_comment_pos := 1;
273315 loop
274- l_comment_pos := regexp_instr(srcstr => l_pkg_spec
275- ,pattern => c_singleline_comment_pattern
276- ,occurrence => 1
277- ,modifier => 'm'
278- ,position => l_comment_pos
279- --,subexpression => 1
280- );
316+ l_comment_pos := regexp_instr(srcstr => l_pkg_spec
317+ ,pattern => c_singleline_comment_pattern
318+ ,occurrence => 1
319+ ,modifier => 'm'
320+ ,position => l_comment_pos
321+ --,subexpression => 1
322+ );
281323 exit when l_comment_pos = 0;
282- l_comment := trim( regexp_substr(srcstr => l_pkg_spec
283- ,pattern => c_singleline_comment_pattern
284- ,occurrence => 1
285- ,position => l_comment_pos
286- ,modifier => 'm'
287- ,subexpression => 1) );
324+ l_comment := regexp_substr(srcstr => l_pkg_spec
325+ ,pattern => c_singleline_comment_pattern
326+ ,occurrence => 1
327+ ,position => l_comment_pos
328+ ,modifier => 'm'
329+ ,subexpression => 1);
288330
289- l_comments(l_comments.count + 1) := l_comment;
331+ l_comments(l_comments.count + 1) := trim( l_comment) ;
290332 l_comment_replacer := replace(c_comment_replacer_patter, '%N%', l_comments.count);
291333
292- l_pkg_spec := regexp_replace(srcstr => l_pkg_spec
293- ,pattern => c_singleline_comment_pattern
294- ,replacestr => l_comment_replacer
295- ,position => l_comment_pos
296- ,occurrence => 1
297- ,modifier => 'm');
334+ l_pkg_spec := regexp_replace(srcstr => l_pkg_spec
335+ ,pattern => c_singleline_comment_pattern
336+ ,replacestr => l_comment_replacer
337+ ,position => l_comment_pos
338+ ,occurrence => 1
339+ ,modifier => 'm');
340+ l_comment_pos := l_comment_pos + length(l_comment);
298341
299342 end loop;
300343
@@ -303,12 +346,11 @@ create or replace package body ut_metadata as
303346 $end
304347
305348 l_package_comments := regexp_substr(srcstr => l_pkg_spec
306- ,pattern => '^\s*CREATE\s+(OR\s+REPLACE)?(\s+(NON)?EDITIONABLE)?\s+PACKAGE .*?(AS|IS)\s+((.*?{COMMENT#\d+}\s?)+)'
349+ ,pattern => '^\s*( CREATE\s+(OR\s+REPLACE)?(\s+(NON)?EDITIONABLE)? )?\s+PACKAGE .*?(AS|IS)\s+((.*?{COMMENT#\d+}\s?)+)'
307350 ,modifier => 'i'
308- ,subexpression => 5 );
351+ ,subexpression => 6 );
309352
310353 -- parsing for package annotations
311- --v_annotated_pkg.name := pkg_name;
312354 if l_package_comments is not null then
313355 a_annotated_pkg.annotations := get_annotations(l_package_comments);
314356 end if;
@@ -320,35 +362,30 @@ create or replace package body ut_metadata as
320362 ,pattern => c_annotation_block_pattern
321363 ,occurrence => 1
322364 ,modifier => 'i'
323- ,position => l_annot_proc_ind
324- --,subexpression => 0
325- );
365+ ,position => l_annot_proc_ind);
326366
327367 exit when l_annot_proc_ind = 0;
328368
329- l_annot_proc_block := trim( regexp_substr(srcstr => l_pkg_spec
330- ,pattern => c_annotation_block_pattern
331- ,position => l_annot_proc_ind
332- ,occurrence => 1
333- ,modifier => 'i'
334- --,subexpression => 0
335- ) );
369+ l_annot_proc_block := regexp_substr(srcstr => l_pkg_spec
370+ ,pattern => c_annotation_block_pattern
371+ ,position => l_annot_proc_ind
372+ ,occurrence => 1
373+ ,modifier => 'i');
374+
375+ l_annot_proc_ind := l_annot_proc_ind + length(l_annot_proc_block );
336376
337- l_proc_comments := trim(regexp_substr(srcstr => l_annot_proc_block
338- ,pattern => c_annotation_block_pattern
339- --,occurrence => 1
377+ l_proc_comments := trim(regexp_substr(srcstr => l_annot_proc_block
378+ ,pattern => c_annotation_block_pattern
340379 ,modifier => 'i'
341380 ,subexpression => 1));
342- l_proc_name := trim(regexp_substr(srcstr => l_annot_proc_block
343- ,pattern => c_annotation_block_pattern
344- --,occurrence => 1
381+ l_proc_name := trim(regexp_substr(srcstr => l_annot_proc_block
382+ ,pattern => c_annotation_block_pattern
345383 ,modifier => 'i'
346384 ,subexpression => 4));
347385
348386 -- parse the comment block for the syntactically correct annotations and store them as an array
349387 a_annotated_pkg.procedures(l_proc_name) := get_annotations(l_proc_comments);
350388
351- l_annot_proc_ind := l_annot_proc_ind + 1;
352389 end loop;
353390
354391 -- printing out parsed structure for debugging
@@ -366,5 +403,19 @@ create or replace package body ut_metadata as
366403 end if;
367404 return l_result;
368405 end get_annotation_param;
406+ begin
407+ declare
408+ l_cur_temp sys_refcursor;
409+ begin
410+
411+ l_cur_temp := get_source_cursor('dba_source', null, null);
412+ g_source_view := 'dba_source';
413+ close l_cur_temp;
414+
415+ exception
416+ when others then
417+ g_source_view := 'all_source';
418+ end;
419+
369420end;
370421/
0 commit comments