Proof of concept of sqlite serialization

This is a minimal proof of concept in order to show that it is easily possible to store the sqlite database within the zip file itself not requiring creating an external file first. Changes include compiling the sqlite library with the serialization flag, adding serialize/deserialize to the lua sqlite library and demonstrating the work via the redbean demo.
This commit is contained in:
oltdaniel 2022-06-20 21:52:02 +02:00
parent d5312b60f7
commit 710c979bfa
3 changed files with 71 additions and 10 deletions

View file

@ -129,6 +129,7 @@ THIRD_PARTY_SQLITE3_FLAGS = \
-DSQLITE_HAVE_C99_MATH_FUNCS \
-DSQLITE_ENABLE_MATH_FUNCTIONS \
-DSQLITE_ENABLE_JSON1 \
-DSQLITE_ENABLE_DESERIALIZE \
$(THIRD_PARTY_SQLITE3_A_OBJS): \
OVERRIDE_CFLAGS += \

View file

@ -9,16 +9,35 @@ HidePath('/usr/share/ssl/')
-- LaunchBrowser('/tool/net/demo/index.html')
-- sql database (see sql.lua)
db = sqlite3.open_memory()
db:exec[[
function StoreSqlite(database, path)
local buffer = database:serialize()
return StoreAsset(path, buffer)
end
function LoadSqlite(path)
local database = sqlite3.open_memory()
local buffer = LoadAsset(path)
database:deserialize(buffer)
return database
end
database = "database.sqlite3"
-- Check if there is already a database
if GetAssetSize(database) ~= nil then
db = LoadSqlite(database)
db:exec[[
INSERT INTO test (content) VALUES ('World');
]]
else
db = sqlite3.open_memory()
db:exec[[
CREATE TABLE test (
id INTEGER PRIMARY KEY,
content TEXT
);
INSERT INTO test (content) VALUES ('Hello World');
INSERT INTO test (content) VALUES ('Hello Lua');
INSERT INTO test (content) VALUES ('Hello Sqlite3');
]]
INSERT INTO test (content) VALUES ('Hello');
]]
end
-- this intercepts all requests if it's defined
function OnHttpRequest()
@ -35,6 +54,11 @@ function OnHttpRequest()
SetHeader('Server', 'redbean!')
end
function OnServerStop()
-- make sure we store the database on exit
StoreSqlite(db, database)
end
function Adder(x, y)
return x + y
end

View file

@ -1683,6 +1683,39 @@ static int db_gc(lua_State *L) {
return 0;
}
static int db_serialize(lua_State *L) {
sdb *db = lsqlite_getdb(L, 1);
sqlite_int64 size = 0;
if (db->db == NULL) /* ignore closed databases */
return 0;
char *buffer = (char *)sqlite3_serialize(db->db, "main", &size, 0);
if (buffer == NULL) /* ignore failed database serialization */
return 0;
lua_pushlstring(L, buffer, size);
free(buffer);
return 1;
}
static int db_deserialize(lua_State *L) {
sdb *db = lsqlite_getdb(L, 1);
size_t size = 0;
if (db->db == NULL) /* ignore closed databases */
return 0;
const char *buffer = luaL_checklstring(L, 2, &size);
if (buffer == NULL || size == 0) /* ignore empty database content */
return 0;
sqlite3_deserialize(db->db, "main", buffer, size, 5, 0);
free(buffer);
return 0;
}
/*
** =======================================================
** General library functions
@ -1857,6 +1890,9 @@ static const luaL_Reg dblib[] = {
{"close", db_close },
{"close_vm", db_close_vm },
{"serialize", db_serialize },
{"deserialize", db_deserialize },
{"__tostring", db_tostring },
{"__gc", db_gc },