diff options
Diffstat (limited to 'src/database/database.cpp')
| -rw-r--r-- | src/database/database.cpp | 67 |
1 files changed, 39 insertions, 28 deletions
diff --git a/src/database/database.cpp b/src/database/database.cpp index 70bbb78a..0a092774 100644 --- a/src/database/database.cpp +++ b/src/database/database.cpp @@ -202,8 +202,8 @@ auto Database::Update() -> std::future<void> { continue; } - if (track->is_tombstoned()) { - ESP_LOGW(kTag, "skipping tombstoned %lx", track->id()); + if (track->is_tombstoned) { + ESP_LOGW(kTag, "skipping tombstoned %lx", track->id); it->Next(); continue; } @@ -212,25 +212,28 @@ auto Database::Update() -> std::future<void> { FILINFO info; { auto lock = drivers::acquire_spi(); - res = f_stat(track->filepath().c_str(), &info); + res = f_stat(track->filepath.c_str(), &info); } std::pair<uint16_t, uint16_t> modified_at{0, 0}; if (res == FR_OK) { modified_at = {info.fdate, info.ftime}; } - if (modified_at == track->modified_at()) { + if (modified_at == track->modified_at) { newest_track = std::max(modified_at, newest_track); + } else { + track->modified_at = modified_at; } std::shared_ptr<TrackTags> tags = - tag_parser_.ReadAndParseTags(track->filepath()); + tag_parser_.ReadAndParseTags(track->filepath); if (!tags || tags->encoding() == Container::kUnsupported) { // We couldn't read the tags for this track. Either they were // malformed, or perhaps the file is missing. Either way, tombstone // this record. - ESP_LOGW(kTag, "entombing missing #%lx", track->id()); - dbPutTrackData(track->Entomb().UpdateModifiedAt(modified_at)); + ESP_LOGW(kTag, "entombing missing #%lx", track->id); + track->is_tombstoned = true; + dbPutTrackData(*track); it->Next(); continue; } @@ -239,15 +242,15 @@ auto Database::Update() -> std::future<void> { // location. All that's left to do is update any metadata about it. uint64_t new_hash = tags->Hash(); - if (new_hash != track->tags_hash()) { + if (new_hash != track->tags_hash) { // This track's tags have changed. Since the filepath is exactly the // same, we assume this is a legitimate correction. Update the // database. - ESP_LOGI(kTag, "updating hash (%llx -> %llx)", track->tags_hash(), + ESP_LOGI(kTag, "updating hash (%llx -> %llx)", track->tags_hash, new_hash); - dbPutTrackData( - track->UpdateHash(new_hash).UpdateModifiedAt(modified_at)); - dbPutHash(new_hash, track->id()); + track->tags_hash = new_hash; + dbPutTrackData(*track); + dbPutHash(new_hash, track->id); } Track t{track, tags}; @@ -274,7 +277,6 @@ auto Database::Update() -> std::future<void> { std::pair<uint16_t, uint16_t> modified{info.fdate, info.ftime}; if (modified < newest_track) { - ESP_LOGI(kTag, "skipping old file"); return; } @@ -299,7 +301,11 @@ auto Database::Update() -> std::future<void> { TrackId id = dbMintNewTrackId(); ESP_LOGI(kTag, "recording new 0x%lx", id); - auto data = std::make_shared<TrackData>(id, path, hash, modified); + auto data = std::make_shared<TrackData>(); + data->id = id; + data->filepath = path; + data->tags_hash = hash; + data->modified_at = modified; dbPutTrackData(*data); dbPutHash(hash, id); @@ -311,22 +317,27 @@ auto Database::Update() -> std::future<void> { std::shared_ptr<TrackData> existing_data = dbGetTrackData(*existing_hash); if (!existing_data) { // We found a hash that matches, but there's no data record? Weird. - auto new_data = - std::make_shared<TrackData>(*existing_hash, path, hash, modified); + auto new_data = std::make_shared<TrackData>(); + new_data->id = dbMintNewTrackId(); + new_data->filepath = path; + new_data->tags_hash = hash; + new_data->modified_at = modified; dbPutTrackData(*new_data); auto t = std::make_shared<Track>(new_data, tags); dbCreateIndexesForTrack(*t); return; } - if (existing_data->is_tombstoned()) { - ESP_LOGI(kTag, "exhuming track %lu", existing_data->id()); - dbPutTrackData(existing_data->Exhume(path)); + if (existing_data->is_tombstoned) { + ESP_LOGI(kTag, "exhuming track %lu", existing_data->id); + existing_data->is_tombstoned = false; + existing_data->modified_at = modified; + dbPutTrackData(*existing_data); auto t = std::make_shared<Track>(existing_data, tags); dbCreateIndexesForTrack(*t); - } else if (existing_data->filepath() != path) { + } else if (existing_data->filepath != path) { ESP_LOGW(kTag, "tag hash collision for %s and %s", - existing_data->filepath().c_str(), path.c_str()); + existing_data->filepath.c_str(), path.c_str()); ESP_LOGI(kTag, "hash components: %s, %s, %s", tags->at(Tag::kTitle).value_or("no title").c_str(), tags->at(Tag::kArtist).value_or("no artist").c_str(), @@ -343,7 +354,7 @@ auto Database::GetTrackPath(TrackId id) [=, this]() -> std::optional<std::pmr::string> { auto track_data = dbGetTrackData(id); if (track_data) { - return track_data->filepath(); + return track_data->filepath; } return {}; }); @@ -353,11 +364,11 @@ auto Database::GetTrack(TrackId id) -> std::future<std::shared_ptr<Track>> { return worker_task_->Dispatch<std::shared_ptr<Track>>( [=, this]() -> std::shared_ptr<Track> { std::shared_ptr<TrackData> data = dbGetTrackData(id); - if (!data || data->is_tombstoned()) { + if (!data || data->is_tombstoned) { return {}; } std::shared_ptr<TrackTags> tags = - tag_parser_.ReadAndParseTags(data->filepath()); + tag_parser_.ReadAndParseTags(data->filepath); if (!tags) { return {}; } @@ -505,10 +516,10 @@ auto Database::dbEntomb(TrackId id, uint64_t hash) -> void { } auto Database::dbPutTrackData(const TrackData& s) -> void { - std::string key = EncodeDataKey(s.id()); + std::string key = EncodeDataKey(s.id); std::string val = EncodeDataValue(s); if (!db_->Put(leveldb::WriteOptions(), key, val).ok()) { - ESP_LOGE(kTag, "failed to write data for #%lx", s.id()); + ESP_LOGE(kTag, "failed to write data for #%lx", s.id); } } @@ -682,11 +693,11 @@ auto Database::ParseRecord<Track>(const leveldb::Slice& key, const leveldb::Slice& val) -> std::shared_ptr<Track> { std::shared_ptr<TrackData> data = ParseDataValue(val); - if (!data || data->is_tombstoned()) { + if (!data || data->is_tombstoned) { return {}; } std::shared_ptr<TrackTags> tags = - tag_parser_.ReadAndParseTags(data->filepath()); + tag_parser_.ReadAndParseTags(data->filepath); if (!tags) { return {}; } |
