mirror of
https://github.com/scsibug/nostr-rs-relay.git
synced 2024-11-22 00:59:07 -05:00
feat(NIP-01): Implement limit
This was quickly sneaked in by fiatjaf per my request[0], it makes many
queries more efficient and allows for paging when combined with until.
It is a bit weird to have multiple limits on each filter... for now we
just choose any or the last limit seen.
[0]: a4aea5337f
Signed-off-by: William Casarin <jb55@jb55.com>
This commit is contained in:
parent
9b351aab9b
commit
4ad483090e
12
src/db.rs
12
src/db.rs
|
@ -385,6 +385,7 @@ fn query_from_sub(sub: &Subscription) -> (String, Vec<Box<dyn ToSql>>) {
|
||||||
// (sqli-safe), or a string that is filtered to only contain
|
// (sqli-safe), or a string that is filtered to only contain
|
||||||
// hexadecimal characters. Strings that require escaping (tag
|
// hexadecimal characters. Strings that require escaping (tag
|
||||||
// names/values) use parameters.
|
// names/values) use parameters.
|
||||||
|
let mut limit: Option<u32> = None;
|
||||||
let mut query =
|
let mut query =
|
||||||
"SELECT DISTINCT(e.content) FROM event e LEFT JOIN tag t ON e.id=t.event_id ".to_owned();
|
"SELECT DISTINCT(e.content) FROM event e LEFT JOIN tag t ON e.id=t.event_id ".to_owned();
|
||||||
// parameters
|
// parameters
|
||||||
|
@ -422,6 +423,9 @@ fn query_from_sub(sub: &Subscription) -> (String, Vec<Box<dyn ToSql>>) {
|
||||||
let authors_clause = format!("({})", auth_searches.join(" OR "));
|
let authors_clause = format!("({})", auth_searches.join(" OR "));
|
||||||
filter_components.push(authors_clause);
|
filter_components.push(authors_clause);
|
||||||
}
|
}
|
||||||
|
if let Some(lim) = f.limit {
|
||||||
|
limit = Some(lim)
|
||||||
|
}
|
||||||
// Query for Kind
|
// Query for Kind
|
||||||
if let Some(ks) = &f.kinds {
|
if let Some(ks) = &f.kinds {
|
||||||
// kind is number, no escaping needed
|
// kind is number, no escaping needed
|
||||||
|
@ -513,7 +517,13 @@ fn query_from_sub(sub: &Subscription) -> (String, Vec<Box<dyn ToSql>>) {
|
||||||
query.push_str(") ");
|
query.push_str(") ");
|
||||||
}
|
}
|
||||||
// add order clause
|
// add order clause
|
||||||
query.push_str(" ORDER BY created_at ASC");
|
query.push_str(&format!(
|
||||||
|
" ORDER BY created_at {}",
|
||||||
|
limit.map_or("ASC", |_| "DESC")
|
||||||
|
));
|
||||||
|
if let Some(lim) = limit {
|
||||||
|
query.push_str(&format!(" LIMIT {}", lim))
|
||||||
|
}
|
||||||
debug!("query string: {}", query);
|
debug!("query string: {}", query);
|
||||||
(query, params)
|
(query, params)
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,8 @@ pub struct ReqFilter {
|
||||||
pub until: Option<u64>,
|
pub until: Option<u64>,
|
||||||
/// List of author public keys
|
/// List of author public keys
|
||||||
pub authors: Option<Vec<String>>,
|
pub authors: Option<Vec<String>>,
|
||||||
|
/// Limit number of results
|
||||||
|
pub limit: Option<u32>,
|
||||||
/// Set of tags
|
/// Set of tags
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
pub tags: Option<HashMap<String, HashSet<String>>>,
|
pub tags: Option<HashMap<String, HashSet<String>>>,
|
||||||
|
@ -54,6 +56,7 @@ impl<'de> Deserialize<'de> for ReqFilter {
|
||||||
since: None,
|
since: None,
|
||||||
until: None,
|
until: None,
|
||||||
authors: None,
|
authors: None,
|
||||||
|
limit: None,
|
||||||
tags: None,
|
tags: None,
|
||||||
};
|
};
|
||||||
let mut ts = None;
|
let mut ts = None;
|
||||||
|
@ -68,6 +71,8 @@ impl<'de> Deserialize<'de> for ReqFilter {
|
||||||
rf.since = Deserialize::deserialize(val).ok();
|
rf.since = Deserialize::deserialize(val).ok();
|
||||||
} else if key == "until" {
|
} else if key == "until" {
|
||||||
rf.until = Deserialize::deserialize(val).ok();
|
rf.until = Deserialize::deserialize(val).ok();
|
||||||
|
} else if key == "limit" {
|
||||||
|
rf.limit = Deserialize::deserialize(val).ok();
|
||||||
} else if key == "authors" {
|
} else if key == "authors" {
|
||||||
rf.authors = Deserialize::deserialize(val).ok();
|
rf.authors = Deserialize::deserialize(val).ok();
|
||||||
} else if key.starts_with('#') && key.len() > 1 && val.is_array() {
|
} else if key.starts_with('#') && key.len() > 1 && val.is_array() {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user