#include "lua_volksdata.h" static int l_store_new (lua_State *L) { const VOLK_StoreType store_type = luaL_checkinteger (L, 1); const char *id = luaL_optstring (L, 2, NULL); const bool clear = lua_toboolean (L, 3); VOLK_Store **store_p = lua_newuserdatauv (L, sizeof (*store_p), 1); luaL_getmetatable (L, "VOLK.Store"); lua_setmetatable (L, -2); // Set up the store if a function for that is defined. if (clear) log_info ("Clearing old store."); *store_p = VOLK_store_new (store_type, id, 0, clear); LUA_NLCHECK (*store_p, "Error creating back end store."); return 1; } // This can be called automatically by te garbage collector, or manually. // It is idempotent. static int l_store_gc (lua_State *L) { VOLK_Store **sp = luaL_checkudata(L, 1, "VOLK.Store"); LOG_DEBUG ("Garbage collecting store @%p.", *sp); VOLK_store_free (*sp); *sp = NULL; return 0; } static int l_store_size (lua_State *L) { const VOLK_Store **store_p = luaL_checkudata (L, 1, "VOLK.Store"); lua_pushinteger (L, VOLK_store_size (*store_p)); return 1; } static int l_store_tostring (lua_State *L) { const VOLK_Store *store = *(VOLK_Store **) luaL_checkudata ( L, 1, "VOLK.Store"); lua_pushfstring ( L, "VOLK.Store @%p <%s>: %s", store, VOLK_store_type_label (store->type), store->id); return 1; } // TODO add transaction handling. static const luaL_Reg store_lib_fn [] = { {"new", l_store_new}, {NULL} }; static const luaL_Reg store_lib_meth [] = { {"__gc", l_store_gc}, {"__len", l_store_size}, {"__tostring", l_store_tostring}, {"close", l_store_gc}, {NULL} }; static const LEnumConst store_enums[] = { {"HTABLE", VOLK_STORE_HTABLE}, {"MDB", VOLK_STORE_MDB}, {NULL, 0} }; int luaopen_volksdata_store (lua_State *L) { VOLK_init(); // This is idempotent: no problem calling it multiple times. luaL_newmetatable (L, "VOLK.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; }