DuroDBMS contains fcgi_durodt, a FastCGI-enabled version of the Duro D/T interpreter. fcgi_durodt uses the FastCGI Developer's Kit, available from fastcgi.com.
fcgi_durodt is not part of the standard DuroDBMS installation. It can be built from the DuroDBMS source distribution. Building fcgi_durodt requires the FastCGI Developer's Kit to be installed which is available from fastcgi.com
To build fcgi_durodt, type:
scons dli/fcgi_durodt
After fcgi_durodt has been built, install it by typing:
scons install
See also the file INSTALL for how to build and install DuroDBMS from the source distribution.
fcgi_durodt provides an update operator fcgi_accept which is defined as follows:
OPERATOR fcgi_accept(request_accepted boolean) UPDATES { request_accepted };
fcgi_accept waits for a request and sets request_accepted to TRUE if a request has arrived and is ready for processing. A value of FALSE indicates that an error occured and the program should exit.
A tiny example program:
#!/usr/local/durodbms.1.4/bin/fcgi_durodt
var request_accepted boolean;
var counter init 0;
while true;
fcgi.accept(request_accepted);
-- Exit loop if fcgi_accept() did not succeed
if not request_accepted then
leave;
end if;
io.put_line('Content-Type: text/html');
io.put_line('');
io.put_line('<html><title>FCGI Hello</title>');
io.put_line('<body>');
io.put('<p>Hello! Request number ');
io.put(counter);
io.put(' running on host ');
io.put_line(os.getenv('SERVER_NAME'));
counter := counter + 1;
end while;
Below a slightly more complex example program which returns the name of all real and virtual tables whose name matches a pattern passed with the request. The programm accesses the database D stored in the database environment /var/db/dbenv.
#!/usr/local/durodbms.1.2/bin/fcgi_durodt
connect('/var/db/dbenv');
current_db := 'D';
var request_method string;
var request_tp tup { pattern string };
var request_accepted bool;
while true;
fcgi.accept(request_accepted);
if not request_accepted then
leave;
end if;
request_method := os.getenv('REQUEST_METHOD');
if request_method = 'POST' or request_method = 'GET' then
if request_method = 'GET' then
net.form_to_tuple(request_tp, os.getenv('QUERY_STRING'));
else
var form_data binary;
read(form_data, cast_as_int(os.getenv('CONTENT_LENGTH')));
net.form_to_tuple(request_tp, cast_as_string(form_data));
end if;
io.put_line('Content-Type: text/html');
io.put_line('');
io.put_line('<html>');
io.put_line('<head>');
io.put_line('<title>Tables</title>');
io.put_line('<body>');
io.put('<p>Tables matching pattern ');
io.put(request_tp.pattern);
io.put_line(':');
var tablenames array tuple{tablename string};
-- Read catalog tables
begin tx;
load tablenames from (sys_rtables { tablename } union sys_vtables { tablename })
where the_name(tablename) like request_tp.pattern
order (tablename asc);
commit;
var i int;
for i := 0 to length(tablenames) - 1;
io.put('<p>');
io.put_line(tablenames[i].tablename);
end for;
io.put_line('</html>');
else
io.put_line('Status: 405 Method Not Allowed');
io.put_line('');
end if;
end while;
The program processes both GET and POST requests. It uses net.form_to_tuple to convert the query string or form data to a tuple.
For example, invoking the program using the URL http://localhost/fcgi-bin/gettables.td?pattern=* (assuming the program is stored under the name getttables.td in the fcgi-bin direcory of the local webserver) lists all tables in the database environment /var/db/dbenv. Make sure the environment directory and its files are readable and writable by the webserver.