Earn and pay now recache value for account

This commit is contained in:
Quentin Snow 2023-01-28 12:05:35 -06:00
parent b02994d041
commit 30290fc317
2 changed files with 55 additions and 1 deletions

View File

@ -108,6 +108,45 @@ double Database::cacheAccountValue(long long accountId, sqlite3 *db) {
throw std::runtime_error("Failed to set cashedValue for " + std::to_string(accountId)); throw std::runtime_error("Failed to set cashedValue for " + std::to_string(accountId));
} }
double Database::cacheAccountValue(const std::string &account, sqlite3 *db) {
sqlite3_stmt *stmt;
int rc = sqlite3_prepare_v2(db, "SELECT SUM(value) FROM ("
"SELECT value * -1 as value FROM payment WHERE "
"(SELECT id FROM account where name = ?) "
"UNION ALL "
"SELECT value FROM earning WHERE "
"(SELECT id FROM account where name = ?));", -1, &stmt, nullptr);
if (rc != SQLITE_OK)
throw std::runtime_error("Failed preparing get cashedValue " + account);
sqlite3_bind_text(stmt, 1, account.c_str(), -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 2, account.c_str(), -1, SQLITE_TRANSIENT);
rc = sqlite3_step(stmt);
double value;
if (rc == SQLITE_ROW)
value = sqlite3_column_double(stmt, 0);
else if (rc == SQLITE_DONE)
value = 0;
else
throw std::runtime_error("Failed get cashedValue " + account);
sqlite3_reset(stmt);
rc = sqlite3_prepare_v2(db, "UPDATE account SET cachedValue = ? WHERE name = ?", -1, &stmt, nullptr);
if (rc != SQLITE_OK)
throw std::runtime_error("Failed preparing set cashedValue " + account);
sqlite3_bind_double(stmt, 1, value);
sqlite3_bind_text(stmt, 2, account.c_str(), -1, SQLITE_TRANSIENT);
rc = sqlite3_step(stmt);
if (rc == SQLITE_DONE)
return value;
throw std::runtime_error("Failed to set cashedValue for " + account);
}
void Database::accountDescription(const std::string &account, const std::string &description, sqlite3 *db) { void Database::accountDescription(const std::string &account, const std::string &description, sqlite3 *db) {
sqlite3_stmt *stmt; sqlite3_stmt *stmt;
int rc = sqlite3_prepare_v2(db, "UPDATE account SET description = ? WHERE name = ?", -1, &stmt, nullptr); int rc = sqlite3_prepare_v2(db, "UPDATE account SET description = ? WHERE name = ?", -1, &stmt, nullptr);
@ -162,7 +201,8 @@ void Database::earn(const std::string &account, long double &value, std::string
long long date, sqlite3 *db) { long long date, sqlite3 *db) {
sqlite3_stmt *stmt; sqlite3_stmt *stmt;
int rc = sqlite3_prepare_v2(db, "INSERT INTO earning (value, description, receipt, accountId, date) VALUES " int rc = sqlite3_prepare_v2(db, "INSERT INTO earning (value, description, receipt, accountId, date) VALUES "
"(?, ?, ?, (SELECT id FROM account WHERE name = ?), ?)", -1, &stmt, nullptr); "(?, ?, ?, (SELECT id FROM account WHERE name = ?), ?);"
"SELECT cachedValue FROM account WHERE name = ?;", -1, &stmt, nullptr);
if (rc != SQLITE_OK) if (rc != SQLITE_OK)
throw std::runtime_error("Failed preparing earn statement"); throw std::runtime_error("Failed preparing earn statement");
@ -178,6 +218,7 @@ void Database::earn(const std::string &account, long double &value, std::string
if (rc != SQLITE_DONE) if (rc != SQLITE_DONE)
throw std::runtime_error("Failed to create earning"); throw std::runtime_error("Failed to create earning");
cacheAccountValue(account, db);
} }
void Database::pay(const std::string &account, long double &value, std::string &description, std::string &receipt, void Database::pay(const std::string &account, long double &value, std::string &description, std::string &receipt,
@ -200,4 +241,5 @@ void Database::pay(const std::string &account, long double &value, std::string &
if (rc != SQLITE_DONE) if (rc != SQLITE_DONE)
throw std::runtime_error("Failed to create payment"); throw std::runtime_error("Failed to create payment");
cacheAccountValue(account, db);
} }

View File

@ -59,6 +59,18 @@ public:
*/ */
static double cacheAccountValue(long long accountId, sqlite3 *db); static double cacheAccountValue(long long accountId, sqlite3 *db);
/**
* @brief Caches the value of an account by calculating the sum of all payments and earnings
*
* @param account The name of the account to cache the value of
* @param db The database connection to use
*
* @return The cached value of the account
*
* @throws std::runtime_error If the database query fails
*/
static double cacheAccountValue(const std::string &account, sqlite3 *db);
/** /**
* @brief Sets a new description for an account * @brief Sets a new description for an account
* *