Files
yourpart3/src/usercharacterworker.h
Torsten Schulz (local) 6a1260687b Implement comprehensive character deletion process in UserCharacterWorker
- Add queries and logic to delete associated data when a character dies, including directors, relationships, child relations, knowledge, debtors prism, political offices, and election candidates.
- Enhance error handling to log issues during the deletion process.
2026-01-14 14:38:42 +01:00

415 lines
13 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#ifndef USERCHARACTERWORKER_H
#define USERCHARACTERWORKER_H
#include "worker.h"
#include <random>
class UserCharacterWorker : public Worker {
public:
UserCharacterWorker(ConnectionPool &pool, MessageBroker &broker);
~UserCharacterWorker() override;
protected:
void run() override;
private:
struct Character {
int id;
int age;
int health;
};
void processCharacterEvents();
void updateCharacterHealth(Character& character);
void updateCharactersMood();
int calculateHealthChange(int age);
void handleCharacterDeath(int characterId);
void recalculateKnowledge();
void processPregnancies();
void handleCredits();
void setHeir(int characterId);
int getFalukantUserId(int characterId);
int getHeirFromChildren(int deceasedCharacterId);
int getRandomHeir(int deceasedCharacterId);
void setNewCharacter(int falukantUserId, int heirCharacterId);
void setNewMoney(int falukantUserId, double newAmount);
double getHouseValue(int falukantUserId);
double getSettlementValue(int falukantUserId);
double getInventoryValue(int falukantUserId);
double getCreditDebt(int falukantUserId);
double getCurrentMoney(int falukantUserId);
double calculateNewMoney(int falukantUserId, bool hasHeir);
int getChildCount(int deceasedUserId);
std::random_device rd;
std::mt19937 gen;
std::uniform_real_distribution<> dist;
bool didRunToday { false };
static constexpr const char *QUERY_GET_USERS_TO_UPDATE = R"(
SELECT "id", CURRENT_DATE - birthdate::date AS age, "health"
FROM "falukant_data"."character"
WHERE "user_id" IS NOT NULL;
)";
static constexpr const char *QUERY_UPDATE_CHARACTERS_HEALTH = R"(
UPDATE "falukant_data"."character"
SET health = $1
WHERE id = $2
)";
static constexpr const char *QUERY_UPDATE_GET_ITEMS_TO_UPDATE = R"(
SELECT id, product_id, producer_id, quantity
FROM falukant_log.production p
WHERE p.production_timestamp::date < current_date
)";
static constexpr const char *QUERY_UPDATE_GET_CHARACTER_IDS = R"(
select fu.id user_id, c.id character_id, c2.id director_id
from falukant_data.falukant_user fu
join falukant_data."character" c
on c.user_id = fu.id
left join falukant_data.director d
on d.employer_user_id = fu.id
left join falukant_data."character" c2
on c2.id = d.director_character_id
where fu.id = $1
)";
static constexpr const char *QUERY_UPDATE_KNOWLEDGE = R"(
update falukant_data.knowledge
set knowledge = least(knowledge + $3, 100)
where character_id = $1
and product_id = $2
)";
static constexpr const char *QUERY_DELETE_LOG_ENTRY = R"(
delete from falukant_log.production
where id = $1
)";
static constexpr char const* QUERY_GET_PREGNANCY_CANDIDATES = R"(
SELECT
r.character1_id AS father_cid,
r.character2_id AS mother_cid,
c1.title_of_nobility,
c1.last_name,
c1.region_id,
fu1.id AS father_uid,
fu2.id AS mother_uid,
-- Durchschnittsalter in Tagen
((NOW()::date - c1.birthdate::date)
+ (NOW()::date - c2.birthdate::date)) / 2 AS avg_age_days,
-- Angepasste Schwangerschaftswahrscheinlichkeit in Prozent
100.0 /
(1
+ EXP(
0.0647 * (
((NOW()::date - c1.birthdate::date)
+ (NOW()::date - c2.birthdate::date)) / 2
)
- 0.0591
)
) AS prob_pct
FROM falukant_data.relationship r
JOIN falukant_type.relationship r2
ON r2.id = r.relationship_type_id
AND r2.tr = 'married'
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_data.falukant_user fu1
ON fu1.id = c1.user_id
LEFT JOIN falukant_data.falukant_user fu2
ON fu2.id = c2.user_id
WHERE random()*100 < (
100.0 /
(1
+ EXP(
0.11166347 * (
((NOW()::date - c1.birthdate::date)
+ (NOW()::date - c2.birthdate::date)) / 2
)
- 2.638267
)
)
) / 2; -- Geburtenrate halbiert
)";
static constexpr char const* QUERY_INSERT_CHILD = R"(
INSERT INTO falukant_data."character" (
user_id,
region_id,
first_name,
last_name,
birthdate,
gender,
title_of_nobility,
mood_id,
created_at,
updated_at
) VALUES (
NULL,
$1::int, -- region_id
/* zufälliger Vorname passend zum Gender */
(
SELECT id
FROM falukant_predefine.firstname
WHERE gender = $2
ORDER BY RANDOM()
LIMIT 1
),
$3::int, -- last_name (Eltern-Nachname)
NOW(),
$2::varchar, -- gender
$4::int, -- title_of_nobility
/* zufällige Stimmung */
(
SELECT id
FROM falukant_type.mood
ORDER BY RANDOM()
LIMIT 1
),
NOW(),
NOW()
)
RETURNING id AS child_cid
)";
static constexpr char const* QUERY_INSERT_CHILD_RELATION = R"(
-- QUERY_INSERT_CHILD_RELATION
INSERT INTO falukant_data.child_relation (
father_character_id,
mother_character_id,
child_character_id,
name_set,
created_at,
updated_at
)
VALUES (
$1::int, -- father_cid
$2::int, -- mother_cid
$3::int, -- child_cid
false,
NOW(), NOW()
)
RETURNING
father_character_id,
-- Vater-User
(SELECT user_id FROM falukant_data."character" WHERE id = father_character_id) AS father_user_id,
mother_character_id,
-- Mutter-User
(SELECT user_id FROM falukant_data."character" WHERE id = mother_character_id) AS mother_user_id,
child_character_id,
-- Kind-User
(SELECT user_id FROM falukant_data."character" WHERE id = child_character_id) AS child_user_id;
)";
static constexpr char const* QUERY_AUTOBATISM = R"(
update falukant_data.child_relation
set name_set = true
where id in (
select cr.id
from falukant_data.child_relation cr
join falukant_data."character" c
on c.id = cr.child_character_id
where cr.name_set = false
and c.birthdate < current_date - interval '5 days'
)
)";
static constexpr char const* QUERY_UPDATE_MOOD = R"(
UPDATE falukant_data."character" AS c
SET mood_id = falukant_data.get_random_mood_id()
WHERE c.health > 0;
)";
static constexpr char const* QUERY_GET_OPEN_CREDITS = R"(
select c.id credit_id, c.amount, c.remaining_amount, c.interest_rate, fu.id user_id, fu."money", c2.id character_id, dp.created_at debitor_prism_start,
dp.created_at::date < current_date prism_started_previously
from falukant_data.credit c
join falukant_data.falukant_user fu
on fu.id = c.id
join falukant_data."character" c2
on c2.user_id = c.falukant_user_id
left join falukant_data.debtors_prism dp
on dp.character_id = c2.id
where c.remaining_amount > 0
and c.updated_at::date < current_date
)";
static constexpr char const* QUERY_UPDATE_CREDIT = R"(
update falukant_data.credit c
set remaining_amount = $1
where falukant_user_id = $2
)";
static constexpr char const* QUERY_CLEANUP_CREDITS = R"(
delete from falukant_data.credit
where remaining_amount >= 0.01
)";
static constexpr char const* QUERY_ADD_CHARACTER_TO_DEBTORS_PRISM = R"(
insert into falukant_data.debtors_prism (character_id) values ($1)
)";
static constexpr const char* QUERY_GET_HEIR = R"(
SELECT child_character_id
FROM falukant_data.child_relation
WHERE father_character_id = $1
OR mother_character_id = $1
ORDER BY (is_heir IS TRUE) DESC,
updated_at DESC
LIMIT 1
)";
static constexpr const char* QUERY_RANDOM_HEIR = R"(
WITH chosen AS (
SELECT
cr.id AS relation_id,
cr.child_character_id
FROM
falukant_data.child_relation AS cr
JOIN
falukant_data."character" AS ch
ON ch.id = cr.child_character_id
WHERE
(cr.father_character_id = $1 OR cr.mother_character_id = $1)
-- gleicher Wohnort wie der Verstorbene
AND ch.region_id = (
SELECT region_id
FROM falukant_data."character"
WHERE id = $1
)
-- nicht älter als 10 Tage
AND ch.birthdate >= NOW() - INTERVAL '10 days'
-- Titel "noncivil"
AND ch.title_of_nobility = (
SELECT id
FROM falukant_type.title
WHERE label_tr = 'noncivil'
)
ORDER BY RANDOM()
LIMIT 1
)
UPDATE
falukant_data.child_relation AS cr2
SET
is_heir = true,
updated_at = NOW()
FROM
chosen
WHERE
cr2.id = chosen.relation_id
RETURNING
chosen.child_character_id
)";
static constexpr const char* QUERY_SET_CHARACTER_USER = R"(
UPDATE falukant_data."character"
SET user_id = $1,
updated_at = NOW()
WHERE id = $2
)";
static constexpr const char* QUERY_UPDATE_USER_MONEY = R"(
UPDATE falukant_data.falukant_user
SET money = $1,
updated_at = NOW()
WHERE user_id = $2
)";
static constexpr const char* QUERY_GET_FALUKANT_USER_ID = R"(
SELECT user_id
FROM falukant_data."character"
WHERE id = $1
LIMIT 1
)";
// SubQueries
static constexpr const char* QUERY_GET_CURRENT_MONEY = R"(
SELECT COALESCE(money,0) AS sum
FROM falukant_data.falukant_user
WHERE user_id = $1
)";
static constexpr const char* QUERY_HOUSE_VALUE = R"(
SELECT COALESCE(SUM(h.cost),0) AS sum
FROM falukant_data.user_house AS uh
JOIN falukant_type.house AS h ON uh.house_type_id = h.id
WHERE uh.user_id = $1
)";
static constexpr const char* QUERY_SETTLEMENT_VALUE = R"(
SELECT COALESCE(SUM(b.base_cost),0) AS sum
FROM falukant_data.branch AS br
JOIN falukant_type.branch AS b ON br.branch_type_id = b.id
WHERE br.falukant_user_id = $1
)";
static constexpr const char* QUERY_INVENTORY_VALUE = R"(
SELECT COALESCE(SUM(i.quantity * p.sell_cost),0) AS sum
FROM falukant_data.inventory AS i
JOIN falukant_type.product AS p ON i.product_id = p.id
JOIN falukant_data.branch AS br ON i.stock_id = br.id
WHERE br.falukant_user_id = $1
)";
static constexpr const char* QUERY_CREDIT_DEBT = R"(
SELECT COALESCE(SUM(remaining_amount),0) AS sum
FROM falukant_data.credit
WHERE falukant_user_id = $1
)";
static constexpr const char* QUERY_COUNT_CHILDREN = R"(
SELECT COUNT(*) AS cnt
FROM falukant_data.child_relation
WHERE father_character_id = $1
OR mother_character_id = $1
)";
// Queries zum Löschen von Character-Verknüpfungen beim Tod
static constexpr const char *QUERY_DELETE_DIRECTOR = R"(
DELETE FROM falukant_data.director
WHERE director_character_id = $1
RETURNING employer_user_id;
)";
static constexpr const char *QUERY_DELETE_RELATIONSHIP = R"(
DELETE FROM falukant_data.relationship
WHERE character1_id = $1
OR character2_id = $1;
)";
static constexpr const char *QUERY_DELETE_CHILD_RELATION = R"(
DELETE FROM falukant_data.child_relation
WHERE child_character_id = $1
OR father_character_id = $1
OR mother_character_id = $1;
)";
static constexpr const char *QUERY_DELETE_KNOWLEDGE = R"(
DELETE FROM falukant_data.knowledge
WHERE character_id = $1;
)";
static constexpr const char *QUERY_DELETE_DEBTORS_PRISM = R"(
DELETE FROM falukant_data.debtors_prism
WHERE character_id = $1;
)";
static constexpr const char *QUERY_DELETE_POLITICAL_OFFICE = R"(
DELETE FROM falukant_data.political_office
WHERE character_id = $1;
)";
static constexpr const char *QUERY_DELETE_ELECTION_CANDIDATE = R"(
DELETE FROM falukant_data.election_candidate
WHERE character_id = $1;
)";
};
#endif // USERCHARACTERWORKER_H