diff options
| author | jacqueline <me@jacqueline.id.au> | 2023-04-26 15:21:32 +1000 |
|---|---|---|
| committer | jacqueline <me@jacqueline.id.au> | 2023-04-26 15:21:32 +1000 |
| commit | fbe047a35fff100cb5f42d10984bccde137f586e (patch) | |
| tree | ab05dff1142f6a6a14f4b03a4340672a5e65976a /src/database | |
| parent | 083f4011aa740d492d9a9ceb07c7228003f5ad39 (diff) | |
| download | tangara-fw-fbe047a35fff100cb5f42d10984bccde137f586e.tar.gz | |
Add some basic data and retrieval
Diffstat (limited to 'src/database')
| -rw-r--r-- | src/database/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/database/database.cpp | 59 | ||||
| -rw-r--r-- | src/database/env_esp.cpp | 2 | ||||
| -rw-r--r-- | src/database/include/database.hpp | 23 | ||||
| -rw-r--r-- | src/database/include/file_gatherer.hpp | 11 | ||||
| -rw-r--r-- | src/database/include/tag_processor.hpp | 13 | ||||
| -rw-r--r-- | src/database/tag_processor.cpp | 15 |
7 files changed, 88 insertions, 37 deletions
diff --git a/src/database/CMakeLists.txt b/src/database/CMakeLists.txt index 01365bf7..3f9ca6fb 100644 --- a/src/database/CMakeLists.txt +++ b/src/database/CMakeLists.txt @@ -1,5 +1,5 @@ idf_component_register( - SRCS "env_esp.cpp" "database.cpp" + SRCS "env_esp.cpp" "database.cpp" "tag_processor.cpp" INCLUDE_DIRS "include" REQUIRES "result" "span" "esp_psram" "fatfs") diff --git a/src/database/database.cpp b/src/database/database.cpp index cfac77af..b677f4ba 100644 --- a/src/database/database.cpp +++ b/src/database/database.cpp @@ -4,6 +4,10 @@ #include "ff.h" #include "leveldb/cache.h" +#include "file_gatherer.hpp" +#include "leveldb/iterator.h" +#include "leveldb/slice.h" +#include "tag_processor.hpp" #include "env_esp.hpp" #include "leveldb/options.h" @@ -38,38 +42,37 @@ Database::Database(leveldb::DB* db, leveldb::Cache* cache) Database::~Database() {} -FRESULT scan_files(const std::string &path) { - FRESULT res; - FF_DIR dir; - static FILINFO fno; - - res = f_opendir(&dir, path.c_str()); - if (res == FR_OK) { - for (;;) { - res = f_readdir(&dir, &fno); - if (res != FR_OK || fno.fname[0] == 0) break; - if (fno.fname[0] == '.') continue; - if (fno.fattrib & AM_DIR) { - std::string new_path = path + "/" + fno.fname; - res = scan_files(new_path); - if (res != FR_OK) break; - } else { - ESP_LOGI(kTag, "found %s", fno.fname); - } - } - f_closedir(&dir); - } - - return res; +auto Database::Initialise() -> void { + leveldb::WriteOptions opt; + opt.sync = true; + FindFiles("", [&](const std::string &path) { + ESP_LOGI(kTag, "considering %s", path.c_str()); + FileInfo info; + if (GetInfo(path, &info)) { + ESP_LOGI(kTag, "added as '%s'", info.title.c_str()); + db_->Put(opt, "title:" + info.title, path); + } + }); + db_->Put(opt, "title:coolkeywithoutval", leveldb::Slice()); } -auto Database::Initialise() -> void { - // TODO(jacqueline): Abstractions lol - scan_files("/"); +auto Database::ByTitle() -> Iterator { + leveldb::Iterator *it = db_->NewIterator(leveldb::ReadOptions()); + it->Seek("title:"); + while (it->Valid()) { + ESP_LOGI(kTag, "%s : %s", it->key().ToString().c_str(), it->value().ToString().c_str()); + it->Next(); + } + return Iterator(it); } -auto Database::Update() -> void { - // TODO(jacqueline): Incremental updates! +auto Iterator::Next() -> std::optional<std::string> { + if (!it_->Valid()) { + return {}; + } + std::string ret = it_->key().ToString(); + it_->Next(); + return ret; } } // namespace database diff --git a/src/database/env_esp.cpp b/src/database/env_esp.cpp index 45129a36..363421a7 100644 --- a/src/database/env_esp.cpp +++ b/src/database/env_esp.cpp @@ -465,7 +465,7 @@ void EspEnv::Schedule( if (!started_background_thread_) { started_background_thread_ = true; xTaskCreate(reinterpret_cast<TaskFunction_t>(BackgroundThreadEntryPoint), - "LVL_ONEOFF", 2048, reinterpret_cast<void*>(this), 3, NULL); + "LVL_ONEOFF", 16 * 1024, reinterpret_cast<void*>(this), 3, NULL); } BackgroundWorkItem item(background_work_function, background_work_arg); diff --git a/src/database/include/database.hpp b/src/database/include/database.hpp index b9df5fd4..cb1437df 100644 --- a/src/database/include/database.hpp +++ b/src/database/include/database.hpp @@ -1,13 +1,18 @@ #pragma once +#include <string> #include <memory> +#include <optional> #include "leveldb/cache.h" #include "leveldb/db.h" +#include "leveldb/iterator.h" #include "result.hpp" namespace database { +class Iterator; + class Database { public: enum DatabaseError { @@ -18,7 +23,10 @@ class Database { ~Database(); auto Initialise() -> void; - auto Update() -> void; + auto ByTitle() -> Iterator; + + Database(const Database&) = delete; + Database& operator=(const Database&) = delete; private: std::unique_ptr<leveldb::DB> db_; @@ -27,4 +35,17 @@ class Database { Database(leveldb::DB* db, leveldb::Cache* cache); }; +class Iterator { + public: + explicit Iterator(leveldb::Iterator *it) : it_(it) {} + + auto Next() -> std::optional<std::string>; + + Iterator(const Iterator&) = delete; + Iterator& operator=(const Iterator&) = delete; + + private: + std::unique_ptr<leveldb::Iterator> it_; +}; + } // namespace database diff --git a/src/database/include/file_gatherer.hpp b/src/database/include/file_gatherer.hpp index 47d40f88..7cf00b41 100644 --- a/src/database/include/file_gatherer.hpp +++ b/src/database/include/file_gatherer.hpp @@ -12,7 +12,7 @@ namespace database { static_assert(sizeof(TCHAR) == sizeof(char), "TCHAR must be CHAR"); template <typename Callback> -auto FindFiles(FATFS* fs, const std::string& root, Callback cb) -> void { +auto FindFiles(const std::string& root, Callback cb) -> void { std::deque<std::string> to_explore; to_explore.push_back(root); @@ -20,7 +20,7 @@ auto FindFiles(FATFS* fs, const std::string& root, Callback cb) -> void { std::string next_path_str = to_explore.front(); const TCHAR* next_path = static_cast<const TCHAR*>(next_path_str.c_str()); - DIR dir; + FF_DIR dir; FRESULT res = f_opendir(&dir, next_path); if (res != FR_OK) { // TODO: log. @@ -30,10 +30,10 @@ auto FindFiles(FATFS* fs, const std::string& root, Callback cb) -> void { for (;;) { FILINFO info; res = f_readdir(&dir, &info); - if (info.fname == NULL) { + if (res != FR_OK || info.fname[0] == 0) { // No more files in the directory. break; - } else if (info.fattrib & (AM_HID | AM_SYS)) { + } else if (info.fattrib & (AM_HID | AM_SYS) || info.fname[0] == '.') { // System or hidden file. Ignore it and move on. continue; } else { @@ -45,7 +45,8 @@ auto FindFiles(FATFS* fs, const std::string& root, Callback cb) -> void { to_explore.push_back(full_path.str()); } else { // 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.str()); } } } diff --git a/src/database/include/tag_processor.hpp b/src/database/include/tag_processor.hpp index 0257fc92..88c95b61 100644 --- a/src/database/include/tag_processor.hpp +++ b/src/database/include/tag_processor.hpp @@ -1,3 +1,14 @@ #pragma once -namespace database {} // namespace database +#include <string> + +namespace database { + +struct FileInfo { + bool is_playable; + std::string title; +}; + +auto GetInfo(const std::string &path, FileInfo *out) -> bool; + +} // namespace database diff --git a/src/database/tag_processor.cpp b/src/database/tag_processor.cpp new file mode 100644 index 00000000..f2d520a4 --- /dev/null +++ b/src/database/tag_processor.cpp @@ -0,0 +1,15 @@ +#include "tag_processor.hpp" + +namespace database { + +auto GetInfo(const std::string &path, FileInfo *out) -> bool { + // TODO(jacqueline): bring in taglib for this + if (path.ends_with(".mp3")) { + out->is_playable = true; + out->title = path.substr(0, path.size() - 4); + return true; + } + return false; +} + +} // namespace database |
