From 4dbb8998f840a771949ed30f9f2b652713edd0f9 Mon Sep 17 00:00:00 2001 From: "Jakob L. Kreuze" Date: Thu, 28 May 2020 18:12:46 -0400 Subject: Implement initial pagination. --- src/database.rs | 43 ++++++++++++++++++++----------------------- src/main.rs | 37 +++++++++++++++++++++++++------------ 2 files changed, 45 insertions(+), 35 deletions(-) (limited to 'src') diff --git a/src/database.rs b/src/database.rs index bd195f2..61a51cb 100644 --- a/src/database.rs +++ b/src/database.rs @@ -198,29 +198,26 @@ impl TagDatabase { ) }; - let query = if let (Some(id), Some(n)) = (q.last_id, q.limit) { - format!( - "SELECT id, blake2, filename, orig_dir - FROM images - {union} - WHERE id > {last_id} - GROUP BY id - ORDER BY id DESC - LIMIT {limit}", - last_id = id, - union = union.or(Some("".into())).unwrap(), - limit = n - ) - } else { - format!( - "SELECT id, blake2, filename, orig_dir - FROM images - {union} - GROUP BY id - ORDER BY id DESC", - union = union.or(Some("".into())).unwrap(), - ) - }; + let query = format!( + "SELECT id, blake2, filename, orig_dir + FROM images + {union} + {since} + GROUP BY id + ORDER BY id DESC + {limit}", + since = if let Some(n) = q.last_id { + format!("WHERE id < {}", n) + } else { + String::from("") + }, + limit = if let Some(n) = q.limit { + format!("LIMIT {}", n) + } else { + String::from("") + }, + union = union.or(Some("".into())).unwrap(), + ); Ok(self .0 diff --git a/src/main.rs b/src/main.rs index fab288c..e2290b9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -61,13 +61,12 @@ impl DatabaseConnection { } #[get("/")] -fn index() -> Template { - let context = HashMap::<&str, &str>::new(); - Template::render("index", &context) +fn index(conn: SiteState) -> Template { + display_posts(conn, String::from(""), None) } -#[get("/posts?")] -fn display_posts(conn: SiteState, tags: String) -> Template { +#[get("/posts?&")] +fn display_posts(conn: SiteState, tags: String, last: Option) -> Template { #[derive(Serialize)] struct TagResult { name: String, @@ -75,11 +74,13 @@ fn display_posts(conn: SiteState, tags: String) -> Template { } #[derive(Serialize)] - struct Asdf { + struct Context { tags: Vec, images: Vec, + next_page: String, } + let tagstr = &tags.clone(); let tag_results = { let tb = &conn.inner().lock().unwrap().tb; tb.top_tags(20) @@ -91,9 +92,15 @@ fn display_posts(conn: SiteState, tags: String) -> Template { }) .collect() }; - let images = get_posts(conn, tags).into_inner(); - let context = Asdf { + let images = get_posts(conn, tags, last).into_inner(); + let context = Context { tags: tag_results, + // FIXME: Magic number for results per request. + next_page: if images.len() == 50 { + format!("/posts?tags={}&last={}", tagstr, images[49].id) + } else { + String::from("") + }, images, }; Template::render("index", context) @@ -101,20 +108,25 @@ fn display_posts(conn: SiteState, tags: String) -> Template { #[derive(Serialize)] struct ImageResult { + id: i64, filename: String, thumb_filename: String, tags: Vec, } -#[get("/posts?")] -fn get_posts(conn: SiteState, tags: String) -> Json> { +#[get("/posts?&")] +fn get_posts(conn: SiteState, tags: String, last: Option) -> Json> { let tb = &conn.inner().lock().unwrap().tb; - let tags = tags.split(",").collect::>(); + let tags = if tags != "" { + tags.split(",").collect::>() + } else { + vec![] + }; let results = tb .query(Query { tags: &tags[..], - last_id: Some(0), + last_id: last, limit: Some(50), }) .unwrap(); @@ -123,6 +135,7 @@ fn get_posts(conn: SiteState, tags: String) -> Json> { results .iter() .map(|image| ImageResult { + id: image.id, filename: image.filename.clone(), thumb_filename: thumb_filename(&image.filename), tags: tb.tags_for_image(image.id).unwrap(), -- cgit v1.3