The package has be 'beautified' 2002-07-15, and it's easier to understand now
This package is intended to provide a 'safe' interaction between a process and a PostgreSQL database. By introducing some rules, the programmer is forced to behave in a certain way, or he/she will get an exception raised. The way of working with the package is aimed to simulate the way of working with Oracle's 'Dynamic SQL method 4'.
First of all, this package is in an early alpha stage, but it works fairly well. Some features are lacking, such as a way of connecting to several databases at a time. It is also made by a large static array, which is a waste of memory... Another drawback is that sql.statement_type variables must be declared globally in packages. The current limit is 700 statement and max 60 bind variables per statement. But that should cover most needs, or alter it in the sql body. I like it though...
The main difference between this package and all other I've seen is that this package uses cursors on the serverside for reading from the database. So selecting all from a table containing 100 000 rows will only send the data for 1 row at a time, which ocuurs when calling 'Fetch'. The next 'Fetch' will bring you the next row.
Quick tutorial
For just reading...
To update..
Transactions can have two modes, read_write or read_only.
sql.start_read_write_transaction(My_transaction2)
sql.start_read_only_transaction(My_transaction2)
In a read_only transaction, execute is not allowed. This is to make sure that no updates occur.
In read_write, update and inserts and deletes are allowed, of course.
It is possible to start several transactions, but they all have to be of the same type
or you are rewared with a TRANSACTION_ERROR exception. If you are not
the owner of a transaction and you try to rollback you also get a TRANSACTION_ERROR.
The transaction varable that starts the first transaction is regarded as the owner of the transaction.
Any started transactions after that, of the same type, is allowed but nothing happens when they commit.
The database will only see the BEGIN, COMMIT and ROLLBACK of the first transaction.
You'll get an exception if you rollback and is not the owner. Your application needs re-design if this happens :-)
A small sample program
with sql;
with text_io;
with gnat.traceback.symbolic;
procedure sql_leak_test is
stm,stm2 : sql.statement_type;
trans : sql.transaction_type;
maxloop : constant integer := 2_000; --4_000;
end_of_set : boolean := false;
f1 : integer := 0;
upd : constant string := "BNL";
begin
sql.Connect(db_name => "bnl");
for i in 1..maxloop loop
if (i mod 100 = 0) then
text_io.put_line ("i: " & i'img & " Total: " & maxloop'img);
end if;
sql.start_read_write_transaction(trans);
sql.prepare(stm,"select * from MY_TABLE where LATEST_UPDATER = :UPDATER");
sql.prepare(stm2,"update ISCONF set LATEST_UPDATER = 'BNL' where LATEST_UPDATER = :UPD");
sql.set(stm2,"UPD",upd);
sql.set(stm,"UPDATER",upd);
sql.open_cursor(stm);
sql.fetch(stm,end_of_set);
sql.close_cursor(stm);
if not end_of_set then
sql.get(stm,1,f1); -- get first column by column order instaed by name
end if;
sql.execute(stm2);
-- text_io.put_line ("f1: " & f1'img );
sql.commit(trans);
end loop;
sql.Close_Session;
exception
when Event: others =>
text_io.put_line(gnat.traceback.symbolic.symbolic_traceback(event));
end sql_leak_test;
If you use it, and find bugs or ways of improve it, please mail me at bjorn dot lundin at swipnet dot se