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.