Implement newsreader counting

This commit is contained in:
2024-07-21 15:13:09 -07:00
parent abaaddae3a
commit 9746c9912b
5 changed files with 67 additions and 18 deletions

View File

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