- 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.
415 lines
13 KiB
C++
415 lines
13 KiB
C++
#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
|
||
)";
|
||
|
||
// Sub‐Queries
|
||
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
|