summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--html.c2
-rw-r--r--search.c50
-rw-r--r--server.h1
3 files changed, 51 insertions, 2 deletions
diff --git a/html.c b/html.c
index f5ea6bd..0433d29 100644
--- a/html.c
+++ b/html.c
@@ -129,7 +129,6 @@ htmlNav(struct khtmlreq *html, struct Scope scope) {
 			KATTR_ACTION, Pages[Search],
 			KATTR__MAX
 		)
-		|| htmlScopeFields(html, scope)
 		|| khtml_attr(
 			html, KELEM_INPUT,
 			KATTR_TYPE, "search",
@@ -137,6 +136,7 @@ htmlNav(struct khtmlreq *html, struct Scope scope) {
 			KATTR_VALUE, (scope.query ? scope.query : ""),
 			KATTR__MAX
 		)
+		|| htmlScopeFields(html, scope)
 		|| khtml_attr(
 			html, KELEM_INPUT,
 			KATTR_TYPE, "submit",
diff --git a/search.c b/search.c
index 7960d6b..2d6e417 100644
--- a/search.c
+++ b/search.c
@@ -64,6 +64,30 @@ enum kcgi_err searchPage(struct kreq *req) {
 		|| khtml_elem(&html, KELEM_TABLE);
 	if (error) return error;
 
+	if (offset) {
+		int64_t prev = offset - eventsLimit;
+		if (prev < 0) prev = 0;
+		char *href = khttp_urlpartx(
+			NULL, NULL, Pages[Search],
+			Keys[Query].name, KATTRX_STRING, scope.query,
+			Keys[Offset].name, KATTRX_INT, prev,
+			(scope.network ? Keys[Network].name : NULL),
+			KATTRX_STRING, scope.network,
+			(scope.context ? Keys[Context].name : NULL),
+			KATTRX_STRING, scope.context,
+			NULL
+		);
+		if (!href) err(EX_OSERR, "khttp_urlpartx");
+		error = 0
+			|| khtml_attr(&html, KELEM_TR, KATTR_CLASS, "page", KATTR__MAX)
+			|| khtml_attr(&html, KELEM_TH, KATTR_COLSPAN, "5", KATTR__MAX)
+			|| khtml_attr(&html, KELEM_A, KATTR_HREF, href, KATTR__MAX)
+			|| khtml_puts(&html, "Earlier results")
+			|| khtml_closeelem(&html, 3);
+		free(href);
+		if (error) return error;
+	}
+
 	sqlite3_reset(stmt.search);
 	dbBindText(stmt.search, ":network", scope.network);
 	dbBindText(stmt.search, ":context", scope.context);
@@ -73,8 +97,9 @@ enum kcgi_err searchPage(struct kreq *req) {
 	dbBindInt(stmt.search, ":offset", offset);
 	dbBindText(stmt.search, ":highlight", "\26");
 
+	int rows;
 	int result;
-	while (SQLITE_ROW == (result = sqlite3_step(stmt.search))) {
+	for (rows = 0; SQLITE_ROW == (result = sqlite3_step(stmt.search)); ++rows) {
 		int i = 0;
 		struct Event event = {0};
 		event.event = sqlite3_column_int64(stmt.search, i++);
@@ -91,5 +116,28 @@ enum kcgi_err searchPage(struct kreq *req) {
 		if (error) return error;
 	}
 	if (result != SQLITE_DONE) errx(EX_SOFTWARE, "%s", sqlite3_errmsg(db));
+
+	if (rows == eventsLimit) {
+		char *href = khttp_urlpartx(
+			NULL, NULL, Pages[Search],
+			Keys[Query].name, KATTRX_STRING, scope.query,
+			Keys[Offset].name, KATTRX_INT, offset + eventsLimit,
+			(scope.network ? Keys[Network].name : NULL),
+			KATTRX_STRING, scope.network,
+			(scope.context ? Keys[Context].name : NULL),
+			KATTRX_STRING, scope.context,
+			NULL
+		);
+		if (!href) err(EX_OSERR, "khttp_urlpartx");
+		error = 0
+			|| khtml_attr(&html, KELEM_TR, KATTR_CLASS, "page", KATTR__MAX)
+			|| khtml_attr(&html, KELEM_TH, KATTR_COLSPAN, "5", KATTR__MAX)
+			|| khtml_attr(&html, KELEM_A, KATTR_HREF, href, KATTR__MAX)
+			|| khtml_puts(&html, "Later results")
+			|| khtml_closeelem(&html, 3);
+		free(href);
+		if (error) return error;
+	}
+
 	return htmlFooter(&html) || khtml_close(&html);
 }
diff --git a/server.h b/server.h
index fd80278..c1943ce 100644
--- a/server.h
+++ b/server.h
@@ -27,6 +27,7 @@
 
 #if KCGI_VMAJOR == 0 && KCGI_VMINOR < 12
 #define khttp_urlpart(...) kutil_urlpart(NULL, __VA_ARGS__)
+#define khttp_urlpartx(...) kutil_urlpartx(NULL, __VA_ARGS__)
 #endif
 
 // Why does it return (const unsigned char *)?