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::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<i32>,
}
impl ChangesResource {
pub fn new(state: State, pagination: Pagination<i32>) -> Self {
Self { state, pagination }
pub fn new(state: State, pagination: Pagination<i32>) -> Box<Future<Item=ChangesResource, Error=::web::Error>> {
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::*;

View file

@ -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))),