]> PatchyGit - patchyircd.git/commitdiff
admin: add database support
authorEgor <egor@patchysicp.xyz>
Tue, 20 Jan 2026 18:58:33 +0000 (20:58 +0200)
committerEgor <egor@patchysicp.xyz>
Tue, 20 Jan 2026 18:58:33 +0000 (20:58 +0200)
lua/irccloud.lua
src/admin.cpp
src/db.cpp
src/db.hpp

index 9026397..6bd3e9f 100644 (file)
@@ -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)
index 53c5cf8..3a545b3 100644 (file)
@@ -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);
index cb060cd..c5a7a53 100644 (file)
@@ -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);
index 3850a48..2e3ee70 100644 (file)
@@ -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);
        };