================================================================================
Bauk HTTP Server
GromJS
Server-Side JavaScript interpreter
================================================================================
Version 1.7.14
Server-Side JavaScript Reference
This manual includes prototypes of built-in classes, objects and functions
available with GromJS Server-Side JavaScript interpreter. In addition to this
manual see sample Server-Side JavaScript Web scripts provided in package.
The definitions of classes, objects and function prototypes in this manual are
given in pseudo-code ie. close resembling C/C++ programming lanugages with
precise definitions of data type, function arguments, return values, etc.
Note that this manual does not cover JavaScript basics, ie. it is assumed that
reader already has minimum previous knowledge of JS.
--------------------------------------------------------------------------------
CONTENTS
--------------------------------------------------------------------------------
- Top level functions
- Cgi object (handles client-sent data in GET/POST request, HTTP uploaded
files, cookies, etc., and provides methods for manipulation of these
values; ie. var myval = Cgi.any("myvar"); see examples below)
- Server object (includes various functions related to JS interpreter
process ie. getpid, timeout, etc., utility functions ie. getenv, time,
rand, FS manipulation ie. mkdir, rmdir, unlink, link, symlink, chmod
etc.)
- Session object (disk-based session variables for data persistence
between script executions)
- File class (manipulation of files on server, ie. open, close, read,
write, lock, seek, truncate, etc.; efficient, unlimited file size
support, easy and intuitive JS API)
- BDB class (BDB database JS API)
- MySQL class (MySQL database JS API)
- PostgreSQL class (PostgreSQL database JS API)
- SQLite class (SQLite3 database JS API)
- Pipe class (executing external programs and communicating through Unix
pipe)
- Dictionary class (hash array, unlimited number of entries, configurable
efficiency/speed)
--------------------------------------------------------------------------------
TOP LEVEL FUNCTIONS
--------------------------------------------------------------------------------
void load(string SCRIPTPATH [,string SCRIPTPATH2 ...]);
//Load script(s) on SCRIPTPATH
void include(string SCRIPTPATH [,string SCRIPTPATH2 ...]);
//Same as "load()"
uint print(string DATA [,string DATA2 ...]);
//Print arguments
uint printf(string DATA [,string DATA2 ...]);
//Same as "print()"
--------------------------------------------------------------------------------
CGI OBJECT
--------------------------------------------------------------------------------
GromJS built-in "Cgi" object provides access to client-sent data ie. query
string, POST data, uploaded files, cookies etc. GromJS interpreter by default
automatically outputs response headers and Cgi.header() function is available
for setting arbitrary response headers.
//object prototype:
object Cgi {
//methods:
string query([string VARNAME [, string DEFAULT]]);
string querystring([string VARNAME [, string DEFAULT]]);
/*Used with no argument, returns whole querystring; with
argument VARNAME returns it's value; if var not found returns
null; if second arg DEFAULT supplied it is returned if var not
found.*/
string post([string VARNAME] [, string DEFAULT]);
string postdata([string VARNAME] [, string DEFAULT]);
/*Values searched in POST data.*/
string any(string VARNAME [, string DEFAULT]);
/*Fetch variable from any available, querystring or POST data,
searched in that order.
Note: methods Cgi.query(), Cgi.post(), Cgi.any() by default
return null if requested var not found. Optional 2nd arg DEFAULT
can be supplied which is returned when requested var is not
found, ie.: var myval = Cgi.any("myvar", "");
returns empty string if myvar not found.*/
array varnames();
/*Returns array of strings with all var names from querystring
and postdata ie. script with URL
"script.js?a=a&b=b" returns array containing "a", "b". */
void varurldecode(uint DECODE);
/*Sets on/off decoding of vars from query/POST data. By default
decoding is enabled, ie. Cgi.any("abc") etc. return URL-decoded
values. Setting Cgi.varurldecode(0) will return values 'as is'
as they are supplied in HTTP request.*/
void separators(string SEPARATORS);
/*Use alternative separator (delimiter) chars for
querystring/postdata; default are "=" and "&" Example:
Cgi.separators("=;") to use "=" and ";" as delimiters.*/
string getcookie(string COOKIENAM [, string DEFAULT]);
/*Get value of COOKIENAM (available in "HTTP_COOKIE" environment
variable), if var not found returns null; second argument
DEFAULT if supplied is returned if requested var not found.*/
bool setcookie(string COOKIESTR);
/*Set cookie.*/
bool header(string HEADER);
/*Add arbitrary response header ie.
Cgi.header("Content-Type: image/gif"); */
void freepost();
/*Optional; POST data automatically released on end of script
execution.*/
//properties:
array Files;
/*Array of "Uploadedfile" objects; see "Uploadedfile" prototype
below.*/
};
//example:
//Hello world JS Web script:
//BEGIN SCRIPT-->
print("
");
print("Hello, world!!
");
print("");
//<--END SCRIPT
//example:
//fetching client-supplied values:
//ie. /script.js?somevar=someval&myvar=myval
//print value of "myvar"
print(Cgi.any("myvar"), "
");
//ie. /script.js?somevar=someval&myvar=myval
//test if "myvar" is supplied in request:
var smyval = Cgi.any("myvar");
if ( smyval!=null ) {
//yes, "myvar" found
}
//print cookie
//test if cookie "myid" is supplied in request:
var myid = Cgi.getcookie("myid");
if ( myid!=null ) {
//yes, "myid" cookie fond
print(myid, "
");
}
//set cookie
Cgi.setcookie("myid=myval;");
//set dynamically generated cookie, expires 7 days from now
Cgi.setcookie("myid=myval; path=/; expires=" +Server.gmtdate(Server.time()+(7*24*60*60)) +";");
--------------------------------------------------------------------------------
UPLOADEDFILE OBJECT
--------------------------------------------------------------------------------
GromJS built-in "Uploadedfile" object is an element of "Cgi.Files" array and
provides information about (by a HTTP client) newly uploaded file on server, ie.
size, file location/path, original filename, encoding, etc.
//Uploadedfile object
//object prototype:
object Uploadedfile {
//properties
string name;
/*Name of HTML form input field ie. "myphoto1".*/
string filename;
/*Filename on client's disk ie. "c:\files\myfile.gif" or
"/files/myfile.gif".*/
string tmpfile;
/*Location of newly created uploaded file on server
ie. /tmp/upload23457742463624355325.dat.*/
string type;
/*File type ie. image/gif.*/
string encoding;
/*Encoding.*/
uint size;
/*Size of uploaded file in bytes.*/
};
//example:
//array length indicates the number of uploaded files
if ( Cgi.Files.length>0 ) {
var Uplfile = Cgi.Files[0]; //0'th Uploadedfile object
print(Uplfile.name,"
"); //print the name of HTML form input field
print(Uplfile.filename,"
"); //print filename of uploaded file
print(Uplfile.tmpfile,"
"); //uploaded tmp file location
print(Uplfile.size,"
"); //size of uploaded file
}
//example:
//BEGIN SCRIPT-->
print("");
print("File upload example
");
var cFile = 0;
//move multiple uploaded files to their destination
while ( cFileMoving uploaded file into upload dir... ");
//move tmp file to destination
if ( Server.move(Upfl.tmpfile, "/path/to/uploaddir/newfile_"+cFile+".jpg")==true ) {
print("[OK] file moved");
}
//error
else {
print("[error] ", Server.errnstr());
}
print("");
cFile++;
}
print("");
//<--END SCRIPT
--------------------------------------------------------------------------------
SERVER OBJECT
--------------------------------------------------------------------------------
GromJS built-in "Server" object includes a set of functions (methods) related to
JavaScript interpreter process such as process PID, errno, exit etc., various
utility functions such as current time, rand etc., file-system interaction
functions ie. mkdir, chmod, stat, file copy, unlink, etc.
//object prototype:
object Server {
//methods:
void timeout(uint SECONDS);
/*Script timeout; set max SECONDS allowed for script execution
after which process exits, ie. abort script in infinite loop.*/
uint sleep(uint SECONDS);
/*Put process to sleep for SECONDS seconds.*/
void gc();
/*Run garbage-collector; Ie. after many vars used, large arrays,
database reads/writes etc.*/
void buffer(uint BUFFER);
/*Output buffer; 0==no buffer, output is sent immediately;
non-zero==output is buffered and sent in blocks of that size
default is buffered to 64kb (max).*/
void verbose(uint VERBOSE);
/*Overrides default GromJS verbosity, ie. Server.verbose(1)
displays script path on error, 0 keeps path descrete.*/
void fflush();
void flush();
/*Force output from buffer (flush output buffer)*/
void exit([string MSG]);
/*Abort script execution and exit process; before exit print
MSG if provided.*/
void quit([string MSG]);
void abort([string MSG]);
/*Abort script execution but without terminating JS
interpreter's persistent process.*/
string version([uint ELEM]);
/*GromJS JavaScript Host Environment version string, ie.
GromJS 1.7.11 JavaScript-C 1.7.0; Optional arg ELEM if supplied
causes return only the specific element 0-3 of complete version
string.*/
uint uptime();
/*Number of seconds persistent process is active.*/
uint requests();
/*Number of requests (scripts) GromJS persistent process has
executed ie. 1, 2, 50, 5000 etc.*/
uint rss();
/*Process resident set size (memory footprint), in kilobytes.*/
uint wsimode();
/*Returns 1 if GromJS is operating in WSI mode, 0 otherwise.*/
uint random();
uint rand();
/*Random 52bit unsigned integer number.*/
uint time();
/*Current time, in seconds; number of seconds since epoch time.*/
uint microtime();
uint utime();
/*Current time in microseconds.*/
string timestamp([uint TIME]);
/*Return date and time string in format yyyymmddhhmmss, for
example 20081124182144. If used without argument, returns
timestamp for current time. */
string localdate([uint SECONDS]);
/*Local date string, if no args date is for current time,
identical to calling Server.localdate(Server.time()).*/
string gmtdate([uint SECONDS]);
/*GMT date.*/
string date([uint SECONDS [, uint LOCALDATE]]);
/*Date format "dd-mmm-yyyy hh:mm:ss", with no args date for
current GMT time; If SECONDS is null date also for current
time; if LOCALDATE supplied and non-zero, date is local,
otherwise GMT; ie. localdate for current time:
Server.date(null,1);*/
uint getpid();
/*Process PID number.*/
string getcwd();
/*Get current working dir.*/
//system error functions
uint errno([uint ERRNO]);
/*System errno. With no argument, get system error number. If
argument is provided and value 0, sets errno to zero.*/
string errstr([uint ERRNO]);
/*System error string. If ERRNO supplied, string for that
specific ERRNO.*/
string errnstr([uint ERRNO]);
/*Returns string with joined errno() and errstr(). If ERRNO
supplied, string for that specific ERRNO.*/
array dirlist(string DIRPATH);
/*List filenames in dir DIRPATH and return as array of
strings, without "." and ".." entries; null returned on error,
ie. unable to read directory, no permission etc.
Server.errno() provides more info.*/
string filemodestring(uint MODE);
/*Ie. for mode 0755 return string -rwxr-xr-x*/
string pathcompile(string ARG [,string ARG2, ...]);
/*Assemble path string from optional number of arguments;
converts backslashes to slashes and removes double slashes:
ie. Server.pathcompile("aaa","\\bbb/","/ccc") returns path
"aaa/bbb/ccc"; to create absolute path simply begin by "/".*/
string includepathget(void);
string getincludepath(void);
/*Returns path of include directories, with multiple paths
separated by colon ':', ie. "/usr/lib:/usr/local/lib".*/
void includepathset(string PATH);
void setincludepath(string PATH);
/*Sets path of include directories, with multiple paths
separated by colon ':' ie. "/usr/lib:/usr/local/lib". Example:
Server.includepathset(Server.includepathget()+":"+"/path/to/xyz");
*/
//environment variables
string getenv(string VARNAME [,string DEFAULT]);
/*Returns value of VARNAME, null if not found; optional second
arg can be supplied which is returned if var is non-existing,
ie. Server.getenv("myvar","") returns empty string if var not
found.*/
string setenv(string VARNAME, string VALUE);
/*Sets env vars passed to Server.execve() or Pipe() program.
Calling with parameter null ie. Server.setenv(null) clears all
vars set by Server.setenv(). It also allows over-writing present
vars if required ie. to hide them from executed script, ie.
Server.setenv("PATH_TRANSLATED",""); causes empty path to be
passed to executed script/program.*/
array envvarnames();
array varnames();
/*Array of all environment variables names.*/
array argv();
/*Returns array of command line arguments*/
//All functions below return true if operation succeeded, false
//otherwise; If operation failed, Server.errno() provides the system
//error number:
bool chdir(string DIRPATH);
/*Change working dir to DIRPATH*/
bool mkdir(string DIRPATH, uint MODE);
/*Make new dir under filemode MODE*/
bool rmdir(string DIRPATH);
/*Remove empty dir*/
bool chmod(string PATH, uint MODE);
/*Change mode of PATH to MODE ie. 0644*/
bool rename(string OLDPATH, string NEWPATH);
bool move(string OLDPATH, string NEWPATH);
/*Rename/move OLDPATH to NEWPATH; if NEWPATH is a directory,
moves to destdir.*/
bool symlink(string EXISTINGPATH, string NEWLINKPATH);
/*Create a symlink.*/
bool link(string EXISTINGPATH, string NEWLINKPATH);
/*Create a hard link.*/
bool unlink(string PATH);
/*Remove a file.*/
bool copy(string FILEPATH, string NEWPATH [, uint APPEND]);
/*Copy regular file on FILEPATH to NEWPATH, if third arg
APPEND present and non-zero then append to destination if
NEWPATH is directory, copies under original filename to
destdir.*/
bool utimes(string PATH [, uint ASEC [, uint AUSEC [, uint MSEC [, uint MUSEC]]]]);
/*Change file access and modification time
only with PATH arg supplied, Server.utimes() changes file
access and modification time to current time optional
arguments are access seconds/microseconds, and modification
seconds/microseconds. Example:
Server.utimes("/path/to/myfile.txt", Server.time()- 10) sets
both acc/mod times to 10 seconds prior current time.*/
int cat(string FILEPATH [, uint OFFSET [, uint LEN]]);
/*Read file contents and output to stdout; if no arguments
OFFSET and LEN, offset is 0 and length is untill end-of-file;
returns number of bytes output, -1 on error.*/
string readlink(string PATH);
/*Read the contents of the symbolic link path in PATH and
return as string. On error returns null.*/
//retrieving file status
object Stat stat(string PATH [, bool INFOABOUTSYMLINK]);
/*get file status information returned as Stat object
(see prototype below); on error function returns null
and Server.errno() provides system error number.
*/
//utility
uint hash(string TEXT);
/*Create unique uint for string TEXT*/
string hashx(string TEXT);
/*For string TEXT calculate 128bit hash number returned as
string; ie. Server.hashx("abcxyz") returns string ie.
83417c95fa27a5ed5c68dc4df3ccca3a.*/
string sha1(string TEXT);
/*For given string TEXT, calculate sha1 and return as string
(hex representation of 160bit sha1 number).*/
string execve(string PROGPATH [,string ARG1 [,string ARG2 ...]]);
/*Run executable on location PROGPATH and return it's output
as a string; on error Server.execvestatus() is non-zero ie.
execve failed/process unclean exit.*/
int execvestatus(void);
/*Returns execve'd program exit status; non-zero on error or
process unclean exit.*/
uint ip2n(string IPADR);
/*IPv4, for string "123.45.67.8" return numeric value 23478899*/
string n2ip(uint IPNUM);
/*IPv4, for numeric value 23478899 return string "123.45.67.8"*/
object Hostent gethostby(string NAMEORADR);
/*IPv4, get hostentry by name or IP address. Argument
NAMEORADR represents an IP ie. 123.4.5.78 or
hostname ie. www.domain.com etc. See object Hostent
prototype below.
*/
string read([uint LEN]);
/*GromJS CLI mode only, in WSI mode returns null; read up to LEN
bytes from stdin and return as string, with no argument reads
untill end of input (closed write end).*/
string readline(void);
/*GromJS CLI mode only, in WSI mode returns null; read a single
line from stdin, or untill end of input (closed write end)*/
//String chars manipulation functions:
int charbfind(string DATA, string CHAR2FIND);
int charlastindexof(string DATA, string CHAR2FIND);
/*Find last index of specific char
var cindex = Server.charbfind("xyxyz", "y");
returns 3 as index for 'y' char first found backwards.
Returns -1 if char not found.
*/
string chartrim(string DATA [, string CHARS2TRIM [, uint WHICHEND]]);
/*Trim chars CHARS2TRIM, WHICHEND 1=leading, 2=trailing,
3=trim both ends. Used only with argument DATA, by default
trims both ends chars TAB CR LF and SPACE ("\t\r\n ").
var trimmed = Server.chartrim(" abc ", "\t\r\n ", 3); returns
string "abc".
*/
string charkeep(string DATA, string CHARS2KEEP);
/*Keep chars CHARS2KEEP remove all other
var cleared = Server.charkeep(" abc ", "ac");
returns string "ac", all other chars removed.
*/
string charremove(string DATA, string CHARSREMOV);
/*Remove chars CHARSREMOV
var cleared = Server.charremove(" abc ", " c");
returns string "ab", spaces and c removed.
*/
string charreplace(string DATA, string CHARSFROM, string CHARSTO);
/*Char by char replace, CHARSFROM change to CHARSTO
var changed = Server.charreplace(" abc ", " b", "_");
returns string "_a_c_", spaces and b changed to _.
*/
string charcutto1(string DATA, string WHICH);
/*Cut repetitive successive chars to 1 count
var ccut = Server.charcutto1(" aaa bbbb ccc ", " a");
returns string " a bbbb ccc ", with a and spaces reduced to 1
count.
*/
};
//Example:
//Simple script printing environment variables:
//BEGIN SCRIPT-->
print("");
//get a single env variable:
var contlen = Server.getenv("CONTENT_LENGTH");
//print all environment variables
var ENVNAMES = Server.envvarnames(); //array of all env var names
var cVarnam = 0;
//Ie.
//REQUEST_METHOD = POST
//CONTENT_LENGTH = 123
//QUERY_STRING = abc=234
//etc. etc.
for ( cVarnam=0; cVarnam");
//<--END SCRIPT
//Utility functions examples:
//print localdate
print(Server.localdate(), "
");
//file copy example:
if ( Server.copy("myfile.txt", "myfile2.txt")==true ) {
//operation succeded
}
--------------------------------------------------------------------------------
STAT OBJECT
--------------------------------------------------------------------------------
GromJS "Stat" object is returned by Server.stat() function and provides file
status information such as file type, size, modification and access time, mode,
etc.
//object prototype:
object Stat {
//properties:
uint size; //size of file in bytes
uint ta; //time of last access, in seconds
uint tm; //time of last modified
uint tc; //time of last file status change
uint mode; //file mode, ie. 0644
//bools indicating file type
bool isreg; //true if regular file
bool isdir; //true if file is a directory
bool islink; //true if symlink
bool ischar; //true if char special
bool isblock; //true if block special
bool isfifo; //true if named pipe (fifo)
bool issock; //true if socket
};
//example:
var statobj = Server.stat(string PATH [, bool SYMLINKINFO]); //prototype
var statobj = Server.stat("/path/to/myfile.txt");
/*get file status information*/
var statobj = Server.stat("/path/to/myfile.txt", 1);
/*same, 2nd argument indicates that if file is symlink get
information about link itself not file it points to*/
//file stat ok
if ( statobj!=null ) {
print("The size of myfile.txt is ", statobj.size, "
");
if ( statobj.isreg ) {
//regular file
}
if ( statobj.isdir ) {
//directory
}
}
//error
else {
print("ERROR: Getting information about myfile.txt failed
");
//ie. [errno 2] No such file or directory
print(Server.errnstr(),"
");
}
--------------------------------------------------------------------------------
HOSTENT OBJECT
--------------------------------------------------------------------------------
The "Hostent" object is returned by Server.gethostby() function and provides
information about host by IP address/hostname.
//object prototype:
object Hostent {
string name; //Official name of host
array aliases ; //String array alias list
array addresses; //String array list of addresses from name server
uint herrno; //herrno (host errno) number; 0 on success
};
//example:
var Hstent = Server.gethostby("123.34.67.89");
var Hstent = Server.gethostby("www.domain.net");
if ( Hstent.error==0 ) {
//operation succeded
print(Hstent.name, "
"); //print official name of host
print(Hstent.aliases.join(", "), "
"); //print joined array of aliases
print(Hstent.addresses.join(", "), "
"); //print joined array of adresses
}
--------------------------------------------------------------------------------
SESSION OBJECT
--------------------------------------------------------------------------------
GromJS built-in "Session" object provides methods for efficiently
reading/storing variables between script executions.
Session variables are disk based (stored on disk) and have no direct memory
limitation ie. it is ok using a 20mb data in session variable if required.
Variables are stored in form of text, meaning that numbers (or objects) must
first be converted to string and then stored in session.
When reading a numeric (or object) value from session variable, it is a reverse
process, value is retrieved as text, then converted to it's original type.
Each session is unique and defined by identifier sent to HTTP client/browser as
session-id cookie, for example, SESSIONID=56827836d5b2f627597894b24793788c.
On reading (fetching) a session var which is not present in session (ie. has not
been set, or has expired) ie. Session.get("varnam") returns null.
Optionally if second arg is supplied ie. Session.get("varnam", "") and var not
found, returns the second arg, ie. empty string.
Storing null as value effectively deletes variable from session, ie.
Session.set("varnam", null) deletes "varnam" from session.
Setting time 0 deletes all variables in session ie. calling Session.time(0);
makes all variables expire immediately and effectively deletes them.
Session object and methods are fully automated and do not require any type of
initialization or special management. Ie. user calls "get()", "set()" etc. at
any desired order/sequence to fetch/store variables, and session management is
done automatically by interpreter (ie. it's automatically initialized on start
and automatically stored to disk at end of script execution).
//object prototype:
object Session {
//methods:
uint time([uint DURATION]);
/*Get or set duration of variables in seconds; used with no
argument returns the duration of session variables, otherwise
argument sets session duration; setting time to 0 has effect
of deleting all variables ie. all vars expire immediately.
*/
string get(string VARNAM [, string DEFAULT]);
/*Get value of variable VARNAM; if variable is not present in
session (not set or has expired) null is returned; optional
second arg DEFAULT can be supplied to be returned if
VARNAM not found in session.
*/
void set(string VARNAM, string VALUE);
/*For variable VARNAM set value to VALUE; supplying null as
value has effect of deleting a var from session.
*/
array varnames();
/*Returns array (of strings) of all var names in session*/
void todisk();
/*Optional, store session to disk (if omitted it is done
automatically by session itself at end of script execution).
*/
};
//Example:
var sessdurat = Session.time(); //get current duration of session
Session.time(7*24*60*60); //set session duration to 7 days
var sessvar1 = Session.get("sessvar1"); //get value of sessvar1
Session.set("sessvar2", "abc"); //set session var
Session.todisk(); //optional force storing to disk
var sessvar3 = Session.get("sessvar3"); //ok to call again after storing on disk
Session.time(10*60); //change duration to 10min
Session.set("sessvar4", "def"); //set another session var
Session.todisk(); //again, to disk
//..etc etc...
//Example:
//BEGIN SCRIPT-->
//Page visit counter:
//Demonstrate usage of session object
var sSessVarName = "visitcount";
var nVisits = parseInt(Session.get(sSessVarName,""));
//if not set or zero
if ( isNaN(nVisits) || nVisits==0 ) {
nVisits = 1;
}
//print HTML page
print("");
print("Page visited: ", nVisits, " times.
");
//set duration of variables
Session.time(7*24*60*60);
//increment value and store to session
Session.set(sSessVarName, (nVisits+1)+"");
print("");
//Session is stored to disk automatically at and of script execution.
//<--END SCRIPT
--------------------------------------------------------------------------------
FILE CLASS
--------------------------------------------------------------------------------
GromJS built-in "File" class provides access to files for read/write, and
additional functions for manipulating file data such as lock, truncate, seek,
etc.
File data I/O by functions read()/write() is in chunk mode and "textual" (data
is first converted to string then stored), ie. calling function myfile.read(20)
reads 20 bytes from current file position, myfile.write("abcd") writes string
"abcd" to file's current position. Numeric values (numbers) are read/written in
their string (textual) representation.
Functions nread()/nwrite() provide binary file I/O for numeric values, ie. each
nwrite() call stores JavaScript Number type binary value to file, and nread()
retrives it from file in same way.
Additional information about file itself ie. file type (regular, dir, symlink
etc.), permissions, etc. can be obtained using Server.stat() function.
//example
var fileobj = new File(string FILEPATH);
var fileobj = new File("/path/to/myfile.txt");
//class prototype:
class File {
//methods
bool open(string OPENMODE [,uint CREATEMODE]);
/*Open file by specified mode OPENMODE; see below.*/
bool close();
/*Close; also removes any lock file has set.*/
int write(string DATA [, string DATA2, ...]);
/*Write to file; multiple arguments; returns number of bytes
written; on error returns -1.
*/
string read([uint LEN]);
/*Read LEN bytes and return as JavaScript string; if no
argument read all available bytes from current file position
onward; on failure null returned.
*/
int cat([uint LEN]);
/*Cat LEN bytes to stdout, if no argument, cat all available
bytes from current file position onward; returns number of
bytes done; -1 returned on error.
*/
uint tell();
/*Returns current file position index.*/
bool seek([uint ABSPOSITION]);
/*Seek to new absolute position within file, if no argument
seek to end of file.
*/
string path();
/*Returns file path used in "new File(PATH)" call.*/
bool lock(string LOCKTYPE);
/*Lock using LOCKTYPE; see below.*/
bool unlock();
/*Release lock.*/
bool truncate([uint LEN]);
/*Truncate opened file to new length; if no argument truncate
to current file position.
*/
};
File open modes:
----------------
r = Open for reading
w = Open for writing and set file position to beggining of file
c = Create file by mode CREATEMODE if not existing
t = Truncate file
a = Open for write/append and set position to end of file, excludes
truncate flag
File lock modes:
----------------
s = Set shared lock
x = Set exclusive lock
n = Non-blocking, attempt to set lock but if locked by another process and
would block, return error EWOULDBLOCK
u = Unlock
//example
var fileobj = new File("/path/to/myfile.txt");
//set errno 0
Server.errno(0);
//open for RW, truncate and if not existing create mode 0644
if ( fileobj.open("rwtc", 0644)==true ) {
//set exclusive lock, blocking
if ( fileobj.lock("x")==true ) {
//locked
fileobj.unlock();
}
//set non-blocking exclusive lock
if ( fileobj.lock("xn")==true ) {
//locked
fileobj.unlock();
}
//set shared lock; process blocked untill capable of setting lock
if ( fileobj.lock("s")==true ) {
//locked
fileobj.unlock();
}
fileobj.close();
}
//error
else {
//ie. [errno 13] Permission denied
print(Server.errnstr(),"
");
}
//open and read complete file
if ( fileobj.open("r")==true ) {
var fdata = fileobj.read(); //read all
if ( fdata!=null ) {
//ok
}
fileobj.close();
}
--------------------------------------------------------------------------------
BDBCLIENT CLASS
--------------------------------------------------------------------------------
GromJS built-in "Bdbclient" class provides JS API for manipulating BDB database.
BDB client is part of native GromJS code and requires no linking.
//constructor
var Bdbc = new Bdbclient();
//class prototype:
class Bdbclient {
//methods
bool connect(string HOST, uint PORT, string USERNAME, string PASSWORD);
/*Connect to BDB database server.*/
void close();
/*Close connection.*/
bool dbcreate(string DATABASE);
bool createdb(string DATABASE);
/*Create new database.*/
bool dbdrop(string DATABASE);
bool dropdb(string DATABASE);
/*Remove an existing database.*/
bool dbselect(string DATABASE);
bool selectdb(string DATABASE);
/*Select database.*/
bool exec(string COMMAND);
/*Execute single or multiple BDB commands separated by semicolon
in COMMAND text. Returs true if all commands executed with no
error. If executed with error, function "error()" provides
additional info.*/
bool rowhas();
bool rowavailable();
/*Returns true if there is a row available in result list and
positiones the cursor on it.*/
uint rowcount();
/*Returns number of rows in result list.*/
array rowget();
array rowfetch();
array fetchrow();
/*Returns next row from result list as array of strings.
Returns null if no row available.*/
object rowobjectget();
object getrowobject();
/*Returns next row from result list as JS object with each
column name as property prepended by '_'. Ie. rowid column as
"rowobj._rowid". If no row available returns null.*/
array object rowobjectlist();
/*Returns array of row objects from result list. On
error returns null.*/
uint rowsaffected();
/*Returns number of rows affected by DELETE or UPDATE command.*/
uint lastinsertrowid();
/*Returns the last rowid generated by INSERT command.*/
uint colcount();
/*Returns number of columns in result list.*/
string colname(uint COL);
/*Returns column name for index COL in result list. Returns null
if no row available.*/
string colget(uint COL);
/*Returns column value for index COL in result list. Returns
null if no row available.*/
string random();
string rand();
/*Returns 64bit uint random number as string, for example
2349843454689430854.*/
string hash64(string TEXT);
/*Returns 64bit uint hash number as string for given TEXT. Ie.
db.hash("abc") returns string such as 8458874259895733280.*/
string composite64(uint32 HI, uint32 LO);
/*Returns 64bit uint number as string composed of two 32bit
numbers. Usable for creating large 64bit identifiers from
smaller 32bit values.*/
bool fdump([string FILEPATH]);
/*Output complete contents of database in form of BDB commands
to a file.*/
bool fexec(string FILEPATH);
/*Load and execute BDB commands from a file.*/
bool reorganize();
/*Notifies server to reorganize database data. Results in
optimized data alignment and eliminating any unused space.
Database must be dbselect()'ed first.*/
string stringescape(string DATA);
/*Returns BDB escaped string.*/
string stringescapeenclose(string DATA);
string see(string DATA);
/*Returns BDB escaped and enclosed by single quotes string.*/
string error();
/*Database error string and information.*/
};
//Example:
//BEGIN SCRIPT-->
//A simple bulletin board script with BDB database
print("");
print("BDB Bulletin Board
");
print("
");
//Wrapper method for handling rows and columns in objective style
Bdbclient.prototype.rowxobjectlist2 = function(sCmnd)
{
//Local class
function ObjectListClass(aRowObjs)
{
var Lst = this; //List
Lst.aROL = aRowObjs; //Row object list
Lst.nRows = aRowObjs.length;
Lst.cRow = 0;
//methods
Lst.count = function() //Number of rows in list
{
return Lst.nRows;
}
Lst.next = function() //Fetch next row
{
if ( Lst.cRow",HTMLENCODE(Thrd._stitle),"");
print("Thread by: ",HTMLENCODE(Thrd._suser),"
");
if ( Msglst!=null ) {
var Msg; //One message
//Print messages in a loop
while ( (Msg=Msglst.next())!=null ) {
//Print messages
print("By: ",
HTMLENCODE(Msg._suser),
"
",
HTMLENCODE(Msg._smessage),
"
"
);
}
}
}
}
//Close connection
Bdbc.close();
}
//Error
else {
print("[error] ",Bdbc.error(),"
");
}
print("");
//<--END SCRIPT
--------------------------------------------------------------------------------
MYSQL CLASS
--------------------------------------------------------------------------------
GromJS "Mysql" class provides JavaScript API for manipulating MySQL database.
//class prototype:
class Mysql {
//methods
bool connect(string HOSTNAM, string USER, string PSWRD [, uint PORT, string FIFOSOCK]);
/*Connect to MySQL database server, returns true on success*/
bool close();
/*Close connection to Mysql database*/
bool query(string STMT);
/*Execute SQL statement STMT and create result set; returns
true on success
*/
bool exec(string STMT);
/*Same as "query()"*/
bool ping();
/*Check if connection active, reconnect if required, returns
true on success
*/
bool selectdb(string DBNAME);
/*Select database*/
array colnames();
/*Returns array of column names in result set*/
uint colnum();
/*Number of columns in result set*/
uint colcount();
/*Same as "colnum()"*/
array rowfetch();
/*Return a single row from result, as JavaScript array of
strings; null returned if no row is available
*/
array fetchrow();
/*Same as "rowfetch()"*/
array array rowsallfetch();
/*Return all rows from result as JavaScript two-
dimensional array of strings
*/
array array fetchallrows();
/*Same as "rowsallfetch()"*/
uint insertid();
/*Returns id created by database last insert operation*/
uint affectedrows();
/*Number of rows affected by INSERT, DELETE etc. operations*/
string error();
/*MySQL db error string*/
uint errno();
/*MySQL db error number*/
string realescapestring(string DATA);
/*Escapes special characters according to character set of the
connection
*/
string escapestring(string DATA);
/*Escape string*/
void freeresult();
/*Results are free'd automatically; if required freeresult()
can be used
*/
};
//BEGIN CODE-->
//Mysql class;
//Create new database and table, insert values, and then select and print
//values from table
print("");
var Mdb = new Mysql(); //Mysql class
//set errno 0
Server.errno(0);
//Connect to MySQL server
if ( Mdb.connect("domain.com","usernam345","pswrd345",3306,"/tmp/mysql.sock")==true ) {
//create database, table, insert values...
//Mdb.query("CREATE DATABASE testdb");
//Mdb.selectdb("testdb");
//Mdb.query("CREATE TABLE testtbl ...");
//Mdb.query("INSERT INTO testtbl ...");
//query values:
if ( Mdb.selectdb("testdb")==true ) {
//now query
if ( Mdb.query("SELECT id FROM testtbl")==true ) {
var onerow;
//get row as JS Array object from result set
while ( (onerow=Mdb.rowfetch())!=null ) {
//print column:
//1
//2
print(onerow[0], "
");
}
//optional; results free'd automatically
Mdb.freeresult();
}
}
//error
else {
//ie. cannot select database etc.
print("Error in exec, error [" ,Mdb.error(), "]
");
}
//close connection
Mdb.close();
}
//error
else {
//ie. can not connect to database server etc.
print("Error connecting to database, error [" ,Mdb.error(), "]
");
//ie. no permission etc.
print("System errno: " , Server.errnstr(), "
");
}
print("");
// <--END CODE
--------------------------------------------------------------------------------
POSTGRESQL CLASS
--------------------------------------------------------------------------------
GromJS "Postgresql" class provides JavaScript API for manipulating PostgreSQL
database.
//class prototype:
class Postgresql {
//methods
bool connect(string CONNARGS);
/*Connect to PostgreSQL database server, returns true on success
*/
bool close();
/*Close connection to Postgresql database*/
bool query(string STMT);
/*Execute SQL statement STMT and create result set, returns
true on success
*/
bool exec(string STMT);
/*Same as "query()"*/
bool ping();
/*Check if connection active, reconnect if required, returns
true on success
*/
array colnames();
/*Returns array of column names in result set*/
uint colnum();
/*Number of columns in result set*/
uint colcount();
/*Same as "colnum()"*/
array rowfetch();
/*Return a single row from result, as JavaScript array of
strings; null returned if no row is available
*/
array fetchrow();
/*Same as "rowfetch()"*/
array array rowsallfetch();
/*Return all rows from result as JavaScript two-
dimensional array of strings
*/
array array fetchallrows();
/*Same as "rowsallfetch()"*/
uint lastoid();
/*Returns object id created by database last insert operation*/
uint insertid();
/*Same as "lastoid()"*/
uint affectedrows();
/*Number of rows affected by INSERT, DELETE, UPDATE etc.
operations
*/
string error();
/*PostgreSQL db error string*/
string escapestring(string DATA);
/*Escape string*/
void freeresult();
/*Results are free'd automatically; if required freeresult()
can be used
*/
};
//Example:
/*
After PostgreSQL server is started, create user "luka" and database "testdb",
from command line:
% /usr/local/pgsql/bin/createuser -P -e -d luka
% /usr/local/pgsql/bin/createdb testdb
*/
//example Server-Side JavaScript Web script
//BEGIN CODE-->
//create Postgresql object
var Pgdb = new Postgresql();
print("");
print("PostgreSQL database
");
//Connect to PostgreSQL server
if ( Pgdb.connect("dbname=testdb user=luka password=lukaspswrd567")==true ) {
print("Ok, connected to PostgreSQL server
");
//SQL statement
var sSqlstmt = "CREATE TABLE ttesttbl( "
+" rowid integer PRIMARY KEY, "
+" smpl2 varchar(255), "
+" smpl3 varchar(255) "
+" ); ";
//execute SQL statement
if ( Pgdb.exec(sSqlstmt)==true ) {
print("Ok, created table
");
}
else {
print("Error exec
");
print("[",Pgdb.error(),"]
");
}
//insert values to database
//Pgdb.exec("INSERT INTO ttesttbl ... ");
//Pgdb.exec("INSERT INTO ttesttbl ... ");
//etc etc..
//execute SQL statement
if ( Pgdb.query("SELECT rowid,smpl2,smpl3 FROM ttesttbl")==true ) {
while ( (onerow=Pgdb.fetchrow())!=null ) {
//123 -- xyz -- abc
print(onerow[0], " -- ", onerow[1], " -- ", onerow[2], "
");
}
}
else {
print("Error query
");
print("[",Pgdb.error(),"]
");
}
Pgdb.close();
}
else {
print("Error connect
");
print("[",Pgdb.error(),"]
");
}
print("");
// <--END CODE
--------------------------------------------------------------------------------
SQLITE CLASS
--------------------------------------------------------------------------------
GromJS "Sqlite" class provides JavaScript API for manipulating Sqlite3 database.
//constructor
var databaseobj = new Sqlite(string DBPATH);
var databaseobj = new Sqlite("/path/to/mydatabase.db");
//class prototype:
class Sqlite {
//methods
bool open();
/*Open database, returns true on success.*/
bool close();
/*Close database.*/
bool exec(string STATEMENT);
/*Execute a result-less SQL statement; returns true on
success.*/
bool query(string SQLQUERY);
/*Execute SQL query SQLQUERY and create result set; returns true
on success
*/
string colname(uint INDX);
/*For column at INDX return column name used in CREATE table
statement
*/
array colnames();
/*Array of column names in result set*/
string coltype(uint INDX);
/*For column at INDX return column data type used in CREATE
statement ie. INTEGER, CHAR, FLOAT
*/
uint colcount();
/*Number of columns in result set*/
uint colnum();
/*Same as "colcount()"*/
uint rowcount();
/*Number of rows in result set*/
bool rowhas();
/*Returns true if there is row under cursor available*/
array rowfetch();
/*From result set get single row, returned as JavaScript array
of strings; null returned if no row available
*/
array fetchrow();
/*Same as "rowfetch()"*/
array array rowsallfetch();
/*From result set get all rows, returned as JavaScript
two-dimensional array of strings
*/
array array fetchallrows();
/*Same as "rowsallfetch()"*/
uint rowlastinsertid();
/*Returns id created by database last insert operation*/
uint lastinsertrowid();
/*Alias for rowlastinsertid*/
bool rewind();
/*Move to first row of result set*/
string error();
/*Returns Sqlite3 error string*/
void freeresult();
/*Results are free'd automatically; if required freeresult()
can be used
*/
};
//Example:
//BEGIN SCRIPT-->
//demonstrate using Sqlite3 database and JavaScript interface
print("");
var dbfilepath = "mydatabase.db";
var Sqdb = new Sqlite(dbfilepath);
print("Opening database.
");
if ( Sqdb.open()==true ) {
print("Executing CREATE and INSERT statement.
");
//statement
var ssqlstmt = ""
+"CREATE TABLE ttesttable (i INTEGER PRIMARY KEY, cname CHAR(255), cweight INTEGER); "
+"INSERT INTO ttesttable (cname,cweight) VALUES ('firstuser',95); "
+"INSERT INTO ttesttable (cname,cweight) VALUES ('anotheruser',263); "
;
//if statements executed ok...
if ( Sqdb.exec(ssqlstmt)==true ) {
print("Using SELECT query to fetch inserted values.
");
//query
if ( Sqdb.query("SELECT * FROM ttesttable")==true ) {
//printing selected values in tabular form ie.
//colname (TYPE) colname (TYPE) colname (TYPE)
//--------------------------------------------------
//value value value
//value value value
//etc etc...
print("Printing selected values in tabular form.
");
print("");
//print header row with column names and types
print("");
for ( var ccol=0; ccol!=Sqdb.colcount(); ccol++ ) {
print("| ");
print(Sqdb.colname(ccol));
print(" (");
print(Sqdb.coltype(ccol));
print(") | ");
}
print("
");
//print rows
var nrows = 0;
var onerow;
while ( (onerow=Sqdb.rowfetch())!=null ) {
print("");
for ( var indx in onerow ) {
print("| ");
print(onerow[indx]);
print(" | ");
}
print("
");
nrows++;
}
print("
");
print("
");
print("number of rows in select statement [",nrows,"]
");
}
}
//error
else {
//ie. table already exist etc
print("Error in exec, error [" ,Sqdb.error(), "]
");
}
print("Closing database.
");
Sqdb.close();
print("Database closed.
");
}
//error
else {
//ie. invalid path, no permission etc
print("Error opening database, error [" ,Sqdb.error(), "]
");
}
print("Deleting database file.
");
//delete database file
if ( Server.unlink(dbfilepath)==true ) {
print("Database file deleted.
");
}
else {
//ie. invalid path, no permission etc
print("Error deleting file ",dbfilepath,", system errno [" ,Server.errno(), "]
");
}
print("");
//<--END SCRIPT
--------------------------------------------------------------------------------
PIPE CLASS
--------------------------------------------------------------------------------
GromJS built-in "Pipe" class provides interface for using inter-process
communication through Unix pipe, a new process is launched from specified path
and bidirectional pipe is opened for reading/writing to new process.
//constructor
var pipeobj = new Pipe(string PROGPATH [,string ARG1 [,string ARG2 ...]]);
var pipeobj = new Pipe("/path/to/executable");
//path to executable
var pipeobj = new Pipe("/path/to/executable","arg0","arg1","arg2");
//executable with command line arguments
//class prototype:
class Pipe {
//methods
bool open();
/*Open bidirectional pipe, returns true if succedded*/
uint close([uint WHICHEND]);
/*Close pipe; if argument is supplied, it's either 0=read end
close, or 1=write end close; with no argument, closes any open
(both) end(s) and returns status 0 for success; status nonzero
indicates error or process unclean exit
*/
string read([uint LEN]);
/*Read from pipe; with argument read LEN bytes from pipe and
return as string; Returns empty string on reading EOF, null on
error. With no argument, read all from pipe in single action and
return as string; returns null on error.
*/
int write(string ARG0 [, string ARG1 , ...]);
/*Write to pipe; returns no of bytes written, -1 on error*/
};
//Example:
//BEGIN SCRIPT-->
//sending email using Pipe class and sendmail:
print("");
var pipeobj = new Pipe("/usr/sbin/sendmail","otheruser@domain.com");
//set errno 0
Server.errno(0);
if ( pipeobj.open()==true ) {
var smsg = ""
+"From: myusernam@domain.com\n"
+"To: otheruser@domain.com\n"
+"Subject: Webscript test email\n"
+"\n"
+"Text text text\n"
+"more text some more text etc.\n"
+"\n"
;
//writing ok
if ( pipeobj.write(smsg)!=(-1) ) {
pipeobj.close(1); //close write end
print("");
print(pipeobj.read()); //read and print output, if any
print("");
}
//error
else {
print("Failed writing to pipe [errno " , Server.errno() ,"]
");
}
//close() with no arg performs final close (closes any open end) and returns program exit status
var xstatus = pipeobj.close(); //final close
//if non-zero there was an error or process unclean exit
if ( xstatus!=0 ) {
print("Closing pipe indicate failure [exit status " , xstatus ,"]
");
print("System status: " , Server.errnstr() ,"
");
}
}
else {
print("Opening pipe failed, system status: " , Server.errnstr() ,"
");
}
print("");
//<--END SCRIPT
--------------------------------------------------------------------------------
DICTIONARY CLASS
--------------------------------------------------------------------------------
GromJS built-in "Dictionary" class is a hash array of unlimited length.
Values are objects of any type and in Dictionary are stored by reference, not
copy. Optional argument SPEEDLEVEL (0-20) is used to increase the speed of
array read/write by setting the size of Dictionary's hash table.
//constructor
var dictobj = new Dictionary([uint SPEEDLEVEL]);
//optional argument SPEEDLEVEL 0-20 is used to increase the
//size of hash table
//class prototype:
class Dictionary {
//methods
uint set(string NAME, object VALUE);
/*Set the value in dictionary; setting new value over-writes
previously set value; if VALUE is null effectively deletes
previously set value from dictionary; returns number of
entries in dictionary
*/
object get(string NAME [, object DEFAULT]);
/*Get value from dictionary; null returned if value not in
dictionary; optional second arg DEFAULT can be supplied
to be returned if NAME not found in dictionary
*/
array varnames();
/*Returns unsorted JS Array of strings containing list of all
names in dictionary
*/
uint length();
/*Number of entries in dictionary*/
uint len();
/*Same as "length()"*/
};
//Example:
//BEGIN SCRIPT-->
var dictobj = new Dictionary(5); //create new dictionary
var exmplobj = new Object(); //create new object to store in dictionary
dictobj.set("name123",exmplobj); //write/set value in dictionary
//now read/get value from dictionary
var rdobj = dictobj.get("name123");
if ( rdobj!=null ) {
//item found..
}
//storing null deletes value from dictionary
dictobj.set("name123",null); //delete value from dictionary
//set multiple values
dictobj.set("name1","val"); //set value
dictobj.set("name2","val"); //set value
dictobj.set("name3","val"); //set value
dictobj.set("name4","val"); //set value
//print all names in dictionary, ie.:
//[name1, name4, name3, name2]
print("[", dictobj.varnames().join(", "), "]");
//<--END SCRIPT
[end of readme]
--------------------------------------------------------------------------------
--