66 lines
2.8 KiB
C++
66 lines
2.8 KiB
C++
#include "database/Database.h"
|
|
#include "zeroerr/assert.h"
|
|
#include "zeroerr/unittest.h"
|
|
|
|
using namespace eve::database;
|
|
|
|
TEST_CASE("Database.SQLiteCrudOrmAndECSExport") {
|
|
Connection db("SQLite", ":memory:");
|
|
CHECK(db.isConnected());
|
|
db.execute("CREATE TABLE actors (id INTEGER, name TEXT, hp REAL)");
|
|
|
|
struct Actor {
|
|
std::int64_t id{};
|
|
std::string name;
|
|
double hp{};
|
|
};
|
|
Mapping<Actor> mapping{"actors",
|
|
{
|
|
{"id", [](const Actor& a) -> Value { return a.id; },
|
|
[](Actor& a, const Value& v) { a.id = std::get<std::int64_t>(v); }, "INTEGER", true},
|
|
{"name", [](const Actor& a) -> Value { return a.name; },
|
|
[](Actor& a, const Value& v) { a.name = std::get<std::string>(v); }},
|
|
{"hp", [](const Actor& a) -> Value { return a.hp; },
|
|
[](Actor& a, const Value& v) { a.hp = std::get<double>(v); }},
|
|
}};
|
|
|
|
Repository<Actor> actors(db, mapping);
|
|
// A real ORM owns schema and typed entity CRUD rather than only serializing a row.
|
|
db.execute("DROP TABLE actors");
|
|
actors.createTable();
|
|
CHECK_EQ(actors.insert(Actor{1, "mage", 80.0}), 1);
|
|
db.insertJson("actors", R"({"id":2,"name":"knight","hp":100})");
|
|
CHECK_EQ(db.updateJson("actors", R"({"hp":95})", "id=2"), 1);
|
|
|
|
std::vector<Actor> ecsView{{3, "rogue", 70.0}, {4, "cleric", 90.0}};
|
|
CHECK_EQ(db.exportECS("actors", ecsView, [&mapping](const Actor& actor) { return mapping.toRow(actor); }), 2);
|
|
auto rows = db.query("SELECT id,name,hp FROM actors ORDER BY id");
|
|
CHECK_EQ(rows.size(), 4);
|
|
CHECK_EQ(std::get<std::string>(rows[1]["name"]), "knight");
|
|
CHECK_EQ(db.remove("actors", "id=1"), 1);
|
|
CHECK_EQ(db.query("SELECT id FROM actors").size(), 3);
|
|
|
|
Actor loaded;
|
|
CHECK(actors.find(std::int64_t(2), loaded));
|
|
CHECK_EQ(loaded.name, "knight");
|
|
loaded.hp = 88.0;
|
|
CHECK_EQ(actors.update(loaded), 1);
|
|
CHECK_EQ(actors.all().size(), 3);
|
|
CHECK_EQ(actors.remove(std::int64_t(2)), 1);
|
|
|
|
std::unique_ptr<Model> model(db.model("actors", "id"));
|
|
model->insertJson(R"({"id":5,"name":"bard","hp":60})");
|
|
CHECK(model->findJson("5").find("bard") != std::string::npos);
|
|
CHECK_EQ(model->updateJson("5", R"({"hp":65})"), 1);
|
|
CHECK_EQ(model->remove("5"), 1);
|
|
|
|
db.insertJson("actors", R"({"id":6,"name":"strategist","hp":75})");
|
|
db.insertJson("actors", R"({"id":7,"name":"general","hp":99})");
|
|
std::unique_ptr<Query> ranked(model->query());
|
|
ranked->where("hp", ">=", 70.0)->orderBy("hp", false)->limit(2);
|
|
auto ranking = ranked->all();
|
|
CHECK_EQ(ranking.size(), 2);
|
|
CHECK_EQ(std::get<std::string>(ranking[0]["name"]), "general");
|
|
CHECK_EQ(ranked->count(), 4);
|
|
}
|