CONTAINS NO JUICE
This commit is contained in:
parent
cf0f91d439
commit
216a04ee90
5 changed files with 199 additions and 106 deletions
|
@ -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>(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>(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>(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>(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<std::string>
|
||||
(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<double>() {
|
||||
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<double>(0);
|
||||
return this->results.GetDouble(0);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t sosc::db::Query::Scalar<int32_t>() {
|
||||
int32_t sosc::db::Query::ScalarInt32() {
|
||||
if(!_ctx.ready || !this->open)
|
||||
return 0;
|
||||
|
||||
if(this->results.Step())
|
||||
return this->results.Get<int32_t>(0);
|
||||
return this->results.GetInt32(0);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int64_t sosc::db::Query::Scalar<int64_t>() {
|
||||
int64_t sosc::db::Query::ScalarInt64() {
|
||||
if(!_ctx.ready || !this->open)
|
||||
return 0;
|
||||
|
||||
if(this->results.Step())
|
||||
return this->results.Get<int64_t>(0);
|
||||
return this->results.GetInt64(0);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
sosc::time sosc::db::Query::Scalar<sosc::time>() {
|
||||
sosc::time sosc::db::Query::ScalarTime() {
|
||||
if(!_ctx.ready || !this->open)
|
||||
return sosc::time::min();
|
||||
|
||||
if(this->results.Step())
|
||||
return this->results.Get<sosc::time>(0);
|
||||
return this->results.GetTime(0);
|
||||
else
|
||||
return sosc::time::min();
|
||||
}
|
||||
|
||||
std::string sosc::db::Query::Scalar<std::string>(int type) {
|
||||
std::string sosc::db::Query::ScalarText() {
|
||||
if(!_ctx.ready || !this->open)
|
||||
return "";
|
||||
|
||||
if(this->results.Step())
|
||||
return this->results.Get<std::string>(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<double>(int column) {
|
||||
double sosc::db::ResultSet::GetDouble(int column) {
|
||||
return sqlite3_column_double(this->query->statement, column);
|
||||
}
|
||||
|
||||
int32_t sosc::db::ResultSet::Get<int32_t>(int column) {
|
||||
int32_t sosc::db::ResultSet::GetInt32(int column) {
|
||||
return sqlite3_column_int(this->query->statement, column);
|
||||
}
|
||||
|
||||
int64_t sosc::db::ResultSet::Get<int64_t>(int column) {
|
||||
int64_t sosc::db::ResultSet::GetInt64(int column) {
|
||||
return sqlite3_column_int64(this->query->statement, column);
|
||||
}
|
||||
|
||||
sosc::time sosc::db::ResultSet::Get<sosc::time>(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<std::string>(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)
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "sqlite/sqlite3.h"
|
||||
#include "../utils/time.hpp"
|
||||
#include "../crypto/sha1.hpp"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
|
@ -14,6 +15,7 @@
|
|||
|
||||
namespace sosc {
|
||||
namespace db {
|
||||
|
||||
class Query;
|
||||
|
||||
class ResultSet {
|
||||
|
@ -21,10 +23,12 @@ public:
|
|||
bool IsOpen() const;
|
||||
bool Step();
|
||||
|
||||
template<typename T>
|
||||
T Get(int column);
|
||||
template<typename T>
|
||||
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<double>(int column);
|
||||
template<> int32_t ResultSet::Get<int32_t>(int column);
|
||||
template<> int64_t ResultSet::Get<int64_t>(int column);
|
||||
template<> sosc::time ResultSet::Get<sosc::time>(int column);
|
||||
template<> std::string ResultSet::Get<std::string>(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<typename T>
|
||||
void Bind(T value, int i);
|
||||
template<typename T>
|
||||
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<typename T>
|
||||
T Scalar();
|
||||
template<typename T>
|
||||
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>(double value, int i);
|
||||
template<> void Query::Bind<int32_t>(int32_t value, int i);
|
||||
template<> void Query::Bind<int64_t>(int64_t value, int i);
|
||||
template<> void Query::Bind<sosc::time>(sosc::time value, int i);
|
||||
template<> std::string Query::Bind<std::string>
|
||||
(const std::string& value, int i, int type);
|
||||
|
||||
template<> double Query::Scalar<double>();
|
||||
template<> int32_t Query::Scalar<int32_t>();
|
||||
template<> int64_t Query::Scalar<int64_t>();
|
||||
template<> sosc::time Query::Scalar<sosc::time>();
|
||||
template<> std::string Query::Scalar<std::string>(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();
|
||||
}}
|
||||
|
||||
|
|
|
@ -21,8 +21,8 @@ bool sosc::Packet::AddRegions(std::vector<std::string> 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<uint16_t>(i->size());
|
||||
*packet += net::htonv<uint16_t>(i.size());
|
||||
} else {
|
||||
*packet += (char)0xFF;
|
||||
*packet += net::htonv<uint32_t>(i->size());
|
||||
*packet += net::htonv<uint32_t>(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<uint32_t>(packet->length()), 2, 4);
|
||||
|
||||
|
|
|
@ -133,11 +133,11 @@ bool Pool<T>::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<T>::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;
|
||||
}
|
||||
|
||||
|
@ -168,12 +168,12 @@ void Pool<T>::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<T>::Stack::ClientCount() {
|
|||
template<class T>
|
||||
void Pool<T>::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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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, ':');
|
||||
|
|
Loading…
Reference in a new issue