Implement newsreader counting
This commit is contained in:
@@ -1,4 +1,8 @@
|
||||
use std::hash::{DefaultHasher, Hash, Hasher};
|
||||
use std::{
|
||||
convert::Infallible,
|
||||
hash::{DefaultHasher, Hash, Hasher},
|
||||
str::FromStr,
|
||||
};
|
||||
|
||||
use async_graphql::connection::{self, Connection, Edge};
|
||||
use log::info;
|
||||
@@ -20,6 +24,15 @@ pub fn is_newsreader_thread(query: &str) -> bool {
|
||||
query.starts_with(THREAD_PREFIX)
|
||||
}
|
||||
|
||||
pub async fn count(pool: &PgPool, query: &str) -> Result<usize, ServerError> {
|
||||
let query: Query = query.parse()?;
|
||||
let site = query.site.expect("search has no site");
|
||||
let row = sqlx::query_file!("sql/count.sql", site, query.unread_only)
|
||||
.fetch_one(pool)
|
||||
.await?;
|
||||
Ok(row.count.unwrap_or(0).try_into().unwrap_or(0))
|
||||
}
|
||||
|
||||
pub async fn search(
|
||||
pool: &PgPool,
|
||||
after: Option<String>,
|
||||
@@ -28,27 +41,16 @@ pub async fn search(
|
||||
last: Option<i32>,
|
||||
query: String,
|
||||
) -> Result<Connection<usize, ThreadSummary>, async_graphql::Error> {
|
||||
let mut unread_only = false;
|
||||
let mut site = None;
|
||||
let site_prefix = format!("tag:{TAG_PREFIX}");
|
||||
for word in query.split_whitespace() {
|
||||
if word == "is:unread" {
|
||||
unread_only = true
|
||||
};
|
||||
if word.starts_with(&site_prefix) {
|
||||
site = Some(word[site_prefix.len()..].to_string())
|
||||
}
|
||||
}
|
||||
let site = site.expect("search has no site");
|
||||
info!("news search unread_only {unread_only} site {site:?}");
|
||||
let query: Query = query.parse()?;
|
||||
info!("news search query {query:?}");
|
||||
let site = query.site.expect("search has no site");
|
||||
connection::query(
|
||||
after,
|
||||
before,
|
||||
first,
|
||||
last,
|
||||
|after, before, first, last| async move {
|
||||
// TODO: handle `unread_only`
|
||||
let rows = sqlx::query_file!("sql/threads.sql", site)
|
||||
let rows = sqlx::query_file!("sql/threads.sql", site, query.unread_only)
|
||||
.fetch_all(pool)
|
||||
.await?;
|
||||
|
||||
@@ -160,3 +162,27 @@ pub async fn thread(pool: &PgPool, thread_id: String) -> Result<Thread, ServerEr
|
||||
}],
|
||||
})
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Query {
|
||||
unread_only: bool,
|
||||
site: Option<String>,
|
||||
}
|
||||
|
||||
impl FromStr for Query {
|
||||
type Err = Infallible;
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let mut unread_only = false;
|
||||
let mut site = None;
|
||||
let site_prefix = format!("tag:{TAG_PREFIX}");
|
||||
for word in s.split_whitespace() {
|
||||
if word == "is:unread" {
|
||||
unread_only = true
|
||||
};
|
||||
if word.starts_with(&site_prefix) {
|
||||
site = Some(word[site_prefix.len()..].to_string())
|
||||
}
|
||||
}
|
||||
Ok(Query { unread_only, site })
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user