Compare commits
2 Commits
434eaf0ce0
...
d3f3ebac3f
Author | SHA1 | Date | |
---|---|---|---|
d3f3ebac3f | |||
e635d80869 |
3
.idea/dataSources.xml
generated
3
.idea/dataSources.xml
generated
@ -7,6 +7,9 @@
|
||||
<jdbc-driver>org.sqlite.JDBC</jdbc-driver>
|
||||
<jdbc-url>jdbc:sqlite:$USER_HOME$/.local/share/budget/budget.sqlite</jdbc-url>
|
||||
<working-dir>$ProjectFileDir$</working-dir>
|
||||
<driver-properties>
|
||||
<property name="foreign_keys" value="true" />
|
||||
</driver-properties>
|
||||
</data-source>
|
||||
</component>
|
||||
</project>
|
@ -24,7 +24,7 @@ set(HEADERS
|
||||
src/database.h
|
||||
src/exceptions/helpRequested.h
|
||||
src/exceptions/badValue.h
|
||||
src/utilities.h)
|
||||
src/utilities.h src/sqliteDb.h)
|
||||
|
||||
|
||||
add_executable(${PROJECT_NAME} ${SOURCES} ${HEADERS})
|
||||
|
@ -28,7 +28,7 @@ bool Database::doesAccountExist(const std::string &account, sqlite3 *db) {
|
||||
|
||||
}
|
||||
|
||||
bool Database::deleteAccount(const std::string &account, sqlite3 *db) {
|
||||
void Database::deleteAccount(const std::string &account, sqlite3 *db) {
|
||||
sqlite3_stmt *stmt;
|
||||
int rc = sqlite3_prepare_v2(db, "DELETE FROM account WHERE name = ?", -1, &stmt, nullptr);
|
||||
|
||||
@ -39,8 +39,9 @@ bool Database::deleteAccount(const std::string &account, sqlite3 *db) {
|
||||
|
||||
rc = sqlite3_step(stmt);
|
||||
sqlite3_finalize(stmt);
|
||||
|
||||
return (rc == SQLITE_DONE);
|
||||
|
||||
if (rc != SQLITE_DONE)
|
||||
throw std::runtime_error("Failed to delete account " + account);
|
||||
}
|
||||
|
||||
double Database::getValue(const std::string &account, sqlite3 *db) {
|
||||
@ -106,3 +107,20 @@ double Database::cacheAccountValue(long long accountId, sqlite3 *db) {
|
||||
return value;
|
||||
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) {
|
||||
sqlite3_stmt *stmt;
|
||||
int rc = sqlite3_prepare_v2(db, "UPDATE account SET description = ? WHERE name = ?", -1, &stmt, nullptr);
|
||||
|
||||
if (rc != SQLITE_OK)
|
||||
throw std::runtime_error("Failed preparing accountDescription statement");
|
||||
|
||||
sqlite3_bind_text(stmt, 1, description.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_text(stmt, 2, account.c_str(), -1, SQLITE_TRANSIENT);
|
||||
|
||||
rc = sqlite3_step(stmt);
|
||||
sqlite3_finalize(stmt);
|
||||
|
||||
if (rc != SQLITE_DONE)
|
||||
throw std::runtime_error("Failed to set description on " + account);
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ public:
|
||||
*
|
||||
* @throws std::runtime_error If the database query fails
|
||||
*/
|
||||
static bool deleteAccount(const std::string &account, sqlite3 *db);
|
||||
static void deleteAccount(const std::string &account, sqlite3 *db);
|
||||
|
||||
/**
|
||||
* @brief Retrieves the cached value of an account from the database
|
||||
@ -58,6 +58,17 @@ public:
|
||||
* @throws std::runtime_error If the database query fails
|
||||
*/
|
||||
static double cacheAccountValue(long long accountId, sqlite3 *db);
|
||||
|
||||
/**
|
||||
* @brief Sets a new description for an account
|
||||
*
|
||||
* @param account The account name
|
||||
* @param description The new description
|
||||
* @param db The database connection to use
|
||||
*
|
||||
* @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);
|
||||
};
|
||||
|
||||
|
||||
|
11
src/main.cpp
11
src/main.cpp
@ -5,6 +5,7 @@
|
||||
#include "optHandlers/mainOptHandler.h"
|
||||
#include "exceptions/helpRequested.h"
|
||||
#include "exceptions/badValue.h"
|
||||
#include "sqliteDb.h"
|
||||
|
||||
#include <pwd.h>
|
||||
#include <unistd.h>
|
||||
@ -30,12 +31,17 @@ void createRequiredFolders() {
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
sqlite3 *db;
|
||||
SqliteDb dbRAII(db);
|
||||
|
||||
int rc;
|
||||
rc = sqlite3_open(databaseFile.c_str(), &db);
|
||||
|
||||
if (rc != SQLITE_OK) {
|
||||
if (rc != SQLITE_OK)
|
||||
throw std::runtime_error("Error opening database connection.");
|
||||
}
|
||||
|
||||
rc = sqlite3_exec(db, "PRAGMA foreign_keys = 1;", nullptr, nullptr, nullptr);
|
||||
if (rc != SQLITE_OK)
|
||||
throw std::runtime_error("Error enabling foreign_keys. Database might be malformed.");
|
||||
|
||||
std::vector<char *> args(argv, argv + argc);
|
||||
try {
|
||||
@ -54,6 +60,5 @@ int main(int argc, char *argv[]) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
sqlite3_close_v2(db);
|
||||
return 0;
|
||||
}
|
||||
|
@ -26,6 +26,10 @@ void AccountOperation::commit() {
|
||||
if (flags.value) {
|
||||
std::cout << Database::getValue(account, db) << std::endl;
|
||||
}
|
||||
|
||||
if (!flags.description.empty()) {
|
||||
Database::accountDescription(account, flags.description, db);
|
||||
}
|
||||
}
|
||||
|
||||
AccountOperation::AccountOperation(sqlite3 *db, std::string account) : Operation(db), account(std::move(account)) {
|
||||
|
@ -64,13 +64,13 @@ void MainOptHandler::accountOptHandler(std::string account) {
|
||||
{"delete", no_argument, nullptr, 'd'},
|
||||
{"force-delete", no_argument, nullptr, 'F'},
|
||||
{"value", no_argument, nullptr, 'v'},
|
||||
{"description", no_argument, nullptr, 'D'},
|
||||
{"description", required_argument, nullptr, 'D'},
|
||||
};
|
||||
|
||||
auto acctOperation = std::make_unique<AccountOperation>(db, account);
|
||||
|
||||
while (true) {
|
||||
int opt = getopt_long(argv.size(), argv.data(), "ha:c:e:p:dFvD", accountLongOpts, nullptr);
|
||||
int opt = getopt_long(argv.size(), argv.data(), "ha:c:e:p:dFvD:", accountLongOpts, nullptr);
|
||||
if (opt == -1)
|
||||
break;
|
||||
|
||||
@ -238,7 +238,7 @@ void MainOptHandler::paymentOptHandler(std::string account) {
|
||||
auto payOperation = std::make_unique<PaymentOperation>(db, account);
|
||||
|
||||
while (true) {
|
||||
int opt = getopt_long(argv.size(), argv.data(), "ha:c:e:p:v:d:r:D", paymentLongOpts, nullptr);
|
||||
int opt = getopt_long(argv.size(), argv.data(), "ha:c:e:p:v:d:r:D:", paymentLongOpts, nullptr);
|
||||
if (opt == -1)
|
||||
break;
|
||||
|
||||
|
24
src/sqliteDb.h
Normal file
24
src/sqliteDb.h
Normal file
@ -0,0 +1,24 @@
|
||||
//
|
||||
// Created by quentin on 1/22/23.
|
||||
//
|
||||
|
||||
#ifndef BUDGET_SQLITEDB_H
|
||||
#define BUDGET_SQLITEDB_H
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
class SqliteDb {
|
||||
public:
|
||||
explicit SqliteDb(sqlite3* db) : m_db(db) {}
|
||||
|
||||
~SqliteDb() {
|
||||
sqlite3_close(m_db);
|
||||
}
|
||||
explicit operator sqlite3*() {
|
||||
return m_db;
|
||||
}
|
||||
private:
|
||||
sqlite3* m_db;
|
||||
};
|
||||
|
||||
#endif //BUDGET_SQLITEDB_H
|
Loading…
x
Reference in New Issue
Block a user