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

Skip to content

Commit 6834866

Browse files
committed
Added test for ut_output_dbms_pipe.
Added abstraction for building other stream outputs: ut_output_stream. Major refactroings done
1 parent f6e4725 commit 6834866

29 files changed

Lines changed: 483 additions & 55 deletions

.travis/create_utplsql_user.sql

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,7 @@ grant create job to &ut3_user;
1818

1919
grant alter session to &ut3_user;
2020

21+
--only needed to run unit tests for utplsql v3, not required to run utplsql v3 itself
22+
grant select any dictionary to &ut3_user;
23+
2124
exit success

source/core/types/ut_clob_list.tps

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
create or replace type ut_clob_list as table of clob
2+
/

source/core/types/ut_output.tps

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ create or replace type ut_output as object (
55
not instantiable member procedure open(self in out nocopy ut_output),
66
not instantiable member procedure send_line(self in out nocopy ut_output, a_text varchar2),
77
not instantiable member procedure send_clob(self in out nocopy ut_output, a_text clob),
8-
not instantiable member procedure close(self in out nocopy ut_output)
8+
not instantiable member procedure close(self in out nocopy ut_output),
9+
not instantiable member function get_lines(a_output_id varchar2) return ut_varchar2_list pipelined,
10+
not instantiable member function get_clob_lines(a_output_id varchar2) return ut_clob_list pipelined
911
) not final not instantiable
1012
/

source/core/types/ut_output_dbms_output.tpb

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,35 @@ create or replace type body ut_output_dbms_output as
2929
null;
3030
end;
3131

32+
overriding final member function get_lines(a_output_id varchar2) return ut_varchar2_list pipelined is
33+
l_buffer clob;
34+
l_status integer;
35+
c_max_line_length constant integer := 4000;
36+
l_results_tab ut_varchar2_list;
37+
begin
38+
loop
39+
dbms_output.get_line (l_buffer, l_status);
40+
exit when l_status != 0;
41+
select column_value bulk collect into l_results_tab from table( ut_utils.clob_to_table(l_buffer, c_max_line_length));
42+
--pipe results one by one
43+
for i in 1 .. l_results_tab.count loop
44+
pipe row( l_results_tab(i) );
45+
end loop;
46+
end loop;
47+
return;
48+
end;
49+
50+
overriding final member function get_clob_lines(a_output_id varchar2) return ut_clob_list pipelined is
51+
l_buffer varchar2(32767);
52+
l_status integer;
53+
begin
54+
loop
55+
dbms_output.get_line (l_buffer, l_status);
56+
exit when l_status != 0;
57+
pipe row(l_buffer);
58+
end loop;
59+
return;
60+
end;
61+
3262
end;
3363
/

source/core/types/ut_output_dbms_output.tps

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ create or replace type ut_output_dbms_output under ut_output (
33
overriding member procedure open(self in out nocopy ut_output_dbms_output),
44
overriding member procedure send_line(self in out nocopy ut_output_dbms_output, a_text varchar2),
55
overriding member procedure send_clob(self in out nocopy ut_output_dbms_output, a_text clob),
6-
overriding member procedure close(self in out nocopy ut_output_dbms_output)
6+
overriding member procedure close(self in out nocopy ut_output_dbms_output),
7+
overriding final member function get_lines(a_output_id varchar2) return ut_varchar2_list pipelined,
8+
overriding final member function get_clob_lines(a_output_id varchar2) return ut_clob_list pipelined
79
) not final
810
/

source/core/types/ut_output_dbms_pipe.tpb

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,15 @@ create or replace type body ut_output_dbms_pipe as
3636
ut_output_pipe_helper.send_eom(self.output_id);
3737
end;
3838

39-
overriding member procedure close(self in out nocopy ut_output_dbms_pipe) is
39+
--we do not remove the pipe here, it is responsibility of the consumer,
40+
--when the pipe is fully consumed (recieved 'eot') then the consumer removed the pipe
41+
overriding member procedure close(self in out nocopy ut_output_dbms_pipe, a_timeout_sec integer) is
4042
begin
4143
ut_output_pipe_helper.send_eot(self.output_id);
42-
ut_output_pipe_helper.flush(self.output_id);
44+
ut_output_pipe_helper.flush(self.output_id, a_timeout_sec);
4345
end;
4446

45-
static function get_lines(a_output_id varchar2, a_timeout_sec integer := 60*60*4) return ut_varchar2_list pipelined is
47+
overriding member function get_lines(a_output_id varchar2, a_timeout_sec naturaln) return ut_varchar2_list pipelined is
4648
c_max_line_length constant integer := 4000;
4749
l_text clob;
4850
l_result_flag integer;
@@ -66,6 +68,32 @@ create or replace type body ut_output_dbms_pipe as
6668

6769
exit when l_result_flag in (ut_output_pipe_helper.gc_eot, ut_output_pipe_helper.gc_timeout);
6870
end loop;
71+
if l_result_flag = ut_output_pipe_helper.gc_eot then
72+
ut_output_pipe_helper.remove_pipe(a_output_id);
73+
end if;
74+
return;
75+
end;
76+
77+
overriding final member function get_clob_lines(a_output_id varchar2, a_timeout_sec naturaln) return ut_clob_list pipelined is
78+
l_text clob;
79+
l_result_flag integer;
80+
l_results_tab ut_varchar2_list;
81+
begin
82+
if a_output_id is null then
83+
return;
84+
end if;
85+
86+
loop
87+
dbms_lob.createtemporary(l_text, true);
88+
l_result_flag := ut_output_pipe_helper.get_message(a_output_id, a_timeout_sec, l_text);
89+
exit when l_result_flag in (ut_output_pipe_helper.gc_eot, ut_output_pipe_helper.gc_timeout);
90+
pipe row( l_text );
91+
dbms_lob.freetemporary(l_text);
92+
end loop;
93+
dbms_lob.freetemporary(l_text);
94+
if l_result_flag = ut_output_pipe_helper.gc_eot then
95+
ut_output_pipe_helper.remove_pipe(a_output_id);
96+
end if;
6997
return;
7098
end;
7199

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
create or replace type ut_output_dbms_pipe under ut_output (
1+
create or replace type ut_output_dbms_pipe under ut_output_stream (
22
constructor function ut_output_dbms_pipe(self in out nocopy ut_output_dbms_pipe) return self as result,
33
overriding member procedure open(self in out nocopy ut_output_dbms_pipe),
44
overriding member procedure send_line(self in out nocopy ut_output_dbms_pipe, a_text varchar2),
55
overriding member procedure send_clob(self in out nocopy ut_output_dbms_pipe, a_text clob),
6-
overriding member procedure close(self in out nocopy ut_output_dbms_pipe),
7-
static function get_lines(a_output_id varchar2, a_timeout_sec integer := 60*60*4) return ut_varchar2_list pipelined
6+
overriding member procedure close(self in out nocopy ut_output_dbms_pipe, a_timeout_sec integer),
7+
overriding member function get_lines(a_output_id varchar2, a_timeout_sec naturaln) return ut_varchar2_list pipelined,
8+
overriding final member function get_clob_lines(a_output_id varchar2, a_timeout_sec naturaln) return ut_clob_list pipelined
89
) not final
910
/
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
create or replace type body ut_output_stream as
2+
3+
overriding final member procedure close(self in out nocopy ut_output_stream) is
4+
begin
5+
self.close( a_timeout_sec=>60 );
6+
end;
7+
8+
overriding final member function get_lines(a_output_id varchar2) return ut_varchar2_list pipelined is
9+
begin
10+
for i in ( select column_value from table( self.get_lines(a_output_id, 60*60*4) ) ) loop
11+
pipe row(i.column_value);
12+
end loop;
13+
return;
14+
end;
15+
16+
overriding final member function get_clob_lines(a_output_id varchar2) return ut_clob_list pipelined is
17+
begin
18+
for i in ( select column_value from table( self.get_clob_lines(a_output_id, 60*60*4) ) ) loop
19+
pipe row(i.column_value);
20+
end loop;
21+
return;
22+
end;
23+
24+
end;
25+
/
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
create or replace type ut_output_stream under ut_output(
2+
overriding final member procedure close(self in out nocopy ut_output_stream),
3+
not instantiable member procedure close(self in out nocopy ut_output_stream, a_timeout_sec integer),
4+
overriding final member function get_lines(a_output_id varchar2) return ut_varchar2_list pipelined,
5+
not instantiable member function get_lines(a_output_id varchar2, a_timeout_sec naturaln) return ut_varchar2_list pipelined,
6+
overriding final member function get_clob_lines(a_output_id varchar2) return ut_clob_list pipelined,
7+
not instantiable member function get_clob_lines(a_output_id varchar2, a_timeout_sec naturaln) return ut_clob_list pipelined
8+
) not final not instantiable
9+
/

source/core/ut_output_pipe_helper.pkb

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,14 @@ create or replace package body ut_output_pipe_helper is
7171
l_output_id t_output_id;
7272
l_output_id_to_delete t_output_id;
7373
l_pipe_removal_status integer;
74-
l_timed_out boolean := false;
74+
l_succeeded boolean := false;
7575
begin
7676
l_output_id := g_outputs_buffer.first;
7777
while l_output_id is not null loop
7878
l_output_id_to_delete := null;
7979

80-
l_timed_out := not send_from_buffer(l_output_id, a_timeout_seconds);
81-
if not l_timed_out then
80+
l_succeeded := send_from_buffer(l_output_id, a_timeout_seconds);
81+
if l_succeeded then
8282
l_output_id_to_delete := l_output_id;
8383
end if;
8484
l_output_id := g_outputs_buffer.next(l_output_id);
@@ -88,7 +88,7 @@ create or replace package body ut_output_pipe_helper is
8888
end if;
8989

9090
end loop;
91-
return not l_timed_out;
91+
return l_succeeded;
9292
end;
9393

9494
--check if all the buffers are waiting to be flushed
@@ -105,12 +105,6 @@ create or replace package body ut_output_pipe_helper is
105105
return true;
106106
end;
107107

108-
procedure remove_pipe(a_output_id t_output_id) is
109-
l_status integer;
110-
begin
111-
l_status := dbms_pipe.remove_pipe(a_output_id);
112-
end;
113-
114108
-- - remove pipes associated with buffers that are not yet deleted
115109
-- - delete all the buffers
116110
-- TODO - The purge procedure needs to be called by top level program (ut_runner)
@@ -174,14 +168,16 @@ create or replace package body ut_output_pipe_helper is
174168
--marks a buffer as ready to be flushed
175169
--tries to flush all the data from all the outputs buffers to the pipes immediately
176170
--in case, all buffers outputs are to be flused, it will try with a timeout.
177-
procedure flush(a_output_id t_output_id, a_timeout_seconds naturaln := gc_flush_timeout_seconds) is
171+
procedure flush(a_output_id t_output_id, a_timeout_seconds naturaln) is
178172
l_buffers_flushed boolean := false;
179173
begin
180174
if g_outputs_buffer.exists(a_output_id) then
181175
g_outputs_buffer(a_output_id).to_flush := true;
182176
end if;
183177

184-
if (flush_buffers() = false) and all_buffers_to_flush() then
178+
l_buffers_flushed := flush_buffers();
179+
--if failed to flush data from buffer and all buffers are ready to be flushed
180+
if not l_buffers_flushed and all_buffers_to_flush() then
185181
--try as many times as there are seconds for timeout
186182
--each time try with one second delay
187183
for i in 1 .. a_timeout_seconds loop
@@ -224,5 +220,12 @@ create or replace package body ut_output_pipe_helper is
224220
end if;
225221
return l_result_flag;
226222
end;
223+
224+
procedure remove_pipe(a_output_id t_output_id) is
225+
l_status integer;
226+
begin
227+
l_status := dbms_pipe.remove_pipe(a_output_id);
228+
end;
229+
227230
end;
228231
/

0 commit comments

Comments
 (0)