This commit is contained in:
@@ -55,6 +55,8 @@ CREATE TABLE IF NOT EXISTS maps (
|
||||
description TEXT NOT NULL DEFAULT '',
|
||||
site_id TEXT,
|
||||
created_by TEXT NOT NULL DEFAULT '',
|
||||
created_by_user TEXT,
|
||||
created_by_group TEXT,
|
||||
width REAL,
|
||||
height REAL,
|
||||
resolution REAL,
|
||||
@@ -268,7 +270,7 @@ bool tableHasColumn(sqlite3* db, const char* table, const char* column)
|
||||
|
||||
bool Database::applySchemaMigrations(std::string& err)
|
||||
{
|
||||
const std::string ver = getMeta("schema_version").value_or("1");
|
||||
std::string ver = getMeta("schema_version").value_or("1");
|
||||
|
||||
if (ver == "1")
|
||||
{
|
||||
@@ -317,6 +319,22 @@ bool Database::applySchemaMigrations(std::string& err)
|
||||
setMeta("schema_version", "2");
|
||||
}
|
||||
|
||||
ver = getMeta("schema_version").value_or("1");
|
||||
if (ver == "2")
|
||||
{
|
||||
if (!tableHasColumn(db_, "maps", "created_by_user"))
|
||||
{
|
||||
if (!execSql(db_, "ALTER TABLE maps ADD COLUMN created_by_user TEXT", err))
|
||||
return false;
|
||||
}
|
||||
if (!tableHasColumn(db_, "maps", "created_by_group"))
|
||||
{
|
||||
if (!execSql(db_, "ALTER TABLE maps ADD COLUMN created_by_group TEXT", err))
|
||||
return false;
|
||||
}
|
||||
setMeta("schema_version", "3");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,9 +14,9 @@ namespace {
|
||||
constexpr const char* kBaseImageName = "map_base.png";
|
||||
|
||||
constexpr const char* kMapSelect =
|
||||
"SELECT id, name, description, site_id, created_by, width, height, resolution, "
|
||||
"origin_x, origin_y, origin_yaw, image_file, yaml_file, zones_json, created_at, updated_at "
|
||||
"FROM maps";
|
||||
"SELECT id, name, description, site_id, created_by, created_by_user, created_by_group, "
|
||||
"width, height, resolution, origin_x, origin_y, origin_yaw, image_file, yaml_file, zones_json, "
|
||||
"created_at, updated_at FROM maps";
|
||||
|
||||
nlohmann::json rowToJson(sqlite3_stmt* stmt)
|
||||
{
|
||||
@@ -32,11 +32,11 @@ nlohmann::json rowToJson(sqlite3_stmt* stmt)
|
||||
};
|
||||
|
||||
nlohmann::json zones = nlohmann::json::array();
|
||||
if (sqlite3_column_type(stmt, 13) != SQLITE_NULL)
|
||||
if (sqlite3_column_type(stmt, 15) != SQLITE_NULL)
|
||||
{
|
||||
try
|
||||
{
|
||||
zones = nlohmann::json::parse(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 13)));
|
||||
zones = nlohmann::json::parse(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 15)));
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
@@ -49,17 +49,19 @@ nlohmann::json rowToJson(sqlite3_stmt* stmt)
|
||||
{"description", textOrNull(2)},
|
||||
{"site_id", textOrNull(3)},
|
||||
{"created_by", textOrNull(4)},
|
||||
{"width", realOrNull(5)},
|
||||
{"height", realOrNull(6)},
|
||||
{"resolution", realOrNull(7)},
|
||||
{"origin_x", realOrNull(8)},
|
||||
{"origin_y", realOrNull(9)},
|
||||
{"origin_yaw", realOrNull(10)},
|
||||
{"image_file", textOrNull(11)},
|
||||
{"yaml_file", textOrNull(12)},
|
||||
{"created_by_user", textOrNull(5)},
|
||||
{"created_by_group", textOrNull(6)},
|
||||
{"width", realOrNull(7)},
|
||||
{"height", realOrNull(8)},
|
||||
{"resolution", realOrNull(9)},
|
||||
{"origin_x", realOrNull(10)},
|
||||
{"origin_y", realOrNull(11)},
|
||||
{"origin_yaw", realOrNull(12)},
|
||||
{"image_file", textOrNull(13)},
|
||||
{"yaml_file", textOrNull(14)},
|
||||
{"zones", zones},
|
||||
{"created_at", textOrNull(14)},
|
||||
{"updated_at", textOrNull(15)}};
|
||||
{"created_at", textOrNull(16)},
|
||||
{"updated_at", textOrNull(17)}};
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -119,6 +121,8 @@ std::optional<nlohmann::json> MapStore::create(const nlohmann::json& payload, st
|
||||
const std::string description = payload.value("description", "");
|
||||
const std::string site_id = payload.value("site_id", "");
|
||||
const std::string created_by = payload.value("created_by", "");
|
||||
const std::string created_by_user = payload.value("created_by_user", "");
|
||||
const std::string created_by_group = payload.value("created_by_group", "");
|
||||
const auto zones = payload.contains("zones") ? payload["zones"] : nlohmann::json::array();
|
||||
|
||||
std::error_code ec;
|
||||
@@ -132,10 +136,10 @@ std::optional<nlohmann::json> MapStore::create(const nlohmann::json& payload, st
|
||||
std::lock_guard<std::mutex> lock(mu_);
|
||||
sqlite3_stmt* stmt = nullptr;
|
||||
if (sqlite3_prepare_v2(db_.handle(),
|
||||
"INSERT INTO maps(id, name, description, site_id, created_by, width, height, resolution, "
|
||||
"origin_x, origin_y, origin_yaw, image_file, yaml_file, zones_json, "
|
||||
"created_at, updated_at) "
|
||||
"VALUES(?1,?2,?3,?4,?5,?6,?7,?8,?9,?10,?11,?12,?13,?14,?15,?16)",
|
||||
"INSERT INTO maps(id, name, description, site_id, created_by, created_by_user, "
|
||||
"created_by_group, width, height, resolution, origin_x, origin_y, origin_yaw, image_file, "
|
||||
"yaml_file, zones_json, created_at, updated_at) "
|
||||
"VALUES(?1,?2,?3,?4,?5,?6,?7,?8,?9,?10,?11,?12,?13,?14,?15,?16,?17,?18)",
|
||||
-1,
|
||||
&stmt,
|
||||
nullptr) != SQLITE_OK)
|
||||
@@ -152,27 +156,35 @@ std::optional<nlohmann::json> MapStore::create(const nlohmann::json& payload, st
|
||||
else
|
||||
sqlite3_bind_text(stmt, 4, site_id.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_text(stmt, 5, created_by.c_str(), -1, SQLITE_TRANSIENT);
|
||||
if (payload.contains("width") && payload["width"].is_number())
|
||||
sqlite3_bind_double(stmt, 6, payload["width"].get<double>());
|
||||
else
|
||||
if (created_by_user.empty())
|
||||
sqlite3_bind_null(stmt, 6);
|
||||
if (payload.contains("height") && payload["height"].is_number())
|
||||
sqlite3_bind_double(stmt, 7, payload["height"].get<double>());
|
||||
else
|
||||
sqlite3_bind_text(stmt, 6, created_by_user.c_str(), -1, SQLITE_TRANSIENT);
|
||||
if (created_by_group.empty())
|
||||
sqlite3_bind_null(stmt, 7);
|
||||
if (payload.contains("resolution") && payload["resolution"].is_number())
|
||||
sqlite3_bind_double(stmt, 8, payload["resolution"].get<double>());
|
||||
else
|
||||
sqlite3_bind_text(stmt, 7, created_by_group.c_str(), -1, SQLITE_TRANSIENT);
|
||||
if (payload.contains("width") && payload["width"].is_number())
|
||||
sqlite3_bind_double(stmt, 8, payload["width"].get<double>());
|
||||
else
|
||||
sqlite3_bind_null(stmt, 8);
|
||||
sqlite3_bind_double(stmt, 9, payload.value("origin_x", 0.0));
|
||||
sqlite3_bind_double(stmt, 10, payload.value("origin_y", 0.0));
|
||||
sqlite3_bind_double(stmt, 11, payload.value("origin_yaw", 0.0));
|
||||
sqlite3_bind_null(stmt, 12);
|
||||
sqlite3_bind_null(stmt, 13);
|
||||
if (payload.contains("height") && payload["height"].is_number())
|
||||
sqlite3_bind_double(stmt, 9, payload["height"].get<double>());
|
||||
else
|
||||
sqlite3_bind_null(stmt, 9);
|
||||
if (payload.contains("resolution") && payload["resolution"].is_number())
|
||||
sqlite3_bind_double(stmt, 10, payload["resolution"].get<double>());
|
||||
else
|
||||
sqlite3_bind_null(stmt, 10);
|
||||
sqlite3_bind_double(stmt, 11, payload.value("origin_x", 0.0));
|
||||
sqlite3_bind_double(stmt, 12, payload.value("origin_y", 0.0));
|
||||
sqlite3_bind_double(stmt, 13, payload.value("origin_yaw", 0.0));
|
||||
sqlite3_bind_null(stmt, 14);
|
||||
sqlite3_bind_null(stmt, 15);
|
||||
const std::string zones_str = zones.dump();
|
||||
sqlite3_bind_text(stmt, 14, zones_str.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_text(stmt, 15, now.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_text(stmt, 16, now.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_text(stmt, 16, zones_str.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_text(stmt, 17, now.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_text(stmt, 18, now.c_str(), -1, SQLITE_TRANSIENT);
|
||||
|
||||
if (sqlite3_step(stmt) != SQLITE_DONE)
|
||||
{
|
||||
@@ -188,6 +200,10 @@ std::optional<nlohmann::json> MapStore::create(const nlohmann::json& payload, st
|
||||
created["description"] = description;
|
||||
created["site_id"] = site_id.empty() ? nullptr : nlohmann::json(site_id);
|
||||
created["created_by"] = created_by;
|
||||
if (!created_by_user.empty())
|
||||
created["created_by_user"] = created_by_user;
|
||||
if (!created_by_group.empty())
|
||||
created["created_by_group"] = created_by_group;
|
||||
if (payload.contains("width") && payload["width"].is_number())
|
||||
created["width"] = payload["width"];
|
||||
if (payload.contains("height") && payload["height"].is_number())
|
||||
@@ -216,7 +232,7 @@ bool MapStore::update(const std::string& id, const nlohmann::json& payload, std:
|
||||
|
||||
nlohmann::json merged = *existing;
|
||||
for (const char* key :
|
||||
{"name", "description", "site_id", "created_by", "width", "height", "resolution", "origin_x", "origin_y", "origin_yaw"})
|
||||
{"name", "description", "site_id", "width", "height", "resolution", "origin_x", "origin_y", "origin_yaw"})
|
||||
{
|
||||
if (payload.contains(key))
|
||||
merged[key] = payload[key];
|
||||
@@ -237,9 +253,8 @@ bool MapStore::update(const std::string& id, const nlohmann::json& payload, std:
|
||||
std::lock_guard<std::mutex> lock(mu_);
|
||||
sqlite3_stmt* stmt = nullptr;
|
||||
if (sqlite3_prepare_v2(db_.handle(),
|
||||
"UPDATE maps SET name=?2, description=?3, site_id=?4, created_by=?5, width=?6, height=?7, "
|
||||
"resolution=?8, origin_x=?9, origin_y=?10, origin_yaw=?11, zones_json=?12, updated_at=?13 "
|
||||
"WHERE id=?1",
|
||||
"UPDATE maps SET name=?2, description=?3, site_id=?4, width=?5, height=?6, resolution=?7, "
|
||||
"origin_x=?8, origin_y=?9, origin_yaw=?10, zones_json=?11, updated_at=?12 WHERE id=?1",
|
||||
-1,
|
||||
&stmt,
|
||||
nullptr) != SQLITE_OK)
|
||||
@@ -256,24 +271,23 @@ bool MapStore::update(const std::string& id, const nlohmann::json& payload, std:
|
||||
sqlite3_bind_null(stmt, 4);
|
||||
else
|
||||
sqlite3_bind_text(stmt, 4, site_id.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_text(stmt, 5, merged.value("created_by", "").c_str(), -1, SQLITE_TRANSIENT);
|
||||
if (merged["width"].is_number())
|
||||
sqlite3_bind_double(stmt, 6, merged["width"].get<double>());
|
||||
sqlite3_bind_double(stmt, 5, merged["width"].get<double>());
|
||||
else
|
||||
sqlite3_bind_null(stmt, 5);
|
||||
if (merged["height"].is_number())
|
||||
sqlite3_bind_double(stmt, 6, merged["height"].get<double>());
|
||||
else
|
||||
sqlite3_bind_null(stmt, 6);
|
||||
if (merged["height"].is_number())
|
||||
sqlite3_bind_double(stmt, 7, merged["height"].get<double>());
|
||||
if (merged["resolution"].is_number())
|
||||
sqlite3_bind_double(stmt, 7, merged["resolution"].get<double>());
|
||||
else
|
||||
sqlite3_bind_null(stmt, 7);
|
||||
if (merged["resolution"].is_number())
|
||||
sqlite3_bind_double(stmt, 8, merged["resolution"].get<double>());
|
||||
else
|
||||
sqlite3_bind_null(stmt, 8);
|
||||
sqlite3_bind_double(stmt, 9, merged.value("origin_x", 0.0));
|
||||
sqlite3_bind_double(stmt, 10, merged.value("origin_y", 0.0));
|
||||
sqlite3_bind_double(stmt, 11, merged.value("origin_yaw", 0.0));
|
||||
sqlite3_bind_text(stmt, 12, zones_str.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_text(stmt, 13, now.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_double(stmt, 8, merged.value("origin_x", 0.0));
|
||||
sqlite3_bind_double(stmt, 9, merged.value("origin_y", 0.0));
|
||||
sqlite3_bind_double(stmt, 10, merged.value("origin_yaw", 0.0));
|
||||
sqlite3_bind_text(stmt, 11, zones_str.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_text(stmt, 12, now.c_str(), -1, SQLITE_TRANSIENT);
|
||||
|
||||
const bool ok = sqlite3_step(stmt) == SQLITE_DONE;
|
||||
if (!ok)
|
||||
|
||||
Reference in New Issue
Block a user