Documentation home

Duro D/T with FastCGI

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.2/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.