Skip to content

Commit 3594725

Browse files
authored
Merge pull request IvorySQL#1168 from yasir-hussain-shah/feature/utl_file
Feature/utl file
2 parents a53ef3a + 8afb1e8 commit 3594725

10 files changed

Lines changed: 2384 additions & 13 deletions

File tree

contrib/ivorysql_ora/Makefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ OBJS = \
2626
src/builtin_functions/numeric_datatype_functions.o \
2727
src/builtin_functions/misc_functions.o \
2828
src/builtin_packages/dbms_output/dbms_output.o \
29+
src/builtin_packages/utl_file/utl_file.o \
2930
src/merge/ora_merge.o \
3031
src/sysview/sysview_functions.o \
3132
src/xml_functions/ora_xml_functions.o \
@@ -74,7 +75,8 @@ ORA_REGRESS = \
7475
ora_xml_functions \
7576
dbms_utility \
7677
ora_dbms_output \
77-
ora_ascii
78+
ora_ascii \
79+
utl_file
7880

7981
SHLIB_LINK += -lxml2
8082

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
--
2+
-- tests for utl_file package
3+
--
4+
-- insert a few directory objects for testing
5+
insert into sys.utl_file_directory(dirname, dir)
6+
select 'data_directory', current_setting('data_directory');
7+
-- test case for fopen with invalid directory object name
8+
declare
9+
f sys.ora_utl_file_file_type;
10+
begin
11+
-- an invalid directory object name
12+
f := utl_file.fopen('wrong_directory','regress.txt','a',1024);
13+
end;
14+
/
15+
ERROR: INVALID_PATH
16+
DETAIL: File location is invalid.
17+
HINT: locality is not found in sys.utl_file_directory table
18+
CONTEXT: PL/iSQL function fopen line 56 at assignment
19+
PL/iSQL function inline_code_block line 5 at assignment
20+
-- test fopen, put, putf, put_line, new_line, get_line, is_open, fclose, fclose_all
21+
declare
22+
f sys.ora_utl_file_file_type;
23+
line text;
24+
i integer;
25+
begin
26+
f := utl_file.fopen('data_directory', 'regress.txt', 'w');
27+
-- data writing
28+
utl_file.put_line(f, 'abc');
29+
utl_file.put_line(f, '123'::numeric);
30+
utl_file.put_line(f, '-----');
31+
utl_file.new_line(f);
32+
utl_file.put_line(f, '-----');
33+
utl_file.new_line(f, 0);
34+
utl_file.put_line(f, '-----');
35+
utl_file.new_line(f, 2);
36+
utl_file.put_line(f, '-----');
37+
utl_file.put(f, 'a');
38+
utl_file.put(f, 'b');
39+
utl_file.new_line(f);
40+
utl_file.putf(f, '[1=%s, 2=%s, 3=%s, 4=%s, 5=%s]', '1', '2', '3', '4', '5');
41+
utl_file.new_line(f);
42+
utl_file.put_line(f, '1234567890');
43+
utl_file.fclose(f);
44+
f := utl_file.fopen('data_directory', 'regress.txt', 'r');
45+
-- data reading
46+
i := 1;
47+
utl_file.get_line(f, line);
48+
while line is not null and i < 11 loop
49+
raise notice '[%] >>%<<', i, line;
50+
utl_file.get_line(f, line);
51+
i:=i+1;
52+
end loop;
53+
while line is not null loop
54+
raise notice '[%] >>%<<', i, line;
55+
utl_file.get_line(f, line, 3);
56+
i:=i+1;
57+
end loop;
58+
raise notice '>>%<<', line;
59+
utl_file.fclose(f);
60+
exception
61+
when others then
62+
raise notice 'exception: % ', sqlerrm;
63+
raise notice 'is_open(f) = %', utl_file.is_open(f);
64+
utl_file.fclose_all();
65+
raise notice 'is_open(f) = %', utl_file.is_open(f);
66+
end;
67+
/
68+
NOTICE: [1] >>abc<<
69+
NOTICE: [2] >>123<<
70+
NOTICE: [3] >>-----<<
71+
NOTICE: [4] >><<
72+
NOTICE: [5] >>-----<<
73+
NOTICE: [6] >>-----<<
74+
NOTICE: [7] >><<
75+
NOTICE: [8] >><<
76+
NOTICE: [9] >>-----<<
77+
NOTICE: [10] >>ab<<
78+
NOTICE: [11] >>[1=1, 2=2, 3=3, 4=4, 5=5]<<
79+
NOTICE: [12] >>123<<
80+
NOTICE: [13] >>456<<
81+
NOTICE: [14] >>789<<
82+
NOTICE: [15] >>0<<
83+
NOTICE: >><NULL><<
84+
-- test fgetattr, fcopy, fremove, frename
85+
declare
86+
fexists boolean;
87+
file_length number;
88+
block_size integer;
89+
begin
90+
utl_file.fgetattr('data_directory', 'regress.txt', fexists, file_length, block_size);
91+
raise notice 'fexists = %, file_length = %, block_size = %', fexists, file_length, block_size;
92+
utl_file.fcopy('data_directory', 'regress.txt', 'data_directory', 'regress2.txt');
93+
utl_file.fgetattr('data_directory', 'regress2.txt', fexists, file_length, block_size);
94+
raise notice 'fexists = %, file_length = %, block_size = %', fexists, file_length, block_size;
95+
utl_file.fremove('data_directory', 'regress2.txt');
96+
utl_file.fgetattr('data_directory', 'regress2.txt', fexists, file_length, block_size);
97+
raise notice 'fexists = %, file_length = %, block_size = %', fexists, file_length, block_size;
98+
utl_file.frename('data_directory', 'regress.txt', 'data_directory', 'regress2.txt', true);
99+
utl_file.fgetattr('data_directory', 'regress2.txt', fexists, file_length, block_size);
100+
raise notice 'fexists = %, file_length = %, block_size = %', fexists, file_length, block_size;
101+
end;
102+
/
103+
NOTICE: fexists = t, file_length = 75, block_size = 4096
104+
NOTICE: fexists = t, file_length = 75, block_size = 4096
105+
NOTICE: fexists = f, file_length = <NULL>, block_size = <NULL>
106+
NOTICE: fexists = t, file_length = 75, block_size = 4096
107+
-- test fflush, fseek
108+
declare
109+
f sys.ora_utl_file_file_type;
110+
f1 sys.ora_utl_file_file_type;
111+
line text;
112+
i integer;
113+
line2_pos integer;
114+
begin
115+
f := utl_file.fopen('data_directory', 'regressflush.txt', 'w');
116+
f1 := utl_file.fopen('data_directory', 'regressflush.txt', 'r');
117+
-- data writing
118+
for i in 1..5 loop
119+
utl_file.put_line(f, 'line ' || i::text);
120+
end loop;
121+
-- data reading before fflush
122+
raise notice 'data read before fflush';
123+
utl_file.get_line(f1, line);
124+
while line is not null loop
125+
raise notice '>>%<<', line;
126+
utl_file.get_line(f1, line);
127+
end loop;
128+
raise notice '>>%<<', line;
129+
utl_file.fflush(f);
130+
-- data reading after fflush
131+
utl_file.fseek(f1); -- reset off_set to 0
132+
raise notice 'data read after fflush';
133+
utl_file.get_line(f1, line);
134+
line2_pos := utl_file.fgetpos(f1); -- after reading line 1, get position
135+
while line is not null loop
136+
raise notice '>>%<<', line;
137+
utl_file.get_line(f1, line);
138+
end loop;
139+
raise notice '>>%<<', line;
140+
raise notice 'lets print line#2 again';
141+
utl_file.fseek(f1, line2_pos, NULL); -- seek to line 2 position
142+
utl_file.get_line(f1, line);
143+
raise notice '>>%<<', line;
144+
raise notice 'lets print line#2 again via relative seek';
145+
utl_file.fseek(f1, NULL, -7); -- move back one fixed "line X\n"
146+
utl_file.get_line(f1, line);
147+
raise notice '>>%<<', line;
148+
utl_file.fclose_all();
149+
exception
150+
when others then
151+
raise notice 'exception: % ', sqlerrm;
152+
raise notice 'is_open(f) = %', utl_file.is_open(f);
153+
raise notice 'is_open(f1) = %', utl_file.is_open(f1);
154+
utl_file.fclose_all();
155+
raise notice 'is_open(f) = %', utl_file.is_open(f);
156+
raise notice 'is_open(f1) = %', utl_file.is_open(f1);
157+
end;
158+
/
159+
NOTICE: data read before fflush
160+
NOTICE: >><NULL><<
161+
NOTICE: data read after fflush
162+
NOTICE: >>line 1<<
163+
NOTICE: >>line 2<<
164+
NOTICE: >>line 3<<
165+
NOTICE: >>line 4<<
166+
NOTICE: >>line 5<<
167+
NOTICE: >><NULL><<
168+
NOTICE: lets print line#2 again
169+
NOTICE: >>line 2<<
170+
NOTICE: lets print line#2 again via relative seek
171+
NOTICE: >>line 2<<
172+
-- test cases for automatic file closing on session terminated/rollback etc
173+
declare
174+
f sys.ora_utl_file_file_type;
175+
begin
176+
f := utl_file.fopen('data_directory','regress.txt','a',1024);
177+
raise notice 'is_open = %', utl_file.is_open(f);
178+
commit;
179+
raise notice 'is_open = %', utl_file.is_open(f);
180+
rollback;
181+
raise notice 'is_open = %', utl_file.is_open(f);
182+
end;
183+
/
184+
NOTICE: is_open = t
185+
NOTICE: is_open = t
186+
NOTICE: is_open = f
187+
-- clean up
188+
delete from sys.utl_file_directory where dirname = 'data_directory';
189+
/
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
src/datatype/datatype
22
src/builtin_functions/builtin_functions
33
src/builtin_packages/dbms_output/dbms_output
4+
src/builtin_packages/utl_file/utl_file
45
src/sysview/sysview
56
src/xml_functions/xml_functions
67
src/builtin_packages/dbms_utility/dbms_utility

contrib/ivorysql_ora/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ ivorysql_ora_sources = files(
2424
'src/builtin_functions/numeric_datatype_functions.c',
2525
'src/builtin_functions/misc_functions.c',
2626
'src/builtin_packages/dbms_output/dbms_output.c',
27+
'src/builtin_packages/utl_file/utl_file.c',
2728
'src/merge/ora_merge.c',
2829
'src/sysview/sysview_functions.c',
2930
'src/xml_functions/ora_xml_functions.c',
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
--
2+
-- tests for utl_file package
3+
--
4+
5+
-- insert a few directory objects for testing
6+
insert into sys.utl_file_directory(dirname, dir)
7+
select 'data_directory', current_setting('data_directory');
8+
9+
-- test case for fopen with invalid directory object name
10+
declare
11+
f sys.ora_utl_file_file_type;
12+
begin
13+
-- an invalid directory object name
14+
f := utl_file.fopen('wrong_directory','regress.txt','a',1024);
15+
end;
16+
/
17+
18+
-- test fopen, put, putf, put_line, new_line, get_line, is_open, fclose, fclose_all
19+
declare
20+
f sys.ora_utl_file_file_type;
21+
line text;
22+
i integer;
23+
begin
24+
f := utl_file.fopen('data_directory', 'regress.txt', 'w');
25+
26+
-- data writing
27+
utl_file.put_line(f, 'abc');
28+
utl_file.put_line(f, '123'::numeric);
29+
utl_file.put_line(f, '-----');
30+
utl_file.new_line(f);
31+
utl_file.put_line(f, '-----');
32+
utl_file.new_line(f, 0);
33+
utl_file.put_line(f, '-----');
34+
utl_file.new_line(f, 2);
35+
utl_file.put_line(f, '-----');
36+
utl_file.put(f, 'a');
37+
utl_file.put(f, 'b');
38+
utl_file.new_line(f);
39+
utl_file.putf(f, '[1=%s, 2=%s, 3=%s, 4=%s, 5=%s]', '1', '2', '3', '4', '5');
40+
utl_file.new_line(f);
41+
utl_file.put_line(f, '1234567890');
42+
utl_file.fclose(f);
43+
44+
f := utl_file.fopen('data_directory', 'regress.txt', 'r');
45+
46+
-- data reading
47+
i := 1;
48+
utl_file.get_line(f, line);
49+
while line is not null and i < 11 loop
50+
raise notice '[%] >>%<<', i, line;
51+
utl_file.get_line(f, line);
52+
i:=i+1;
53+
54+
end loop;
55+
56+
while line is not null loop
57+
raise notice '[%] >>%<<', i, line;
58+
utl_file.get_line(f, line, 3);
59+
i:=i+1;
60+
end loop;
61+
62+
raise notice '>>%<<', line;
63+
utl_file.fclose(f);
64+
65+
exception
66+
when others then
67+
raise notice 'exception: % ', sqlerrm;
68+
raise notice 'is_open(f) = %', utl_file.is_open(f);
69+
utl_file.fclose_all();
70+
raise notice 'is_open(f) = %', utl_file.is_open(f);
71+
end;
72+
/
73+
74+
-- test fgetattr, fcopy, fremove, frename
75+
declare
76+
fexists boolean;
77+
file_length number;
78+
block_size integer;
79+
begin
80+
utl_file.fgetattr('data_directory', 'regress.txt', fexists, file_length, block_size);
81+
raise notice 'fexists = %, file_length = %, block_size = %', fexists, file_length, block_size;
82+
utl_file.fcopy('data_directory', 'regress.txt', 'data_directory', 'regress2.txt');
83+
utl_file.fgetattr('data_directory', 'regress2.txt', fexists, file_length, block_size);
84+
raise notice 'fexists = %, file_length = %, block_size = %', fexists, file_length, block_size;
85+
utl_file.fremove('data_directory', 'regress2.txt');
86+
utl_file.fgetattr('data_directory', 'regress2.txt', fexists, file_length, block_size);
87+
raise notice 'fexists = %, file_length = %, block_size = %', fexists, file_length, block_size;
88+
utl_file.frename('data_directory', 'regress.txt', 'data_directory', 'regress2.txt', true);
89+
utl_file.fgetattr('data_directory', 'regress2.txt', fexists, file_length, block_size);
90+
raise notice 'fexists = %, file_length = %, block_size = %', fexists, file_length, block_size;
91+
end;
92+
/
93+
94+
-- test fflush, fseek
95+
declare
96+
f sys.ora_utl_file_file_type;
97+
f1 sys.ora_utl_file_file_type;
98+
line text;
99+
i integer;
100+
line2_pos integer;
101+
begin
102+
f := utl_file.fopen('data_directory', 'regressflush.txt', 'w');
103+
f1 := utl_file.fopen('data_directory', 'regressflush.txt', 'r');
104+
105+
-- data writing
106+
for i in 1..5 loop
107+
utl_file.put_line(f, 'line ' || i::text);
108+
end loop;
109+
110+
-- data reading before fflush
111+
raise notice 'data read before fflush';
112+
utl_file.get_line(f1, line);
113+
while line is not null loop
114+
raise notice '>>%<<', line;
115+
utl_file.get_line(f1, line);
116+
end loop;
117+
raise notice '>>%<<', line;
118+
119+
utl_file.fflush(f);
120+
121+
-- data reading after fflush
122+
utl_file.fseek(f1); -- reset off_set to 0
123+
raise notice 'data read after fflush';
124+
utl_file.get_line(f1, line);
125+
line2_pos := utl_file.fgetpos(f1); -- after reading line 1, get position
126+
while line is not null loop
127+
raise notice '>>%<<', line;
128+
utl_file.get_line(f1, line);
129+
end loop;
130+
raise notice '>>%<<', line;
131+
raise notice 'lets print line#2 again';
132+
utl_file.fseek(f1, line2_pos, NULL); -- seek to line 2 position
133+
utl_file.get_line(f1, line);
134+
raise notice '>>%<<', line;
135+
raise notice 'lets print line#2 again via relative seek';
136+
utl_file.fseek(f1, NULL, -7); -- move back one fixed "line X\n"
137+
utl_file.get_line(f1, line);
138+
raise notice '>>%<<', line;
139+
140+
utl_file.fclose_all();
141+
142+
exception
143+
when others then
144+
raise notice 'exception: % ', sqlerrm;
145+
raise notice 'is_open(f) = %', utl_file.is_open(f);
146+
raise notice 'is_open(f1) = %', utl_file.is_open(f1);
147+
utl_file.fclose_all();
148+
raise notice 'is_open(f) = %', utl_file.is_open(f);
149+
raise notice 'is_open(f1) = %', utl_file.is_open(f1);
150+
end;
151+
/
152+
153+
-- test cases for automatic file closing on session terminated/rollback etc
154+
declare
155+
f sys.ora_utl_file_file_type;
156+
begin
157+
f := utl_file.fopen('data_directory','regress.txt','a',1024);
158+
159+
raise notice 'is_open = %', utl_file.is_open(f);
160+
commit;
161+
raise notice 'is_open = %', utl_file.is_open(f);
162+
rollback;
163+
raise notice 'is_open = %', utl_file.is_open(f);
164+
end;
165+
/
166+
167+
-- clean up
168+
delete from sys.utl_file_directory where dirname = 'data_directory';
169+
/

0 commit comments

Comments
 (0)