Add support for filtering _changes by article_id
This commit is contained in:
parent
955254335d
commit
dd22bcde98
1 changed files with 43 additions and 25 deletions
|
@ -25,7 +25,6 @@ pub struct ChangesLookup {
|
||||||
state: State,
|
state: State,
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Optionally filter by article_id
|
|
||||||
// TODO: Optionally filter by author
|
// TODO: Optionally filter by author
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Default)]
|
#[derive(Serialize, Deserialize, Default)]
|
||||||
|
@ -33,6 +32,8 @@ struct QueryParameters {
|
||||||
after: Option<i32>,
|
after: Option<i32>,
|
||||||
before: Option<i32>,
|
before: Option<i32>,
|
||||||
|
|
||||||
|
article_id: Option<i32>,
|
||||||
|
|
||||||
limit: Option<i32>,
|
limit: Option<i32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,6 +46,13 @@ impl QueryParameters {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn article_id(self, article_id: Option<i32>) -> Self {
|
||||||
|
Self {
|
||||||
|
article_id,
|
||||||
|
..self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn limit(self, limit: i32) -> Self {
|
fn limit(self, limit: i32) -> Self {
|
||||||
Self {
|
Self {
|
||||||
limit: if limit != DEFAULT_LIMIT { Some(limit) } else { None },
|
limit: if limit != DEFAULT_LIMIT { Some(limit) } else { None },
|
||||||
|
@ -63,15 +71,19 @@ impl QueryParameters {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_query_config<'a>(
|
fn apply_query_config<'a>(
|
||||||
query: article_revisions::BoxedQuery<'a, diesel::sqlite::Sqlite>,
|
mut query: article_revisions::BoxedQuery<'a, diesel::sqlite::Sqlite>,
|
||||||
|
article_id: Option<i32>,
|
||||||
limit: i32,
|
limit: i32,
|
||||||
)
|
)
|
||||||
-> article_revisions::BoxedQuery<'a, diesel::sqlite::Sqlite>
|
-> article_revisions::BoxedQuery<'a, diesel::sqlite::Sqlite>
|
||||||
{
|
{
|
||||||
use diesel::prelude::*;
|
use diesel::prelude::*;
|
||||||
|
|
||||||
query
|
if let Some(article_id) = article_id {
|
||||||
.limit(limit as i64 + 1)
|
query = query.filter(article_revisions::article_id.eq(article_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
query.limit(limit as i64 + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ChangesLookup {
|
impl ChangesLookup {
|
||||||
|
@ -96,17 +108,16 @@ impl ChangesLookup {
|
||||||
_ => Err("`limit` argument must be in range [1, 100]"),
|
_ => Err("`limit` argument must be in range [1, 100]"),
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
Ok((pagination, limit))
|
Ok((pagination, params.article_id, limit))
|
||||||
})())
|
})())
|
||||||
.and_then(move |(pagination, limit)| match pagination {
|
.and_then(move |(pagination, article_id, limit)| match pagination {
|
||||||
Pagination::After(x) => Box::new(
|
Pagination::After(x) => Box::new(
|
||||||
state.query_article_revision_stubs(move |query| {
|
state.query_article_revision_stubs(move |query| {
|
||||||
use diesel::prelude::*;
|
use diesel::prelude::*;
|
||||||
use schema::article_revisions::dsl::*;
|
|
||||||
|
|
||||||
apply_query_config(query, limit)
|
apply_query_config(query, article_id, limit)
|
||||||
.filter(sequence_number.gt(x))
|
.filter(article_revisions::sequence_number.gt(x))
|
||||||
.order(sequence_number.asc())
|
.order(article_revisions::sequence_number.asc())
|
||||||
}).and_then(move |mut data| {
|
}).and_then(move |mut data| {
|
||||||
let extra_element = if data.len() > limit as usize {
|
let extra_element = if data.len() > limit as usize {
|
||||||
data.pop()
|
data.pop()
|
||||||
|
@ -114,23 +125,29 @@ impl ChangesLookup {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let args =
|
||||||
|
QueryParameters {
|
||||||
|
after: None,
|
||||||
|
before: None,
|
||||||
|
article_id,
|
||||||
|
limit: None,
|
||||||
|
}
|
||||||
|
.limit(limit);
|
||||||
|
|
||||||
Ok(Some(match extra_element {
|
Ok(Some(match extra_element {
|
||||||
Some(x) => Box::new(TemporaryRedirectResource::new(
|
Some(x) => Box::new(TemporaryRedirectResource::new(
|
||||||
QueryParameters::default()
|
args
|
||||||
.limit(limit)
|
|
||||||
.pagination(Pagination::Before(x.sequence_number))
|
.pagination(Pagination::Before(x.sequence_number))
|
||||||
.into_link()
|
.into_link()
|
||||||
)) as BoxResource,
|
)) as BoxResource,
|
||||||
None => Box::new(TemporaryRedirectResource::new(
|
None => Box::new(TemporaryRedirectResource::new(
|
||||||
QueryParameters::default()
|
args.into_link()
|
||||||
.limit(limit)
|
|
||||||
.into_link()
|
|
||||||
)) as BoxResource,
|
)) as BoxResource,
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
) as Box<Future<Item=Option<BoxResource>, Error=::web::Error>>,
|
) as Box<Future<Item=Option<BoxResource>, Error=::web::Error>>,
|
||||||
Pagination::Before(x) => Box::new(finished(Some(Box::new(ChangesResource::new(state, Some(x), limit)) as BoxResource))),
|
Pagination::Before(x) => Box::new(finished(Some(Box::new(ChangesResource::new(state, Some(x), article_id, limit)) as BoxResource))),
|
||||||
Pagination::None => Box::new(finished(Some(Box::new(ChangesResource::new(state, None, limit)) as BoxResource))),
|
Pagination::None => Box::new(finished(Some(Box::new(ChangesResource::new(state, None, article_id, limit)) as BoxResource))),
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -139,18 +156,20 @@ impl ChangesLookup {
|
||||||
pub struct ChangesResource {
|
pub struct ChangesResource {
|
||||||
state: State,
|
state: State,
|
||||||
before: Option<i32>,
|
before: Option<i32>,
|
||||||
|
article_id: Option<i32>,
|
||||||
limit: i32,
|
limit: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ChangesResource {
|
impl ChangesResource {
|
||||||
pub fn new(state: State, before: Option<i32>, limit: i32) -> Self {
|
pub fn new(state: State, before: Option<i32>, article_id: Option<i32>, limit: i32) -> Self {
|
||||||
Self { state, before, limit }
|
Self { state, before, article_id, limit }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn query_args(&self) -> QueryParameters {
|
fn query_args(&self) -> QueryParameters {
|
||||||
QueryParameters {
|
QueryParameters {
|
||||||
after: None,
|
after: None,
|
||||||
before: self.before,
|
before: self.before,
|
||||||
|
article_id: self.article_id,
|
||||||
..QueryParameters::default()
|
..QueryParameters::default()
|
||||||
}
|
}
|
||||||
.limit(self.limit)
|
.limit(self.limit)
|
||||||
|
@ -198,17 +217,16 @@ impl Resource for ChangesResource {
|
||||||
changes: &'a [Row],
|
changes: &'a [Row],
|
||||||
}
|
}
|
||||||
|
|
||||||
let before = self.before.clone();
|
let (before, article_id, limit) =
|
||||||
let limit = self.limit;
|
(self.before.clone(), self.article_id.clone(), self.limit);
|
||||||
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::*;
|
||||||
use schema::article_revisions::dsl::*;
|
|
||||||
|
|
||||||
let query = apply_query_config(query, limit)
|
let query = apply_query_config(query, article_id, limit)
|
||||||
.order(sequence_number.desc());
|
.order(article_revisions::sequence_number.desc());
|
||||||
|
|
||||||
match before {
|
match before {
|
||||||
Some(x) => query.filter(sequence_number.lt(x)),
|
Some(x) => query.filter(article_revisions::sequence_number.lt(x)),
|
||||||
None => query,
|
None => query,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue