From 50b86db59750b3d10e9ba5b27ce7bd10309c0965 Mon Sep 17 00:00:00 2001 From: Magnus Hoff Date: Sun, 22 Oct 2017 13:07:45 +0200 Subject: [PATCH] Internally reformulate all pagination queries as before-queries This fixes the pagination links so they only show up when relevant --- src/resources/changes_resource.rs | 37 +++++++++++++++++++++++++++---- src/wiki_lookup.rs | 12 +++++----- 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/src/resources/changes_resource.rs b/src/resources/changes_resource.rs index 9d729a1..8a2707d 100644 --- a/src/resources/changes_resource.rs +++ b/src/resources/changes_resource.rs @@ -1,4 +1,5 @@ use futures::{self, Future}; +use futures::future::finished; use hyper; use hyper::header::ContentType; use hyper::server::*; @@ -11,14 +12,44 @@ use web::{Resource, ResponseFuture}; use super::pagination::Pagination; +const PAGE_SIZE: i32 = 30; + pub struct ChangesResource { state: State, pagination: Pagination, } impl ChangesResource { - pub fn new(state: State, pagination: Pagination) -> Self { - Self { state, pagination } + pub fn new(state: State, pagination: Pagination) -> Box> { + match pagination { + Pagination::After(x) => Box::new( + state.query_article_revision_stubs(move |query| { + use diesel::prelude::*; + use schema::article_revisions::dsl::*; + + query + .limit(PAGE_SIZE as i64 + 1) + .filter(sequence_number.gt(x)) + .order(sequence_number.asc()) + }).and_then(|mut data| { + let extra_element = if data.len() > PAGE_SIZE as usize { + data.pop() + } else { + None + }; + + Ok(Self { + state, + pagination: match extra_element { + Some(x) => Pagination::Before(x.sequence_number), + None => Pagination::None + } + }) + }) + ), + Pagination::Before(x) => Box::new(finished(Self { state, pagination })), + Pagination::None => Box::new(finished(Self { state, pagination })), + } } } @@ -63,8 +94,6 @@ impl Resource for ChangesResource { changes: &'a [Row], } - const PAGE_SIZE: i32 = 30; - let pagination = self.pagination.clone(); let data = self.state.query_article_revision_stubs(move |query| { use diesel::prelude::*; diff --git a/src/wiki_lookup.rs b/src/wiki_lookup.rs index 5d5397b..44ffc65 100644 --- a/src/wiki_lookup.rs +++ b/src/wiki_lookup.rs @@ -83,12 +83,12 @@ impl WikiLookup { ("_assets", Some(asset)) => Box::new(asset_lookup(asset)), ("_changes", None) => { - Box::new(done( - pagination::from_str(query.unwrap_or("")).map_err(Into::into) - .and_then(|pagination| Ok(Some( - Box::new(ChangesResource::new(self.state.clone(), pagination)) as BoxResource - ))) - )) + let state = self.state.clone(); + Box::new( + done(pagination::from_str(query.unwrap_or("")).map_err(Into::into)) + .and_then(move |pagination| ChangesResource::new(state, pagination)) + .and_then(|changes_resource| Ok(Some(Box::new(changes_resource) as BoxResource))) + ) }, ("_new", None) => Box::new(finished(Some(Box::new(NewArticleResource::new(self.state.clone(), None)) as BoxResource))),