Internally reformulate all pagination queries as before-queries

This fixes the pagination links so they only show up when relevant
This commit is contained in:
Magnus Hoff 2017-10-22 13:07:45 +02:00
parent 6c36e3cb49
commit 50b86db597
2 changed files with 39 additions and 10 deletions

View file

@ -1,4 +1,5 @@
use futures::{self, Future}; use futures::{self, Future};
use futures::future::finished;
use hyper; use hyper;
use hyper::header::ContentType; use hyper::header::ContentType;
use hyper::server::*; use hyper::server::*;
@ -11,14 +12,44 @@ use web::{Resource, ResponseFuture};
use super::pagination::Pagination; use super::pagination::Pagination;
const PAGE_SIZE: i32 = 30;
pub struct ChangesResource { pub struct ChangesResource {
state: State, state: State,
pagination: Pagination<i32>, pagination: Pagination<i32>,
} }
impl ChangesResource { impl ChangesResource {
pub fn new(state: State, pagination: Pagination<i32>) -> Self { pub fn new(state: State, pagination: Pagination<i32>) -> Box<Future<Item=ChangesResource, Error=::web::Error>> {
Self { state, pagination } 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], changes: &'a [Row],
} }
const PAGE_SIZE: i32 = 30;
let pagination = self.pagination.clone(); let pagination = self.pagination.clone();
let data = self.state.query_article_revision_stubs(move |query| { let data = self.state.query_article_revision_stubs(move |query| {
use diesel::prelude::*; use diesel::prelude::*;

View file

@ -83,12 +83,12 @@ impl WikiLookup {
("_assets", Some(asset)) => ("_assets", Some(asset)) =>
Box::new(asset_lookup(asset)), Box::new(asset_lookup(asset)),
("_changes", None) => { ("_changes", None) => {
Box::new(done( let state = self.state.clone();
pagination::from_str(query.unwrap_or("")).map_err(Into::into) Box::new(
.and_then(|pagination| Ok(Some( done(pagination::from_str(query.unwrap_or("")).map_err(Into::into))
Box::new(ChangesResource::new(self.state.clone(), pagination)) as BoxResource .and_then(move |pagination| ChangesResource::new(state, pagination))
))) .and_then(|changes_resource| Ok(Some(Box::new(changes_resource) as BoxResource)))
)) )
}, },
("_new", None) => ("_new", None) =>
Box::new(finished(Some(Box::new(NewArticleResource::new(self.state.clone(), None)) as BoxResource))), Box::new(finished(Some(Box::new(NewArticleResource::new(self.state.clone(), None)) as BoxResource))),