summaryrefslogtreecommitdiff
path: root/src/database
diff options
context:
space:
mode:
authorjacqueline <me@jacqueline.id.au>2023-10-31 09:01:34 +1100
committerjacqueline <me@jacqueline.id.au>2023-10-31 09:01:34 +1100
commit4cc5fa4c9c324c18908a7786358c7f6cac8a7f82 (patch)
tree76ed59e88579a909bb5118941e55c148de0e6086 /src/database
parentb58c08150853b8055093dc116d407ffd543f8ec8 (diff)
downloadtangara-fw-4cc5fa4c9c324c18908a7786358c7f6cac8a7f82.tar.gz
Store the current collator in the database
Diffstat (limited to 'src/database')
-rw-r--r--src/database/database.cpp60
1 files changed, 47 insertions, 13 deletions
diff --git a/src/database/database.cpp b/src/database/database.cpp
index 9b978b8c..e826f576 100644
--- a/src/database/database.cpp
+++ b/src/database/database.cpp
@@ -28,6 +28,7 @@
#include "leveldb/iterator.h"
#include "leveldb/options.h"
#include "leveldb/slice.h"
+#include "leveldb/status.h"
#include "leveldb/write_batch.h"
#include "db_events.hpp"
@@ -51,12 +52,13 @@ static const char kDbPath[] = "/.tangara-db";
static const char kKeyDbVersion[] = "schema_version";
static const uint8_t kCurrentDbVersion = 3;
-
+static const char kKeyCollator[] = "collator";
static const char kKeyTrackId[] = "next_track_id";
static std::atomic<bool> sIsDbOpen(false);
-static auto CreateNewDatabase(leveldb::Options& options) -> leveldb::DB* {
+static auto CreateNewDatabase(leveldb::Options& options, locale::ICollator& col)
+ -> leveldb::DB* {
Database::Destroy();
leveldb::DB* db;
options.create_if_missing = true;
@@ -71,9 +73,48 @@ static auto CreateNewDatabase(leveldb::Options& options) -> leveldb::DB* {
delete db;
return nullptr;
}
+ ESP_LOGI(kTag, "opening db with collator %s",
+ col.Describe().value_or("NULL").c_str());
+ status = db->Put(leveldb::WriteOptions{}, kKeyCollator,
+ col.Describe().value_or(""));
+ if (!status.ok()) {
+ delete db;
+ return nullptr;
+ }
return db;
}
+static auto CheckDatabase(leveldb::DB& db, locale::ICollator& col) -> bool {
+ leveldb::Status status;
+
+ std::string raw_version;
+ std::optional<uint8_t> version{};
+ status = db.Get(leveldb::ReadOptions{}, kKeyDbVersion, &raw_version);
+ if (status.ok()) {
+ version = std::stoi(raw_version);
+ }
+ if (!version || *version != kCurrentDbVersion) {
+ ESP_LOGW(kTag, "db version missing or incorrect");
+ return false;
+ }
+
+ std::string collator;
+ status = db.Get(leveldb::ReadOptions{}, kKeyCollator, &collator);
+ if (!status.ok()) {
+ ESP_LOGW(kTag, "db collator is unknown");
+ return false;
+ }
+ auto needed = col.Describe();
+
+ if ((needed && needed.value() != collator) ||
+ (!needed && !collator.empty())) {
+ ESP_LOGW(kTag, "db collator is mismatched");
+ return false;
+ }
+
+ return true;
+}
+
auto Database::Open(IFileGatherer& gatherer,
ITagParser& parser,
locale::ICollator& collator)
@@ -107,23 +148,16 @@ auto Database::Open(IFileGatherer& gatherer,
auto status = leveldb::DB::Open(options, kDbPath, &db);
if (!status.ok()) {
ESP_LOGI(kTag, "opening db failed. recreating.");
- db = CreateNewDatabase(options);
+ db = CreateNewDatabase(options, collator);
if (db == nullptr) {
return cpp::fail(FAILED_TO_OPEN);
}
}
- std::string raw_version;
- std::optional<uint8_t> version{};
- status =
- db->Get(leveldb::ReadOptions{}, kKeyDbVersion, &raw_version);
- if (status.ok()) {
- version = std::stoi(raw_version);
- }
- if (!version || *version != kCurrentDbVersion) {
- ESP_LOGI(kTag, "db version missing or incorrect. recreating.");
+ if (!CheckDatabase(*db, collator)) {
+ ESP_LOGI(kTag, "db incompatible. recreating.");
delete db;
- db = CreateNewDatabase(options);
+ db = CreateNewDatabase(options, collator);
if (db == nullptr) {
return cpp::fail(FAILED_TO_OPEN);
}