mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-08-08 19:00:27 +00:00
Add session support to SQLite Lua API
This commit is contained in:
parent
539bddce8c
commit
67f4e932d5
3 changed files with 137 additions and 4 deletions
7
third_party/sqlite3/sqlite3.mk
vendored
7
third_party/sqlite3/sqlite3.mk
vendored
|
@ -126,7 +126,9 @@ THIRD_PARTY_SQLITE3_FLAGS = \
|
|||
-DSQLITE_HAVE_C99_MATH_FUNCS \
|
||||
-DSQLITE_ENABLE_MATH_FUNCTIONS \
|
||||
-DSQLITE_ENABLE_JSON1 \
|
||||
-DSQLITE_ENABLE_DESERIALIZE
|
||||
-DSQLITE_ENABLE_DESERIALIZE \
|
||||
-DSQLITE_ENABLE_PREUPDATE_HOOK \
|
||||
-DSQLITE_ENABLE_SESSION
|
||||
|
||||
ifeq ($(MODE),dbg)
|
||||
THIRD_PARTY_SQLITE3_CPPFLAGS_DEBUG = -DSQLITE_DEBUG
|
||||
|
@ -136,7 +138,6 @@ $(THIRD_PARTY_SQLITE3_A_OBJS): private \
|
|||
OVERRIDE_CFLAGS += \
|
||||
$(THIRD_PARTY_SQLITE3_FLAGS) \
|
||||
$(THIRD_PARTY_SQLITE3_CPPFLAGS_DEBUG) \
|
||||
-DSQLITE_OMIT_UPDATE_HOOK
|
||||
|
||||
$(THIRD_PARTY_SQLITE3_SHELL_OBJS): private \
|
||||
OVERRIDE_CFLAGS += \
|
||||
|
@ -146,11 +147,9 @@ $(THIRD_PARTY_SQLITE3_SHELL_OBJS): private \
|
|||
-DHAVE_EDITLINE=0 \
|
||||
-DSQLITE_HAVE_ZLIB \
|
||||
-DSQLITE_ENABLE_IOTRACE \
|
||||
-DSQLITE_ENABLE_PREUPDATE_HOOK \
|
||||
-DSQLITE_ENABLE_COLUMN_METADATA \
|
||||
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
|
||||
-DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION \
|
||||
-DSQLITE_ENABLE_SESSION \
|
||||
-DSQLITE_ENABLE_STMTVTAB \
|
||||
-DSQLITE_ENABLE_DBPAGE_VTAB \
|
||||
-DSQLITE_ENABLE_DBSTAT_VTAB \
|
||||
|
|
|
@ -119,7 +119,9 @@ static const char *const sqlite_meta = ":sqlite3";
|
|||
static const char *const sqlite_vm_meta = ":sqlite3:vm";
|
||||
static const char *const sqlite_bu_meta = ":sqlite3:bu";
|
||||
static const char *const sqlite_ctx_meta = ":sqlite3:ctx";
|
||||
static const char *const sqlite_ses_meta = ":sqlite3:ses";
|
||||
static int sqlite_ctx_meta_ref;
|
||||
static int sqlite_ses_meta_ref;
|
||||
|
||||
/*
|
||||
** =======================================================
|
||||
|
@ -1728,6 +1730,104 @@ static int db_deserialize(lua_State *L) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** =======================================================
|
||||
** Session functions
|
||||
** =======================================================
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
sqlite3_session *ses;
|
||||
} lsession;
|
||||
|
||||
static lsession *lsqlite_makesession(lua_State *L, sqlite3_session *ses) {
|
||||
lsession *lses = (lsession*)lua_newuserdata(L, sizeof(lsession));
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, sqlite_ses_meta_ref);
|
||||
lua_setmetatable(L, -2);
|
||||
lses->ses = ses;
|
||||
return lses;
|
||||
}
|
||||
|
||||
static lsession *lsqlite_getsession(lua_State *L, int index) {
|
||||
return (lsession *)luaL_checkudata(L, index, sqlite_ses_meta);
|
||||
}
|
||||
|
||||
static lsession *lsqlite_checksession(lua_State *L, int index) {
|
||||
lsession *lses = lsqlite_getsession(L, index);
|
||||
if (lses->ses == NULL) luaL_argerror(L, index, "invalid sqlite session");
|
||||
return lses;
|
||||
}
|
||||
|
||||
static int lsession_attach(lua_State *L) {
|
||||
lsession *lses = lsqlite_checksession(L, 1);
|
||||
const char *zTab = luaL_optstring(L, 2, NULL);
|
||||
|
||||
if (sqlite3session_attach(lses->ses, zTab) != SQLITE_OK) {
|
||||
lua_pushnil(L);
|
||||
} else {
|
||||
lua_pushboolean(L, 1);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lsession_isempty(lua_State *L) {
|
||||
lsession *lses = lsqlite_checksession(L, 1);
|
||||
lua_pushboolean(L, sqlite3session_isempty(lses->ses));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lsession_changeset(lua_State *L) {
|
||||
lsession *lses = lsqlite_checksession(L, 1);
|
||||
int size;
|
||||
void *buf;
|
||||
if (sqlite3session_changeset(lses->ses, &size, &buf) != SQLITE_OK) {
|
||||
lua_pushnil(L);
|
||||
} else {
|
||||
lua_pushlstring(L, buf, size);
|
||||
sqlite3_free(buf);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lsession_tostring(lua_State *L) {
|
||||
char buff[30];
|
||||
lsession *lses = lsqlite_getsession(L, 1);
|
||||
if (lses->ses == NULL)
|
||||
strcpy(buff, "closed");
|
||||
else
|
||||
sprintf(buff, "%p", lses->ses);
|
||||
lua_pushfstring(L, "sqlite session (%s)", buff);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lsession_delete(lua_State *L) {
|
||||
lsession *lses = lsqlite_getsession(L, 1);
|
||||
if (lses->ses != NULL) {
|
||||
sqlite3session_delete(lses->ses);
|
||||
lses->ses = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lsession_gc(lua_State *L) {
|
||||
return lsession_delete(L);
|
||||
}
|
||||
|
||||
static int db_create_session(lua_State *L) {
|
||||
sdb *db = lsqlite_checkdb(L, 1);
|
||||
const char *zDb = luaL_optstring(L, 2, "main");
|
||||
sqlite3_session *ses;
|
||||
|
||||
if (sqlite3session_create(db->db, zDb, &ses) != SQLITE_OK) {
|
||||
lua_pushnil(L);
|
||||
lua_pushinteger(L, sqlite3_errcode(db->db));
|
||||
return 2;
|
||||
}
|
||||
|
||||
(void)lsqlite_makesession(L, ses);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
** =======================================================
|
||||
** General library functions
|
||||
|
@ -1859,6 +1959,19 @@ static const struct {
|
|||
SC(OPEN_SHAREDCACHE)
|
||||
SC(OPEN_PRIVATECACHE)
|
||||
|
||||
/* session constants */
|
||||
SC(CHANGESETSTART_INVERT)
|
||||
SC(CHANGESETAPPLY_NOSAVEPOINT)
|
||||
SC(CHANGESETAPPLY_INVERT)
|
||||
SC(CHANGESET_DATA)
|
||||
SC(CHANGESET_NOTFOUND)
|
||||
SC(CHANGESET_CONFLICT)
|
||||
SC(CHANGESET_CONSTRAINT)
|
||||
SC(CHANGESET_FOREIGN_KEY)
|
||||
SC(CHANGESET_OMIT)
|
||||
SC(CHANGESET_REPLACE)
|
||||
SC(CHANGESET_ABORT)
|
||||
|
||||
/* terminator */
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
@ -1900,6 +2013,8 @@ static const luaL_Reg dblib[] = {
|
|||
{"serialize", db_serialize },
|
||||
{"deserialize", db_deserialize },
|
||||
|
||||
{"create_session", db_create_session },
|
||||
|
||||
{"__tostring", db_tostring },
|
||||
{"__gc", db_gc },
|
||||
|
||||
|
@ -1973,6 +2088,17 @@ static const luaL_Reg ctxlib[] = {
|
|||
{NULL, NULL}
|
||||
};
|
||||
|
||||
static const luaL_Reg seslib[] = {
|
||||
{"attach", lsession_attach },
|
||||
{"changeset", lsession_changeset },
|
||||
{"isempty", lsession_isempty },
|
||||
{"delete", lsession_delete },
|
||||
|
||||
{"__tostring", lsession_tostring },
|
||||
{"__gc", lsession_gc },
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
static const luaL_Reg sqlitelib[] = {
|
||||
{"lversion", lsqlite_lversion },
|
||||
{"version", lsqlite_version },
|
||||
|
@ -2002,10 +2128,14 @@ 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);
|
||||
create_meta(L, sqlite_ses_meta, seslib);
|
||||
|
||||
luaL_getmetatable(L, sqlite_ctx_meta);
|
||||
sqlite_ctx_meta_ref = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
|
||||
luaL_getmetatable(L, sqlite_ses_meta);
|
||||
sqlite_ses_meta_ref = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
|
||||
/* register (local) sqlite metatable */
|
||||
luaL_register(L, "sqlite3", sqlitelib);
|
||||
|
||||
|
|
|
@ -128,6 +128,10 @@ o/$(MODE)/tool/net/redbean.com: \
|
|||
@$(MAKE_SYMTAB_ZIP)
|
||||
@$(TOOL_NET_REDBEAN_STANDARD_ASSETS_ZIP)
|
||||
|
||||
o/$(MODE)/tool/net/lsqlite3.o: private \
|
||||
OVERRIDE_CFLAGS += \
|
||||
-DSQLITE_ENABLE_SESSION
|
||||
|
||||
# REDBEAN-DEMO.COM
|
||||
#
|
||||
# This redbean-demo.com program is the same as redbean.com except it
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue