@@ -16,6 +16,9 @@ create or replace package body ut_metadata as
1616 limitations under the License.
1717 */
1818
19+ type t_cache is table of all_source.text%type;
20+ g_source_cache t_cache;
21+ g_cached_object varchar2(500);
1922 ------------------------------
2023 --public definitions
2124
@@ -63,19 +66,20 @@ create or replace package body ut_metadata as
6366 l_schema varchar2(200);
6467 l_package_name varchar2(200);
6568 l_procedure_name varchar2(200);
69+ l_view_name varchar2(200) := get_dba_view('dba_objects');
6670 begin
6771
6872 l_schema := a_owner_name;
6973 l_package_name := a_package_name;
7074
7175 do_resolve(l_schema, l_package_name, l_procedure_name);
7276
73- select count(decode(status, 'VALID', 1, null)) / count(*)
74- into l_cnt
75- from all_objects
76- where owner = l_schema
77- and object_name = l_package_name
78- and object_type in ('PACKAGE') ;
77+ execute immediate q'[ select count(decode(status, 'VALID', 1, null)) / count(*)
78+ from ]'||l_view_name||q'[
79+ where owner = :l_schema
80+ and object_name = :l_package_name
81+ and object_type in ('PACKAGE')]'
82+ into l_cnt using l_schema, l_package_name ;
7983
8084 -- expect both package and body to be valid
8185 return l_cnt = 1;
@@ -90,6 +94,7 @@ create or replace package body ut_metadata as
9094 l_schema varchar2(200);
9195 l_package_name varchar2(200);
9296 l_procedure_name varchar2(200);
97+ l_view_name varchar2(200) := get_dba_view('dba_procedures');
9398 begin
9499
95100 l_schema := a_owner_name;
@@ -98,12 +103,10 @@ create or replace package body ut_metadata as
98103
99104 do_resolve(l_schema, l_package_name, l_procedure_name);
100105
101- select count(*)
102- into l_cnt
103- from all_procedures
104- where owner = l_schema
105- and object_name = l_package_name
106- and procedure_name = l_procedure_name;
106+ execute immediate
107+ 'select count(*) from '||l_view_name
108+ ||' where owner = :l_schema and object_name = :l_package_name and procedure_name = :l_procedure_name'
109+ into l_cnt using l_schema, l_package_name, l_procedure_name;
107110
108111 --expect one method only for the package with that name.
109112 return l_cnt = 1;
@@ -113,38 +116,59 @@ create or replace package body ut_metadata as
113116 end;
114117
115118 function get_package_spec_source(a_owner varchar2, a_object_name varchar2) return clob is
116- l_lines sys.dbms_preprocessor.source_lines_t;
117- l_source clob;
119+ l_lines sys.dbms_preprocessor.source_lines_t;
120+ l_cursor sys_refcursor;
121+ l_source clob;
122+ l_view_name varchar2(128) := get_dba_view('dba_source');
118123 begin
119- begin
120- l_lines := sys.dbms_preprocessor.get_post_processed_source(object_type => 'PACKAGE',
121- schema_name => a_owner,
122- object_name => a_object_name);
123-
124- for i in 1..l_lines.count loop
125- ut_utils.append_to_clob(l_source, l_lines(i));
126- end loop;
127-
128- end;
124+ open l_cursor for 'select text from '||l_view_name||q'[ s
125+ where s.owner = :a_owner and s.name = :a_object_name and s.type = 'PACKAGE'
126+ order by s.line]' using upper(a_owner), upper(a_object_name);
127+ fetch l_cursor bulk collect into l_lines;
128+ -- we fetch the source explicitly as dbms_preprocessor is very sow on 12.1 and 12.2 when grabbing the sources.
129+ l_lines := sys.dbms_preprocessor.get_post_processed_source(l_lines);
130+ for i in 1..l_lines.count loop
131+ ut_utils.append_to_clob(l_source, l_lines(i));
132+ end loop;
129133 return l_source;
130134 end;
131135
132136 function get_source_definition_line(a_owner varchar2, a_object_name varchar2, a_line_no integer) return varchar2 is
133- l_line varchar2(4000);
134137 l_cursor sys_refcursor;
138+ l_view_name varchar2(128) := get_dba_view('dba_source');
139+ l_line all_source.text%type;
140+ c_key constant varchar2(500) := a_owner || '.' || a_object_name;
135141 begin
136- open l_cursor for
137- select text from all_source s
138- where s.owner = a_owner and s.name = a_object_name and s.line = a_line_no
139- -- skip the declarations, consider only definitions
140- and s.type not in ('PACKAGE','TYPE');
141- fetch l_cursor into l_line;
142- close l_cursor;
143- return ltrim(rtrim( l_line, chr(10) ));
144- exception
145- when no_data_found then
146- return null;
142+ if not nvl(c_key = g_cached_object, false) then
143+ g_cached_object := c_key;
144+ execute immediate
145+ 'select trim(text) text
146+ from '||l_view_name||q'[ s
147+ where s.owner = :a_owner
148+ and s.name = :a_object_name
149+ /*skip the declarations, consider only definitions*/
150+ and s.type not in ('PACKAGE', 'TYPE')
151+ order by line]'
152+ bulk collect into g_source_cache
153+ using a_owner, a_object_name;
154+ end if;
155+
156+ if g_source_cache.exists(a_line_no) then
157+ l_line := g_source_cache(a_line_no);
158+ end if;
159+ return l_line;
147160 end;
148161
162+ function get_dba_view(a_view_name varchar2) return varchar2 is
163+ l_invalid_object_name exception;
164+ l_result varchar2(128) := lower(a_view_name);
165+ pragma exception_init(l_invalid_object_name,-44002);
166+ begin
167+ l_result := dbms_assert.sql_object_name(l_result);
168+ return l_result;
169+ exception
170+ when l_invalid_object_name then
171+ return replace(l_result,'dba_','all_');
172+ end;
149173end;
150174/
0 commit comments