Add modified time to TrackData

custom
jacqueline 2 years ago
parent afbf3c31f4
commit ceba508593
  1. 12
      src/database/database.cpp
  2. 4
      src/database/file_gatherer.cpp
  3. 10
      src/database/include/file_gatherer.hpp
  4. 19
      src/database/include/track.hpp
  5. 16
      src/database/records.cpp
  6. 6
      src/database/track.cpp
  7. 1
      src/system_fsm/running.cpp

@ -7,6 +7,7 @@
#include "database.hpp" #include "database.hpp"
#include <stdint.h> #include <stdint.h>
#include <sys/_stdint.h>
#include <algorithm> #include <algorithm>
#include <cstdint> #include <cstdint>
@ -200,13 +201,16 @@ auto Database::Update() -> std::future<void> {
// Stage 2: search for newly added files. // Stage 2: search for newly added files.
ESP_LOGI(kTag, "scanning for new tracks"); ESP_LOGI(kTag, "scanning for new tracks");
uint64_t num_processed = 0; uint64_t num_processed = 0;
file_gatherer_.FindFiles("", [&](const std::pmr::string& path) { file_gatherer_.FindFiles("", [&](const std::pmr::string& path,
const FILINFO& info) {
num_processed++; num_processed++;
events::Ui().Dispatch(event::UpdateProgress{ events::Ui().Dispatch(event::UpdateProgress{
.stage = event::UpdateProgress::Stage::kScanningForNewTracks, .stage = event::UpdateProgress::Stage::kScanningForNewTracks,
.val = num_processed, .val = num_processed,
}); });
std::pair<uint16_t, uint16_t> modified{info.fdate, info.ftime};
std::shared_ptr<TrackTags> tags = tag_parser_.ReadAndParseTags(path); std::shared_ptr<TrackTags> tags = tag_parser_.ReadAndParseTags(path);
if (!tags || tags->encoding() == Container::kUnsupported) { if (!tags || tags->encoding() == Container::kUnsupported) {
// No parseable tags; skip this fiile. // No parseable tags; skip this fiile.
@ -228,7 +232,8 @@ auto Database::Update() -> std::future<void> {
TrackId id = dbMintNewTrackId(); TrackId id = dbMintNewTrackId();
ESP_LOGI(kTag, "recording new 0x%lx", id); ESP_LOGI(kTag, "recording new 0x%lx", id);
auto data = std::make_shared<TrackData>(id, path, hash); auto data = std::make_shared<TrackData>(id, path, hash, modified);
dbPutTrackData(*data); dbPutTrackData(*data);
dbPutHash(hash, id); dbPutHash(hash, id);
auto t = std::make_shared<Track>(data, tags); auto t = std::make_shared<Track>(data, tags);
@ -239,7 +244,8 @@ auto Database::Update() -> std::future<void> {
std::shared_ptr<TrackData> existing_data = dbGetTrackData(*existing_hash); std::shared_ptr<TrackData> existing_data = dbGetTrackData(*existing_hash);
if (!existing_data) { if (!existing_data) {
// We found a hash that matches, but there's no data record? Weird. // We found a hash that matches, but there's no data record? Weird.
auto new_data = std::make_shared<TrackData>(*existing_hash, path, hash); auto new_data =
std::make_shared<TrackData>(*existing_hash, path, hash, modified);
dbPutTrackData(*new_data); dbPutTrackData(*new_data);
auto t = std::make_shared<Track>(new_data, tags); auto t = std::make_shared<Track>(new_data, tags);
dbCreateIndexesForTrack(*t); dbCreateIndexesForTrack(*t);

@ -22,7 +22,7 @@ static_assert(sizeof(TCHAR) == sizeof(char), "TCHAR must be CHAR");
auto FileGathererImpl::FindFiles( auto FileGathererImpl::FindFiles(
const std::pmr::string& root, const std::pmr::string& root,
std::function<void(const std::pmr::string&)> cb) -> void { std::function<void(const std::pmr::string&, const FILINFO&)> cb) -> void {
std::pmr::deque<std::pmr::string> to_explore(&memory::kSpiRamResource); std::pmr::deque<std::pmr::string> to_explore(&memory::kSpiRamResource);
to_explore.push_back(root); to_explore.push_back(root);
@ -65,7 +65,7 @@ auto FileGathererImpl::FindFiles(
} else { } else {
// This is a file! Let the callback know about it. // This is a file! Let the callback know about it.
// std::invoke(cb, full_path.str(), info); // std::invoke(cb, full_path.str(), info);
std::invoke(cb, full_path); std::invoke(cb, full_path, info);
} }
} }
} }

@ -19,15 +19,17 @@ class IFileGatherer {
public: public:
virtual ~IFileGatherer(){}; virtual ~IFileGatherer(){};
virtual auto FindFiles(const std::pmr::string& root, virtual auto FindFiles(
std::function<void(const std::pmr::string&)> cb) const std::pmr::string& root,
std::function<void(const std::pmr::string&, const FILINFO&)> cb)
-> void = 0; -> void = 0;
}; };
class FileGathererImpl : public IFileGatherer { class FileGathererImpl : public IFileGatherer {
public: public:
virtual auto FindFiles(const std::pmr::string& root, virtual auto FindFiles(
std::function<void(const std::pmr::string&)> cb) const std::pmr::string& root,
std::function<void(const std::pmr::string&, const FILINFO&)> cb)
-> void override; -> void override;
}; };

@ -7,6 +7,7 @@
#pragma once #pragma once
#include <stdint.h> #include <stdint.h>
#include <sys/_stdint.h>
#include <map> #include <map>
#include <memory> #include <memory>
@ -118,23 +119,30 @@ class TrackData {
const std::pmr::string filepath_; const std::pmr::string filepath_;
const uint64_t tags_hash_; const uint64_t tags_hash_;
const bool is_tombstoned_; const bool is_tombstoned_;
const std::pair<uint16_t, uint16_t> modified_at_;
public: public:
/* Constructor used when adding new tracks to the database. */ /* Constructor used when adding new tracks to the database. */
TrackData(TrackId id, const std::pmr::string& path, uint64_t hash) TrackData(TrackId id,
const std::pmr::string& path,
uint64_t hash,
std::pair<uint16_t, uint16_t> modified_at)
: id_(id), : id_(id),
filepath_(path, &memory::kSpiRamResource), filepath_(path, &memory::kSpiRamResource),
tags_hash_(hash), tags_hash_(hash),
is_tombstoned_(false) {} is_tombstoned_(false),
modified_at_(modified_at) {}
TrackData(TrackId id, TrackData(TrackId id,
const std::pmr::string& path, const std::pmr::string& path,
uint64_t hash, uint64_t hash,
bool is_tombstoned) bool is_tombstoned,
std::pair<uint16_t, uint16_t> modified_at)
: id_(id), : id_(id),
filepath_(path, &memory::kSpiRamResource), filepath_(path, &memory::kSpiRamResource),
tags_hash_(hash), tags_hash_(hash),
is_tombstoned_(is_tombstoned) {} is_tombstoned_(is_tombstoned),
modified_at_(modified_at) {}
TrackData(TrackData&& other) = delete; TrackData(TrackData&& other) = delete;
TrackData& operator=(TrackData& other) = delete; TrackData& operator=(TrackData& other) = delete;
@ -145,6 +153,9 @@ class TrackData {
auto filepath() const -> std::pmr::string { return filepath_; } auto filepath() const -> std::pmr::string { return filepath_; }
auto tags_hash() const -> uint64_t { return tags_hash_; } auto tags_hash() const -> uint64_t { return tags_hash_; }
auto is_tombstoned() const -> bool { return is_tombstoned_; } auto is_tombstoned() const -> bool { return is_tombstoned_; }
auto modified_at() const -> std::pair<uint16_t, uint16_t> {
return modified_at_;
}
auto UpdateHash(uint64_t new_hash) const -> TrackData; auto UpdateHash(uint64_t new_hash) const -> TrackData;

@ -67,6 +67,8 @@ auto EncodeDataValue(const TrackData& track) -> std::string {
cppbor::Tstr{track.filepath()}, cppbor::Tstr{track.filepath()},
cppbor::Uint{track.tags_hash()}, cppbor::Uint{track.tags_hash()},
cppbor::Bool{track.is_tombstoned()}, cppbor::Bool{track.is_tombstoned()},
cppbor::Uint{track.modified_at().first},
cppbor::Uint{track.modified_at().second},
}; };
return val.toString(); return val.toString();
} }
@ -78,18 +80,24 @@ auto ParseDataValue(const leveldb::Slice& slice) -> std::shared_ptr<TrackData> {
return nullptr; return nullptr;
} }
auto vals = item->asArray(); auto vals = item->asArray();
if (vals->size() != 4 || vals->get(0)->type() != cppbor::UINT || if (vals->size() != 6 || vals->get(0)->type() != cppbor::UINT ||
vals->get(1)->type() != cppbor::TSTR || vals->get(1)->type() != cppbor::TSTR ||
vals->get(2)->type() != cppbor::UINT || vals->get(2)->type() != cppbor::UINT ||
vals->get(3)->type() != cppbor::SIMPLE) { vals->get(3)->type() != cppbor::SIMPLE ||
vals->get(4)->type() != cppbor::UINT ||
vals->get(5)->type() != cppbor::UINT) {
return {}; return {};
} }
TrackId id = vals->get(0)->asUint()->unsignedValue(); TrackId id = vals->get(0)->asUint()->unsignedValue();
auto path = vals->get(1)->asViewTstr()->view(); auto path = vals->get(1)->asViewTstr()->view();
uint64_t hash = vals->get(2)->asUint()->unsignedValue(); uint64_t hash = vals->get(2)->asUint()->unsignedValue();
bool tombstoned = vals->get(3)->asBool()->value(); bool tombstoned = vals->get(3)->asBool()->value();
return std::make_shared<TrackData>( auto modified_at = std::make_pair<uint16_t, uint16_t>(
id, std::pmr::string{path.data(), path.size()}, hash, tombstoned); vals->get(4)->asUint()->unsignedValue(),
vals->get(5)->asUint()->unsignedValue());
return std::make_shared<TrackData>(id,
std::pmr::string{path.data(), path.size()},
hash, tombstoned, modified_at);
} }
/* 'H/ 0xBEEF' */ /* 'H/ 0xBEEF' */

@ -53,15 +53,15 @@ auto TrackTags::Hash() const -> uint64_t {
} }
auto TrackData::UpdateHash(uint64_t new_hash) const -> TrackData { auto TrackData::UpdateHash(uint64_t new_hash) const -> TrackData {
return TrackData(id_, filepath_, new_hash, is_tombstoned_); return TrackData(id_, filepath_, new_hash, is_tombstoned_, modified_at_);
} }
auto TrackData::Entomb() const -> TrackData { auto TrackData::Entomb() const -> TrackData {
return TrackData(id_, filepath_, tags_hash_, true); return TrackData(id_, filepath_, tags_hash_, true, modified_at_);
} }
auto TrackData::Exhume(const std::pmr::string& new_path) const -> TrackData { auto TrackData::Exhume(const std::pmr::string& new_path) const -> TrackData {
return TrackData(id_, new_path, tags_hash_, false); return TrackData(id_, new_path, tags_hash_, false, modified_at_);
} }
auto Track::TitleOrFilename() const -> std::pmr::string { auto Track::TitleOrFilename() const -> std::pmr::string {

@ -55,6 +55,7 @@ void Running::entry() {
ESP_LOGI(kTag, "opening database"); ESP_LOGI(kTag, "opening database");
sFileGatherer = new database::FileGathererImpl(); sFileGatherer = new database::FileGathererImpl();
database::Database::Destroy();
auto database_res = auto database_res =
database::Database::Open(*sFileGatherer, sServices->tag_parser()); database::Database::Open(*sFileGatherer, sServices->tag_parser());
if (database_res.has_error()) { if (database_res.has_error()) {

Loading…
Cancel
Save