Compare commits
3 Commits
d3f3ebac3f
...
c610a0572c
Author | SHA1 | Date | |
---|---|---|---|
c610a0572c | |||
2c3436ee94 | |||
5a88299f9e |
@ -39,7 +39,7 @@ void Database::deleteAccount(const std::string &account, sqlite3 *db) {
|
|||||||
|
|
||||||
rc = sqlite3_step(stmt);
|
rc = sqlite3_step(stmt);
|
||||||
sqlite3_finalize(stmt);
|
sqlite3_finalize(stmt);
|
||||||
|
|
||||||
if (rc != SQLITE_DONE)
|
if (rc != SQLITE_DONE)
|
||||||
throw std::runtime_error("Failed to delete account " + account);
|
throw std::runtime_error("Failed to delete account " + account);
|
||||||
}
|
}
|
||||||
@ -108,7 +108,7 @@ 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));
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
@ -124,3 +124,58 @@ void Database::accountDescription(const std::string& account, const std::string&
|
|||||||
if (rc != SQLITE_DONE)
|
if (rc != SQLITE_DONE)
|
||||||
throw std::runtime_error("Failed to set description on " + account);
|
throw std::runtime_error("Failed to set description on " + account);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Database::createAccount(const std::string &account, const std::string &description, sqlite3 *db) {
|
||||||
|
sqlite3_stmt *stmt;
|
||||||
|
int rc = sqlite3_prepare_v2(db, "INSERT INTO account (name, description) VALUES (?, ?)", -1, &stmt, nullptr);
|
||||||
|
|
||||||
|
if (rc != SQLITE_OK)
|
||||||
|
throw std::runtime_error("Failed preparing createAccount statement");
|
||||||
|
|
||||||
|
sqlite3_bind_text(stmt, 1, account.c_str(), -1, SQLITE_TRANSIENT);
|
||||||
|
sqlite3_bind_text(stmt, 2, description.c_str(), -1, SQLITE_TRANSIENT);
|
||||||
|
|
||||||
|
rc = sqlite3_step(stmt);
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
|
||||||
|
if (rc != SQLITE_DONE)
|
||||||
|
throw std::runtime_error("Failed to create account " + account);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Database::createAccount(const std::string &account, sqlite3 *db) {
|
||||||
|
sqlite3_stmt *stmt;
|
||||||
|
int rc = sqlite3_prepare_v2(db, "INSERT INTO account (name) VALUES (?)", -1, &stmt, nullptr);
|
||||||
|
|
||||||
|
if (rc != SQLITE_OK)
|
||||||
|
throw std::runtime_error("Failed preparing createAccount statement");
|
||||||
|
|
||||||
|
sqlite3_bind_text(stmt, 1, account.c_str(), -1, SQLITE_TRANSIENT);
|
||||||
|
|
||||||
|
rc = sqlite3_step(stmt);
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
|
||||||
|
if (rc != SQLITE_DONE)
|
||||||
|
throw std::runtime_error("Failed to create account " + account);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Database::earn(const std::string &account, long double &value, std::string &description, std::string &receipt,
|
||||||
|
long long date, sqlite3 *db) {
|
||||||
|
sqlite3_stmt *stmt;
|
||||||
|
int rc = sqlite3_prepare_v2(db, "INSERT INTO earning (value, description, receipt, accountId, date) VALUES "
|
||||||
|
"(?, ?, ?, (SELECT id FROM account WHERE name = ?), ?)", -1, &stmt, nullptr);
|
||||||
|
|
||||||
|
if (rc != SQLITE_OK)
|
||||||
|
throw std::runtime_error("Failed preparing earn statement");
|
||||||
|
|
||||||
|
sqlite3_bind_double(stmt, 1, value);
|
||||||
|
sqlite3_bind_text(stmt, 2, (description.empty() ? nullptr : description.c_str()), -1, SQLITE_TRANSIENT);
|
||||||
|
sqlite3_bind_text(stmt, 3, (receipt.empty() ? nullptr : receipt.c_str()), -1, SQLITE_TRANSIENT);
|
||||||
|
sqlite3_bind_text(stmt, 4, (account.empty() ? nullptr : account.c_str()), -1, SQLITE_TRANSIENT);
|
||||||
|
sqlite3_bind_int64(stmt, 5, date);
|
||||||
|
|
||||||
|
rc = sqlite3_step(stmt);
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
|
||||||
|
if (rc != SQLITE_DONE)
|
||||||
|
throw std::runtime_error("Failed to create earning");
|
||||||
|
}
|
||||||
|
@ -68,7 +68,47 @@ public:
|
|||||||
*
|
*
|
||||||
* @throws std::runtime_error If the statement fails to prepare or the step fails to execute
|
* @throws std::runtime_error If the statement fails to prepare or the step fails to execute
|
||||||
*/
|
*/
|
||||||
static void accountDescription(const std::string& account, const std::string& description, sqlite3 *db);
|
static void accountDescription(const std::string &account, const std::string &description, sqlite3 *db);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Creates a new account in the database with the given name and description
|
||||||
|
*
|
||||||
|
* @param account The name of the account to create
|
||||||
|
* @param description The description of the account to create
|
||||||
|
* @param db The sqlite3 database connection to use
|
||||||
|
*
|
||||||
|
* @throws std::runtime_error If the account could not be created in the database
|
||||||
|
*/
|
||||||
|
static void createAccount(const std::string &account, const std::string &description, sqlite3 *db);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Creates a new account in the database with the given name
|
||||||
|
*
|
||||||
|
* @param account The name of the account to create
|
||||||
|
* @param db The sqlite3 database connection to use
|
||||||
|
*
|
||||||
|
* @throws std::runtime_error If the account could not be created in the database
|
||||||
|
*/
|
||||||
|
static void createAccount(const std::string &account, sqlite3 *db);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The function records an earning in the database
|
||||||
|
*
|
||||||
|
* @param account The name of the account to record the earning in
|
||||||
|
* @param value The value of the earning
|
||||||
|
* @param description A description of the earning, can be an empty string
|
||||||
|
* @param receipt A receipt of the earning, can be an empty string
|
||||||
|
* @param date The date of the earning in UNIX time
|
||||||
|
* @param db The sqlite3 database connection
|
||||||
|
*
|
||||||
|
* This function records an earning in the database by inserting a new row in the 'earning' table with the provided information.
|
||||||
|
* The accountId is retrieved from the 'account' table using the provided account name.
|
||||||
|
* If the query fails to prepare or execute, the function throws a runtime_error.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
earn(const std::string &account, long double &value, std::string &description, std::string &receipt,
|
||||||
|
long long int date,
|
||||||
|
sqlite3 *db);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -10,6 +10,4 @@ void PaymentOperation::commit() {
|
|||||||
//TODO This function will be called when the action needs to be done
|
//TODO This function will be called when the action needs to be done
|
||||||
}
|
}
|
||||||
|
|
||||||
PaymentOperation::PaymentOperation(sqlite3 *db, std::string account) : Operation(db), account(std::move(account)) {
|
PaymentOperation::PaymentOperation(sqlite3 *db, std::string account) : Operation(db), account(std::move(account)) {}
|
||||||
|
|
||||||
}
|
|
@ -32,6 +32,4 @@ void AccountOperation::commit() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)) {}
|
||||||
|
|
||||||
}
|
|
||||||
|
@ -3,13 +3,20 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include "createOperation.h"
|
#include "createOperation.h"
|
||||||
|
#include "../database.h"
|
||||||
|
#include "../exceptions/badValue.h"
|
||||||
|
|
||||||
using namespace Budget::OptHandlers;
|
using namespace Budget::OptHandlers;
|
||||||
|
|
||||||
void CreateOperation::commit() {
|
void CreateOperation::commit() {
|
||||||
//TODO This function will be called when the action needs to be done
|
if (Database::doesAccountExist(account, db)) {
|
||||||
|
throw Budget::Exceptions::BadValue("Account already exists, cant create " + account);
|
||||||
|
}
|
||||||
|
if (flags.description.empty()) {
|
||||||
|
Database::createAccount(account, db);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Database::createAccount(account, flags.description, db);
|
||||||
}
|
}
|
||||||
|
|
||||||
CreateOperation::CreateOperation(sqlite3 *db, std::string account) : Operation(db), account(std::move(account)) {
|
CreateOperation::CreateOperation(sqlite3 *db, std::string account) : Operation(db), account(std::move(account)) {}
|
||||||
|
|
||||||
}
|
|
||||||
|
@ -3,13 +3,16 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include "earnOperation.h"
|
#include "earnOperation.h"
|
||||||
|
#include "../database.h"
|
||||||
|
#include "../exceptions/badValue.h"
|
||||||
|
|
||||||
using namespace Budget::OptHandlers;
|
using namespace Budget::OptHandlers;
|
||||||
|
|
||||||
void EarnOperation::commit() {
|
void EarnOperation::commit() {
|
||||||
//TODO This function will be called when the action needs to be done
|
if (!Database::doesAccountExist(account, db))
|
||||||
|
throw Budget::Exceptions::BadValue("Account " + account + " doesn't exist");
|
||||||
|
|
||||||
|
Database::earn(account, flags.value, flags.description, flags.receipt, flags.date, db);
|
||||||
}
|
}
|
||||||
|
|
||||||
EarnOperation::EarnOperation(sqlite3 *db, std::string account) : Operation(db), account(std::move(account)) {
|
EarnOperation::EarnOperation(sqlite3 *db, std::string account) : Operation(db), account(std::move(account)) {}
|
||||||
|
|
||||||
}
|
|
@ -64,7 +64,7 @@ void MainOptHandler::accountOptHandler(std::string account) {
|
|||||||
{"delete", no_argument, nullptr, 'd'},
|
{"delete", no_argument, nullptr, 'd'},
|
||||||
{"force-delete", no_argument, nullptr, 'F'},
|
{"force-delete", no_argument, nullptr, 'F'},
|
||||||
{"value", no_argument, nullptr, 'v'},
|
{"value", no_argument, nullptr, 'v'},
|
||||||
{"description", required_argument, nullptr, 'D'},
|
{"description", required_argument, nullptr, 'D'},
|
||||||
};
|
};
|
||||||
|
|
||||||
auto acctOperation = std::make_unique<AccountOperation>(db, account);
|
auto acctOperation = std::make_unique<AccountOperation>(db, account);
|
||||||
@ -293,40 +293,39 @@ void MainOptHandler::paymentOptHandler(std::string account) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MainOptHandler::help() {
|
void MainOptHandler::help() {
|
||||||
std::cout << "Output of budget." << std::endl;
|
std::cout << "Output of budget.\n"
|
||||||
std::cout << "Usage:" << std::endl;
|
"Usage:\n"
|
||||||
std::cout << "\tbudget <action> [options] ..." << std::endl;
|
" budget <action> [options] ...\n"
|
||||||
std::cout << "Actions:" << std::endl;
|
"Actions:\n"
|
||||||
std::cout << "\t-h --help Prints this." << std::endl;
|
" -h --help Prints this.\n"
|
||||||
std::cout << "\t-a --account<=STRING> Management tools for an account." << std::endl;
|
" -a --account<=STRING> Management tools for an account.\n"
|
||||||
std::cout << "\t-c --create<=STRING> Creates a new account with NAME." << std::endl;
|
" -c --create<=STRING> Creates a new account with NAME.\n"
|
||||||
std::cout << "\t-e --earn<=STRING> Add an earning to an account." << std::endl;
|
" -e --earn<=STRING> Add an earning to an account.\n"
|
||||||
std::cout << "\t-p --payment<=STRING> Add a payment to an account." << std::endl;
|
" -p --payment<=STRING> Add a payment to an account.\n"
|
||||||
std::cout << "Account Options: [-dvD]" << std::endl;
|
"Account Options: [-dvD]\n"
|
||||||
std::cout << "\t-d --delete Deletes specified account." << std::endl;
|
" -d --delete Deletes specified account.\n"
|
||||||
std::cout << "\t--force-delete Deletes the specified account without confirmation." << std::endl;
|
" --force-delete Deletes the specified account without confirmation.\n"
|
||||||
std::cout << "\t-v --value Gets the current value of the account." << std::endl;
|
" -v --value Gets the current value of the account.\n"
|
||||||
std::cout << "\t-D --description<=STRING> Changes the description of the account." << std::endl;
|
" -D --description<=STRING> Changes the description of the account.\n"
|
||||||
std::cout << "Create Options: [-d]" << std::endl;
|
"Create Options: [-d]\n"
|
||||||
std::cout << "\t-d --description<=STRING> Sets a description for an account." << std::endl;
|
" -d --description<=STRING> Sets a description for an account.\n"
|
||||||
std::cout << "Earn Options: -v [-drD]" << std::endl;
|
"Earn Options: -v [-drD]\n"
|
||||||
std::cout << "\t-v --value=<FlOAT> Value for earning." << std::endl;
|
" -v --value=<FlOAT> Value for earning.\n"
|
||||||
std::cout << "\t-d --description=<STRING> Description for earning." << std::endl;
|
" -d --description=<STRING> Description for earning.\n"
|
||||||
std::cout << "\t-r --receipt=<PATH> Path to file to store in DB as receipt." << std::endl;
|
" -r --receipt=<PATH> Path to file to store in DB as receipt.\n"
|
||||||
std::cout << "\t-D --date=<mm/dd/yyyyTHH:MM:SS> Date as dd/mm/yyyyTHH:MM:SS. Default will be today." << std::endl;
|
" -D --date=<mm/dd/yyyyTHH:MM:SS> Date as dd/mm/yyyyTHH:MM:SS. Default will be today.\n"
|
||||||
std::cout << "Payment Options: -v [-drD]" << std::endl;
|
"Payment Options: -v [-drD]\n"
|
||||||
std::cout << "\t-v --value=<FlOAT> Value for payment." << std::endl;
|
" -v --value=<FlOAT> Value for payment.\n"
|
||||||
std::cout << "\t-d --description=<STRING> Description for payment." << std::endl;
|
" -d --description=<STRING> Description for payment.\n"
|
||||||
std::cout << "\t-r --receipt=<PATH> Path to file to store in DB as receipt." << std::endl;
|
" -r --receipt=<PATH> Path to file to store in DB as receipt.\n"
|
||||||
std::cout << "\t-D --date=<mm/dd/yyyyTHH:MM:SS> Date as dd/mm/yyyyTHH:MM:SS. Default will be today." << std::endl;
|
" -D --date=<mm/dd/yyyyTHH:MM:SS> Date as dd/mm/yyyyTHH:MM:SS. Default will be today.\n"
|
||||||
std::cout << std::endl;
|
"\n"
|
||||||
std::cout << "Arguments are processed like blocks with each one terminated by the next Action. For example"
|
"Arguments are processed like blocks with each one terminated by the next Action. For example\n"
|
||||||
<< std::endl;
|
"\n"
|
||||||
std::cout << std::endl;
|
"budget -cAcct -eAcct -v10.00 -r\"./receipt.pdf\" -pAcct -v5.50 -r\"./payment.pdf\"\n"
|
||||||
std::cout << R"(budget -cAcct -eAcct -v10.00 -r"./receipt.pdf" -pAcct -v5.50 -r"./payment.pdf")" << std::endl;
|
"\n"
|
||||||
std::cout << std::endl;
|
"Does the following in order:\n"
|
||||||
std::cout << "Does the following in order:" << std::endl;
|
"Creates an account named Acct with no description.\n"
|
||||||
std::cout << "Creates an account named Acct with no description." << std::endl;
|
"Earns 10.00 to it with a receipt.\n"
|
||||||
std::cout << "Earns 10.00 to it with a receipt." << std::endl;
|
"Pays 5.50 to it with a receipt." << std::endl;
|
||||||
std::cout << "Pays 5.50 to it with a receipt." << std::endl;
|
|
||||||
}
|
}
|
||||||
|
@ -9,16 +9,18 @@
|
|||||||
|
|
||||||
class SqliteDb {
|
class SqliteDb {
|
||||||
public:
|
public:
|
||||||
explicit SqliteDb(sqlite3* db) : m_db(db) {}
|
explicit SqliteDb(sqlite3 *db) : m_db(db) {}
|
||||||
|
|
||||||
~SqliteDb() {
|
~SqliteDb() {
|
||||||
sqlite3_close(m_db);
|
sqlite3_close(m_db);
|
||||||
}
|
}
|
||||||
explicit operator sqlite3*() {
|
|
||||||
|
explicit operator sqlite3 *() {
|
||||||
return m_db;
|
return m_db;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
sqlite3* m_db;
|
sqlite3 *m_db;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //BUDGET_SQLITEDB_H
|
#endif //BUDGET_SQLITEDB_H
|
||||||
|
Loading…
x
Reference in New Issue
Block a user