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:
@ -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"))]
|
||||||
|
|||||||
Reference in New Issue
Block a user