| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885 | 
							- /************************************************************************
 
- * lsqlite3                                                              *
 
- * Copyright (C) 2002-2007 Tiago Dionizio, Doug Currie                   *
 
- * All rights reserved.                                                  *
 
- * Author    : Tiago Dionizio <tiago.dionizio@ist.utl.pt>                *
 
- * Author    : Doug Currie <doug.currie@alum.mit.edu>                    *
 
- * Library   : lsqlite3 - a SQLite 3 database binding for Lua 5          *
 
- *                                                                       *
 
- * Permission is hereby granted, free of charge, to any person obtaining *
 
- * a copy of this software and associated documentation files (the       *
 
- * "Software"), to deal in the Software without restriction, including   *
 
- * without limitation the rights to use, copy, modify, merge, publish,   *
 
- * distribute, sublicense, and/or sell copies of the Software, and to    *
 
- * permit persons to whom the Software is furnished to do so, subject to *
 
- * the following conditions:                                             *
 
- *                                                                       *
 
- * The above copyright notice and this permission notice shall be        *
 
- * included in all copies or substantial portions of the Software.       *
 
- *                                                                       *
 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       *
 
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    *
 
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*
 
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  *
 
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  *
 
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     *
 
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                *
 
- ************************************************************************/
 
- #include <stdlib.h>
 
- #include <string.h>
 
- #include <assert.h>
 
- #define LUA_LIB
 
- #include "lua.h"
 
- #include "lauxlib.h"
 
- #include "sqlite3.h"
 
- /* compile time features */
 
- #if !defined(SQLITE_OMIT_PROGRESS_CALLBACK)
 
-     #define SQLITE_OMIT_PROGRESS_CALLBACK 0
 
- #endif
 
- typedef struct sdb sdb;
 
- typedef struct sdb_vm sdb_vm;
 
- typedef struct sdb_func sdb_func;
 
- /* to use as C user data so i know what function sqlite is calling */
 
- struct sdb_func {
 
-     /* references to associated lua values */
 
-     int fn_step;
 
-     int fn_finalize;
 
-     int udata;
 
-     sdb *db;
 
-     char aggregate;
 
-     sdb_func *next;
 
- };
 
- /* information about database */
 
- struct sdb {
 
-     /* associated lua state */
 
-     lua_State *L;
 
-     /* sqlite database handle */
 
-     sqlite3 *db;
 
-     /* sql functions stack usage */
 
-     sdb_func *func;         /* top SQL function being called */
 
-     /* references */
 
-     int busy_cb;        /* busy callback */
 
-     int busy_udata;
 
-     int progress_cb;    /* progress handler */
 
-     int progress_udata;
 
-     int trace_cb;       /* trace callback */
 
-     int trace_udata;
 
- };
 
- static const char *sqlite_meta      = ":sqlite3";
 
- static const char *sqlite_vm_meta   = ":sqlite3:vm";
 
- static const char *sqlite_ctx_meta  = ":sqlite3:ctx";
 
- static int sqlite_ctx_meta_ref;
 
- /*
 
- ** =======================================================
 
- ** Database Virtual Machine Operations
 
- ** =======================================================
 
- */
 
- static void vm_push_column(lua_State *L, sqlite3_stmt *vm, int idx) {
 
-     switch (sqlite3_column_type(vm, idx)) {
 
-         case SQLITE_INTEGER:
 
-             {
 
-                 sqlite_int64 i64 = sqlite3_column_int64(vm, idx);
 
-                 lua_Number n = (lua_Number)i64;
 
-                 if (n == i64)
 
-                     lua_pushnumber(L, n);
 
-                 else
 
-                     lua_pushlstring(L, (const char*)sqlite3_column_text(vm, idx), sqlite3_column_bytes(vm, idx));
 
-             }
 
-             break;
 
-         case SQLITE_FLOAT:
 
-             lua_pushnumber(L, sqlite3_column_double(vm, idx));
 
-             break;
 
-         case SQLITE_TEXT:
 
-             lua_pushlstring(L, (const char*)sqlite3_column_text(vm, idx), sqlite3_column_bytes(vm, idx));
 
-             break;
 
-         case SQLITE_BLOB:
 
-             lua_pushlstring(L, sqlite3_column_blob(vm, idx), sqlite3_column_bytes(vm, idx));
 
-             break;
 
-         case SQLITE_NULL:
 
-             lua_pushnil(L);
 
-             break;
 
-         default:
 
-             lua_pushnil(L);
 
-             break;
 
-     }
 
- }
 
- /* virtual machine information */
 
- struct sdb_vm {
 
-     sdb *db;                /* associated database handle */
 
-     sqlite3_stmt *vm;       /* virtual machine */
 
-     /* sqlite3_step info */
 
-     int columns;            /* number of columns in result */
 
-     char has_values;        /* true when step succeeds */
 
-     char temp;              /* temporary vm used in db:rows */
 
- };
 
- /* called with sql text on the lua stack */
 
- static sdb_vm *newvm(lua_State *L, sdb *db) {
 
-     sdb_vm *svm = (sdb_vm*)lua_newuserdata(L, sizeof(sdb_vm));
 
-     luaL_getmetatable(L, sqlite_vm_meta);
 
-     lua_setmetatable(L, -2);        /* set metatable */
 
-     svm->db = db;
 
-     svm->columns = 0;
 
-     svm->has_values = 0;
 
-     svm->vm = NULL;
 
-     svm->temp = 0;
 
-     /* add an entry on the database table: svm -> sql text */
 
-     lua_pushlightuserdata(L, db);
 
-     lua_rawget(L, LUA_REGISTRYINDEX);
 
-     lua_pushlightuserdata(L, svm);
 
-     lua_pushvalue(L, -4); /* the sql text */
 
-     lua_rawset(L, -3);
 
-     lua_pop(L, 1);
 
-     return svm;
 
- }
 
- static int cleanupvm(lua_State *L, sdb_vm *svm) {
 
-     /* remove entry in database table - no harm if not present in the table */
 
-     lua_pushlightuserdata(L, svm->db);
 
-     lua_rawget(L, LUA_REGISTRYINDEX);
 
-     lua_pushlightuserdata(L, svm);
 
-     lua_pushnil(L);
 
-     lua_rawset(L, -3);
 
-     lua_pop(L, 1);
 
-     svm->columns = 0;
 
-     svm->has_values = 0;
 
-     if (!svm->vm) return 0;
 
-     lua_pushnumber(L, sqlite3_finalize(svm->vm));
 
-     svm->vm = NULL;
 
-     return 1;
 
- }
 
- static int stepvm(lua_State *L, sdb_vm *svm) {
 
-     int result;
 
-     int loop_limit = 3;
 
-     while ( loop_limit-- ) {
 
-         result = sqlite3_step(svm->vm);
 
-         if ( result==SQLITE_ERROR ) {
 
-           result = sqlite3_reset (svm->vm);
 
-         }
 
-         if ( result==SQLITE_SCHEMA ) {
 
-             sqlite3_stmt *vn;
 
-             const char *sql;
 
-             /* recover sql text */
 
-             lua_pushlightuserdata(L, svm->db);
 
-             lua_rawget(L, LUA_REGISTRYINDEX);
 
-             lua_pushlightuserdata(L, svm);
 
-             lua_rawget(L, -2); /* sql text */
 
-             sql = luaL_checkstring(L, -1);
 
-             /* re-prepare */
 
-             result = sqlite3_prepare(svm->db->db, sql, -1, &vn, NULL);
 
-             if (result != SQLITE_OK) break;
 
-             sqlite3_transfer_bindings(svm->vm, vn);
 
-             sqlite3_finalize(svm->vm);
 
-             svm->vm = vn;
 
-             lua_pop(L,2);
 
-         } else {
 
-           break;
 
-         }
 
-     }
 
-     return result;
 
- }
 
- static sdb_vm *lsqlite_getvm(lua_State *L, int index) {
 
-     sdb_vm *svm = (sdb_vm*)luaL_checkudata(L, index, sqlite_vm_meta);
 
-     if (svm == NULL) luaL_argerror(L, index, "bad sqlite virtual machine");
 
-     return svm;
 
- }
 
- static sdb_vm *lsqlite_checkvm(lua_State *L, int index) {
 
-     sdb_vm *svm = lsqlite_getvm(L, index);
 
-     if (svm->vm == NULL) luaL_argerror(L, index, "attempt to use closed sqlite virtual machine");
 
-     return svm;
 
- }
 
- static int dbvm_isopen(lua_State *L) {
 
-     sdb_vm *svm = lsqlite_getvm(L, 1);
 
-     lua_pushboolean(L, svm->vm != NULL ? 1 : 0);
 
-     return 1;
 
- }
 
- static int dbvm_tostring(lua_State *L) {
 
-     char buff[39];
 
-     sdb_vm *svm = lsqlite_getvm(L, 1);
 
-     if (svm->vm == NULL)
 
-         strcpy(buff, "closed");
 
-     else
 
-         sprintf(buff, "%p", svm);
 
-     lua_pushfstring(L, "sqlite virtual machine (%s)", buff);
 
-     return 1;
 
- }
 
- static int dbvm_gc(lua_State *L) {
 
-     sdb_vm *svm = lsqlite_getvm(L, 1);
 
-     if (svm->vm != NULL)  /* ignore closed vms */
 
-         cleanupvm(L, svm);
 
-     return 0;
 
- }
 
- static int dbvm_step(lua_State *L) {
 
-     int result;
 
-     sdb_vm *svm = lsqlite_checkvm(L, 1);
 
-     result = stepvm(L, svm);
 
-     svm->has_values = result == SQLITE_ROW ? 1 : 0;
 
-     svm->columns = sqlite3_data_count(svm->vm);
 
-     lua_pushnumber(L, result);
 
-     return 1;
 
- }
 
- static int dbvm_finalize(lua_State *L) {
 
-     sdb_vm *svm = lsqlite_checkvm(L, 1);
 
-     return cleanupvm(L, svm);
 
- }
 
- static int dbvm_reset(lua_State *L) {
 
-     sdb_vm *svm = lsqlite_checkvm(L, 1);
 
-     sqlite3_reset(svm->vm);
 
-     lua_pushnumber(L, sqlite3_errcode(svm->db->db));
 
-     return 1;
 
- }
 
- static void dbvm_check_contents(lua_State *L, sdb_vm *svm) {
 
-     if (!svm->has_values) {
 
-         luaL_error(L, "misuse of function");
 
-     }
 
- }
 
- static void dbvm_check_index(lua_State *L, sdb_vm *svm, int index) {
 
-     if (index < 0 || index >= svm->columns) {
 
-         luaL_error(L, "index out of range [0..%d]", svm->columns - 1);
 
-     }
 
- }
 
- static void dbvm_check_bind_index(lua_State *L, sdb_vm *svm, int index) {
 
-     if (index < 1 || index > sqlite3_bind_parameter_count(svm->vm)) {
 
-         luaL_error(L, "bind index out of range [1..%d]", sqlite3_bind_parameter_count(svm->vm));
 
-     }
 
- }
 
- /*
 
- ** =======================================================
 
- ** Virtual Machine - generic info
 
- ** =======================================================
 
- */
 
- static int dbvm_columns(lua_State *L) {
 
-     sdb_vm *svm = lsqlite_checkvm(L, 1);
 
-     lua_pushnumber(L, sqlite3_column_count(svm->vm));
 
-     return 1;
 
- }
 
- /*
 
- ** =======================================================
 
- ** Virtual Machine - getters
 
- ** =======================================================
 
- */
 
- static int dbvm_get_value(lua_State *L) {
 
-     sdb_vm *svm = lsqlite_checkvm(L, 1);
 
-     int index = luaL_checkint(L, 2);
 
-     dbvm_check_contents(L, svm);
 
-     dbvm_check_index(L, svm, index);
 
-     vm_push_column(L, svm->vm, index);
 
-     return 1;
 
- }
 
- static int dbvm_get_name(lua_State *L) {
 
-     sdb_vm *svm = lsqlite_checkvm(L, 1);
 
-     int index = luaL_checknumber(L, 2);
 
-     dbvm_check_index(L, svm, index);
 
-     lua_pushstring(L, sqlite3_column_name(svm->vm, index));
 
-     return 1;
 
- }
 
- static int dbvm_get_type(lua_State *L) {
 
-     sdb_vm *svm = lsqlite_checkvm(L, 1);
 
-     int index = luaL_checknumber(L, 2);
 
-     dbvm_check_index(L, svm, index);
 
-     lua_pushstring(L, sqlite3_column_decltype(svm->vm, index));
 
-     return 1;
 
- }
 
- static int dbvm_get_values(lua_State *L) {
 
-     sdb_vm *svm = lsqlite_checkvm(L, 1);
 
-     sqlite3_stmt *vm = svm->vm;
 
-     int columns = svm->columns;
 
-     int n;
 
-     dbvm_check_contents(L, svm);
 
-     lua_newtable(L);
 
-     for (n = 0; n < columns;) {
 
-         vm_push_column(L, vm, n++);
 
-         lua_rawseti(L, -2, n);
 
-     }
 
-     return 1;
 
- }
 
- static int dbvm_get_names(lua_State *L) {
 
-     sdb_vm *svm = lsqlite_checkvm(L, 1);
 
-     sqlite3_stmt *vm = svm->vm;
 
-     int columns = sqlite3_column_count(vm); /* valid as soon as statement prepared */
 
-     int n;
 
-     lua_newtable(L);
 
-     for (n = 0; n < columns;) {
 
-         lua_pushstring(L, sqlite3_column_name(vm, n++));
 
-         lua_rawseti(L, -2, n);
 
-     }
 
-     return 1;
 
- }
 
- static int dbvm_get_types(lua_State *L) {
 
-     sdb_vm *svm = lsqlite_checkvm(L, 1);
 
-     sqlite3_stmt *vm = svm->vm;
 
-     int columns = sqlite3_column_count(vm); /* valid as soon as statement prepared */
 
-     int n;
 
-     lua_newtable(L);
 
-     for (n = 0; n < columns;) {
 
-         lua_pushstring(L, sqlite3_column_decltype(vm, n++));
 
-         lua_rawseti(L, -2, n);
 
-     }
 
-     return 1;
 
- }
 
- static int dbvm_get_uvalues(lua_State *L) {
 
-     sdb_vm *svm = lsqlite_checkvm(L, 1);
 
-     sqlite3_stmt *vm = svm->vm;
 
-     int columns = svm->columns;
 
-     int n;
 
-     dbvm_check_contents(L, svm);
 
-     lua_checkstack(L, columns);
 
-     for (n = 0; n < columns; ++n)
 
-         vm_push_column(L, vm, n);
 
-     return columns;
 
- }
 
- static int dbvm_get_unames(lua_State *L) {
 
-     sdb_vm *svm = lsqlite_checkvm(L, 1);
 
-     sqlite3_stmt *vm = svm->vm;
 
-     int columns = sqlite3_column_count(vm); /* valid as soon as statement prepared */
 
-     int n;
 
-     lua_checkstack(L, columns);
 
-     for (n = 0; n < columns; ++n)
 
-         lua_pushstring(L, sqlite3_column_name(vm, n));
 
-     return columns;
 
- }
 
- static int dbvm_get_utypes(lua_State *L) {
 
-     sdb_vm *svm = lsqlite_checkvm(L, 1);
 
-     sqlite3_stmt *vm = svm->vm;
 
-     int columns = sqlite3_column_count(vm); /* valid as soon as statement prepared */
 
-     int n;
 
-     lua_checkstack(L, columns);
 
-     for (n = 0; n < columns; ++n)
 
-         lua_pushstring(L, sqlite3_column_decltype(vm, n));
 
-     return columns;
 
- }
 
- static int dbvm_get_named_values(lua_State *L) {
 
-     sdb_vm *svm = lsqlite_checkvm(L, 1);
 
-     sqlite3_stmt *vm = svm->vm;
 
-     int columns = svm->columns;
 
-     int n;
 
-     dbvm_check_contents(L, svm);
 
-     lua_newtable(L);
 
-     for (n = 0; n < columns; ++n) {
 
-         lua_pushstring(L, sqlite3_column_name(vm, n));
 
-         vm_push_column(L, vm, n);
 
-         lua_rawset(L, -3);
 
-     }
 
-     return 1;
 
- }
 
- static int dbvm_get_named_types(lua_State *L) {
 
-     sdb_vm *svm = lsqlite_checkvm(L, 1);
 
-     sqlite3_stmt *vm = svm->vm;
 
-     int columns = sqlite3_column_count(vm);
 
-     int n;
 
-     lua_newtable(L);
 
-     for (n = 0; n < columns; ++n) {
 
-         lua_pushstring(L, sqlite3_column_name(vm, n));
 
-         lua_pushstring(L, sqlite3_column_decltype(vm, n));
 
-         lua_rawset(L, -3);
 
-     }
 
-     return 1;
 
- }
 
- /*
 
- ** =======================================================
 
- ** Virtual Machine - Bind
 
- ** =======================================================
 
- */
 
- static int dbvm_bind_index(lua_State *L, sqlite3_stmt *vm, int index, int lindex) {
 
-     switch (lua_type(L, lindex)) {
 
-         case LUA_TSTRING:
 
-             return sqlite3_bind_text(vm, index, lua_tostring(L, lindex), lua_strlen(L, lindex), SQLITE_TRANSIENT);
 
-         case LUA_TNUMBER:
 
-             return sqlite3_bind_double(vm, index, lua_tonumber(L, lindex));
 
-         case LUA_TBOOLEAN:
 
-             return sqlite3_bind_int(vm, index, lua_toboolean(L, lindex) ? 1 : 0);
 
-         case LUA_TNONE:
 
-         case LUA_TNIL:
 
-             return sqlite3_bind_null(vm, index);
 
-         default:
 
-             luaL_error(L, "index (%d) - invalid data type for bind (%s)", index, lua_typename(L, lua_type(L, lindex)));
 
-             return SQLITE_MISUSE; /*!*/
 
-     }
 
- }
 
- static int dbvm_bind_parameter_count(lua_State *L) {
 
-     sdb_vm *svm = lsqlite_checkvm(L, 1);
 
-     lua_pushnumber(L, sqlite3_bind_parameter_count(svm->vm));
 
-     return 1;
 
- }
 
- static int dbvm_bind_parameter_name(lua_State *L) {
 
-     sdb_vm *svm = lsqlite_checkvm(L, 1);
 
-     int index = luaL_checknumber(L, 2);
 
-     dbvm_check_bind_index(L, svm, index);
 
-     lua_pushstring(L, sqlite3_bind_parameter_name(svm->vm, index));
 
-     return 1;
 
- }
 
- static int dbvm_bind(lua_State *L) {
 
-     sdb_vm *svm = lsqlite_checkvm(L, 1);
 
-     sqlite3_stmt *vm = svm->vm;
 
-     int index = luaL_checkint(L, 2);
 
-     int result;
 
-     dbvm_check_bind_index(L, svm, index);
 
-     result = dbvm_bind_index(L, vm, index, 3);
 
-     lua_pushnumber(L, result);
 
-     return 1;
 
- }
 
- static int dbvm_bind_blob(lua_State *L) {
 
-     sdb_vm *svm = lsqlite_checkvm(L, 1);
 
-     int index = luaL_checkint(L, 2);
 
-     const char *value = luaL_checkstring(L, 3);
 
-     int len = lua_strlen(L, 3);
 
-     lua_pushnumber(L, sqlite3_bind_blob(svm->vm, index, value, len, SQLITE_TRANSIENT));
 
-     return 1;
 
- }
 
- static int dbvm_bind_values(lua_State *L) {
 
-     sdb_vm *svm = lsqlite_checkvm(L, 1);
 
-     sqlite3_stmt *vm = svm->vm;
 
-     int top = lua_gettop(L);
 
-     int result, n;
 
-     if (top - 1 != sqlite3_bind_parameter_count(vm))
 
-         luaL_error(L,
 
-             "incorrect number of parameters to bind (%d given, %d to bind)",
 
-             top - 1,
 
-             sqlite3_bind_parameter_count(vm)
 
-         );
 
-     for (n = 2; n <= top; ++n) {
 
-         if ((result = dbvm_bind_index(L, vm, n - 1, n)) != SQLITE_OK) {
 
-             lua_pushnumber(L, result);
 
-             return 1;
 
-         }
 
-     }
 
-     lua_pushnumber(L, SQLITE_OK);
 
-     return 1;
 
- }
 
- static int dbvm_bind_names(lua_State *L) {
 
-     sdb_vm *svm = lsqlite_checkvm(L, 1);
 
-     sqlite3_stmt *vm = svm->vm;
 
-     int count = sqlite3_bind_parameter_count(vm);
 
-     const char *name;
 
-     int result, n;
 
-     luaL_checktype(L, 2, LUA_TTABLE);
 
-     for (n = 1; n <= count; ++n) {
 
-         name = sqlite3_bind_parameter_name(vm, n);
 
-         if (name && (name[0] == ':' || name[0] == '$')) {
 
-             lua_pushstring(L, ++name);
 
-             lua_gettable(L, 2);
 
-             result = dbvm_bind_index(L, vm, n, -1);
 
-             lua_pop(L, 1);
 
-         }
 
-         else {
 
-             lua_pushnumber(L, n);
 
-             lua_gettable(L, 2);
 
-             result = dbvm_bind_index(L, vm, n, -1);
 
-             lua_pop(L, 1);
 
-         }
 
-         if (result != SQLITE_OK) {
 
-             lua_pushnumber(L, result);
 
-             return 1;
 
-         }
 
-     }
 
-     lua_pushnumber(L, SQLITE_OK);
 
-     return 1;
 
- }
 
- /*
 
- ** =======================================================
 
- ** Database (internal management)
 
- ** =======================================================
 
- */
 
- /*
 
- ** When creating database handles, always creates a `closed' database handle
 
- ** before opening the actual database; so, if there is a memory error, the
 
- ** database is not left opened.
 
- **
 
- ** Creates a new 'table' and leaves it in the stack
 
- */
 
- static sdb *newdb (lua_State *L) {
 
-     sdb *db = (sdb*)lua_newuserdata(L, sizeof(sdb));
 
-     db->L = L;
 
-     db->db = NULL;  /* database handle is currently `closed' */
 
-     db->func = NULL;
 
-     db->busy_cb =
 
-     db->busy_udata =
 
-     db->progress_cb =
 
-     db->progress_udata =
 
-     db->trace_cb =
 
-     db->trace_udata = LUA_NOREF;
 
-     luaL_getmetatable(L, sqlite_meta);
 
-     lua_setmetatable(L, -2);        /* set metatable */
 
-     /* to keep track of 'open' virtual machines */
 
-     lua_pushlightuserdata(L, db);
 
-     lua_newtable(L);
 
-     lua_rawset(L, LUA_REGISTRYINDEX);
 
-     return db;
 
- }
 
- static int cleanupdb(lua_State *L, sdb *db) {
 
-     sdb_func *func;
 
-     sdb_func *func_next;
 
-     int top;
 
-     int result;
 
-     /* free associated virtual machines */
 
-     lua_pushlightuserdata(L, db);
 
-     lua_rawget(L, LUA_REGISTRYINDEX);
 
-     /* close all used handles */
 
-     top = lua_gettop(L);
 
-     lua_pushnil(L);
 
-     while (lua_next(L, -2)) {
 
-         sdb_vm *svm = lua_touserdata(L, -2); /* key: vm; val: sql text */
 
-         cleanupvm(L, svm);
 
-         lua_settop(L, top);
 
-         lua_pushnil(L);
 
-     }
 
-     lua_pop(L, 1); /* pop vm table */
 
-     /* remove entry in lua registry table */
 
-     lua_pushlightuserdata(L, db);
 
-     lua_pushnil(L);
 
-     lua_rawset(L, LUA_REGISTRYINDEX);
 
-     /* 'free' all references */
 
-     luaL_unref(L, LUA_REGISTRYINDEX, db->busy_cb);
 
-     luaL_unref(L, LUA_REGISTRYINDEX, db->busy_udata);
 
-     luaL_unref(L, LUA_REGISTRYINDEX, db->progress_cb);
 
-     luaL_unref(L, LUA_REGISTRYINDEX, db->progress_udata);
 
-     luaL_unref(L, LUA_REGISTRYINDEX, db->trace_cb);
 
-     luaL_unref(L, LUA_REGISTRYINDEX, db->trace_udata);
 
-     /* close database */
 
-     result = sqlite3_close(db->db);
 
-     db->db = NULL;
 
-     /* free associated memory with created functions */
 
-     func = db->func;
 
-     while (func) {
 
-         func_next = func->next;
 
-         luaL_unref(L, LUA_REGISTRYINDEX, func->fn_step);
 
-         luaL_unref(L, LUA_REGISTRYINDEX, func->fn_finalize);
 
-         luaL_unref(L, LUA_REGISTRYINDEX, func->udata);
 
-         free(func);
 
-         func = func_next;
 
-     }
 
-     db->func = NULL;
 
-     return result;
 
- }
 
- static sdb *lsqlite_getdb(lua_State *L, int index) {
 
-     sdb *db = (sdb*)luaL_checkudata(L, index, sqlite_meta);
 
-     // TODO lsm if (db == NULL) luaL_typerror(L, index, "sqlite database");
 
-     return db;
 
- }
 
- static sdb *lsqlite_checkdb(lua_State *L, int index) {
 
-     sdb *db = lsqlite_getdb(L, index);
 
-     if (db->db == NULL) luaL_argerror(L, index, "attempt to use closed sqlite database");
 
-     return db;
 
- }
 
- /*
 
- ** =======================================================
 
- ** User Defined Functions - Context Methods
 
- ** =======================================================
 
- */
 
- typedef struct {
 
-     sqlite3_context *ctx;
 
-     int ud;
 
- } lcontext;
 
- static lcontext *lsqlite_make_context(lua_State *L) {
 
-     lcontext *ctx = (lcontext*)lua_newuserdata(L, sizeof(lcontext));
 
-     lua_rawgeti(L, LUA_REGISTRYINDEX, sqlite_ctx_meta_ref);
 
-     lua_setmetatable(L, -2);
 
-     ctx->ctx = NULL;
 
-     ctx->ud = LUA_NOREF;
 
-     return ctx;
 
- }
 
- static lcontext *lsqlite_getcontext(lua_State *L, int index) {
 
-     lcontext *ctx = (lcontext*)luaL_checkudata(L, index, sqlite_ctx_meta);
 
-     // TODO lsm if (ctx == NULL) luaL_typerror(L, index, "sqlite context");
 
-     return ctx;
 
- }
 
- static lcontext *lsqlite_checkcontext(lua_State *L, int index) {
 
-     lcontext *ctx = lsqlite_getcontext(L, index);
 
-     if (ctx->ctx == NULL) luaL_argerror(L, index, "invalid sqlite context");
 
-     return ctx;
 
- }
 
- static int lcontext_tostring(lua_State *L) {
 
-     char buff[39];
 
-     lcontext *ctx = lsqlite_getcontext(L, 1);
 
-     if (ctx->ctx == NULL)
 
-         strcpy(buff, "closed");
 
-     else
 
-         sprintf(buff, "%p", ctx->ctx);
 
-     lua_pushfstring(L, "sqlite function context (%s)", buff);
 
-     return 1;
 
- }
 
- static void lcontext_check_aggregate(lua_State *L, lcontext *ctx) {
 
-     sdb_func *func = (sdb_func*)sqlite3_user_data(ctx->ctx);
 
-     if (!func->aggregate) {
 
-         luaL_error(L, "attempt to call aggregate method from scalar function");
 
-     }
 
- }
 
- static int lcontext_user_data(lua_State *L) {
 
-     lcontext *ctx = lsqlite_checkcontext(L, 1);
 
-     sdb_func *func = (sdb_func*)sqlite3_user_data(ctx->ctx);
 
-     lua_rawgeti(L, LUA_REGISTRYINDEX, func->udata);
 
-     return 1;
 
- }
 
- static int lcontext_get_aggregate_context(lua_State *L) {
 
-     lcontext *ctx = lsqlite_checkcontext(L, 1);
 
-     lcontext_check_aggregate(L, ctx);
 
-     lua_rawgeti(L, LUA_REGISTRYINDEX, ctx->ud);
 
-     return 1;
 
- }
 
- static int lcontext_set_aggregate_context(lua_State *L) {
 
-     lcontext *ctx = lsqlite_checkcontext(L, 1);
 
-     lcontext_check_aggregate(L, ctx);
 
-     lua_settop(L, 2);
 
-     luaL_unref(L, LUA_REGISTRYINDEX, ctx->ud);
 
-     ctx->ud = luaL_ref(L, LUA_REGISTRYINDEX);
 
-     return 0;
 
- }
 
- static int lcontext_aggregate_count(lua_State *L) {
 
-     lcontext *ctx = lsqlite_checkcontext(L, 1);
 
-     lcontext_check_aggregate(L, ctx);
 
-     lua_pushnumber(L, sqlite3_aggregate_count(ctx->ctx));
 
-     return 1;
 
- }
 
- #if 0
 
- void *sqlite3_get_auxdata(sqlite3_context*, int);
 
- void sqlite3_set_auxdata(sqlite3_context*, int, void*, void (*)(void*));
 
- #endif
 
- static int lcontext_result(lua_State *L) {
 
-     lcontext *ctx = lsqlite_checkcontext(L, 1);
 
-     switch (lua_type(L, 2)) {
 
-         case LUA_TNUMBER:
 
-             sqlite3_result_double(ctx->ctx, luaL_checknumber(L, 2));
 
-             break;
 
-         case LUA_TSTRING:
 
-             sqlite3_result_text(ctx->ctx, luaL_checkstring(L, 2), lua_strlen(L, 2), SQLITE_TRANSIENT);
 
-             break;
 
-         case LUA_TNIL:
 
-         case LUA_TNONE:
 
-             sqlite3_result_null(ctx->ctx);
 
-             break;
 
-         default:
 
-             luaL_error(L, "invalid result type %s", lua_typename(L, 2));
 
-             break;
 
-     }
 
-     return 0;
 
- }
 
- static int lcontext_result_blob(lua_State *L) {
 
-     lcontext *ctx = lsqlite_checkcontext(L, 1);
 
-     const char *blob = luaL_checkstring(L, 2);
 
-     int size = lua_strlen(L, 2);
 
-     sqlite3_result_blob(ctx->ctx, (const void*)blob, size, SQLITE_TRANSIENT);
 
-     return 0;
 
- }
 
- static int lcontext_result_double(lua_State *L) {
 
-     lcontext *ctx = lsqlite_checkcontext(L, 1);
 
-     double d = luaL_checknumber(L, 2);
 
-     sqlite3_result_double(ctx->ctx, d);
 
-     return 0;
 
- }
 
- static int lcontext_result_error(lua_State *L) {
 
-     lcontext *ctx = lsqlite_checkcontext(L, 1);
 
-     const char *err = luaL_checkstring(L, 2);
 
-     int size = lua_strlen(L, 2);
 
-     sqlite3_result_error(ctx->ctx, err, size);
 
-     return 0;
 
- }
 
- static int lcontext_result_int(lua_State *L) {
 
-     lcontext *ctx = lsqlite_checkcontext(L, 1);
 
-     int i = luaL_checkint(L, 2);
 
-     sqlite3_result_int(ctx->ctx, i);
 
-     return 0;
 
- }
 
- static int lcontext_result_null(lua_State *L) {
 
-     lcontext *ctx = lsqlite_checkcontext(L, 1);
 
-     sqlite3_result_null(ctx->ctx);
 
-     return 0;
 
- }
 
- static int lcontext_result_text(lua_State *L) {
 
-     lcontext *ctx = lsqlite_checkcontext(L, 1);
 
-     const char *text = luaL_checkstring(L, 2);
 
-     int size = lua_strlen(L, 2);
 
-     sqlite3_result_text(ctx->ctx, text, size, SQLITE_TRANSIENT);
 
-     return 0;
 
- }
 
- /*
 
- ** =======================================================
 
- ** Database Methods
 
- ** =======================================================
 
- */
 
- static int db_isopen(lua_State *L) {
 
-     sdb *db = lsqlite_getdb(L, 1);
 
-     lua_pushboolean(L, db->db != NULL ? 1 : 0);
 
-     return 1;
 
- }
 
- static int db_last_insert_rowid(lua_State *L) {
 
-     sdb *db = lsqlite_checkdb(L, 1);
 
-     /* conversion warning: int64 -> luaNumber */
 
-     sqlite_int64 rowid = sqlite3_last_insert_rowid(db->db);
 
-     lua_Number n = (lua_Number)rowid;
 
-     if (n == rowid)
 
-         lua_pushnumber(L, n);
 
-     else
 
-         lua_pushfstring(L, "%ll", rowid);
 
-     return 1;
 
- }
 
- static int db_changes(lua_State *L) {
 
-     sdb *db = lsqlite_checkdb(L, 1);
 
-     lua_pushnumber(L, sqlite3_changes(db->db));
 
-     return 1;
 
- }
 
- static int db_total_changes(lua_State *L) {
 
-     sdb *db = lsqlite_checkdb(L, 1);
 
-     lua_pushnumber(L, sqlite3_total_changes(db->db));
 
-     return 1;
 
- }
 
- static int db_errcode(lua_State *L) {
 
-     sdb *db = lsqlite_checkdb(L, 1);
 
-     lua_pushnumber(L, sqlite3_errcode(db->db));
 
-     return 1;
 
- }
 
- static int db_errmsg(lua_State *L) {
 
-     sdb *db = lsqlite_checkdb(L, 1);
 
-     lua_pushstring(L, sqlite3_errmsg(db->db));
 
-     return 1;
 
- }
 
- static int db_interrupt(lua_State *L) {
 
-     sdb *db = lsqlite_checkdb(L, 1);
 
-     sqlite3_interrupt(db->db);
 
-     return 0;
 
- }
 
- /*
 
- ** Registering SQL functions:
 
- */
 
- static void db_push_value(lua_State *L, sqlite3_value *value) {
 
-     switch (sqlite3_value_type(value)) {
 
-         case SQLITE_TEXT:
 
-             lua_pushlstring(L, (const char*)sqlite3_value_text(value), sqlite3_value_bytes(value));
 
-             break;
 
-         case SQLITE_INTEGER:
 
-             {
 
-                 sqlite_int64 i64 = sqlite3_value_int64(value);
 
-                 lua_Number n = (lua_Number)i64;
 
-                 if (n == i64)
 
-                     lua_pushnumber(L, n);
 
-                 else
 
-                     lua_pushlstring(L, (const char*)sqlite3_value_text(value), sqlite3_value_bytes(value));
 
-             }
 
-             break;
 
-         case SQLITE_FLOAT:
 
-             lua_pushnumber(L, sqlite3_value_double(value));
 
-             break;
 
-         case SQLITE_BLOB:
 
-             lua_pushlstring(L, sqlite3_value_blob(value), sqlite3_value_bytes(value));
 
-             break;
 
-         case SQLITE_NULL:
 
-             lua_pushnil(L);
 
-             break;
 
-         default:
 
-             /* things done properly (SQLite + Lua SQLite)
 
-             ** this should never happen */
 
-             lua_pushnil(L);
 
-             break;
 
-     }
 
- }
 
- /*
 
- ** callback functions used when calling registered sql functions
 
- */
 
- /* scalar function to be called
 
- ** callback params: context, values... */
 
- static void db_sql_normal_function(sqlite3_context *context, int argc, sqlite3_value **argv) {
 
-     sdb_func *func = (sdb_func*)sqlite3_user_data(context);
 
-     lua_State *L = func->db->L;
 
-     int n;
 
-     lcontext *ctx;
 
-     int top = lua_gettop(L);
 
-     /* ensure there is enough space in the stack */
 
-     lua_checkstack(L, argc + 3);
 
-     lua_rawgeti(L, LUA_REGISTRYINDEX, func->fn_step);   /* function to call */
 
-     if (!func->aggregate) {
 
-         ctx = lsqlite_make_context(L); /* push context - used to set results */
 
-     }
 
-     else {
 
-         /* reuse context userdata value */
 
-         void *p = sqlite3_aggregate_context(context, 1);
 
-         /* i think it is OK to use assume that using a light user data
 
-         ** as an entry on LUA REGISTRY table will be unique */
 
-         lua_pushlightuserdata(L, p);
 
-         lua_rawget(L, LUA_REGISTRYINDEX);       /* context table */
 
-         if (lua_isnil(L, -1)) { /* not yet created? */
 
-             lua_pop(L, 1);
 
-             ctx = lsqlite_make_context(L);
 
-             lua_pushlightuserdata(L, p);
 
-             lua_pushvalue(L, -2);
 
-             lua_rawset(L, LUA_REGISTRYINDEX);
 
-         }
 
-         else
 
-             ctx = lsqlite_getcontext(L, -1);
 
-     }
 
-     /* push params */
 
-     for (n = 0; n < argc; ++n) {
 
-         db_push_value(L, argv[n]);
 
-     }
 
-     /* set context */
 
-     ctx->ctx = context;
 
-     if (lua_pcall(L, argc + 1, 0, 0)) {
 
-         const char *errmsg = lua_tostring(L, -1);
 
-         int size = lua_strlen(L, -1);
 
-         sqlite3_result_error(context, errmsg, size);
 
-     }
 
-     /* invalidate context */
 
-     ctx->ctx = NULL;
 
-     if (!func->aggregate) {
 
-         luaL_unref(L, LUA_REGISTRYINDEX, ctx->ud);
 
-     }
 
-     lua_settop(L, top);
 
- }
 
- static void db_sql_finalize_function(sqlite3_context *context) {
 
-     sdb_func *func = (sdb_func*)sqlite3_user_data(context);
 
-     lua_State *L = func->db->L;
 
-     void *p = sqlite3_aggregate_context(context, 1); /* minimal mem usage */
 
-     lcontext *ctx;
 
-     int top = lua_gettop(L);
 
-     lua_rawgeti(L, LUA_REGISTRYINDEX, func->fn_finalize);   /* function to call */
 
-     /* i think it is OK to use assume that using a light user data
 
-     ** as an entry on LUA REGISTRY table will be unique */
 
-     lua_pushlightuserdata(L, p);
 
-     lua_rawget(L, LUA_REGISTRYINDEX);       /* context table */
 
-     if (lua_isnil(L, -1)) { /* not yet created? - shouldn't happen in finalize function */
 
-         lua_pop(L, 1);
 
-         ctx = lsqlite_make_context(L);
 
-         lua_pushlightuserdata(L, p);
 
-         lua_pushvalue(L, -2);
 
-         lua_rawset(L, LUA_REGISTRYINDEX);
 
-     }
 
-     else
 
-         ctx = lsqlite_getcontext(L, -1);
 
-     /* set context */
 
-     ctx->ctx = context;
 
-     if (lua_pcall(L, 1, 0, 0)) {
 
-         sqlite3_result_error(context, lua_tostring(L, -1), -1);
 
-     }
 
-     /* invalidate context */
 
-     ctx->ctx = NULL;
 
-     /* cleanup context */
 
-     luaL_unref(L, LUA_REGISTRYINDEX, ctx->ud);
 
-     /* remove it from registry */
 
-     lua_pushlightuserdata(L, p);
 
-     lua_pushnil(L);
 
-     lua_rawset(L, LUA_REGISTRYINDEX);
 
-     lua_settop(L, top);
 
- }
 
- /*
 
- ** Register a normal function
 
- ** Params: db, function name, number arguments, [ callback | step, finalize], user data
 
- ** Returns: true on sucess
 
- **
 
- ** Normal function:
 
- ** Params: context, params
 
- **
 
- ** Aggregate function:
 
- ** Params of step: context, params
 
- ** Params of finalize: context
 
- */
 
- static int db_register_function(lua_State *L, int aggregate) {
 
-     sdb *db = lsqlite_checkdb(L, 1);
 
-     const char *name;
 
-     int args;
 
-     int result;
 
-     sdb_func *func;
 
-     /* safety measure */
 
-     if (aggregate) aggregate = 1;
 
-     name = luaL_checkstring(L, 2);
 
-     args = luaL_checkint(L, 3);
 
-     luaL_checktype(L, 4, LUA_TFUNCTION);
 
-     if (aggregate) luaL_checktype(L, 5, LUA_TFUNCTION);
 
-     /* maybe an alternative way to allocate memory should be used/avoided */
 
-     func = (sdb_func*)malloc(sizeof(sdb_func));
 
-     if (func == NULL) {
 
-         luaL_error(L, "out of memory");
 
-     }
 
-     result = sqlite3_create_function(
 
-         db->db, name, args, SQLITE_UTF8, func,
 
-         aggregate ? NULL : db_sql_normal_function,
 
-         aggregate ? db_sql_normal_function : NULL,
 
-         aggregate ? db_sql_finalize_function : NULL
 
-     );
 
-     if (result == SQLITE_OK) {
 
-         /* safety measures for userdata field to be present in the stack */
 
-         lua_settop(L, 5 + aggregate);
 
-         /* save registered function in db function list */
 
-         func->db = db;
 
-         func->aggregate = aggregate;
 
-         func->next = db->func;
 
-         db->func = func;
 
-         /* save the setp/normal function callback */
 
-         lua_pushvalue(L, 4);
 
-         func->fn_step = luaL_ref(L, LUA_REGISTRYINDEX);
 
-         /* save user data */
 
-         lua_pushvalue(L, 5+aggregate);
 
-         func->udata = luaL_ref(L, LUA_REGISTRYINDEX);
 
-         if (aggregate) {
 
-             lua_pushvalue(L, 5);
 
-             func->fn_finalize = luaL_ref(L, LUA_REGISTRYINDEX);
 
-         }
 
-         else
 
-             func->fn_finalize = LUA_NOREF;
 
-     }
 
-     else {
 
-         /* free allocated memory */
 
-         free(func);
 
-     }
 
-     lua_pushboolean(L, result == SQLITE_OK ? 1 : 0);
 
-     return 1;
 
- }
 
- static int db_create_function(lua_State *L) {
 
-     return db_register_function(L, 0);
 
- }
 
- static int db_create_aggregate(lua_State *L) {
 
-     return db_register_function(L, 1);
 
- }
 
- /* create_collation; contributed by Thomas Lauer
 
- */
 
- typedef struct {
 
-     lua_State *L;
 
-     int ref;
 
- } scc;
 
- static int collwrapper(scc *co,int l1,const void *p1,
 
-                         int l2,const void *p2) {
 
-     int res=0;
 
-     lua_State *L=co->L;
 
-     lua_rawgeti(L,LUA_REGISTRYINDEX,co->ref);
 
-     lua_pushlstring(L,p1,l1);
 
-     lua_pushlstring(L,p2,l2);
 
-     if (lua_pcall(L,2,1,0)==0) res=(int)lua_tonumber(L,-1);
 
-     lua_pop(L,1);
 
-     return res;
 
- }
 
- static void collfree(scc *co) {
 
-     if (co) {
 
-         luaL_unref(co->L,LUA_REGISTRYINDEX,co->ref);
 
-         free(co);
 
-     }
 
- }
 
- static int db_create_collation(lua_State *L) {
 
-     sdb *db=lsqlite_checkdb(L,1);
 
-     const char *collname=luaL_checkstring(L,2);
 
-     scc *co=NULL;
 
-     int (*collfunc)(scc *,int,const void *,int,const void *)=NULL;
 
-     lua_settop(L,3); /* default args to nil, and exclude extras */
 
-     if (lua_isfunction(L,3)) collfunc=collwrapper;
 
-     else if (!lua_isnil(L,3))
 
-         luaL_error(L,"create_collation: function or nil expected");
 
-     if (collfunc != NULL) {
 
-         co=(scc *)malloc(sizeof(scc)); /* userdata is a no-no as it
 
-                                           will be garbage-collected */
 
-         if (co) {
 
-             co->L=L;
 
-             /* lua_settop(L,3) above means we don't need: lua_pushvalue(L,3); */
 
-             co->ref=luaL_ref(L,LUA_REGISTRYINDEX);
 
-         }
 
-         else luaL_error(L,"create_collation: could not allocate callback");
 
-     }
 
-     sqlite3_create_collation_v2(db->db, collname, SQLITE_UTF8,
 
-         (void *)co,
 
-         (int(*)(void*,int,const void*,int,const void*))collfunc,
 
-         (void(*)(void*))collfree);
 
-     return 0;
 
- }
 
- /*
 
- ** trace callback:
 
- ** Params: database, callback function, userdata
 
- **
 
- ** callback function:
 
- ** Params: userdata, sql
 
- */
 
- static void db_trace_callback(void *user, const char *sql) {
 
-     sdb *db = (sdb*)user;
 
-     lua_State *L = db->L;
 
-     int top = lua_gettop(L);
 
-     /* setup lua callback call */
 
-     lua_rawgeti(L, LUA_REGISTRYINDEX, db->trace_cb);    /* get callback */
 
-     lua_rawgeti(L, LUA_REGISTRYINDEX, db->trace_udata); /* get callback user data */
 
-     lua_pushstring(L, sql); /* traced sql statement */
 
-     /* call lua function */
 
-     lua_pcall(L, 2, 0, 0);
 
-     /* ignore any error generated by this function */
 
-     lua_settop(L, top);
 
- }
 
- static int db_trace(lua_State *L) {
 
-     sdb *db = lsqlite_checkdb(L, 1);
 
-     if (lua_gettop(L) < 2 || lua_isnil(L, 2)) {
 
-         luaL_unref(L, LUA_REGISTRYINDEX, db->trace_cb);
 
-         luaL_unref(L, LUA_REGISTRYINDEX, db->trace_udata);
 
-         db->trace_cb =
 
-         db->trace_udata = LUA_NOREF;
 
-         /* clear busy handler */
 
-         sqlite3_trace(db->db, NULL, NULL);
 
-     }
 
-     else {
 
-         luaL_checktype(L, 2, LUA_TFUNCTION);
 
-         /* make sure we have an userdata field (even if nil) */
 
-         lua_settop(L, 3);
 
-         luaL_unref(L, LUA_REGISTRYINDEX, db->trace_cb);
 
-         luaL_unref(L, LUA_REGISTRYINDEX, db->trace_udata);
 
-         db->trace_udata = luaL_ref(L, LUA_REGISTRYINDEX);
 
-         db->trace_cb = luaL_ref(L, LUA_REGISTRYINDEX);
 
-         /* set busy handler */
 
-         sqlite3_trace(db->db, db_trace_callback, db);
 
-     }
 
-     return 0;
 
- }
 
- #if !defined(SQLITE_OMIT_PROGRESS_CALLBACK) || !SQLITE_OMIT_PROGRESS_CALLBACK
 
- /*
 
- ** progress handler:
 
- ** Params: database, number of opcodes, callback function, userdata
 
- **
 
- ** callback function:
 
- ** Params: userdata
 
- ** returns: 0 to return immediatly and return SQLITE_ABORT, non-zero to continue
 
- */
 
- static int db_progress_callback(void *user) {
 
-     int result = 1; /* abort by default */
 
-     sdb *db = (sdb*)user;
 
-     lua_State *L = db->L;
 
-     int top = lua_gettop(L);
 
-     lua_rawgeti(L, LUA_REGISTRYINDEX, db->progress_cb);
 
-     lua_rawgeti(L, LUA_REGISTRYINDEX, db->progress_udata);
 
-     /* call lua function */
 
-     if (!lua_pcall(L, 1, 1, 0))
 
-         result = lua_toboolean(L, -1);
 
-     lua_settop(L, top);
 
-     return result;
 
- }
 
- static int db_progress_handler(lua_State *L) {
 
-     sdb *db = lsqlite_checkdb(L, 1);
 
-     if (lua_gettop(L) < 2 || lua_isnil(L, 2)) {
 
-         luaL_unref(L, LUA_REGISTRYINDEX, db->progress_cb);
 
-         luaL_unref(L, LUA_REGISTRYINDEX, db->progress_udata);
 
-         db->progress_cb =
 
-         db->progress_udata = LUA_NOREF;
 
-         /* clear busy handler */
 
-         sqlite3_progress_handler(db->db, 0, NULL, NULL);
 
-     }
 
-     else {
 
-         int nop = luaL_checkint(L, 2);  /* number of opcodes */
 
-         luaL_checktype(L, 3, LUA_TFUNCTION);
 
-         /* make sure we have an userdata field (even if nil) */
 
-         lua_settop(L, 4);
 
-         luaL_unref(L, LUA_REGISTRYINDEX, db->progress_cb);
 
-         luaL_unref(L, LUA_REGISTRYINDEX, db->progress_udata);
 
-         db->progress_udata = luaL_ref(L, LUA_REGISTRYINDEX);
 
-         db->progress_cb = luaL_ref(L, LUA_REGISTRYINDEX);
 
-         /* set progress callback */
 
-         sqlite3_progress_handler(db->db, nop, db_progress_callback, db);
 
-     }
 
-     return 0;
 
- }
 
- #else /* #if !defined(SQLITE_OMIT_PROGRESS_CALLBACK) || !SQLITE_OMIT_PROGRESS_CALLBACK */
 
- static int db_progress_handler(lua_State *L) {
 
-     lua_pushliteral(L, "progress callback support disabled at compile time");
 
-     lua_error(L);
 
-     return 0;
 
- }
 
- #endif /* #if !defined(SQLITE_OMIT_PROGRESS_CALLBACK) || !SQLITE_OMIT_PROGRESS_CALLBACK */
 
- /*
 
- ** busy handler:
 
- ** Params: database, callback function, userdata
 
- **
 
- ** callback function:
 
- ** Params: userdata, number of tries
 
- ** returns: 0 to return immediatly and return SQLITE_BUSY, non-zero to try again
 
- */
 
- static int db_busy_callback(void *user, int tries) {
 
-     int retry = 0; /* abort by default */
 
-     sdb *db = (sdb*)user;
 
-     lua_State *L = db->L;
 
-     int top = lua_gettop(L);
 
-     lua_rawgeti(L, LUA_REGISTRYINDEX, db->busy_cb);
 
-     lua_rawgeti(L, LUA_REGISTRYINDEX, db->busy_udata);
 
-     lua_pushnumber(L, tries);
 
-     /* call lua function */
 
-     if (!lua_pcall(L, 2, 1, 0))
 
-         retry = lua_toboolean(L, -1);
 
-     lua_settop(L, top);
 
-     return retry;
 
- }
 
- static int db_busy_handler(lua_State *L) {
 
-     sdb *db = lsqlite_checkdb(L, 1);
 
-     if (lua_gettop(L) < 2 || lua_isnil(L, 2)) {
 
-         luaL_unref(L, LUA_REGISTRYINDEX, db->busy_cb);
 
-         luaL_unref(L, LUA_REGISTRYINDEX, db->busy_udata);
 
-         db->busy_cb =
 
-         db->busy_udata = LUA_NOREF;
 
-         /* clear busy handler */
 
-         sqlite3_busy_handler(db->db, NULL, NULL);
 
-     }
 
-     else {
 
-         luaL_checktype(L, 2, LUA_TFUNCTION);
 
-         /* make sure we have an userdata field (even if nil) */
 
-         lua_settop(L, 3);
 
-         luaL_unref(L, LUA_REGISTRYINDEX, db->busy_cb);
 
-         luaL_unref(L, LUA_REGISTRYINDEX, db->busy_udata);
 
-         db->busy_udata = luaL_ref(L, LUA_REGISTRYINDEX);
 
-         db->busy_cb = luaL_ref(L, LUA_REGISTRYINDEX);
 
-         /* set busy handler */
 
-         sqlite3_busy_handler(db->db, db_busy_callback, db);
 
-     }
 
-     return 0;
 
- }
 
- static int db_busy_timeout(lua_State *L) {
 
-     sdb *db = lsqlite_checkdb(L, 1);
 
-     int timeout = luaL_checkint(L, 2);
 
-     sqlite3_busy_timeout(db->db, timeout);
 
-     /* if there was a timeout callback registered, it is now
 
-     ** invalid/useless. free any references we may have */
 
-     luaL_unref(L, LUA_REGISTRYINDEX, db->busy_cb);
 
-     luaL_unref(L, LUA_REGISTRYINDEX, db->busy_udata);
 
-     db->busy_cb =
 
-     db->busy_udata = LUA_NOREF;
 
-     return 0;
 
- }
 
- /*
 
- ** Params: db, sql, callback, user
 
- ** returns: code [, errmsg]
 
- **
 
- ** Callback:
 
- ** Params: user, number of columns, values, names
 
- ** Returns: 0 to continue, other value will cause abort
 
- */
 
- static int db_exec_callback(void* user, int columns, char **data, char **names) {
 
-     int result = SQLITE_ABORT; /* abort by default */
 
-     lua_State *L = (lua_State*)user;
 
-     int n;
 
-     int top = lua_gettop(L);
 
-     lua_pushvalue(L, 3); /* function to call */
 
-     lua_pushvalue(L, 4); /* user data */
 
-     lua_pushnumber(L, columns); /* total number of rows in result */
 
-     /* column values */
 
-     lua_pushvalue(L, 6);
 
-     for (n = 0; n < columns;) {
 
-         lua_pushstring(L, data[n++]);
 
-         lua_rawseti(L, -2, n);
 
-     }
 
-     /* columns names */
 
-     lua_pushvalue(L, 5);
 
-     if (lua_isnil(L, -1)) {
 
-         lua_pop(L, 1);
 
-         lua_newtable(L);
 
-         lua_pushvalue(L, -1);
 
-         lua_replace(L, 5);
 
-         for (n = 0; n < columns;) {
 
-             lua_pushstring(L, names[n++]);
 
-             lua_rawseti(L, -2, n);
 
-         }
 
-     }
 
-     /* call lua function */
 
-     if (!lua_pcall(L, 4, 1, 0)) {
 
-         if (lua_isnumber(L, -1))
 
-             result = lua_tonumber(L, -1);
 
-     }
 
-     lua_settop(L, top);
 
-     return result;
 
- }
 
- static int db_exec(lua_State *L) {
 
-     sdb *db = lsqlite_checkdb(L, 1);
 
-     const char *sql = luaL_checkstring(L, 2);
 
-     int result;
 
-     if (!lua_isnoneornil(L, 3)) {
 
-         /* stack:
 
-         **  3: callback function
 
-         **  4: userdata
 
-         **  5: column names
 
-         **  6: reusable column values
 
-         */
 
-         luaL_checktype(L, 3, LUA_TFUNCTION);
 
-         lua_settop(L, 4);   /* 'trap' userdata - nil extra parameters */
 
-         lua_pushnil(L);     /* column names not known at this point */
 
-         lua_newtable(L);    /* column values table */
 
-         result = sqlite3_exec(db->db, sql, db_exec_callback, L, NULL);
 
-     }
 
-     else {
 
-         /* no callbacks */
 
-         result = sqlite3_exec(db->db, sql, NULL, NULL, NULL);
 
-     }
 
-     lua_pushnumber(L, result);
 
-     return 1;
 
- }
 
- /*
 
- ** Params: db, sql
 
- ** returns: code, compiled length or error message
 
- */
 
- static int db_prepare(lua_State *L) {
 
-     sdb *db = lsqlite_checkdb(L, 1);
 
-     const char *sql = luaL_checkstring(L, 2);
 
-     int sql_len = lua_strlen(L, 2);
 
-     const char *sqltail;
 
-     sdb_vm *svm;
 
-     lua_settop(L,2); /* sql is on top of stack for call to newvm */
 
-     svm = newvm(L, db);
 
-     if (sqlite3_prepare(db->db, sql, sql_len, &svm->vm, &sqltail) != SQLITE_OK) {
 
-         cleanupvm(L, svm);
 
-         lua_pushnil(L);
 
-         lua_pushnumber(L, sqlite3_errcode(db->db));
 
-         return 2;
 
-     }
 
-     /* vm already in the stack */
 
-     lua_pushstring(L, sqltail);
 
-     return 2;
 
- }
 
- static int db_do_next_row(lua_State *L, int packed) {
 
-     int result;
 
-     sdb_vm *svm = lsqlite_checkvm(L, 1);
 
-     sqlite3_stmt *vm;
 
-     int columns;
 
-     int i;
 
-     result = stepvm(L, svm);
 
-     vm = svm->vm; /* stepvm may change svm->vm if re-prepare is needed */
 
-     svm->has_values = result == SQLITE_ROW ? 1 : 0;
 
-     svm->columns = columns = sqlite3_data_count(vm);
 
-     if (result == SQLITE_ROW) {
 
-         if (packed) {
 
-             lua_newtable(L);
 
-             if (packed == 1) {
 
-                 for (i = 0; i < columns;) {
 
-                     vm_push_column(L, vm, i);
 
-                     lua_rawseti(L, -2, ++i);
 
-                 }
 
-             }
 
-             else {
 
-                 for (i = 0; i < columns; ++i) {
 
-                     lua_pushstring(L, sqlite3_column_name(vm, i));
 
-                     vm_push_column(L, vm, i);
 
-                     lua_rawset(L, -3);
 
-                 }
 
-             }
 
-             return 1;
 
-         }
 
-         else {
 
-             lua_checkstack(L, columns);
 
-             for (i = 0; i < columns; ++i)
 
-                 vm_push_column(L, vm, i);
 
-             return svm->columns;
 
-         }
 
-     }
 
-     if (svm->temp) {
 
-         /* finalize and check for errors */
 
-         result = sqlite3_finalize(vm);
 
-         svm->vm = NULL;
 
-         cleanupvm(L, svm);
 
-     }
 
-     else if (result == SQLITE_DONE) {
 
-         result = sqlite3_reset(vm);
 
-     }
 
-     if (result != SQLITE_OK) {
 
-         lua_pushstring(L, sqlite3_errmsg(svm->db->db));
 
-         lua_error(L);
 
-     }
 
-     return 0;
 
- }
 
- static int db_next_row(lua_State *L) {
 
-     return db_do_next_row(L, 0);
 
- }
 
- static int db_next_packed_row(lua_State *L) {
 
-     return db_do_next_row(L, 1);
 
- }
 
- static int db_next_named_row(lua_State *L) {
 
-     return db_do_next_row(L, 2);
 
- }
 
- static int dbvm_do_rows(lua_State *L, int(*f)(lua_State *)) {
 
-     /* sdb_vm *svm =  */
 
-     lsqlite_checkvm(L, 1);
 
-     lua_pushvalue(L,1);
 
-     lua_pushcfunction(L, f);
 
-     lua_insert(L, -2);
 
-     return 2;
 
- }
 
- static int dbvm_rows(lua_State *L) {
 
-     return dbvm_do_rows(L, db_next_packed_row);
 
- }
 
- static int dbvm_nrows(lua_State *L) {
 
-     return dbvm_do_rows(L, db_next_named_row);
 
- }
 
- static int dbvm_urows(lua_State *L) {
 
-     return dbvm_do_rows(L, db_next_row);
 
- }
 
- static int db_do_rows(lua_State *L, int(*f)(lua_State *)) {
 
-     sdb *db = lsqlite_checkdb(L, 1);
 
-     const char *sql = luaL_checkstring(L, 2);
 
-     sdb_vm *svm;
 
-     lua_settop(L,2); /* sql is on top of stack for call to newvm */
 
-     svm = newvm(L, db);
 
-     svm->temp = 1;
 
-     if (sqlite3_prepare(db->db, sql, -1, &svm->vm, NULL) != SQLITE_OK) {
 
-         cleanupvm(L, svm);
 
-         lua_pushstring(L, sqlite3_errmsg(svm->db->db));
 
-         lua_error(L);
 
-     }
 
-     lua_pushcfunction(L, f);
 
-     lua_insert(L, -2);
 
-     return 2;
 
- }
 
- static int db_rows(lua_State *L) {
 
-     return db_do_rows(L, db_next_packed_row);
 
- }
 
- static int db_nrows(lua_State *L) {
 
-     return db_do_rows(L, db_next_named_row);
 
- }
 
- /* unpacked version of db:rows */
 
- static int db_urows(lua_State *L) {
 
-     return db_do_rows(L, db_next_row);
 
- }
 
- static int db_tostring(lua_State *L) {
 
-     char buff[32];
 
-     sdb *db = lsqlite_getdb(L, 1);
 
-     if (db->db == NULL)
 
-         strcpy(buff, "closed");
 
-     else
 
-         sprintf(buff, "%p", lua_touserdata(L, 1));
 
-     lua_pushfstring(L, "sqlite database (%s)", buff);
 
-     return 1;
 
- }
 
- static int db_close(lua_State *L) {
 
-     sdb *db = lsqlite_checkdb(L, 1);
 
-     lua_pushnumber(L, cleanupdb(L, db));
 
-     return 1;
 
- }
 
- static int db_close_vm(lua_State *L) {
 
-     sdb *db = lsqlite_checkdb(L, 1);
 
-     /* cleanup temporary only tables? */
 
-     int temp = lua_toboolean(L, 2);
 
-     /* free associated virtual machines */
 
-     lua_pushlightuserdata(L, db);
 
-     lua_rawget(L, LUA_REGISTRYINDEX);
 
-     /* close all used handles */
 
-     lua_pushnil(L);
 
-     while (lua_next(L, -2)) {
 
-         sdb_vm *svm = lua_touserdata(L, -2); /* key: vm; val: sql text */
 
-         if ((!temp || svm->temp) && svm->vm)
 
-         {
 
-             sqlite3_finalize(svm->vm);
 
-             svm->vm = NULL;
 
-         }
 
-         /* leave key in the stack */
 
-         lua_pop(L, 1);
 
-     }
 
-     return 0;
 
- }
 
- static int db_gc(lua_State *L) {
 
-     sdb *db = lsqlite_getdb(L, 1);
 
-     if (db->db != NULL)  /* ignore closed databases */
 
-         cleanupdb(L, db);
 
-     return 0;
 
- }
 
- /*
 
- ** =======================================================
 
- ** General library functions
 
- ** =======================================================
 
- */
 
- static int lsqlite_version(lua_State *L) {
 
-     lua_pushstring(L, sqlite3_libversion());
 
-     return 1;
 
- }
 
- static int lsqlite_complete(lua_State *L) {
 
-     const char *sql = luaL_checkstring(L, 1);
 
-     lua_pushboolean(L, sqlite3_complete(sql));
 
-     return 1;
 
- }
 
- #ifndef WIN32
 
- static int lsqlite_temp_directory(lua_State *L) {
 
-     const char *oldtemp = sqlite3_temp_directory;
 
-     if (!lua_isnone(L, 1)) {
 
-         const char *temp = luaL_optstring(L, 1, NULL);
 
-         if (sqlite3_temp_directory) {
 
-             sqlite3_free((char*)sqlite3_temp_directory);
 
-         }
 
-         if (temp) {
 
-             sqlite3_temp_directory = sqlite3_mprintf("%s", temp);
 
-         }
 
-         else {
 
-             sqlite3_temp_directory = NULL;
 
-         }
 
-     }
 
-     lua_pushstring(L, oldtemp);
 
-     return 1;
 
- }
 
- #endif
 
- static int lsqlite_do_open(lua_State *L, const char *filename) {
 
-     sdb *db = newdb(L); /* create and leave in stack */
 
-     if (sqlite3_open(filename, &db->db) == SQLITE_OK) {
 
-         /* database handle already in the stack - return it */
 
-         return 1;
 
-     }
 
-     /* failed to open database */
 
-     lua_pushnil(L);                             /* push nil */
 
-     lua_pushnumber(L, sqlite3_errcode(db->db));
 
-     lua_pushstring(L, sqlite3_errmsg(db->db));  /* push error message */
 
-     /* clean things up */
 
-     cleanupdb(L, db);
 
-     /* return */
 
-     return 3;
 
- }
 
- static int lsqlite_open(lua_State *L) {
 
-     const char *filename = luaL_checkstring(L, 1);
 
-     return lsqlite_do_open(L, filename);
 
- }
 
- static int lsqlite_open_memory(lua_State *L) {
 
-     return lsqlite_do_open(L, ":memory:");
 
- }
 
- static int lsqlite_newindex(lua_State *L) {
 
-     lua_pushliteral(L, "attempt to change readonly table");
 
-     lua_error(L);
 
-     return 0;
 
- }
 
- /*
 
- ** =======================================================
 
- ** Register functions
 
- ** =======================================================
 
- */
 
- #define SC(s)   { #s, SQLITE_ ## s },
 
- #define LSC(s)  { #s, LSQLITE_ ## s },
 
- static const struct {
 
-     const char* name;
 
-     int value;
 
- } sqlite_constants[] = {
 
-     /* error codes */
 
-     SC(OK)          SC(ERROR)       SC(INTERNAL)    SC(PERM)
 
-     SC(ABORT)       SC(BUSY)        SC(LOCKED)      SC(NOMEM)
 
-     SC(READONLY)    SC(INTERRUPT)   SC(IOERR)       SC(CORRUPT)
 
-     SC(NOTFOUND)    SC(FULL)        SC(CANTOPEN)    SC(PROTOCOL)
 
-     SC(EMPTY)       SC(SCHEMA)      SC(TOOBIG)      SC(CONSTRAINT)
 
-     SC(MISMATCH)    SC(MISUSE)      SC(NOLFS)
 
-     SC(FORMAT)      SC(NOTADB)
 
-     /* sqlite_step specific return values */
 
-     SC(RANGE)       SC(ROW)         SC(DONE)
 
-     /* column types */
 
-     SC(INTEGER)     SC(FLOAT)       SC(TEXT)        SC(BLOB)
 
-     SC(NULL)
 
-     /* terminator */
 
-     { NULL, 0 }
 
- };
 
- /* ======================================================= */
 
- static const luaL_Reg dblib[] = {
 
-     {"isopen",              db_isopen               },
 
-     {"last_insert_rowid",   db_last_insert_rowid    },
 
-     {"changes",             db_changes              },
 
-     {"total_changes",       db_total_changes        },
 
-     {"errcode",             db_errcode              },
 
-     {"error_code",          db_errcode              },
 
-     {"errmsg",              db_errmsg               },
 
-     {"error_message",       db_errmsg               },
 
-     {"interrupt",           db_interrupt            },
 
-     {"create_function",     db_create_function      },
 
-     {"create_aggregate",    db_create_aggregate     },
 
-     {"create_collation",    db_create_collation     },
 
-     {"trace",               db_trace                },
 
-     {"progress_handler",    db_progress_handler     },
 
-     {"busy_timeout",        db_busy_timeout         },
 
-     {"busy_handler",        db_busy_handler         },
 
-     {"prepare",             db_prepare              },
 
-     {"rows",                db_rows                 },
 
-     {"urows",               db_urows                },
 
-     {"nrows",               db_nrows                },
 
-     {"exec",                db_exec                 },
 
-     {"execute",             db_exec                 },
 
-     {"close",               db_close                },
 
-     {"close_vm",            db_close_vm             },
 
-     {"__tostring",          db_tostring             },
 
-     {"__gc",                db_gc                   },
 
-     {NULL, NULL}
 
- };
 
- static const luaL_Reg vmlib[] = {
 
-     {"isopen",              dbvm_isopen             },
 
-     {"step",                dbvm_step               },
 
-     {"reset",               dbvm_reset              },
 
-     {"finalize",            dbvm_finalize           },
 
-     {"columns",             dbvm_columns            },
 
-     {"bind",                dbvm_bind               },
 
-     {"bind_values",         dbvm_bind_values        },
 
-     {"bind_names",          dbvm_bind_names         },
 
-     {"bind_blob",           dbvm_bind_blob          },
 
-     {"bind_parameter_count",dbvm_bind_parameter_count},
 
-     {"bind_parameter_name", dbvm_bind_parameter_name},
 
-     {"get_value",           dbvm_get_value          },
 
-     {"get_values",          dbvm_get_values         },
 
-     {"get_name",            dbvm_get_name           },
 
-     {"get_names",           dbvm_get_names          },
 
-     {"get_type",            dbvm_get_type           },
 
-     {"get_types",           dbvm_get_types          },
 
-     {"get_uvalues",         dbvm_get_uvalues        },
 
-     {"get_unames",          dbvm_get_unames         },
 
-     {"get_utypes",          dbvm_get_utypes         },
 
-     {"get_named_values",    dbvm_get_named_values   },
 
-     {"get_named_types",     dbvm_get_named_types    },
 
-     {"rows",                dbvm_rows               },
 
-     {"urows",               dbvm_urows              },
 
-     {"nrows",               dbvm_nrows              },
 
-     /* compatibility names (added by request) */
 
-     {"idata",               dbvm_get_values         },
 
-     {"inames",              dbvm_get_names          },
 
-     {"itypes",              dbvm_get_types          },
 
-     {"data",                dbvm_get_named_values   },
 
-     {"type",                dbvm_get_named_types    },
 
-     {"__tostring",          dbvm_tostring           },
 
-     {"__gc",                dbvm_gc                 },
 
-     { NULL, NULL }
 
- };
 
- static const luaL_Reg ctxlib[] = {
 
-     {"user_data",               lcontext_user_data              },
 
-     {"get_aggregate_data",      lcontext_get_aggregate_context  },
 
-     {"set_aggregate_data",      lcontext_set_aggregate_context  },
 
-     {"aggregate_count",         lcontext_aggregate_count        },
 
-     {"result",                  lcontext_result                 },
 
-     {"result_null",             lcontext_result_null            },
 
-     {"result_number",           lcontext_result_double          },
 
-     {"result_double",           lcontext_result_double          },
 
-     {"result_int",              lcontext_result_int             },
 
-     {"result_text",             lcontext_result_text            },
 
-     {"result_blob",             lcontext_result_blob            },
 
-     {"result_error",            lcontext_result_error           },
 
-     {"__tostring",              lcontext_tostring               },
 
-     {NULL, NULL}
 
- };
 
- static const luaL_Reg sqlitelib[] = {
 
-     {"version",         lsqlite_version         },
 
-     {"complete",        lsqlite_complete        },
 
- #ifndef WIN32
 
-     {"temp_directory",  lsqlite_temp_directory  },
 
- #endif
 
-     {"open",            lsqlite_open            },
 
-     {"open_memory",     lsqlite_open_memory     },
 
-     {"__newindex",      lsqlite_newindex        },
 
-     {NULL, NULL}
 
- };
 
- static void create_meta(lua_State *L, const char *name, const luaL_Reg *lib) {
 
-     luaL_newmetatable(L, name);
 
-     lua_pushstring(L, "__index");
 
-     lua_pushvalue(L, -2);               /* push metatable */
 
-     lua_rawset(L, -3);                  /* metatable.__index = metatable */
 
-     /* register metatable functions */
 
-     luaL_openlib(L, NULL, lib, 0);
 
-     /* remove metatable from stack */
 
-     lua_pop(L, 1);
 
- }
 
- LUALIB_API int luaopen_lsqlite3(lua_State *L) {
 
-     create_meta(L, sqlite_meta, dblib);
 
-     create_meta(L, sqlite_vm_meta, vmlib);
 
-     create_meta(L, sqlite_ctx_meta, ctxlib);
 
-     luaL_getmetatable(L, sqlite_ctx_meta);
 
-     sqlite_ctx_meta_ref = luaL_ref(L, LUA_REGISTRYINDEX);
 
-     /* register (local) sqlite metatable */
 
-     luaL_register(L, "sqlite3", sqlitelib);
 
-     {
 
-         int i = 0;
 
-         /* add constants to global table */
 
-         while (sqlite_constants[i].name) {
 
-             lua_pushstring(L, sqlite_constants[i].name);
 
-             lua_pushnumber(L, sqlite_constants[i].value);
 
-             lua_rawset(L, -3);
 
-             ++i;
 
-         }
 
-     }
 
-     /* set sqlite's metatable to itself - set as readonly (__newindex) */
 
-     lua_pushvalue(L, -1);
 
-     lua_setmetatable(L, -2);
 
-     return 1;
 
- }
 
 
  |