108 lines
3.6 KiB
C++
108 lines
3.6 KiB
C++
|
#include "Database.h"
|
||
|
#include "BoostLog.h"
|
||
|
#include <sqlite3.h>
|
||
|
#include <sstream>
|
||
|
|
||
|
bool Database::open(const std::string &path) {
|
||
|
bool ret = true;
|
||
|
int result = sqlite3_open(path.c_str(), &m_sqlite3);
|
||
|
if (result != SQLITE_OK) {
|
||
|
ret = false;
|
||
|
LOG(error) << "open database failed.";
|
||
|
}
|
||
|
initialize();
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
static int selectTaskCallback(void *data, int argc, char **argv, char **columnName) {
|
||
|
auto tasks = reinterpret_cast<Tasks *>(data);
|
||
|
Task task;
|
||
|
for (int i = 0; i < argc; i++) {
|
||
|
if (argv[i] == nullptr) continue;
|
||
|
if (strcmp(columnName[i], "id") == 0) {
|
||
|
task.id = std::atol(argv[i]);
|
||
|
} else if (strcmp(columnName[i], "create_time") == 0) {
|
||
|
task.createTime = std::atol(argv[i]);
|
||
|
} else if (strcmp(columnName[i], "content") == 0) {
|
||
|
task.content = argv[i];
|
||
|
} else if (strcmp(columnName[i], "comment") == 0) {
|
||
|
task.comment = argv[i];
|
||
|
} else if (strcmp(columnName[i], "finished") == 0) {
|
||
|
task.finished = std::atol(argv[i]);
|
||
|
}
|
||
|
}
|
||
|
tasks->push_back(task);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
Tasks Database::tasks() {
|
||
|
Tasks ret;
|
||
|
char *error = nullptr;
|
||
|
if (sqlite3_exec(m_sqlite3, "select * from tasks", selectTaskCallback, &ret, &error) != SQLITE_OK) {
|
||
|
LOG(error) << "sqlite3_exec() failed: " << error << std::endl;
|
||
|
sqlite3_free(error);
|
||
|
}
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
bool Database::addTask(uint64_t createTime, const std::string &content, const std::string &comment, bool finished) {
|
||
|
bool ret = true;
|
||
|
std::ostringstream oss;
|
||
|
oss << "INSERT INTO tasks (create_time,content,comment,finished) VALUES (" << createTime << ",\"" << content
|
||
|
<< "\",\"" << comment << "\"," << finished << ");";
|
||
|
auto sql = oss.str();
|
||
|
char *error = nullptr;
|
||
|
int result = sqlite3_exec(m_sqlite3, sql.c_str(), NULL, NULL, &error);
|
||
|
if (result != SQLITE_OK) {
|
||
|
LOG(error) << "add task failed: " << error << ", sql: " << sql;
|
||
|
sqlite3_free(error);
|
||
|
ret = false;
|
||
|
}
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
bool Database::removeTask(int id) {
|
||
|
bool ret = true;
|
||
|
std::ostringstream oss;
|
||
|
oss << "DELETE FROM tasks WHERE id = " << id << ";";
|
||
|
auto sql = oss.str();
|
||
|
char *error = nullptr;
|
||
|
int result = sqlite3_exec(m_sqlite3, sql.c_str(), NULL, NULL, &error);
|
||
|
if (result != SQLITE_OK) {
|
||
|
LOG(error) << "add task failed: " << error << ", sql: " << sql;
|
||
|
sqlite3_free(error);
|
||
|
ret = false;
|
||
|
}
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
void Database::setTaskFinished(int id, bool finished, uint64_t finishedTime) {
|
||
|
std::ostringstream oss;
|
||
|
oss << "UPDATE tasks SET finished = " << finished << ", finished_time = " << finishedTime << " WHERE id = " << id;
|
||
|
auto sql = oss.str();
|
||
|
int result = sqlite3_exec(m_sqlite3, sql.c_str(), NULL, NULL, NULL);
|
||
|
if (result != SQLITE_OK) {
|
||
|
LOG(error) << "add task failed: " << sqlite3_errmsg(m_sqlite3) << ", sql: " << sql;
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void Database::initialize() {
|
||
|
const char *sql =
|
||
|
"CREATE TABLE IF NOT EXISTS tasks (id INTEGER PRIMARY KEY AUTOINCREMENT, create_time INTEGER NOT NULL, "
|
||
|
"parent_id INTEGER, content VARCHAR(512) NOT NULL, comment VARCHAR(512) NOT NULL, finished BOLL, finished_time "
|
||
|
"INTEGER);";
|
||
|
int result = sqlite3_exec(m_sqlite3, sql, NULL, NULL, NULL);
|
||
|
if (result != SQLITE_OK) {
|
||
|
LOG(error) << "Failed to create table: " << sqlite3_errmsg(m_sqlite3);
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Database::~Database() {
|
||
|
if (m_sqlite3 != nullptr) {
|
||
|
sqlite3_close(m_sqlite3);
|
||
|
m_sqlite3 = nullptr;
|
||
|
}
|
||
|
}
|