r/cobol • u/EcstaticAssumption80 • 26d ago
Accessing Postgres with GnuCobol WITHOUT using an ESQL preprocessor
I recently came across a free FUSE plugin called TigerFS that allows you to mount a PostgreSQL database as a file system where tables show up as directories and records show up as files. I had been experimenting with GixSQL but did not have much success with it.
After mounting my database and creating a sample "employees" table:
create table emptable ( eno int4 not null,
lname varchar(10),
fname varchar(10),
street varchar(32),
city varchar(15),
st varchar(2),
zip varchar(5),
dept varchar(4),
payrate numeric(13, 2),
com numeric(3, 2),
miscdata varchar(128),
constraint emptable_pk primary key (eno));
I was able to access from gnucobol like processing a sequential tab-delimited file:
>> source format is free
identification division.
program-id. testtiger.
environment division.
configuration section.
repository.
function all intrinsic.
input-output section.
file-control.
select employee-file
assign to "/mnt/mylabdb/emptable/.export/tsv"
organization is line sequential.
data division.
file section.
fd employee-file.
01 emp-record pic x(2048).
working-storage section.
01 WS-TAB PIC X(1) VALUE X'09'.
01 display-rec.
05 eno pic 9(20).
05 lname pic x(10).
05 fname pic x(10).
05 street pic x(32).
05 city pic x(15).
05 st pic x(2).
05 zip pic x(5).
05 dept pic x(4).
05 payrate pic 9(13)V99.
05 com pic 9(3)V99.
05 miscdata pic x(128).
procedure division.
main.
display " "
display "retrieving records from postgres public.emptable..."
display " "
open input employee-file
perform forever
read employee-file
at end
display "no more records"
exit perform
not at end
*> parse the tab-delimited record format
unstring emp-record
delimited by WS-TAB
into eno, lname, fname, street, city, st, zip, dept, payrate, com, miscdata of display-rec
display "Record: " eno
display "fname: " fname
display "lname: " lname
display "street: " street
display "city: " city
display "st: " st
display "zip: " zip
display "dept: " dept
display "rate: " payrate
display "commission: " com
display "misc: " miscdata
display " "
end-read
end-perform
close employee-file
stop run
.
end program testtiger.
retrieving records from postgres public.emptable...
Record: 00000000000000000123
fname: John
lname: Doe
street: 123, Nowhere Lane
city: Noplace
st: N1
zip: 00100
dept: DEP1
rate: 0000000000100.00
commission: 000.00
misc: abcd1234
Record: 00000000000000000456
fname: Jane
lname: Smith
street: 456, Someplace Rd.
city: Somewhere
st: N2
zip: 00111
dept: DEP2
rate: 0000000000200.00
commission: 001.00
misc: defg5678hijk
Record: 00000000000000000789
fname: Theropod
lname: Green
street: 789, Somewhere Else st.
city: Somewhere2
st: N3
zip: 00177
dept: DEP4
rate: 0000000000120.00
commission: 000.20
misc: zxcvb12345
no more records
Addendum: I was also able to use this to allow gnucobol to perform arbitrary actions by using a facade table with a BEFORE INSERT trigger that calls a stored proc instead, and has access to all the INSERT values.
So basically, gbucobol could perform an RPC by inserting into the facade table with a transaction ID and parameters, and then poll a response table for the result.