|
From: David G. <dav...@us...> - 2006-03-24 01:32:37
|
Update of /cvsroot/frontierkernel/Frontier/Common/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2299/Common/source Added Files: Tag: sqlite-embedded-experimental langsqlite.c Log Message: --- NEW FILE: langsqlite.c --- /* $Id: langsqlite.c,v 1.1.2.1 2006/03/24 01:32:31 davidgewirtz Exp $ */ /****************************************************************************** UserLand Frontier(tm) -- High performance Web content management, object database, system-level and Internet scripting environment, including source code editing and debugging. Copyright (C) 1992-2004 UserLand Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ******************************************************************************/ #include "frontier.h" #include "standard.h" #include "frontierconfig.h" #include "error.h" #include "ops.h" #include "langinternal.h" #include "kernelverbs.h" #include "kernelverbdefs.h" #include "resources.h" #include "strings.h" #include "tablestructure.h" #include "lang.h" #include "langexternal.h" #include "langsqlite.h" #include <sqlite3.h> typedef enum tysqliteverbtoken { /* verbs that are processed by langsqlite.c */ openfunc, execfunc, closefunc, ctsqliteverbs } tysqliteverbtoken; static boolean sqlitefunctionvalue (short token, hdltreenode hparam1, tyvaluerecord *vreturned, bigstring bserror) { /* 2006-03-15 gewirtz: created, cribbed from langcrypt, itself cribbed from htmlfunctionvalue */ hdltreenode hp1 = hparam1; tyvaluerecord *v = vreturned; setbooleanvalue (false, v); /* by default, sqlite functions return false */ switch (token) { case openfunc: { /* 2006-03-14 gewirtz: open an SQLite db */ return (sqliteopenverb (hp1, v, bserror)); } /* openfunc */ case execfunc: { /* 2006-03-15 gewirtz: execute an SQLite statement */ return (sqliteexecverb (hp1, v, bserror)); } /* execfunc */ case closefunc: { /* 2006-03-15 gewirtz: close an SQLite db */ return (sqlitecloseverb (hp1, v, bserror)); } /* closefunc */ default: getstringlist (langerrorlist, unimplementedverberror, bserror); return (false); } /* switch */ } /* sqlitefunctionvalue */ boolean sqliteinitverbs (void) { /* 2006-03-15 gewirtz: created, cribbed from cryptinitverbs */ return (loadfunctionprocessor (idsqliteverbs, &sqlitefunctionvalue)); } /* sqliteinitverbs */ static void sqliteOpenError (const char *errmsg, bigstring bserror) { bigstring bserrmsg; copyctopstring (errmsg, bserrmsg); /* This creates a pstring at bserrmsg */ getstringlist (langerrorlist, sqliteopenerror, bserror); parsedialogstring (bserror, bserrmsg, nil, nil, nil, bserror); return; } /*sqliteOpenError*/ static void sqliteDatabaseError (const char *errmsg, bigstring bserror) { bigstring bserrmsg; copyctopstring (errmsg, bserrmsg); /* This creates a pstring at bserrmsg */ getstringlist (langerrorlist, sqlitedberror, bserror); parsedialogstring (bserror, bserrmsg, nil, nil, nil, bserror); return; } /*sqliteDatabaseError*/ static void sqliteScriptError (const char *errmsg, bigstring bserror) { bigstring bserrmsg; copyctopstring (errmsg, bserrmsg); /* This creates a pstring at bserrmsg */ getstringlist (langerrorlist, notfunctionerror, bserror); parsedialogstring (bserror, bserrmsg, nil, nil, nil, bserror); return; } /*sqliteScriptError*/ boolean sqliteopenverb (hdltreenode hparam1, tyvaluerecord *vreturned, bigstring bserror) { Handle h = nil; Handle returnH = nil; sqlite3 *db; /* the SQLite DB handle, be careful to not pass this across threads */ int returnCode; /* return code from SQLite call */ flnextparamislast = true; /* makes sure Frontier throws an error if more than one param is passed */ /* This routine takes one parameter: the filename. It returns a handle and a result code. See: http://www.sqlite.org/capi3ref.html#sqlite3_open */ /* Enter the verb, convert the param to null-terminated string */ if (!getexempttextvalue (hparam1, 1, &h)) return (false); pushcharhandle (0x00, h); /* this should convert *h to a string */ /* Process the SQLite sequence */ returnCode = sqlite3_open(*h, &db); if(returnCode) { sqliteOpenError(sqlite3_errmsg(db), bserror); /* send database open error */ disposehandle(h); /* get rid of the provided, original handle */ sqlite3_close(db); return (false); } return (setheapvalue ((Handle) db, longvaluetype, vreturned)); /* return the db address to the scripter */ /* for now, close the database, simply because we don't have any other code */ /* sqlite3_close(db); */ /* Exit the verb, converting string back to Frontier handle */ /* newfilledhandle (*h, strlen (*h), &returnH); */ /* disposehandle (h); */ /* get rid of the provided, original handle */ /* return (setheapvalue (returnH, stringvaluetype, vreturned)); */ } /* sqliteopenverb */ boolean sqlitecloseverb (hdltreenode hparam1, tyvaluerecord *vreturned, bigstring bserror) { Handle h = nil; Handle returnH = nil; sqlite3 *db; /* the SQLite DB handle, be careful to not pass this across threads */ int returnCode; /* return code from SQLite call */ flnextparamislast = true; /* makes sure Frontier throws an error if more than one param is passed */ /* This routine takes one parameter: the database. It true if the file closed successfully, or throws a script error if not. See: http://www.sqlite.org/capi3ref.html#sqlite3_close */ if (!getlongvalue (hparam1, 1, &db)) /* Get the long value, which becomes the db pointer */ return (false); /* Process the SQLite sequence */ returnCode = sqlite3_close(db); if(returnCode != SQLITE_OK) { sqliteDatabaseError(sqlite3_errmsg(db), bserror); /* send database error */ disposehandle(h); /* get rid of the provided, original handle */ return (false); } return setbooleanvalue (true, vreturned); } /* sqlitecloseverb */ boolean sqliteexecverb (hdltreenode hparam1, tyvaluerecord *vreturned, bigstring bserror) { Handle h = nil; Handle returnH = nil; char *zErrMsg = 0; /* SQLite's error message */ sqlite3 *db; /* the SQLite DB handle, be careful to not pass this across threads */ int returnCode; /* return code from SQLite call */ /* This routine takes one parameter: the filename. It returns a handle and a result code. See: http://www.sqlite.org/capi3ref.html#sqlite3_exec We're not going to use the SQLite callback mechanism for the sqlite3_exec function. The most obvious approach inside Frontier would be to pass a script into SQLite, but the potential problems, bugs, and difficulty in debugging makes this an unnecessary exercise. The sqlite3_exec function will return data, which can then be munged by a script once it leaves SQLite. So sayeth the coder. -- DG */ if (!getlongvalue (hparam1, 1, &db)) /* Get the long value, which becomes the db pointer */ return (false); flnextparamislast = true; /* makes sure Frontier throws an error if more than one param is passed */ /* Enter the verb, convert the param to null-terminated string */ if (!getexempttextvalue (hparam1, 2, &h)) return (false); pushcharhandle (0x00, h); /* this should convert *h to a string */ /* Process the SQLite sequence */ returnCode = sqlite3_exec(db, *h, 0, 0, &zErrMsg); if(returnCode != SQLITE_OK) { sqliteDatabaseError(zErrMsg, bserror); /* send database open error */ disposehandle(h); /* get rid of the provided, original handle */ sqlite3_close(db); return (false); } return (setheapvalue ((Handle) db, longvaluetype, vreturned)); /* return the db address to the scripter */ /* for now, close the database, simply because we don't have any other code */ /* sqlite3_close(db); */ /* Exit the verb, converting string back to Frontier handle */ /* newfilledhandle (*h, strlen (*h), &returnH); */ /* disposehandle (h); */ /* get rid of the provided, original handle */ /* return (setheapvalue (returnH, stringvaluetype, vreturned)); */ } /* sqliteexecverb */ /* boolean hmacmd5 (unsigned char * text, int text_len, unsigned char * key, int key_len, unsigned char * digest) function code went here */ /* boolean hmacsha1 (unsigned char * text, int text_len, unsigned char * key, int key_len, unsigned char * digest) function code went here */ |