From 7e8bdfea27b999e0660d5ef05900e949a399a0e2 Mon Sep 17 00:00:00 2001 From: Egor Date: Tue, 20 Jan 2026 20:58:33 +0200 Subject: [PATCH] admin: add database support --- lua/irccloud.lua | 5 ++++- src/admin.cpp | 51 ++++++++++++++++++++++++++++++++++++++++-------- src/db.cpp | 6 ++++++ src/db.hpp | 2 ++ 4 files changed, 55 insertions(+), 9 deletions(-) diff --git a/lua/irccloud.lua b/lua/irccloud.lua index 9026397..6bd3e9f 100644 --- a/lua/irccloud.lua +++ b/lua/irccloud.lua @@ -43,6 +43,9 @@ end hook_add("newuser", "irccloud_auth", function(hook, cl1, cl2, chan, txt) local netid, ifaceid = parseipv6(cl1.peername) if netid and isirccloudnetwork(netid) then - client_chghost(cl1, db_read_rhs(tostring(ifaceid), "irccloud")) + local row = querydisk("SELECT account FROM irccloud WHERE irccloudid = ?;", tostring(ifaceid))[1] + if row then + client_chghost(cl1, row[1]) + end end end) diff --git a/src/admin.cpp b/src/admin.cpp index 53c5cf8..3a545b3 100644 --- a/src/admin.cpp +++ b/src/admin.cpp @@ -319,13 +319,6 @@ static int fn_rpl_whoisspecial(lua_State *L) { rpl_whoisspecial(cl1, cl2, "", text), sendbuf(cl1); return 0; } -static int fn_db_read_rhs(lua_State *L) { - const char *key = luaL_checkstring(L, 1); - const char *fn = luaL_checkstring(L, 2); - const char *res = db_read_rhs(key, fn); - lua_pushstring(L, res); - return 1; -} static int fn_getdatafile(lua_State *L) { const char *fn = luaL_checkstring(L, 1); const char *res = getdatafile(fn); @@ -338,6 +331,47 @@ static int fn_getluafile(lua_State *L) { lua_pushstring(L, res); return 1; } +static int query(lua_State *L, db::Database &db) { + const char *sql = luaL_checkstring(L, 1); + auto stmt = db(sql); + for (int i = 2; i <= lua_gettop(L); i++) { + if (lua_isinteger(L, i)) { + stmt.bind(i-1, lua_tointeger(L, i)); + } else { + size_t len = 0; + const char *p = lua_tolstring(L, i, &len); + stmt.bind(i-1, std::string_view(p, len)); + } + } + int cols = stmt.columns(); + int row = 0; + // FIXME: createtable/newtable/rawseti can fail on memory allocation + // if we link to lua using C ABI, this will cause a Statement leak + lua_newtable(L); + while (stmt.step()) { + lua_createtable(L, cols, 0); + for (int i = 0; i < cols; i++) { + if (stmt.is_num(i)) { + lua_pushinteger(L, stmt.num(i)); + } else { + auto sv = stmt.text(i); + if (sv.data()) + lua_pushlstring(L, sv.data(), sv.size()); + else + lua_pushnil(L); + } + lua_rawseti(L, -2, i+1); + } + lua_rawseti(L, -2, ++row); + } + return 1; +} +static int fn_querydisk(lua_State *L) { + return query(L, db::disk); +} +static int fn_querymemory(lua_State *L) { + return query(L, db::memory); +} void admin_init(void) { @@ -400,9 +434,10 @@ void admin_init(void) {"channel_topic", fn_channel_topic}, {"client_chghost", fn_client_chghost}, {"rpl_whoisspecial", fn_rpl_whoisspecial}, - {"db_read_rhs", fn_db_read_rhs}, {"getdatafile", fn_getdatafile}, {"getluafile", fn_getluafile}, + {"querydisk", fn_querydisk}, + {"querymemory", fn_querymemory}, {0, 0}, }; lua_pushglobaltable(L); diff --git a/src/db.cpp b/src/db.cpp index cb060cd..c5a7a53 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -49,6 +49,12 @@ void Statement::bind(int i, std::string_view text) { void Statement::bind(int i, int64_t num) { sqlite3_bind_int64(stmt, i, num); } +int Statement::columns() { + return sqlite3_column_count(stmt); +} +bool Statement::is_num(int i) { + return sqlite3_column_type(stmt, i) == SQLITE_INTEGER; +} std::string_view Statement::text(int i) { auto p = sqlite3_column_text(stmt, i); int len = sqlite3_column_bytes(stmt, i); diff --git a/src/db.hpp b/src/db.hpp index 3850a48..2e3ee70 100644 --- a/src/db.hpp +++ b/src/db.hpp @@ -43,6 +43,8 @@ namespace db { bool step(); void bind(int i, std::string_view text); void bind(int i, int64_t num); + int columns(); + bool is_num(int i); std::string_view text(int i); int64_t num(int i); }; -- 2.56.0