diff --git a/src/worker/sql.rs b/src/worker/sql.rs index d82b62a..0758b5d 100644 --- a/src/worker/sql.rs +++ b/src/worker/sql.rs @@ -85,136 +85,83 @@ WHERE current_time BETWEEN '08:00:00' AND '17:00:00'; /// `worth_percent`: mit Fahrzeug `MAX` über Filialregionen; ohne Fahrzeug nur Direktor-Region. /// **Ein** Spielercharakter je User (`ORDER BY id DESC LIMIT 1`, `health > 0`). 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, -COALESCE(ftp.category, 1)::int AS product_category, 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, -( +WITH candidates AS ( + SELECT + fdu.id AS falukant_user_id, + CAST(fdu.money AS text) AS money, + fdu.certificate, + ftp.id AS product_id, + ftp.label_tr, + COALESCE(ftp.category, 1)::int AS product_category, + fdb.region_id, + fdb.id AS branch_id, + COALESCE((SELECT SUM(quantity) FROM falukant_data.stock fds WHERE fds.branch_id = fdb.id), 0) 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, + COALESCE((SELECT COUNT(id) FROM falukant_data.production WHERE branch_id = fdb.id), 0) 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, + ftp.sell_cost::float8 AS sell_cost, + CASE + WHEN EXISTS (SELECT 1 FROM falukant_data.vehicle v WHERE v.falukant_user_id = fdu.id) + THEN bw.max_worth_pct + ELSE COALESCE(fdtpw_local.worth_percent::float8, 0.0) + END AS market_percent, + LEAST(100.0, GREATEST(0.0, (2.0 * COALESCE(fdk_character.knowledge, 0)::float8 + COALESCE(fdk_director.knowledge, 0)::float8) / 3.0)) AS quality_estimate, + ( + (6.0 + GREATEST(COALESCE(ftp.category, 1)::float8, 1.0)) + * (1.0 - LEAST(GREATEST(COALESCE(fdu.certificate, 1)::float8 - GREATEST(COALESCE(ftp.category, 1)::float8, 1.0), 0.0) * 0.035, 0.14)) + ) AS one_piece_cost, + COALESCE(ftp.production_time::float8, 0.0) AS production_time + 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.id = ( + SELECT c2.id + FROM falukant_data.character c2 + WHERE c2.user_id = fdu.id + AND c2.health > 0 + ORDER BY c2.id DESC + LIMIT 1 + ) + JOIN falukant_data.branch fdb ON fdb.falukant_user_id = fdu.id AND fdb.region_id = fdc.region_id + JOIN ( + SELECT tpw.product_id, MAX(tpw.worth_percent)::float8 AS max_worth_pct + FROM falukant_data.town_product_worth tpw + WHERE tpw.region_id IN ( + SELECT DISTINCT br.region_id + FROM falukant_data.branch br + WHERE br.falukant_user_id = (SELECT d0.employer_user_id FROM falukant_data.director d0 WHERE d0.id = $1::int) + ) + GROUP BY tpw.product_id + ) bw ON TRUE + JOIN falukant_type.product ftp ON ftp.id = bw.product_id AND ftp.category <= fdu.certificate + LEFT JOIN falukant_data.town_product_worth fdtpw_local ON fdtpw_local.region_id = fdb.region_id AND fdtpw_local.product_id = ftp.id + JOIN falukant_data.knowledge fdk_character ON fdk_character.product_id = ftp.id AND fdk_character.character_id = user_character.id + JOIN falukant_data.knowledge fdk_director ON fdk_director.product_id = ftp.id AND fdk_director.character_id = fdd.director_character_id + WHERE fdd.id = $1 AND fdb.id = $2 +) +SELECT + falukant_user_id, + money, + certificate, + product_id, + label_tr, + product_category, + region_id, + stock_size, + used_in_stock, ( ( - ( - ftp.sell_cost - * ( - CASE - WHEN EXISTS ( - SELECT 1 FROM falukant_data.vehicle v - WHERE v.falukant_user_id = fdu.id - ) - THEN bw.max_worth_pct - ELSE COALESCE(fdtpw_local.worth_percent::float8, 0.0) - END - ) / 100.0 - ) * ( - 0.6 + 0.4 * ( - LEAST( - 100.0, - GREATEST( - 0.0, - (2.0 * COALESCE(fdk_character.knowledge, 0)::float8 - + COALESCE(fdk_director.knowledge, 0)::float8) / 3.0 - ) - ) / 100.0 - ) - ) - ) - - ( - GREATEST( - ( - ( - ( - ( - ftp.sell_cost - * ( - CASE - WHEN EXISTS ( - SELECT 1 FROM falukant_data.vehicle v - WHERE v.falukant_user_id = fdu.id - ) - THEN bw.max_worth_pct - ELSE COALESCE(fdtpw_local.worth_percent::float8, 0.0) - END - ) / 100.0 - ) * ( - 0.6 + 0.4 * ( - LEAST( - 100.0, - GREATEST( - 0.0, - (2.0 * COALESCE(fdk_character.knowledge, 0)::float8 - + COALESCE(fdk_director.knowledge, 0)::float8) / 3.0 - ) - ) / 100.0 - ) - ) - ) - - ( - ( - 6.0 + GREATEST(COALESCE(ftp.category, 1)::float8, 1.0) - ) * ( - 1.0 - LEAST( - GREATEST( - COALESCE(fdu.certificate, 1)::float8 - - GREATEST(COALESCE(ftp.category, 1)::float8, 1.0), - 0.0 - ) * 0.035, - 0.14 - ) - ) - ) - ), - 0.0 - ) * (COALESCE($3::float8, 0.0) / 100.0) - ) - + ( - ( - 6.0 + GREATEST(COALESCE(ftp.category, 1)::float8, 1.0) - ) * ( - 1.0 - LEAST( - GREATEST( - COALESCE(fdu.certificate, 1)::float8 - - GREATEST(COALESCE(ftp.category, 1)::float8, 1.0), - 0.0 - ) * 0.035, - 0.14 - ) - ) - ) - ) - ) / NULLIF(ftp.production_time::float8, 0.0) -) 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 -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.id = ( - SELECT c2.id - FROM falukant_data.character c2 - WHERE c2.user_id = fdu.id - AND c2.health > 0 - ORDER BY c2.id DESC - LIMIT 1 - ) -JOIN falukant_data.branch fdb ON fdb.falukant_user_id = fdu.id AND fdb.region_id = fdc.region_id -JOIN ( - SELECT tpw.product_id, - MAX(tpw.worth_percent)::float8 AS max_worth_pct - FROM falukant_data.town_product_worth tpw - WHERE tpw.region_id IN ( - SELECT DISTINCT br.region_id - FROM falukant_data.branch br - WHERE br.falukant_user_id = (SELECT d0.employer_user_id FROM falukant_data.director d0 WHERE d0.id = $1::int) - ) - GROUP BY tpw.product_id -) bw ON TRUE -JOIN falukant_type.product ftp ON ftp.id = bw.product_id AND ftp.category <= fdu.certificate -LEFT JOIN falukant_data.town_product_worth fdtpw_local - ON fdtpw_local.region_id = fdb.region_id - AND fdtpw_local.product_id = ftp.id -JOIN falukant_data.knowledge fdk_character ON fdk_character.product_id = ftp.id AND fdk_character.character_id = user_character.id -JOIN falukant_data.knowledge fdk_director ON fdk_director.product_id = ftp.id AND fdk_director.character_id = fdd.director_character_id -WHERE fdd.id = $1 AND fdb.id = $2 ORDER BY worth DESC LIMIT 1; + (sell_cost * market_percent / 100.0 * (0.6 + 0.4 * (quality_estimate / 100.0))) + - (GREATEST((sell_cost * market_percent / 100.0 * (0.6 + 0.4 * (quality_estimate / 100.0)) - one_piece_cost), 0.0) * (COALESCE($3::float8, 0.0) / 100.0)) + - one_piece_cost + ) / NULLIF(production_time, 0.0) + ) AS worth, + branch_id, + running_productions, + running_productions_quantity +FROM candidates +ORDER BY worth DESC +LIMIT 1; "#; /// Debug-Variante zur Nachvollziehbarkeit der Direktoren-Entscheidung. @@ -1917,11 +1864,13 @@ pub const QUERY_DEBTORS_SUBTRACT_REPUTATION: &str = r#" "#; pub const QUERY_DEBTORS_MARRIAGE_SATISFACTION_SUB: &str = r#" - UPDATE falukant_data.relationship r - SET marriage_satisfaction = GREATEST(0, COALESCE(r.marriage_satisfaction, 55) - $2::int), + UPDATE falukant_data.relationship_state rs + SET marriage_satisfaction = GREATEST(0, COALESCE(rs.marriage_satisfaction, 55) - $2::int), updated_at = NOW() - FROM falukant_type.relationship rt + FROM falukant_data.relationship r + JOIN falukant_type.relationship rt ON rt.id = r.relationship_type_id WHERE rt.id = r.relationship_type_id + AND rs.relationship_id = r.id AND rt.tr IN ('married', 'engaged', 'wooing') AND (r.character1_id = $1::int OR r.character2_id = $1::int); "#; @@ -1959,11 +1908,13 @@ pub const QUERY_DEBTORS_IMPRISONED_PENALTY_PLUS1: &str = r#" "#; pub const QUERY_DEBTORS_IMPRISONED_MARRIAGE_SUB1: &str = r#" - UPDATE falukant_data.relationship r - SET marriage_satisfaction = GREATEST(0, COALESCE(r.marriage_satisfaction, 55) - 1), + UPDATE falukant_data.relationship_state rs + SET marriage_satisfaction = GREATEST(0, COALESCE(rs.marriage_satisfaction, 55) - 1), updated_at = NOW() - FROM falukant_type.relationship rt + FROM falukant_data.relationship r + JOIN falukant_type.relationship rt ON rt.id = r.relationship_type_id WHERE rt.id = r.relationship_type_id + AND rs.relationship_id = r.id AND rt.tr IN ('married', 'engaged', 'wooing') AND (r.character1_id = $1::int OR r.character2_id = $1::int); "#; @@ -3419,10 +3370,13 @@ pub const QUERY_UPDATE_USER_HOUSE_SERVANT_DAILY: &str = r#" "#; pub const QUERY_UPDATE_MARRIAGE_SATISFACTION_ADD_FOR_CHARACTER: &str = r#" - UPDATE falukant_data.relationship r - SET marriage_satisfaction = GREATEST(0, LEAST(100, marriage_satisfaction + $1::int)) - FROM falukant_type.relationship rt + UPDATE falukant_data.relationship_state rs + SET marriage_satisfaction = GREATEST(0, LEAST(100, COALESCE(rs.marriage_satisfaction, 55) + $1::int)), + updated_at = NOW() + FROM falukant_data.relationship r + JOIN falukant_type.relationship rt ON rt.id = r.relationship_type_id WHERE rt.id = r.relationship_type_id + AND rs.relationship_id = r.id AND rt.tr IN ('married', 'engaged', 'wooing') AND (r.character1_id = $2::int OR r.character2_id = $2::int); "#; @@ -3611,10 +3565,10 @@ pub const QUERY_GET_MARRIAGE_ROWS: &str = r#" r.id AS marriage_id, r.character1_id AS m1, r.character2_id AS m2, - r.marriage_satisfaction, - COALESCE(r.marriage_public_stability, 55)::int AS marriage_public_stability, - r.marriage_drift_high, - r.marriage_drift_low, + COALESCE((to_jsonb(rs)->>'marriage_satisfaction')::int, 55)::int AS marriage_satisfaction, + COALESCE((to_jsonb(rs)->>'marriage_public_stability')::int, 55)::int AS marriage_public_stability, + COALESCE((to_jsonb(rs)->>'marriage_drift_high')::int, 0)::int AS marriage_drift_high, + COALESCE((to_jsonb(rs)->>'marriage_drift_low')::int, 0)::int AS marriage_drift_low, COALESCE(t1.tr, '') AS title1_tr, COALESCE(t2.tr, '') AS title2_tr, fu1.id AS user1_id, @@ -3642,6 +3596,7 @@ pub const QUERY_GET_MARRIAGE_ROWS: &str = r#" FROM falukant_data.relationship r JOIN falukant_type.relationship rt ON rt.id = r.relationship_type_id AND rt.tr IN ('married', 'engaged', 'wooing') + LEFT JOIN falukant_data.relationship_state rs ON rs.relationship_id = r.id JOIN falukant_data.character c1 ON c1.id = r.character1_id JOIN falukant_data.character c2 ON c2.id = r.character2_id LEFT JOIN falukant_type.title t1 ON t1.id = c1.title_of_nobility @@ -3652,25 +3607,24 @@ pub const QUERY_GET_MARRIAGE_ROWS: &str = r#" #[allow(dead_code)] // Einfaches Update ohne Buff-Spalten; Daemon nutzt QUERY_UPDATE_MARRIAGE_STATE_AND_BUFFS. pub const QUERY_UPDATE_MARRIAGE_STATE: &str = r#" - UPDATE falukant_data.relationship + UPDATE falukant_data.relationship_state SET marriage_satisfaction = $1::smallint, marriage_drift_high = $2::smallint, - marriage_drift_low = $3::smallint - WHERE id = $4::int; + marriage_drift_low = $3::smallint, + updated_at = NOW() + WHERE relationship_id = $4::int; "#; /// Inkl. Geschenk-/Fest-/Haus-Zähler (Migration `003_falukant_family_marriage_buffs.sql`). /// `marriage_public_stability`: Migration `005_falukant_marriage_housepeace.sql`. pub const QUERY_UPDATE_MARRIAGE_STATE_AND_BUFFS: &str = r#" - UPDATE falukant_data.relationship + UPDATE falukant_data.relationship_state SET marriage_satisfaction = $1::smallint, marriage_drift_high = $2::smallint, marriage_drift_low = $3::smallint, - marriage_gift_buff_days_remaining = $4::smallint, - marriage_pending_feast_bonus = $5::smallint, - marriage_no_lover_bonus_counter = $6::smallint, - marriage_public_stability = $7::smallint - WHERE id = $8::int; + marriage_public_stability = $7::smallint, + updated_at = NOW() + WHERE relationship_id = $8::int; "#; /// Persistiert berechneten Hausfrieden (0..100), Migration `005_falukant_marriage_housepeace.sql`. @@ -3713,12 +3667,15 @@ pub const QUERY_GET_USER_HOUSE_ROW_BY_USER: &str = r#" "#; pub const QUERY_MARRIAGE_SUBTRACT_SATISFACTION: &str = r#" - UPDATE falukant_data.relationship r - SET marriage_satisfaction = GREATEST(0, r.marriage_satisfaction - $2::int) - FROM falukant_type.relationship rt + UPDATE falukant_data.relationship_state rs + SET marriage_satisfaction = GREATEST(0, COALESCE(rs.marriage_satisfaction, 55) - $2::int), + updated_at = NOW() + FROM falukant_data.relationship r + JOIN falukant_type.relationship rt ON rt.id = r.relationship_type_id WHERE rt.id = r.relationship_type_id + AND rs.relationship_id = r.id AND rt.tr IN ('married', 'engaged', 'wooing') - AND r.id = $1::int; + AND rs.relationship_id = $1::int; "#; pub const QUERY_RESET_LOVER_UNDERPAY_COUNTERS: &str = r#" @@ -3871,10 +3828,13 @@ pub const QUERY_GET_LOVER_PREGNANCY_CANDIDATES: &str = r#" "#; pub const QUERY_LOVER_BIRTH_PENALTY_MARRIAGE: &str = r#" - UPDATE falukant_data.relationship r - SET marriage_satisfaction = GREATEST(0, r.marriage_satisfaction - 8) - FROM falukant_type.relationship rt + UPDATE falukant_data.relationship_state rs + SET marriage_satisfaction = GREATEST(0, COALESCE(rs.marriage_satisfaction, 55) - 8), + updated_at = NOW() + FROM falukant_data.relationship r + JOIN falukant_type.relationship rt ON rt.id = r.relationship_type_id WHERE rt.id = r.relationship_type_id + AND rs.relationship_id = r.id AND rt.tr IN ('married', 'engaged', 'wooing') AND (r.character1_id = $1::int OR r.character2_id = $1::int); "#;