Refactor QUERY_GET_BEST_PRODUCTION SQL query in Worker: Improve readability and maintainability by restructuring the query with clearer aliases and consistent use of COALESCE. Enhance join conditions and ensure proper handling of character health, resulting in more accurate production worth calculations.

This commit is contained in:
Torsten Schulz (local)
2026-01-05 11:44:44 +01:00
parent 713504d3ab
commit 108ac6c82b
2 changed files with 90 additions and 19 deletions

View File

@@ -3,6 +3,7 @@ use std::collections::HashMap;
use crate::message_broker::MessageBroker;
use std::sync::atomic::Ordering;
use std::sync::Arc;
use std::sync::Mutex;
use std::time::{Duration, Instant};
use crate::db::ConnectionPool;
@@ -318,10 +319,36 @@ impl DirectorWorker {
conn.prepare("get_to_produce", QUERY_GET_BEST_PRODUCTION)?;
let rows = conn.execute("get_to_produce", &[&director.id, &director.branch_id])?;
if rows.is_empty() {
// Debug: SQL-Vorschau nur gedrosselt loggen, damit wir die Query testen können
// ohne Log-Flut.
static LAST_EMPTY_PROD_LOG: Mutex<Option<Instant>> = Mutex::new(None);
let mut last = LAST_EMPTY_PROD_LOG.lock().unwrap();
let should_log = last
.map(|t| t.elapsed().as_secs() >= 60)
.unwrap_or(true);
if should_log {
// SQL ggf. kürzen, um Log-Flut zu vermeiden
let mut sql_preview = QUERY_GET_BEST_PRODUCTION.to_string();
const MAX_SQL_PREVIEW: usize = 1200;
if sql_preview.len() > MAX_SQL_PREVIEW {
sql_preview.truncate(MAX_SQL_PREVIEW);
sql_preview.push_str("");
}
eprintln!(
"[DirectorWorker] Keine Produktionskandidaten für Director {} (branch_id={}). Query (get_to_produce): {} | params: director_id={}, branch_id={}",
director.id,
director.branch_id,
sql_preview,
director.id,
director.branch_id
);
*last = Some(Instant::now());
} else {
eprintln!(
"[DirectorWorker] Keine Produktionskandidaten für Director {} gefunden.",
director.id
);
}
return Ok(());
}

View File

@@ -122,22 +122,66 @@ UPDATE falukant_data.vehicle v
"#;
pub const QUERY_GET_BEST_PRODUCTION: &str = r#"
SELECT fdu.id falukant_user_id, CAST(fdu.money AS text) AS money, fdu.certificate, ftp.id product_id, ftp.label_tr, fdb.region_id,
(SELECT SUM(quantity) FROM falukant_data.stock fds WHERE fds.branch_id = fdb.id) AS stock_size,
COALESCE((SELECT SUM(COALESCE(fdi.quantity, 0)) FROM falukant_data.stock fds JOIN falukant_data.inventory fdi ON fdi.stock_id = fds.id WHERE fds.branch_id = fdb.id), 0) AS used_in_stock,
(ftp.sell_cost * (fdtpw.worth_percent + (fdk_character.knowledge * 2 + fdk_director.knowledge) / 3) / 100 - 6 * ftp.category) / (300.0 * ftp.production_time) AS worth,
fdb.id AS branch_id, (SELECT COUNT(id) FROM falukant_data.production WHERE branch_id = fdb.id) AS running_productions,
COALESCE((SELECT SUM(COALESCE(fdp.quantity, 0)) quantity FROM falukant_data.production fdp WHERE fdp.branch_id = fdb.id), 0) AS running_productions_quantity
SELECT
fdu.id AS falukant_user_id,
CAST(fdu.money AS text) AS money,
fdu.certificate,
ftp.id AS product_id,
ftp.label_tr,
fdb.region_id,
(SELECT SUM(quantity) FROM falukant_data.stock fds WHERE fds.branch_id = fdb.id) AS stock_size,
COALESCE(
(SELECT SUM(COALESCE(fdi.quantity, 0))
FROM falukant_data.stock fds
JOIN falukant_data.inventory fdi ON fdi.stock_id = fds.id
WHERE fds.branch_id = fdb.id),
0
) AS used_in_stock,
(
ftp.sell_cost
* (
COALESCE(tpw.worth_percent, 100.0)
+ (
(COALESCE(k_char.knowledge, 0) * 2 + COALESCE(k_dir.knowledge, 0))::double precision / 3.0
)
) / 100.0
- 6 * ftp.category
) / (300.0 * GREATEST(1, ftp.production_time)) AS worth,
fdb.id AS branch_id,
(SELECT COUNT(id) FROM falukant_data.production WHERE branch_id = fdb.id) AS running_productions,
COALESCE(
(SELECT SUM(COALESCE(fdp.quantity, 0))
FROM falukant_data.production fdp
WHERE fdp.branch_id = fdb.id),
0
) AS running_productions_quantity
FROM falukant_data.director fdd
JOIN falukant_data.character fdc ON fdc.id = fdd.director_character_id
JOIN falukant_data.falukant_user fdu ON fdd.employer_user_id = fdu.id
JOIN falukant_data.character user_character ON user_character.user_id = fdu.id
JOIN falukant_data.branch fdb ON fdb.falukant_user_id = fdu.id AND fdb.region_id = fdc.region_id
JOIN falukant_data.town_product_worth fdtpw ON fdtpw.region_id = fdb.region_id
JOIN falukant_data.knowledge fdk_character ON fdk_character.product_id = fdtpw.product_id AND fdk_character.character_id = user_character.id
JOIN falukant_data.knowledge fdk_director ON fdk_director.product_id = fdtpw.product_id AND fdk_director.character_id = fdd.director_character_id
JOIN falukant_type.product ftp ON ftp.id = fdtpw.product_id AND ftp.category <= fdu.certificate
WHERE fdd.id = $1 AND fdb.id = $2 ORDER BY worth DESC LIMIT 1;
JOIN falukant_data."character" fdc
ON fdc.id = fdd.director_character_id
JOIN falukant_data.falukant_user fdu
ON fdd.employer_user_id = fdu.id
LEFT JOIN falukant_data."character" user_character
ON user_character.user_id = fdu.id
AND user_character.health > 0
JOIN falukant_data.branch fdb
ON fdb.falukant_user_id = fdu.id
AND fdb.region_id = fdc.region_id
JOIN falukant_type.product ftp
ON ftp.category <= fdu.certificate
LEFT JOIN falukant_data.town_product_worth tpw
ON tpw.region_id = fdb.region_id
AND tpw.product_id = ftp.id
LEFT JOIN falukant_data.knowledge k_char
ON k_char.product_id = ftp.id
AND user_character.id IS NOT NULL
AND k_char.character_id = user_character.id
LEFT JOIN falukant_data.knowledge k_dir
ON k_dir.product_id = ftp.id
AND k_dir.character_id = fdd.director_character_id
WHERE fdd.id = $1
AND fdb.id = $2
ORDER BY worth DESC
LIMIT 1;
"#;
pub const QUERY_INSERT_PRODUCTION: &str = r#"