Adjusted the tale summary retrieval.

The SQL was not properly searching the tales. It had been searching and
finding all the tags that matched the search criteria, but it was
dropping all the other tag information. Now it properly keeps all the
tag information. This fixed an issue where the tags of a post were
disapearing and reapearing as the TagSelector was toggled.
This commit is contained in:
2025-09-24 19:36:29 -04:00
parent 2ffe20254c
commit 01dacabc03

View File

@ -299,70 +299,82 @@ impl Database
pub async fn get_tales_summary(&self, categories: &[String]) pub async fn get_tales_summary(&self, categories: &[String])
-> Result<Vec<Lore>> -> Result<Vec<Lore>>
{ {
let mut tales = Vec::new(); let mut tales = Vec::new();
// Start a read-only transaction. // Start a read-only transaction.
let mut tx = self.pool.begin().await?; let mut tx = self.pool.begin().await?;
// Dynamically build the query. // Build the base query string with placeholders for categories in the EXISTS clause.
let mut query = String::from( // We add a parameter for categories length to check if filtering is needed.
"SELECT let mut query = String::from(
t.title, "SELECT
t.slug, t.title,
t.summary, t.slug,
t.author, t.summary,
t.publish_date, t.author,
GROUP_CONCAT(tg.name, ',') AS tags t.publish_date,
FROM tales AS t GROUP_CONCAT(tg_all.name, ',') AS tags
LEFT JOIN tale_tags AS tt ON t.slug = tt.tale_slug FROM tales AS t
LEFT JOIN tags AS tg ON tt.tag_id = tg.id" LEFT JOIN tale_tags AS tt_all ON t.slug = tt_all.tale_slug
); LEFT JOIN tags AS tg_all ON tt_all.tag_id = tg_all.id
WHERE (? = 0 OR EXISTS (
SELECT 1 FROM tale_tags tt_filter
JOIN tags tg_filter ON tt_filter.tag_id = tg_filter.id
WHERE tt_filter.tale_slug = t.slug
AND tg_filter.name IN ("
);
if !categories.is_empty() // Add placeholders for category names in EXISTS IN clause
{ if !categories.is_empty() {
query.push_str(" WHERE tg.name IN ("); let placeholders: Vec<_> = (0..categories.len()).map(|_| "?").collect();
let placeholders: Vec<_> = query.push_str(&placeholders.join(", "));
(0..categories.len()).map(|_| "?").collect(); } else {
query.push_str(&placeholders.join(", ")); // No categories, so dummy placeholder to satisfy SQL syntax
query.push(')'); query.push_str("NULL");
} }
query.push_str("))) GROUP BY t.slug ORDER BY t.publish_date DESC");
query.push_str(" GROUP BY t.slug ORDER BY t.publish_date DESC"); // Prepare query with sqlx
let mut q = sqlx::query(&query);
let mut q = sqlx::query(&query); // Bind the length of categories for the (? = 0) check
for cat in categories q = q.bind(categories.len() as i64);
{
q = q.bind(cat);
}
let rows = q.fetch_all(&mut *tx).await?; // Bind the category names if any
let current_time = chrono::Utc::now().naive_utc(); for cat in categories {
q = q.bind(cat);
}
for row in rows // Execute the query
{ let rows = q.fetch_all(&mut *tx).await?;
let date_str: String = row.try_get("publish_date")?; let current_time = chrono::Utc::now().naive_utc();
let publish_date = chrono::NaiveDateTime::parse_from_str(&date_str, "%Y-%m-%d %H:%M:%S")
.map_err(|e| sqlx::Error::Decode(e.into()))?;
// Only give tales that are ready to be published. for row in rows {
if current_time >= publish_date let date_str: String = row.try_get("publish_date")?;
{ let publish_date = chrono::NaiveDateTime::parse_from_str(&date_str, "%Y-%m-%d %H:%M:%S")
let tags_str: Option<String> = row.try_get("tags")?; .map_err(|e| sqlx::Error::Decode(e.into()))?;
let tags = tags_str.map(|s| s.split(',').map(String::from).collect())
.unwrap_or_default();
tales.push(Lore { title: row.try_get("title")?, // Only include tales that are ready to be published.
slug: row.try_get("slug")?, if current_time >= publish_date {
summary: row.try_get("summary")?, let tags_str: Option<String> = row.try_get("tags")?;
author: row.try_get("author")?, let tags = tags_str
publish_date, .map(|s| s.split(',').map(String::from).collect())
tags }); .unwrap_or_default();
}
}
tx.commit().await?; // Explicit commit, even for read transactions. tales.push(Lore {
title: row.try_get("title")?,
slug: row.try_get("slug")?,
summary: row.try_get("summary")?,
author: row.try_get("author")?,
publish_date,
tags,
});
}
}
Ok(tales) tx.commit().await?; // Explicit commit, even for read transactions.
Ok(tales)
} }
#[cfg(any(not(feature = "publisher"), feature = "tester"))] #[cfg(any(not(feature = "publisher"), feature = "tester"))]