summary refs log tree commit diff
path: root/server.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--server.h195
1 files changed, 105 insertions, 90 deletions
diff --git a/server.h b/server.h
index c04b871..45008a1 100644
--- a/server.h
+++ b/server.h
@@ -29,56 +29,73 @@
 #define khttp_urlpart(...) kutil_urlpart(NULL, __VA_ARGS__)
 #endif
 
-#define SQL(...) #__VA_ARGS__
-
 // Why does it return (const unsigned char *)?
 #define sqlite3_column_text(...) (const char *)sqlite3_column_text(__VA_ARGS__)
 
+#define SQL(...) #__VA_ARGS__
+
+#define ENUM_PAGES \
+	X(Networks, "networks") \
+	X(Contexts, "contexts") \
+	X(Events, "events") \
+	X(Search, "search") \
+	X(Stylesheet, "stylesheet")
+
 enum {
-	DatabaseVersionMin = 4,
-	DatabaseVersionMax = 5,
+#define X(page, path) page,
+	ENUM_PAGES
+#undef X
+	PagesLen,
 };
+extern const char *Pages[PagesLen];
 
-#define ENUM_TYPE \
-	X(Privmsg, "privmsg") \
-	X(Notice, "notice") \
-	X(Action, "action") \
-	X(Join, "join") \
-	X(Part, "part") \
-	X(Quit, "quit") \
-	X(Kick, "kick") \
-	X(Nick, "nick") \
-	X(Topic, "topic") \
-	X(Ban, "ban") \
-	X(Unban, "unban")
+#define ENUM_KEYS \
+	X(Network, "network", kvalid_stringne) \
+	X(Context, "context", kvalid_stringne) \
+	X(After, "after", kvalid_stringne) \
+	X(Before, "before", kvalid_stringne) \
+	X(Query, "query", kvalid_stringne) \
+	X(Offset, "offset", kvalid_int)
 
-enum Type {
-#define X(id, name) id,
-	ENUM_TYPE
+enum {
+#define X(key, name, valid) key,
+	ENUM_KEYS
 #undef X
-	TypesLen,
+	KeysLen,
 };
+extern const struct kvalid Keys[KeysLen];
 
-struct Event {
-	int64_t event;
-	time_t time;
+struct Scope {
 	const char *network;
 	const char *context;
-	enum Type type;
-	const char *nick;
-	const char *user;
-	const char *host;
-	const char *target;
-	const char *message;
+	const char *query;
 };
 
-extern sqlite3 *db;
+static inline struct Scope pageScope(struct kreq *req) {
+	struct Scope s = {0};
+	if (req->fieldmap[Network]) s.network = req->fieldmap[Network]->parsed.s;
+	if (req->fieldmap[Context]) s.context = req->fieldmap[Context]->parsed.s;
+	if (req->fieldmap[Query]) s.query = req->fieldmap[Query]->parsed.s;
+	return s;
+}
 
+extern int contextsRecent;
+extern bool contextsPublic;
 extern const char *NetworksQuery;
 extern const char *ContextsQuery;
+enum kcgi_err networksPage(struct kreq *req);
+enum kcgi_err contextsPage(struct kreq *req);
+
+extern int eventsGap;
+extern int eventsOverlap;
+extern int eventsLimit;
 extern const char *EventsAfterQuery;
 extern const char *EventsBeforeQuery;
 extern const char *SearchQuery;
+enum kcgi_err eventsPage(struct kreq *req);
+enum kcgi_err searchPage(struct kreq *req);
+
+extern sqlite3 *db;
 
 extern struct Statements {
 	sqlite3_stmt *networks;
@@ -88,12 +105,27 @@ extern struct Statements {
 	sqlite3_stmt *search;
 } stmt;
 
+static inline void dbPrepare(sqlite3_stmt **stmt, const char *query) {
+	int error = sqlite3_prepare_v3(
+		db, query, -1, SQLITE_PREPARE_PERSISTENT, stmt, NULL
+	);
+	if (error) errx(EX_SOFTWARE, "%s: %s", sqlite3_errmsg(db), query);
+}
+
+static inline void dbPrepareAll(void) {
+	dbPrepare(&stmt.networks, NetworksQuery);
+	dbPrepare(&stmt.contexts, ContextsQuery);
+	dbPrepare(&stmt.eventsAfter, EventsAfterQuery);
+	dbPrepare(&stmt.eventsBefore, EventsBeforeQuery);
+	dbPrepare(&stmt.search, SearchQuery);
+}
+
 static inline void dbClose(void) {
-	if (stmt.networks) sqlite3_finalize(stmt.networks);
-	if (stmt.contexts) sqlite3_finalize(stmt.contexts);
-	if (stmt.eventsAfter) sqlite3_finalize(stmt.eventsAfter);
-	if (stmt.eventsBefore) sqlite3_finalize(stmt.eventsBefore);
-	if (stmt.search) sqlite3_finalize(stmt.search);
+	sqlite3_finalize(stmt.networks);
+	sqlite3_finalize(stmt.contexts);
+	sqlite3_finalize(stmt.eventsAfter);
+	sqlite3_finalize(stmt.eventsBefore);
+	sqlite3_finalize(stmt.search);
 	sqlite3_close(db);
 }
 
@@ -115,47 +147,52 @@ dbBindText(sqlite3_stmt *stmt, const char *param, const char *value) {
 	errx(EX_SOFTWARE, "sqlite3_bind_text: %s", sqlite3_errmsg(db));
 }
 
-#define ENUM_PAGES \
-	X(Networks, "networks") \
-	X(Contexts, "contexts") \
-	X(Events, "events") \
-	X(Search, "search") \
-	X(Stylesheet, "stylesheet")
-
 enum {
-#define X(page, path) page,
-	ENUM_PAGES
-#undef X
-	PagesLen,
+	DatabaseVersionMin = 4,
+	DatabaseVersionMax = 5,
 };
 
-extern const char *Pages[PagesLen];
-
-#define ENUM_KEYS \
-	X(Network, "network", kvalid_stringne) \
-	X(Context, "context", kvalid_stringne) \
-	X(After, "after", kvalid_stringne) \
-	X(Before, "before", kvalid_stringne) \
-	X(Query, "query", kvalid_stringne) \
-	X(Offset, "offset", kvalid_int)
+#define ENUM_TYPE \
+	X(Privmsg, "privmsg") \
+	X(Notice, "notice") \
+	X(Action, "action") \
+	X(Join, "join") \
+	X(Part, "part") \
+	X(Quit, "quit") \
+	X(Kick, "kick") \
+	X(Nick, "nick") \
+	X(Topic, "topic") \
+	X(Ban, "ban") \
+	X(Unban, "unban")
 
-enum {
-#define X(key, name, valid) key,
-	ENUM_KEYS
+enum Type {
+#define X(id, name) id,
+	ENUM_TYPE
 #undef X
-	KeysLen,
+	TypesLen,
 };
 
-extern const struct kvalid Keys[KeysLen];
-
-extern bool pagePublic;
-extern int pageLimit;
-extern int pageRecent;
+struct Event {
+	int64_t event;
+	time_t time;
+	const char *network;
+	const char *context;
+	enum Type type;
+	const char *nick;
+	const char *user;
+	const char *host;
+	const char *target;
+	const char *message;
+};
 
-enum kcgi_err pageNetworks(struct kreq *req);
-enum kcgi_err pageContexts(struct kreq *req);
-enum kcgi_err pageEvents(struct kreq *req);
-enum kcgi_err pageSearch(struct kreq *req);
+extern const char *htmlStylesheet;
+enum kcgi_err htmlHead(struct khtmlreq *html, const char *title);
+enum kcgi_err htmlScopeFields(struct khtmlreq *html, struct Scope scope);
+enum kcgi_err htmlNav(struct khtmlreq *html, struct Scope scope);
+enum kcgi_err htmlFooter(struct khtmlreq *html);
+enum kcgi_err htmlEvent(
+	struct khtmlreq *html, struct Scope scope, struct Event event
+);
 
 static inline enum kcgi_err
 httpHead(struct kreq *req, enum khttp http, enum kmime mime) {
@@ -176,25 +213,3 @@ static inline enum kcgi_err httpFail(struct kreq *req, enum khttp http) {
 		|| khttp_body(req)
 		|| khttp_printf(req, "%s\n", khttps[http]);
 }
-
-struct Scope {
-	const char *network;
-	const char *context;
-	const char *query;
-};
-
-static inline struct Scope htmlScope(struct kreq *req) {
-	struct Scope s = {0};
-	if (req->fieldmap[Network]) s.network = req->fieldmap[Network]->parsed.s;
-	if (req->fieldmap[Context]) s.context = req->fieldmap[Context]->parsed.s;
-	if (req->fieldmap[Query]) s.query = req->fieldmap[Query]->parsed.s;
-	return s;
-}
-
-extern const char *htmlStylesheet;
-enum kcgi_err htmlHead(struct khtmlreq *html, const char *title);
-enum kcgi_err htmlNav(struct khtmlreq *html, struct Scope scope);
-enum kcgi_err htmlFooter(struct khtmlreq *html);
-enum kcgi_err htmlEvent(
-	struct khtmlreq *html, struct Scope scope, struct Event event
-);