new db interface
This commit is contained in:
parent
89e3b95ca2
commit
dd56a8d57e
@ -55,6 +55,7 @@ add_executable(${TARGET_NAME}
|
|||||||
|
|
||||||
src/database/database.cpp
|
src/database/database.cpp
|
||||||
src/database/database.hpp
|
src/database/database.hpp
|
||||||
|
src/database/sqlite_orm.h
|
||||||
|
|
||||||
# Shadowrun
|
# Shadowrun
|
||||||
src/shadowrun/HtmxShItemList.cpp
|
src/shadowrun/HtmxShItemList.cpp
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
#include "utils.hpp"
|
#include "utils.hpp"
|
||||||
#include "database.hpp"
|
#include "databasepool.h"
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@ -110,3 +110,5 @@ bool Database::open(){
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DatabasePool dbpool(std::thread::hardware_concurrency());
|
||||||
@ -9,12 +9,16 @@
|
|||||||
#include <set>
|
#include <set>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include "crow.h"
|
#include "crow.h"
|
||||||
|
#include "sqlite_orm.h"
|
||||||
|
#include "ShadowrunDb.hpp"
|
||||||
|
|
||||||
class Database {
|
class Database {
|
||||||
|
|
||||||
typedef std::vector<std::variant<int64_t, std::string>> QueryData;
|
typedef std::vector<std::variant<int64_t, std::string>> QueryData;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
static constexpr std::string dbFile = "app.db";
|
||||||
|
|
||||||
Database();
|
Database();
|
||||||
~Database();
|
~Database();
|
||||||
|
|
||||||
@ -74,6 +78,26 @@ private:
|
|||||||
sqlite3_stmt* prepareStmt(const std::string& sql);
|
sqlite3_stmt* prepareStmt(const std::string& sql);
|
||||||
|
|
||||||
sqlite3* m_db;
|
sqlite3* m_db;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
inline auto make_database() {
|
||||||
|
return sqlite_orm::make_storage(Database::dbFile,
|
||||||
|
sqlite_orm::make_table("shadowrun_characters",
|
||||||
|
sqlite_orm::make_column("id", &shadowrun::ShadowrunCharacter::id, sqlite_orm::primary_key()),
|
||||||
|
sqlite_orm::make_column("name", &shadowrun::ShadowrunCharacter::name, sqlite_orm::not_null()),
|
||||||
|
sqlite_orm::make_column("created_at", &shadowrun::ShadowrunCharacter::created_at, sqlite_orm::default_value("CURRENT_TIMESTAMP"))
|
||||||
|
),
|
||||||
|
sqlite_orm::make_table("shadowrun_data",
|
||||||
|
sqlite_orm::make_column("id", &shadowrun::ShadowrunData::id, sqlite_orm::primary_key()),
|
||||||
|
sqlite_orm::make_column("character_id", &shadowrun::ShadowrunData::character_id, sqlite_orm::not_null()),
|
||||||
|
sqlite_orm::make_column("name", &shadowrun::ShadowrunData::name, sqlite_orm::not_null()),
|
||||||
|
sqlite_orm::make_column("value", &shadowrun::ShadowrunData::value),
|
||||||
|
sqlite_orm::make_column("created_at", &shadowrun::ShadowrunData::created_at, sqlite_orm::default_value("CURRENT_TIMESTAMP")),
|
||||||
|
sqlite_orm::make_column("updated_at", &shadowrun::ShadowrunData::updated_at, sqlite_orm::default_value("CURRENT_TIMESTAMP")),
|
||||||
|
sqlite_orm::foreign_key(&shadowrun::ShadowrunData::character_id).references(&shadowrun::ShadowrunCharacter::id).on_delete.cascade()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
#endif // __DATABASE_H__
|
#endif // __DATABASE_H__
|
||||||
40
src/database/databasepool.h
Normal file
40
src/database/databasepool.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
#include <queue>
|
||||||
|
#include <mutex>
|
||||||
|
#include <thread>
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <memory>
|
||||||
|
#include "database.hpp"
|
||||||
|
|
||||||
|
class DatabasePool {
|
||||||
|
public:
|
||||||
|
DatabasePool(size_t size) {
|
||||||
|
for (size_t i = 0; i < size; ++i){
|
||||||
|
auto db = std::make_shared<decltype(make_database())>(make_database());
|
||||||
|
db->sync_schema();
|
||||||
|
pool.push(db);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<decltype(make_database())> acquire() {
|
||||||
|
std::unique_lock<std::mutex> lock(mutex);
|
||||||
|
cv.wait(lock, [&]{ return !pool.empty(); });
|
||||||
|
auto db = pool.front();
|
||||||
|
pool.pop();
|
||||||
|
return db;
|
||||||
|
}
|
||||||
|
|
||||||
|
void release(std::shared_ptr<decltype(make_database())> db) {
|
||||||
|
std::unique_lock<std::mutex> lock(mutex);
|
||||||
|
pool.push(db);
|
||||||
|
lock.unlock();
|
||||||
|
cv.notify_one();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::queue<std::shared_ptr<decltype(make_database())>> pool;
|
||||||
|
std::mutex mutex;
|
||||||
|
std::condition_variable cv;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
extern DatabasePool dbpool;
|
||||||
24841
src/database/sqlite_orm.h
Normal file
24841
src/database/sqlite_orm.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -109,9 +109,6 @@ void initApi(crow::SimpleApp& app)
|
|||||||
return crow::response{html.str()};
|
return crow::response{html.str()};
|
||||||
}));
|
}));
|
||||||
|
|
||||||
if(!shadowrun::initDb()){
|
|
||||||
CROW_LOG_ERROR << "Failed to Init shadowrun database";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1,65 +1,25 @@
|
|||||||
#include <format>
|
#include <format>
|
||||||
#include "database.hpp"
|
#include "databasepool.h"
|
||||||
#include "crow.h"
|
#include "crow.h"
|
||||||
|
#include "sqlite_orm.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
using namespace sqlite_orm;
|
||||||
|
|
||||||
namespace shadowrun {
|
namespace shadowrun {
|
||||||
|
|
||||||
bool initDb() {
|
|
||||||
auto db = Database();
|
|
||||||
|
|
||||||
if (!db.open()){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a tables
|
|
||||||
const char* create_sql_chars = "CREATE TABLE IF NOT EXISTS shadowrun_characters ("
|
|
||||||
"id INTEGER PRIMARY KEY,"
|
|
||||||
"name TEXT NOT NULL,"
|
|
||||||
"created_at DATETIME DEFAULT CURRENT_TIMESTAMP);";
|
|
||||||
|
|
||||||
if (!db.exec(create_sql_chars)){
|
|
||||||
CROW_LOG_ERROR << "Failed to create shadowrun_characters table";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* create_sql_data = "CREATE TABLE IF NOT EXISTS shadowrun_data ("
|
|
||||||
"id INTEGER PRIMARY KEY,"
|
|
||||||
"character_id INTEGER NOT NULL,"
|
|
||||||
"name TEXT NOT NULL,"
|
|
||||||
"value TEXT,"
|
|
||||||
"created_at DATETIME DEFAULT CURRENT_TIMESTAMP,"
|
|
||||||
"updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,"
|
|
||||||
"FOREIGN KEY (character_id) REFERENCES shadowrun_characters(id) ON DELETE CASCADE);";
|
|
||||||
|
|
||||||
if (!db.exec(create_sql_data)){
|
|
||||||
CROW_LOG_ERROR << "Failed to create shadowrun_data table";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t getKeyOfCharacter(const string& name){
|
int64_t getKeyOfCharacter(const string& name){
|
||||||
std::string sql = "SELECT id FROM shadowrun_characters WHERE name = ? LIMIT 1;";
|
auto db = dbpool.acquire();
|
||||||
auto db = Database();
|
|
||||||
|
|
||||||
if (!db.open())
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
auto opt_int = db.get<int>(sql, {name});
|
auto character = db->get_all<ShadowrunCharacter>(
|
||||||
if (opt_int.has_value()) {
|
where(c(&ShadowrunCharacter::name) == name),
|
||||||
return opt_int.value();
|
limit(1)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!character.empty()) {
|
||||||
|
return character[0].id;
|
||||||
} else {
|
} else {
|
||||||
sql = format("INSERT INTO shadowrun_characters (name) VALUES ('{}');", name);
|
return db->insert(ShadowrunCharacter{-1, name, ""});
|
||||||
auto key = db.insert(sql.c_str());
|
|
||||||
|
|
||||||
if(key.has_value()){
|
|
||||||
return key.value();
|
|
||||||
} else {
|
|
||||||
CROW_LOG_ERROR << "Failed to insert character " << name;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -7,9 +7,22 @@
|
|||||||
#include <set>
|
#include <set>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
namespace shadowrun{
|
namespace shadowrun {
|
||||||
|
struct ShadowrunCharacter {
|
||||||
|
int id;
|
||||||
|
std::string name;
|
||||||
|
std::string created_at; // SQLite stores DATETIME as TEXT
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ShadowrunData {
|
||||||
|
int id;
|
||||||
|
int character_id;
|
||||||
|
std::string name;
|
||||||
|
std::string value;
|
||||||
|
std::string created_at;
|
||||||
|
std::string updated_at;
|
||||||
|
};
|
||||||
|
|
||||||
bool initDb();
|
|
||||||
int64_t getKeyOfCharacter(const std::string& name);
|
int64_t getKeyOfCharacter(const std::string& name);
|
||||||
bool storeCharacterData(int64_t characterKey, std::vector<std::pair<const std::string, const std::string>>& idValues);
|
bool storeCharacterData(int64_t characterKey, std::vector<std::pair<const std::string, const std::string>>& idValues);
|
||||||
std::set<std::string> getCharacters();
|
std::set<std::string> getCharacters();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user