From ff7338d9d40f73aa00b2f5d46573b4250e5240a4 Mon Sep 17 00:00:00 2001 From: malloc Date: Wed, 2 May 2018 17:03:05 -0500 Subject: [PATCH] flat database the RECKONING --- server/src/db/database.cpp | 129 ++++++++++++++++++++++++++++++++++++- server/src/db/database.hpp | 11 ++-- server/src/utils/time.cpp | 12 ++++ server/src/utils/time.hpp | 2 + 4 files changed, 148 insertions(+), 6 deletions(-) diff --git a/server/src/db/database.cpp b/server/src/db/database.cpp index 5186eb3..bc320df 100644 --- a/server/src/db/database.cpp +++ b/server/src/db/database.cpp @@ -32,6 +32,10 @@ void sosc::db::close_databases() { _ctx.ready = false; } +// ************ // +// QUERY CODE // +// ************ // + sosc::db::Query::Query() : results(this) { this->open = false; } @@ -47,8 +51,9 @@ void sosc::db::Query::SetQuery(const std::string &query, int db) { if(!this->open) this->Close(); + this->database = db == DB_USE_MEMORY ? _ctx.mem_db : _ctx.hard_db; int status = sqlite3_prepare_v2( - db == DB_USE_MEMORY ? _ctx.mem_db : _ctx.hard_db, + this->database, query.c_str(), query.length() + 1, &this->statement, @@ -63,5 +68,127 @@ void sosc::db::Query::NonQuery() { if(!_ctx.ready || !this->open) return; + this->results.Step(); +} +double sosc::db::Query::Scalar() { + if(!_ctx.ready || !this->open) + return 0; + + if(this->results.Step()) + return this->results.Get(0); + else + return 0; +} + +int32_t sosc::db::Query::Scalar() { + if(!_ctx.ready || !this->open) + return 0; + + if(this->results.Step()) + return this->results.Get(0); + else + return 0; +} + +int64_t sosc::db::Query::Scalar() { + if(!_ctx.ready || !this->open) + return 0; + + if(this->results.Step()) + return this->results.Get(0); + else + return 0; +} + +sosc::time sosc::db::Query::Scalar() { + if(!_ctx.ready || !this->open) + return sosc::time::min(); + + if(this->results.Step()) + return this->results.Get(0); + else + return sosc::time::min(); +} + +std::string sosc::db::Query::Scalar(int type) { + if(!_ctx.ready || !this->open) + return ""; + + if(this->results.Step()) + return this->results.Get(0, type); + else + return ""; +} + +sosc::db::ResultSet* sosc::db::Query::GetResults() const { + return &this->results; +} + +void sosc::db::Query::Reset(bool clearBinds) { + if(clearBinds) + sqlite3_clear_bindings(this->statement); + + sqlite3_reset(this->statement); +} + +void sosc::db::Query::Close() { + sqlite3_finalize(this->statement); + this->open = false; +} + +// ***************** // +// RESULT SET CODE // +// ***************** // + +sosc::db::ResultSet::ResultSet(sosc::db::Query *query) { + this->query = query; +} + +bool sosc::db::ResultSet::IsOpen() const { + return this->query->IsOpen(); +} + +bool sosc::db::ResultSet::Step() { + int result = sqlite3_step(this->query->statement); + + if(result == SQLITE_ROW) + return true; + else if(result == SQLITE_DONE) + return false; + else + throw std::string(sqlite3_errmsg(this->query->database)); +} + +double sosc::db::ResultSet::Get(int column) { + return sqlite3_column_double(this->query->statement, column); +} + +int32_t sosc::db::ResultSet::Get(int column) { + return sqlite3_column_int(this->query->statement, column); +} + +int64_t sosc::db::ResultSet::Get(int column) { + return sqlite3_column_int64(this->query->statement, column); +} + +sosc::time sosc::db::ResultSet::Get(int column) { + return clk::from_unix_time( + sqlite3_column_int64(this->query->statement, column) + ); +} + +std::string sosc::db::ResultSet::Get(int column, int type) { + auto data = (const char*) + (type == DB_COL_TEXT + ? sqlite3_column_text(this->query->statement, column) + : sqlite3_column_blob(this->query->statement, column)); + + return std::string( + data, sqlite3_column_bytes(this->query->statement, column) + ); +} + +int sosc::db::ResultSet::ColumnCount() { + return sqlite3_column_count(this->query->statement); } \ No newline at end of file diff --git a/server/src/db/database.hpp b/server/src/db/database.hpp index bd20af6..e7db6b1 100644 --- a/server/src/db/database.hpp +++ b/server/src/db/database.hpp @@ -19,17 +19,17 @@ class Query; class ResultSet { public: bool IsOpen() const; - bool IsReadable() const; bool Step(); template T Get(int column); template T Get(int column, int type); + + int ColumnCount(); private: ResultSet(Query* query); Query* query; - bool readable; friend class Query; }; @@ -58,14 +58,15 @@ public: return this->open; } - void Reset(); + void Reset(bool clearBinds = true); void Close(); private: ResultSet results; sqlite3_stmt* statement; - - std::string query; + sqlite3* database; bool open; + + friend class ResultSet; }; /*double Query::Scalar(); diff --git a/server/src/utils/time.cpp b/server/src/utils/time.cpp index ce4307f..b9e8358 100644 --- a/server/src/utils/time.cpp +++ b/server/src/utils/time.cpp @@ -1,5 +1,17 @@ #include "time.hpp" +sosc::time sosc::clk::from_unix_time(uint64_t unix) { + std::tm raw = std::tm(); + raw.tm_year = 70; + raw.tm_yday = 0; + raw.tm_hour = 0; + raw.tm_min = 0; + raw.tm_sec = 0; + + return sosc::clock::from_time_t(std::mktime(&raw)) + + std::chrono::seconds(unix); +} + std::tm sosc::clk::to_utc(sosc::time time) { time_t ctime = sosc::clock::to_time_t(time); return to_utc(&ctime); diff --git a/server/src/utils/time.hpp b/server/src/utils/time.hpp index d987a3a..8ec2716 100644 --- a/server/src/utils/time.hpp +++ b/server/src/utils/time.hpp @@ -14,6 +14,8 @@ typedef std::chrono::system_clock clock; typedef std::chrono::time_point time; namespace clk { +sosc::time from_unix_time(uint64_t unix); + std::tm to_utc(sosc::time time); std::tm to_utc(const time_t* time);