#include "lua_lsup.h" static int l_store_new (lua_State *L) { const LSUP_StoreType store_type = luaL_checkinteger (L, 1); const char *id = luaL_optstring (L, 2, NULL); const bool clear = lua_toboolean (L, 3); LSUP_Store **store_p = lua_newuserdatauv (L, sizeof (*store_p), 1); luaL_getmetatable (L, "LSUP.Store"); lua_setmetatable (L, -2); const LSUP_StoreInt *sif = LSUP_store_int (store_type); LUA_NLCHECK (sif, "No interface defined for store type: %d.", store_type); *store_p = LSUP_store_new (store_type, id, 0); LUA_NLCHECK (*store_p, "Error creating back end store."); // Set up the store if a function for that is defined. if (clear) log_info ("Clearing old store."); if (sif->setup_fn) LUA_PCHECK ( sif->setup_fn (id, clear), "Error initializing back end store."); return 1; } static int store_gc (lua_State *L) { LSUP_Store **sp = luaL_checkudata(L, 1, "LSUP.Store"); LOG_DEBUG ("Garbage collecting store @%p.", *sp); LSUP_store_free (*sp); *sp = NULL; return 0; } static int l_store_tostring (lua_State *L) { const LSUP_Store *store = *(LSUP_Store **) luaL_checkudata ( L, 1, "LSUP.Store"); lua_pushfstring ( L, "LSUP.Store @%p <%s>: %s", store, LSUP_store_type_label (store->type), store->id); return 1; } // TODO add transaction handling. static const luaL_Reg store_lib_fn [] = { {"new", l_store_new}, {"__gc", store_gc}, {NULL} }; static const luaL_Reg store_lib_meth [] = { {"__gc", store_gc}, {"__tostring", l_store_tostring}, {NULL} }; static const LEnumConst store_enums[] = { {"HTABLE", LSUP_STORE_HTABLE}, {"MDB", LSUP_STORE_MDB}, {NULL, 0} }; int luaopen_lsup_store (lua_State *L) { LSUP_init(); // This is idempotent: no problem calling it multiple times. luaL_newmetatable (L, "LSUP.Store"); lua_pushvalue (L, -1); lua_setfield (L, -2, "__index"); luaL_setfuncs (L, store_lib_meth, 0); luaL_newlib (L, store_lib_fn); push_int_const (L, store_enums); return 1; }