diff --git a/server/src/db/database.cpp b/server/src/db/database.cpp index 8761fc8..941fc85 100644 --- a/server/src/db/database.cpp +++ b/server/src/db/database.cpp @@ -8,17 +8,21 @@ static struct { sqlite3* hard_db; } _ctx; -void sosc::db::init_databases() { +bool sosc::db::init_databases(std::string* error) { if(_ctx.ready) - return; + return true; sqlite3_open(":memory:", &_ctx.mem_db); sqlite3_exec(_ctx.mem_db, _mem_db_sql, nullptr, nullptr, nullptr); sqlite3_open("scape.db", &_ctx.hard_db); - db::Query query("SELECT * FROM MIGRATIONS ORDER BY ID ASC"); - auto results = query.GetResults(); - //while() + int32_t result = db::Query::ScalarInt32("SELECT MAX(ID) FROM MIGRATIONS"); + if(result > _hard_db_sql.size()) { + *error = "HARD DB: RECORDED MIGRATION COUNT TOO HIGH"; + return false; + } + + _ctx.ready = true; } @@ -64,37 +68,36 @@ void sosc::db::Query::SetQuery(const std::string &query, int db) { this->open = true; } -void sosc::db::Query::Bind(double value, int i) { +void sosc::db::Query::BindDouble(double value, int i) { sqlite3_bind_double(this->statement, i, value); } -void sosc::db::Query::Bind(int32_t value, int i) { +void sosc::db::Query::BindInt32(int32_t value, int i) { sqlite3_bind_int(this->statement, i, value); } -void sosc::db::Query::Bind(int64_t value, int i) { +void sosc::db::Query::BindInt64(int64_t value, int i) { sqlite3_bind_int64(this->statement, i, value); } -void sosc::db::Query::Bind(sosc::time value, int i) { +void sosc::db::Query::BindTime(sosc::time value, int i) { sqlite3_bind_int64(this->statement, i, clk::to_unix_time(value)); } -void sosc::db::Query::Bind - (const std::string& value, int i, int type) -{ - if(type == DB_COL_TEXT) - sqlite3_bind_text( - this->statement, i, - value.c_str(), -1, - SQLITE_TRANSIENT - ); - else - sqlite3_bind_blob( - this->statement, i, - value.c_str(), value.length(), - SQLITE_TRANSIENT - ); +void sosc::db::Query::BindText(const std::string& value, int i) { + sqlite3_bind_text( + this->statement, i, + value.c_str(), -1, + SQLITE_TRANSIENT + ); +} + +void sosc::db::Query::BindBlob(const std::string& value, int i) { + sqlite3_bind_blob( + this->statement, i, + value.c_str(), value.length(), + SQLITE_TRANSIENT + ); } void sosc::db::Query::NonQuery() { @@ -104,57 +107,142 @@ void sosc::db::Query::NonQuery() { this->results.Step(); } -double sosc::db::Query::Scalar() { +void sosc::db::Query::NonQuery(const std::string &query) { + if(!_ctx.ready) + return; + + Query q(query); + q.NonQuery(); + q.Close(); +} + +double sosc::db::Query::ScalarDouble() { if(!_ctx.ready || !this->open) return 0; if(this->results.Step()) - return this->results.Get(0); + return this->results.GetDouble(0); else return 0; } -int32_t sosc::db::Query::Scalar() { +int32_t sosc::db::Query::ScalarInt32() { if(!_ctx.ready || !this->open) return 0; if(this->results.Step()) - return this->results.Get(0); + return this->results.GetInt32(0); else return 0; } -int64_t sosc::db::Query::Scalar() { +int64_t sosc::db::Query::ScalarInt64() { if(!_ctx.ready || !this->open) return 0; if(this->results.Step()) - return this->results.Get(0); + return this->results.GetInt64(0); else return 0; } -sosc::time sosc::db::Query::Scalar() { +sosc::time sosc::db::Query::ScalarTime() { if(!_ctx.ready || !this->open) return sosc::time::min(); if(this->results.Step()) - return this->results.Get(0); + return this->results.GetTime(0); else return sosc::time::min(); } -std::string sosc::db::Query::Scalar(int type) { +std::string sosc::db::Query::ScalarText() { if(!_ctx.ready || !this->open) return ""; if(this->results.Step()) - return this->results.Get(0, type); + return this->results.GetText(0); else return ""; } -sosc::db::ResultSet* sosc::db::Query::GetResults() const { +std::string sosc::db::Query::ScalarBlob() { + if(!_ctx.ready || !this->open) + return ""; + + if(this->results.Step()) + return this->results.GetBlob(0); + else + return ""; +} + +double sosc::db::Query::ScalarDouble(const std::string &query) { + if(!_ctx.ready) + return 0; + + Query q(query); + double result = q.ScalarDouble(); + q.Close(); + + return result; +} + +int32_t sosc::db::Query::ScalarInt32(const std::string &query) { + if(!_ctx.ready) + return 0; + + Query q(query); + int32_t result = q.ScalarInt32(); + q.Close(); + + return result; +} + +int64_t sosc::db::Query::ScalarInt64(const std::string &query) { + if(!_ctx.ready) + return 0; + + Query q(query); + int64_t result = q.ScalarInt64(); + q.Close(); + + return result; +} + +sosc::time sosc::db::Query::ScalarTime(const std::string &query) { + if(!_ctx.ready) + return sosc::time::min(); + + Query q(query); + sosc::time result = q.ScalarTime(); + q.Close(); + + return result; +} + +std::string sosc::db::Query::ScalarText(const std::string &query) { + if(!_ctx.ready) + return ""; + + Query q(query); + std::string result = q.ScalarText(); + q.Close(); + + return result; +} + +std::string sosc::db::Query::ScalarBlob(const std::string &query) { + if(!_ctx.ready) + return ""; + + Query q(query); + std::string result = q.ScalarBlob(); + q.Close(); + + return result; +} + +sosc::db::ResultSet* sosc::db::Query::GetResults() { return &this->results; } @@ -193,29 +281,36 @@ bool sosc::db::ResultSet::Step() { throw std::string(sqlite3_errmsg(this->query->database)); } -double sosc::db::ResultSet::Get(int column) { +double sosc::db::ResultSet::GetDouble(int column) { return sqlite3_column_double(this->query->statement, column); } -int32_t sosc::db::ResultSet::Get(int column) { +int32_t sosc::db::ResultSet::GetInt32(int column) { return sqlite3_column_int(this->query->statement, column); } -int64_t sosc::db::ResultSet::Get(int column) { +int64_t sosc::db::ResultSet::GetInt64(int column) { return sqlite3_column_int64(this->query->statement, column); } -sosc::time sosc::db::ResultSet::Get(int column) { +sosc::time sosc::db::ResultSet::GetTime(int column) { return clk::from_unix_time( sqlite3_column_int64(this->query->statement, column) ); } -std::string sosc::db::ResultSet::Get(int column, int type) { +std::string sosc::db::ResultSet::GetText(int column) { auto data = (const char*) - (type == DB_COL_TEXT - ? sqlite3_column_text(this->query->statement, column) - : sqlite3_column_blob(this->query->statement, column)); + sqlite3_column_text(this->query->statement, column); + + return std::string( + data, sqlite3_column_bytes(this->query->statement, column) + ); +} + +std::string sosc::db::ResultSet::GetBlob(int column) { + auto data = (const char*) + sqlite3_column_blob(this->query->statement, column); return std::string( data, sqlite3_column_bytes(this->query->statement, column) diff --git a/server/src/db/database.hpp b/server/src/db/database.hpp index 871c0d3..3195a41 100644 --- a/server/src/db/database.hpp +++ b/server/src/db/database.hpp @@ -3,6 +3,7 @@ #include "sqlite/sqlite3.h" #include "../utils/time.hpp" +#include "../crypto/sha1.hpp" #include #include @@ -14,6 +15,7 @@ namespace sosc { namespace db { + class Query; class ResultSet { @@ -21,10 +23,12 @@ public: bool IsOpen() const; bool Step(); - template - T Get(int column); - template - T Get(int column, int type); + double GetDouble(int column); + int32_t GetInt32(int column); + int64_t GetInt64(int column); + sosc::time GetTime(int column); + std::string GetText(int column); + std::string GetBlob(int column); int ColumnCount(); private: @@ -34,33 +38,37 @@ private: friend class Query; }; -/* -template<> double ResultSet::Get(int column); -template<> int32_t ResultSet::Get(int column); -template<> int64_t ResultSet::Get(int column); -template<> sosc::time ResultSet::Get(int column); -template<> std::string ResultSet::Get(int column, int type); - */ - class Query { public: Query(); Query(const std::string& query, int db = DB_USE_HARD); void SetQuery(const std::string& query, int db = DB_USE_HARD); - template - void Bind(T value, int i); - template - void Bind(const T& value, int i, int type); + void BindDouble(double value, int i); + void BindInt32(int32_t value, int i); + void BindInt64(int64_t value, int i); + void BindTime(sosc::time value, int i); + void BindText(const std::string& value, int i); + void BindBlob(const std::string& value, int i); void NonQuery(); + static void NonQuery(const std::string& query); - template - T Scalar(); - template - T Scalar(int type); + double ScalarDouble(); + int32_t ScalarInt32(); + int64_t ScalarInt64(); + sosc::time ScalarTime(); + std::string ScalarText(); + std::string ScalarBlob(); - ResultSet* GetResults() const; + static double ScalarDouble(const std::string& query); + static int32_t ScalarInt32(const std::string& query); + static int64_t ScalarInt64(const std::string& query); + static sosc::time ScalarTime(const std::string& query); + static std::string ScalarText(const std::string& query); + static std::string ScalarBlob(const std::string& query); + + ResultSet* GetResults(); inline bool IsOpen() const { return this->open; } @@ -76,24 +84,9 @@ private: friend class ResultSet; }; -/* -template<> void Query::Bind(double value, int i); -template<> void Query::Bind(int32_t value, int i); -template<> void Query::Bind(int64_t value, int i); -template<> void Query::Bind(sosc::time value, int i); -template<> std::string Query::Bind - (const std::string& value, int i, int type); - -template<> double Query::Scalar(); -template<> int32_t Query::Scalar(); -template<> int64_t Query::Scalar(); -template<> sosc::time Query::Scalar(); -template<> std::string Query::Scalar(int type); -*/ - // THE FOLLOWING ARE NOT THREAD SAFE !! // CALL THEM ONLY WHEN MASTER POOL IS INACTIVE -void init_databases(); +bool init_databases(std::string* error); void close_databases(); }} diff --git a/server/src/sock/packet.cpp b/server/src/sock/packet.cpp index dc50704..0170f73 100644 --- a/server/src/sock/packet.cpp +++ b/server/src/sock/packet.cpp @@ -20,9 +20,9 @@ bool sosc::Packet::AddRegion(std::string data) { bool sosc::Packet::AddRegions(std::vector data) { if(this->regions.size() + data.size() > 256) return false; - - for(auto i = data.begin(); i != data.end(); ++i) - this->regions.push_back(*i); + + for(const auto& i : data) + this->regions.push_back(i); } void sosc::Packet::SetRegion(uint8_t index, std::string data) { @@ -150,20 +150,22 @@ std::string* sosc::Packet::ToString(std::string* packet) const { (*packet)[6] = this->id; (*packet)[7] = regions.size(); - for(auto i = this->regions.begin(); i != this->regions.end(); ++i) { - if(i->size() < 0xFE) - *packet += (char)i->size(); - else if(i->size() <= 0xFFFF) { + //for(auto i = this->regions.begin(); i != this->regions.end(); ++i) { + for(const auto& i : this->regions) { + if(i.size() < 0xFE) + *packet += (char)i.size(); + else if(i.size() <= 0xFFFF) { *packet += (char)0xFE; - *packet += net::htonv(i->size()); + *packet += net::htonv(i.size()); } else { *packet += (char)0xFF; - *packet += net::htonv(i->size()); + *packet += net::htonv(i.size()); } } - for(auto i = this->regions.begin(); i != this->regions.end(); ++i) - *packet += *i; + //for(auto i = this->regions.begin(); i != this->regions.end(); ++i) + for(const auto& i : this->regions) + *packet += i; packet->assign(net::htonv(packet->length()), 2, 4); diff --git a/server/src/sock/pool.hpp b/server/src/sock/pool.hpp index f1584cd..89cac5c 100644 --- a/server/src/sock/pool.hpp +++ b/server/src/sock/pool.hpp @@ -133,11 +133,11 @@ bool Pool::AddClient(T client) { int lowestCount = -1; Stack* lowestStack = nullptr; - for(auto i = this->stacks.begin(); i != this->stacks.end(); ++i) { + for(const auto& stack : this->stacks) { int thisCount; - if((thisCount = (*i)->ClientCount()) > lowestCount) { + if((thisCount = stack->ClientCount()) > lowestCount) { lowestCount = thisCount; - lowestStack = *i; + lowestStack = stack; } } @@ -158,8 +158,8 @@ int Pool::ClientCount() { return 0; int count = 0; - for(auto i = this->stacks.begin(); i != this->stacks.end(); ++i) - count += (*i)->ClientCount(); + for(const auto& stack : this->stacks) + count += stack->ClientCount(); return count; } @@ -167,13 +167,13 @@ template void Pool::Stop() { if(!this->is_open) return; - - for(auto i = this->stacks.begin(); i != this->stacks.end(); ++i) { - (*i)->Stop(); - delete *i; + + for(const auto& stack : this->stacks) { + stack->Stop(); + delete stack; } - stacks->clear(); + this->stacks.clear(); this->is_open = false; } @@ -221,13 +221,16 @@ int Pool::Stack::ClientCount() { template void Pool::Stack::StackThread() { while(this->is_running) { - for(auto i = this->clients.begin(); i != this->clients.end(); ++i) { + for(auto client = this->clients.begin(); + client != this->clients.end(); + ++client) + { if(!this->is_running) break; this->clients_mtx.lock(); - if(!this->pool->ProcessClient(*i)) - this->clients.erase(i); + if(!this->pool->ProcessClient(*client)) + this->clients.erase(client); this->clients_mtx.unlock(); } } diff --git a/server/src/sock/scapesock.cpp b/server/src/sock/scapesock.cpp index dee073d..087707a 100644 --- a/server/src/sock/scapesock.cpp +++ b/server/src/sock/scapesock.cpp @@ -35,8 +35,8 @@ int sosc::ScapeConnection::Handshake() { std::string websocket_key = ""; auto lines = str::split(this->buffer, "\r\n"); - for(auto line_r = lines.begin() + 1; line_r != lines.end(); ++line_r) { - std::string line = str::trim(*line_r); + for(const auto& line_r : lines) { + std::string line = str::trim(line_r); if(str::starts(line, "Sec-WebSocket-Key")) { auto parts = str::split(line, ':');