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

@ -304,7 +304,8 @@ impl Database
// 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.
// We add a parameter for categories length to check if filtering is needed.
let mut query = String::from( let mut query = String::from(
"SELECT "SELECT
t.title, t.title,
@ -312,51 +313,62 @@ impl Database
t.summary, t.summary,
t.author, t.author,
t.publish_date, t.publish_date,
GROUP_CONCAT(tg.name, ',') AS tags GROUP_CONCAT(tg_all.name, ',') AS tags
FROM tales AS t FROM tales AS t
LEFT JOIN tale_tags AS tt ON t.slug = tt.tale_slug LEFT JOIN tale_tags AS tt_all ON t.slug = tt_all.tale_slug
LEFT JOIN tags AS tg ON tt.tag_id = tg.id" 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<_> =
(0..categories.len()).map(|_| "?").collect();
query.push_str(&placeholders.join(", ")); query.push_str(&placeholders.join(", "));
query.push(')'); } else {
// No categories, so dummy placeholder to satisfy SQL syntax
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);
for cat in categories
{ // Bind the length of categories for the (? = 0) check
q = q.bind(categories.len() as i64);
// Bind the category names if any
for cat in categories {
q = q.bind(cat); q = q.bind(cat);
} }
// Execute the query
let rows = q.fetch_all(&mut *tx).await?; let rows = q.fetch_all(&mut *tx).await?;
let current_time = chrono::Utc::now().naive_utc(); let current_time = chrono::Utc::now().naive_utc();
for row in rows for row in rows {
{
let date_str: String = row.try_get("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 publish_date = chrono::NaiveDateTime::parse_from_str(&date_str, "%Y-%m-%d %H:%M:%S")
.map_err(|e| sqlx::Error::Decode(e.into()))?; .map_err(|e| sqlx::Error::Decode(e.into()))?;
// Only give tales that are ready to be published. // Only include tales that are ready to be published.
if current_time >= publish_date if current_time >= publish_date {
{
let tags_str: Option<String> = row.try_get("tags")?; let tags_str: Option<String> = row.try_get("tags")?;
let tags = tags_str.map(|s| s.split(',').map(String::from).collect()) let tags = tags_str
.map(|s| s.split(',').map(String::from).collect())
.unwrap_or_default(); .unwrap_or_default();
tales.push(Lore { title: row.try_get("title")?, tales.push(Lore {
title: row.try_get("title")?,
slug: row.try_get("slug")?, slug: row.try_get("slug")?,
summary: row.try_get("summary")?, summary: row.try_get("summary")?,
author: row.try_get("author")?, author: row.try_get("author")?,
publish_date, publish_date,
tags }); tags,
});
} }
} }