diff --git a/tool/net/lsqlite3.c b/tool/net/lsqlite3.c index 07ebec105..1cfe102b9 100644 --- a/tool/net/lsqlite3.c +++ b/tool/net/lsqlite3.c @@ -194,29 +194,19 @@ static sdb_vm *newvm(lua_State *L, sdb *db) { /* add an entry on the database table: svm -> db to keep db live while svm is live */ lua_pushlightuserdata(L, db); /* db sql svm_ud db_lud -- */ lua_rawget(L, LUA_REGISTRYINDEX); /* db sql svm_ud reg[db_lud] -- */ - lua_pushlightuserdata(L, svm); /* db sql svm_ud reg[db_lud] svm_lud -- */ - lua_pushvalue(L, -5); /* db sql svm_ud reg[db_lud] svm_lud db -- */ - lua_rawset(L, -3); /* (reg[db_lud])[svm_lud] = db ; set the db for this vm */ + lua_pushvalue(L, -2); /* db sql svm_ud reg[db_lud] svm_ud -- */ + lua_pushvalue(L, -5); /* db sql svm_ud reg[db_lud] svm_ud db -- */ + lua_rawset(L, -3); /* (reg[db_lud])[svm_ud] = db ; set the db for this vm */ lua_pop(L, 1); /* db sql svm_ud -- */ 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_pushinteger(L, sqlite3_finalize(svm->vm)); svm->vm = NULL; return 1; @@ -245,7 +235,7 @@ static int dbvm_isopen(lua_State *L) { } static int dbvm_tostring(lua_State *L) { - char buff[39]; + char buff[40]; sdb_vm *svm = lsqlite_getvm(L, 1); if (svm->vm == NULL) strcpy(buff, "closed"); @@ -256,9 +246,7 @@ static int dbvm_tostring(lua_State *L) { } static int dbvm_gc(lua_State *L) { - sdb_vm *svm = lsqlite_getvm(L, 1); - if (svm->vm != NULL) /* ignore closed vms */ - cleanupvm(L, svm); + cleanupvm(L, lsqlite_getvm(L, 1)); return 0; } @@ -621,36 +609,42 @@ static sdb *newdb (lua_State *L) { luaL_getmetatable(L, sqlite_meta); lua_setmetatable(L, -2); /* set metatable */ - /* to keep track of 'open' virtual machines */ + /* to keep track of 'open' virtual machines; make keys week */ lua_pushlightuserdata(L, db); - lua_newtable(L); + lua_newtable(L); // t + lua_newtable(L); // t mt + lua_pushstring(L, "k"); // t mt v + lua_setfield(L, -2, "__mode"); // t mt + lua_setmetatable(L, -2); // t lua_rawset(L, LUA_REGISTRYINDEX); return db; } +/* cleanup all vms or just temporary ones */ +static void closevms(lua_State *L, sdb *db, int temp) { + /* 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)) lua_pop(L, cleanupvm(L, svm)); + lua_pop(L, 1); /* pop value; leave key in the stack */ + } +} + 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); + if (!db->db) return SQLITE_MISUSE; - /* 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 */ + closevms(L, db, 0); /* remove entry in lua registry table */ lua_pushlightuserdata(L, db); @@ -669,8 +663,9 @@ static int cleanupdb(lua_State *L, sdb *db) { luaL_unref(L, LUA_REGISTRYINDEX, db->rollback_hook_cb); luaL_unref(L, LUA_REGISTRYINDEX, db->rollback_hook_udata); - /* close database */ - result = sqlite3_close(db->db); + /* close database; _v2 is intended for use with garbage collected languages + and where the order in which destructors are called is arbitrary. */ + result = sqlite3_close_v2(db->db); db->db = NULL; /* free associated memory with created functions */ @@ -732,7 +727,7 @@ static lcontext *lsqlite_checkcontext(lua_State *L, int index) { } static int lcontext_tostring(lua_State *L) { - char buff[39]; + char buff[41]; lcontext *ctx = lsqlite_getcontext(L, 1); if (ctx->ctx == NULL) strcpy(buff, "closed"); @@ -1723,7 +1718,7 @@ static int db_urows(lua_State *L) { } static int db_tostring(lua_State *L) { - char buff[32]; + char buff[33]; sdb *db = lsqlite_getdb(L, 1); if (db->db == NULL) strcpy(buff, "closed"); @@ -1741,27 +1736,7 @@ static int db_close(lua_State *L) { 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); - } + closevms(L, db, lua_toboolean(L, 2)); return 0; } @@ -1858,7 +1833,7 @@ static int liter_gc(lua_State *L) { } static int liter_tostring(lua_State *L) { - char buff[32]; + char buff[33]; liter *litr = lsqlite_getiter(L, 1); if (litr->itr == NULL) strcpy(buff, "closed"); @@ -1997,7 +1972,7 @@ static int lrebaser_gc(lua_State *L) { } static int lrebaser_tostring(lua_State *L) { - char buff[30]; + char buff[32]; lrebaser *lreb = lsqlite_getrebaser(L, 1); if (lreb->reb == NULL) strcpy(buff, "closed"); @@ -2258,7 +2233,7 @@ static int lsession_gc(lua_State *L) { } static int lsession_tostring(lua_State *L) { - char buff[30]; + char buff[32]; lsession *lses = lsqlite_getsession(L, 1); if (lses->ses == NULL) strcpy(buff, "closed");