waitman

Waitman Gobble, San Jose California

Hello, I am experimenting with the "Database as a Program" methodology described by D. Richard Hipp in the article SQLite and Tcl

At the moment my application consists of a short and simple main.tcl which decides which code segment to load from an sqlite3 database, executes the code and outputs the result.

I'm using the websh wrapper via mod_websh

Here is some sample code:

The app will process a request URI like http://example.com/main.ws3/hello Strategy: Create a directory on the machine to create all the snippet Tcl files, then package into SQLite database

package.tcl (package all tcl scripts in current directory into SQLite database)

load /usr/local/lib/sqlite3/libtclsqlite3.so Sqlite3

sqlite3 db task.db

db eval {CREATE TABLE hd(path TEXT,src TEXT)}
set files glob *.tcl
foreach x $files {
        set fp open $x r
        set src read $fp
        close $fp
        set path /$x
        db eval {INSERT INTO hd VALUES ($path,$src)}
}
db close

hello.tcl (hello world example)

set content "Hello, World"

main.ws3 (process request in URI and load corresponding tcl code)

set fp open "layout.html" r
set layout read $fp
close $fp

set path web::request PATH_INFO.tcl
load /usr/local/lib/sqlite3/libtclsqlite3.so Sqlite3
sqlite3 db task.db
set process db onecolumn {SELECT src FROM hd WHERE path=$path}
eval $process
db close

set html regsub "<!--Content-->" $layout $content
web::put $html

layout.html (a template)

<!doctype html>
<html>
<head>
<title>boo</title>
</head>

<body>
<!--Content-->
</body>
</html>

Experiments... Sample output (note, in development ;-)

#1 display CGI env info

http://creamy.mobi/test-series/testdt/main.ws3/testcmd

(ssl vars) https://creamy.mobi/test-series/testdt/main.ws3/testcmd

testcmd.tcl

set request web::request -names
set combine join $request ", "

set path web::request PATH_INFO

set content "<h1>Request Info</h1>
<p>${combine}</p>
<p>${path}</p>
"

#2 load and display static HTML file. The static page is specified in the query string (parameter pg). For test purposes adds the page request at the top. NOTE: You have to modify glob line in package.tcl, above, to also package html files in the current directory.

http://creamy.mobi/test-series/testdt/main.ws3/static?pg=contact

static.tcl (load html)

web::dispatch -postdata "" -cmd ""
set page /web::param pg.html
set content "<h1>$page</h1>"
append content db onecolumn {SELECT src FROM hd WHERE path=$page}

contact.html

<h1>Contact</h1>
<p>Contact us page</p>
<p>(650) 396-7580</p>

#3 test file_mtime and file_md5

http://creamy.mobi/test-series/testdt/main.ws3/checkfile

package require md5

set file_mtime file mtime "layout.html"
set file_md5 md5::md5 -hex -filename "layout.html"

set content "<h1>Layout File</h1>
<p>File Modification Check</p>
<p>Last Modified: ${file_mtime}</p>
<p>MD5: ${file_md5}</p>
"

#4 test time/ip

http://creamy.mobi/test-series/testdt/main.ws3/hash

set time clock clicks
set ip web::request REMOTE_ADDR
append content "<p>time: $time $ip</p>"

Notes using websh/mod_websh

1. using mod_websh cwd is set to "/" (and not the directory in which the script is running)

2. when using mod_websh pkg download from site, also in freebsd /usr/ports/www/websh/ does not appear to log errors. download from svn and build seems to fix this problem (?)

sample build on freebsd

svn co http://svn.apache.org/repos/asf/tcl/websh/trunk  websh
cd websh/src/unix
autoconf
./configure --with-tcl=/usr/local/lib/tcl8.5-threads \
        --with-tclinclude=/usr/local/include/tcl8.5 \
        --with-aprinclude=/usr/local/apache2/include/ \
        --with-apuinclude=/usr/local/apache2/include/ \
        --with-httpdinclude=/usr/local/apache2/include
gmake && gmake install
cp mod_websh* /usr/local/apache2/modules/
cp libwebsh85-threads.so.1 /usr/local/apache2/lib/

(vi httpd.conf)

LoadModule websh_module modules/mod_websh.so
AddType application/x-httpd-tcl .ws3
AddHandler websh .ws3
WebshConfig conf/websh.conf

(see files in src dist:)

doc/mod_websh/conf/httpd.conf
doc/mod_websh/conf/otherhandler.ws3
doc/mod_websh/conf/websh.conf
doc/mod_websh/conf/htmlhandler.ws3