Account getValue and cacheing

This commit is contained in:
Quentin Snow 2023-01-22 17:05:29 -06:00
parent 983f1827e6
commit 3941e43e7f
3 changed files with 74 additions and 1 deletions

View File

@ -11,7 +11,7 @@ bool Database::doesAccountExist(const std::string &account, sqlite3 *db) {
int rc = sqlite3_prepare_v2(db, "SELECT * FROM account WHERE name = ?", -1, &stmt, nullptr); int rc = sqlite3_prepare_v2(db, "SELECT * FROM account WHERE name = ?", -1, &stmt, nullptr);
if (rc != SQLITE_OK) if (rc != SQLITE_OK)
throw std::runtime_error("Failed to create account existing query"); throw std::runtime_error("Failed to prepare account exist query.");
sqlite3_bind_text(stmt, 1, account.c_str(), -1, SQLITE_TRANSIENT); sqlite3_bind_text(stmt, 1, account.c_str(), -1, SQLITE_TRANSIENT);
@ -42,3 +42,67 @@ bool Database::deleteAccount(const std::string &account, sqlite3 *db) {
return (rc == SQLITE_DONE); return (rc == SQLITE_DONE);
} }
double Database::getValue(const std::string &account, sqlite3 *db) {
sqlite3_stmt *stmt;
int rc = sqlite3_prepare_v2(db, "SELECT id, cachedValue FROM account WHERE name = ?", -1, &stmt, nullptr);
if (rc != SQLITE_OK)
throw std::runtime_error("Failed preparing cashedValue " + account);
sqlite3_bind_text(stmt, 1, account.c_str(), -1, SQLITE_TRANSIENT);
rc = sqlite3_step(stmt);
if (rc == SQLITE_ROW) {
double value;
if (sqlite3_column_type(stmt, 1) == SQLITE_NULL) {
value = cacheAccountValue(sqlite3_column_int64(stmt, 0), db);
sqlite3_finalize(stmt);
return value;
}
value = sqlite3_column_double(stmt, 1);
sqlite3_finalize(stmt);
return value;
} else if (rc == SQLITE_DONE)
throw std::runtime_error("Account doesnt exist? Shouldn't be possible in this call.");
else
throw std::runtime_error("Failed to step getValue statement.");
}
double Database::cacheAccountValue(long long accountId, sqlite3 *db) {
sqlite3_stmt *stmt;
int rc = sqlite3_prepare_v2(db, "SELECT SUM(value) FROM ("
"SELECT value * -1 as value FROM payment WHERE accountId = ? "
"UNION ALL "
"SELECT value FROM earning WHERE accountId = ?);", -1, &stmt, nullptr);
if (rc != SQLITE_OK)
throw std::runtime_error("Failed preparing get cashedValue " + std::to_string(accountId));
sqlite3_bind_int64(stmt, 1, accountId);
sqlite3_bind_int64(stmt, 2, accountId);
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 " + std::to_string(accountId));
sqlite3_reset(stmt);
rc = sqlite3_prepare_v2(db, "UPDATE account SET cachedValue = ? WHERE id = ?", -1, &stmt, nullptr);
if (rc != SQLITE_OK)
throw std::runtime_error("Failed preparing set cashedValue " + std::to_string(accountId));
sqlite3_bind_double(stmt, 1, value);
sqlite3_bind_int64(stmt, 2, accountId);
rc = sqlite3_step(stmt);
if (rc == SQLITE_DONE)
return value;
throw std::runtime_error("Failed to set cashedValue for " + std::to_string(accountId));
}

View File

@ -14,6 +14,10 @@ public:
static bool doesAccountExist(const std::string &account, sqlite3 *db); static bool doesAccountExist(const std::string &account, sqlite3 *db);
static bool deleteAccount(const std::string &account, sqlite3 *db); static bool deleteAccount(const std::string &account, sqlite3 *db);
static double getValue(const std::string &account, sqlite3 *db);
static double cacheAccountValue(long long accountId, sqlite3 *db);
}; };

View File

@ -8,6 +8,7 @@
#include "../utilities.h" #include "../utilities.h"
#include <utility> #include <utility>
#include <iostream>
using namespace Budget::OptHandlers; using namespace Budget::OptHandlers;
@ -21,6 +22,10 @@ void AccountOperation::commit() {
return; return;
} }
} }
if (flags.value) {
std::cout << Database::getValue(account, db) << std::endl;
}
} }
AccountOperation::AccountOperation(sqlite3 *db, std::string account) : Operation(db), account(std::move(account)) { AccountOperation::AccountOperation(sqlite3 *db, std::string account) : Operation(db), account(std::move(account)) {