mirror of
https://github.com/MeshEnvy/lobbs.git
synced 2026-10-31 02:11:59 +01:00
159 lines
4.1 KiB
C++
159 lines
4.1 KiB
C++
#if !MESHTASTIC_EXCLUDE_LOBBS
|
|
|
|
#include "ConfigDal.h"
|
|
#include "../../LoBBSCommandCtx.h"
|
|
#include "../../LoBBSHooks.h"
|
|
#include "../../LoBBSModule.h"
|
|
#include "../AppUtil.h"
|
|
#include "ConfigRecords.h"
|
|
#include <cstdio>
|
|
#include <cstring>
|
|
|
|
#include "LoBBSStackGuard.h"
|
|
|
|
ConfigDal::ConfigDal(LoDb &lodb) : lodb_(lodb)
|
|
{
|
|
lodb_.registerTable("config");
|
|
}
|
|
|
|
lodb_uuid_t ConfigDal::rowUuid(const char *key) const
|
|
{
|
|
return lodb_new_uuid(key, 0);
|
|
}
|
|
|
|
void ConfigDal::resetCache()
|
|
{
|
|
overrides_.clear();
|
|
registry_.clear();
|
|
registryBuilt_ = false;
|
|
overridesLoaded_ = false;
|
|
}
|
|
|
|
void ConfigDal::reloadOverrides()
|
|
{
|
|
overrides_.clear();
|
|
overridesLoaded_ = true;
|
|
auto rows = lodb_.select(
|
|
"config", [](const LoScalar &) { return true; }, LoDbComparator());
|
|
for (const LoScalar &rec : rows) {
|
|
std::string key;
|
|
if (!rec.getString(LODB_F_TITLE, key) || key.empty())
|
|
continue;
|
|
uint32_t val = 0;
|
|
if (rec.getUint32(ConfigStoreField::FIELD_VALUE, val))
|
|
overrides_[key] = val;
|
|
}
|
|
}
|
|
|
|
void ConfigDal::ensureRegistry(LoBBSCommandCtx &ctx)
|
|
{
|
|
if (registryBuilt_)
|
|
return;
|
|
registryBuilt_ = true;
|
|
registry_.clear();
|
|
lobbsApplyFilter("config_keys", ctx, registry_, LoScalar());
|
|
}
|
|
|
|
const std::vector<LoScalar> &ConfigDal::keyDefs(LoBBSCommandCtx &ctx)
|
|
{
|
|
ensureRegistry(ctx);
|
|
return registry_;
|
|
}
|
|
|
|
const LoScalar *ConfigDal::findKeyDef(const char *key)
|
|
{
|
|
if (!key)
|
|
return nullptr;
|
|
for (const LoScalar &rec : registry_) {
|
|
std::string title;
|
|
if (rec.getString(LODB_F_TITLE, title) && strcasecmp(title.c_str(), key) == 0)
|
|
return &rec;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
uint32_t ConfigDal::effectiveValue(LoBBSCommandCtx &ctx, const char *key)
|
|
{
|
|
ensureRegistry(ctx);
|
|
const LoScalar *def = findKeyDef(key);
|
|
if (!def)
|
|
return 0;
|
|
uint32_t fallback = 0;
|
|
def->getUint32(ConfigKeyField::FIELD_DEFAULT, fallback);
|
|
if (!overridesLoaded_)
|
|
return fallback;
|
|
auto it = overrides_.find(key);
|
|
if (it != overrides_.end())
|
|
return it->second;
|
|
return fallback;
|
|
}
|
|
|
|
void ConfigDal::fireConfigChanged(LoBBSCommandCtx &ctx, const char *key, uint32_t value)
|
|
{
|
|
LoScalar args;
|
|
args.setString(LODB_F_TITLE, key);
|
|
args.setUint32(ConfigValidateField::FIELD_VALUE, value);
|
|
lobbsDoAction("config_changed", ctx, args);
|
|
}
|
|
|
|
const char *ConfigDal::validateAndSet(LoBBSCommandCtx &ctx, const char *key, uint32_t value)
|
|
{
|
|
ensureRegistry(ctx);
|
|
const LoScalar *def = findKeyDef(key);
|
|
if (!def)
|
|
return "Unknown setting.";
|
|
|
|
LoScalar probe;
|
|
probe.setString(LODB_F_TITLE, key);
|
|
probe.setUint32(ConfigValidateField::FIELD_VALUE, value);
|
|
lobbsApplyFilter("config_validate", ctx, probe, *def);
|
|
|
|
std::string err;
|
|
if (probe.getString(LODB_F_ERROR, err) && !err.empty()) {
|
|
strncpy(lastValidateError_, err.c_str(), sizeof(lastValidateError_) - 1);
|
|
lastValidateError_[sizeof(lastValidateError_) - 1] = '\0';
|
|
return lastValidateError_;
|
|
}
|
|
|
|
LoScalar row;
|
|
row.setString(LODB_F_TITLE, key);
|
|
row.setUint32(ConfigStoreField::FIELD_VALUE, value);
|
|
LoDbError dbErr = lodb_.upsert("config", rowUuid(key), row);
|
|
if (dbErr != LODB_OK)
|
|
return lobbsDbErrorText(dbErr);
|
|
overrides_[key] = value;
|
|
fireConfigChanged(ctx, key, value);
|
|
return nullptr;
|
|
}
|
|
|
|
const char *ConfigDal::resetKey(LoBBSCommandCtx &ctx, const char *key)
|
|
{
|
|
ensureRegistry(ctx);
|
|
const LoScalar *def = findKeyDef(key);
|
|
if (!def)
|
|
return "Unknown setting.";
|
|
uint32_t fallback = 0;
|
|
def->getUint32(ConfigKeyField::FIELD_DEFAULT, fallback);
|
|
lodb_.deleteRecord("config", rowUuid(key));
|
|
overrides_.erase(key);
|
|
fireConfigChanged(ctx, key, fallback);
|
|
return nullptr;
|
|
}
|
|
|
|
void ConfigDal::notifyDatabaseOpened(LoBBSModule &mod)
|
|
{
|
|
resetCache();
|
|
reloadOverrides();
|
|
LoBBSCommandCtx ctx;
|
|
ctx.mod = &mod;
|
|
ensureRegistry(ctx);
|
|
for (const LoScalar &rec : registry_) {
|
|
std::string key;
|
|
if (!rec.getString(LODB_F_TITLE, key) || key.empty())
|
|
continue;
|
|
fireConfigChanged(ctx, key.c_str(), effectiveValue(ctx, key.c_str()));
|
|
}
|
|
}
|
|
|
|
#endif
|