diff options
Diffstat (limited to 'events.c')
-rw-r--r-- | events.c | 78 |
1 files changed, 76 insertions, 2 deletions
diff --git a/events.c b/events.c index 9262225..04fdbf8 100644 --- a/events.c +++ b/events.c @@ -21,9 +21,59 @@ #include "server.h" +const char *EventsAfterQuery = SQL( + SELECT + events.event, + events.time, + events.type, + names.nick, + names.user, + names.host, + events.target, + events.message + FROM events + JOIN contexts USING (context) + JOIN names USING (name) + WHERE contexts.network = :network + AND contexts.name = :context + AND coalesce(contexts.query = :query, true) + AND events.time >= strftime('%s', :time) + ORDER BY events.time + LIMIT :limit; +); + +const char *EventsBeforeQuery = SQL( + WITH before AS ( + SELECT + events.event, + events.time, + events.type, + names.nick, + names.user, + names.host, + events.target, + events.message + FROM events + JOIN contexts USING (context) + JOIN names USING (name) + WHERE contexts.network = :network + AND contexts.name = :context + AND coalesce(contexts.query = :query, true) + AND events.time < strftime('%s', :time) + ORDER BY events.time DESC + LIMIT :limit + ) + SELECT * + FROM before + ORDER BY time; +); + enum kcgi_err pageEvents(struct kreq *req) { if (!req->fieldmap[Network] || !req->fieldmap[Context]) { - return httpFail(req, KHTTP_404); + return httpFail(req, KHTTP_400); + } + if (!req->fieldmap[After] && !req->fieldmap[Before]) { + return httpFail(req, KHTTP_400); } enum kcgi_err error = httpHead(req, KHTTP_200, KMIME_TEXT_HTML); @@ -31,6 +81,9 @@ enum kcgi_err pageEvents(struct kreq *req) { const char *network = req->fieldmap[Network]->parsed.s; const char *context = req->fieldmap[Context]->parsed.s; + const char *time = req->fieldmap[Before] + ? req->fieldmap[Before]->parsed.s + : req->fieldmap[After]->parsed.s; struct khtmlreq html; error = error @@ -41,5 +94,26 @@ enum kcgi_err pageEvents(struct kreq *req) { || htmlSearch(&html, network, context); if (error) return error; - return khtml_close(&html); + sqlite3_stmt *events = stmt.eventsAfter; + if (req->fieldmap[Before]) events = stmt.eventsBefore; + + dbBindText(events, ":network", network); + dbBindText(events, ":context", context); + if (pagePublic) dbBindInt(events, ":query", false); + dbBindText(events, ":time", time); + dbBindInt(events, ":limit", pageLimit); + + int result; + while (SQLITE_ROW == (result = sqlite3_step(events))) { + const char *msg = (const char *)sqlite3_column_text(events, 7); + if (!msg) continue; + error = 0 + || khtml_puts(&html, msg) + || khtml_elem(&html, KELEM_BR); + if (error) break; + } + if (result != SQLITE_DONE) errx(EX_SOFTWARE, "%s", sqlite3_errmsg(db)); + sqlite3_reset(events); + + return error || khtml_close(&html); } |