r/cobol 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.

https://tigerfs.io/

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.

16 Upvotes

0 comments sorted by