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)
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);
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)
{
{"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);
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);