diff options
Diffstat (limited to 'src/database/include')
| -rw-r--r-- | src/database/include/database.hpp | 70 | ||||
| -rw-r--r-- | src/database/include/records.hpp | 32 | ||||
| -rw-r--r-- | src/database/include/song.hpp | 76 | ||||
| -rw-r--r-- | src/database/include/tag_processor.hpp | 16 |
4 files changed, 137 insertions, 57 deletions
diff --git a/src/database/include/database.hpp b/src/database/include/database.hpp index 61918d96..6cdaaca6 100644 --- a/src/database/include/database.hpp +++ b/src/database/include/database.hpp @@ -1,5 +1,6 @@ #pragma once +#include <stdint.h> #include <cstdint> #include <future> #include <memory> @@ -13,46 +14,37 @@ #include "leveldb/iterator.h" #include "leveldb/options.h" #include "leveldb/slice.h" +#include "records.hpp" #include "result.hpp" +#include "song.hpp" namespace database { -struct Artist { - std::string name; -}; - -struct Album { - std::string name; -}; - -typedef uint64_t SongId_t; - -struct Song { - std::string title; - uint64_t id; -}; - -struct SongMetadata {}; - typedef std::unique_ptr<leveldb::Iterator> Continuation; +/* + * Wrapper for a set of results from the database. Owns the list of results, as + * well as a continuation token that can be used to continue fetching more + * results if they were paginated. + */ template <typename T> class Result { public: - auto values() -> std::unique_ptr<std::vector<T>> { - return std::move(values_); - } + auto values() -> std::vector<T>* { return values_.release(); } auto continuation() -> Continuation { return std::move(c_); } auto HasMore() -> bool { return c_->Valid(); } + Result(std::vector<T>* values, Continuation c) + : values_(values), c_(std::move(c)) {} + Result(std::unique_ptr<std::vector<T>> values, Continuation c) : values_(std::move(values)), c_(std::move(c)) {} Result(Result&& other) - : values_(std::move(other.values_)), c_(std::move(other.c_)) {} + : values_(move(other.values_)), c_(std::move(other.c_)) {} Result operator=(Result&& other) { - return Result(other.values(), other.continuation()); + return Result(other.values(), std::move(other.continuation())); } Result(const Result&) = delete; @@ -73,30 +65,16 @@ class Database { ~Database(); - auto Populate() -> std::future<void>; - - auto GetArtists(std::size_t page_size) -> std::future<Result<Artist>>; - auto GetMoreArtists(std::size_t page_size, Continuation c) - -> std::future<Result<Artist>>; - - auto GetAlbums(std::size_t page_size, std::optional<Artist> artist) - -> std::future<Result<Album>>; - auto GetMoreAlbums(std::size_t page_size, Continuation c) - -> std::future<Result<Album>>; + auto Update() -> std::future<void>; + auto Destroy() -> std::future<void>; auto GetSongs(std::size_t page_size) -> std::future<Result<Song>>; - auto GetSongs(std::size_t page_size, std::optional<Artist> artist) - -> std::future<Result<Song>>; - auto GetSongs(std::size_t page_size, - std::optional<Artist> artist, - std::optional<Album> album) -> std::future<Result<Song>>; auto GetMoreSongs(std::size_t page_size, Continuation c) -> std::future<Result<Song>>; - auto GetSongIds(std::optional<Artist> artist, std::optional<Album> album) - -> std::future<std::vector<SongId_t>>; - auto GetSongFilePath(SongId_t id) -> std::future<std::optional<std::string>>; - auto GetSongMetadata(SongId_t id) -> std::future<std::optional<SongMetadata>>; + auto GetDump(std::size_t page_size) -> std::future<Result<std::string>>; + auto GetMoreDump(std::size_t page_size, Continuation c) + -> std::future<Result<std::string>>; Database(const Database&) = delete; Database& operator=(const Database&) = delete; @@ -107,6 +85,16 @@ class Database { Database(leveldb::DB* db, leveldb::Cache* cache); + auto dbMintNewSongId() -> SongId; + auto dbEntomb(SongId song, uint64_t hash) -> void; + + auto dbPutSongData(const SongData& s) -> void; + auto dbGetSongData(SongId id) -> std::optional<SongData>; + auto dbPutHash(const uint64_t& hash, SongId i) -> void; + auto dbGetHash(const uint64_t& hash) -> std::optional<SongId>; + auto dbPutSong(SongId id, const std::string& path, const uint64_t& hash) + -> void; + template <typename T> using Parser = std::function<std::optional<T>(const leveldb::Slice& key, const leveldb::Slice& value)>; diff --git a/src/database/include/records.hpp b/src/database/include/records.hpp new file mode 100644 index 00000000..22d2ca5b --- /dev/null +++ b/src/database/include/records.hpp @@ -0,0 +1,32 @@ +#pragma once + +#include <leveldb/db.h> +#include <stdint.h> +#include <string> + +#include "leveldb/slice.h" +#include "song.hpp" + +namespace database { + +class OwningSlice { + public: + std::string data; + leveldb::Slice slice; + + explicit OwningSlice(std::string d); +}; + +auto CreateDataPrefix() -> OwningSlice; +auto CreateDataKey(const SongId& id) -> OwningSlice; +auto CreateDataValue(const SongData& song) -> OwningSlice; +auto ParseDataValue(const leveldb::Slice& slice) -> std::optional<SongData>; + +auto CreateHashKey(const uint64_t& hash) -> OwningSlice; +auto ParseHashValue(const leveldb::Slice&) -> std::optional<SongId>; +auto CreateHashValue(SongId id) -> OwningSlice; + +auto SongIdToBytes(SongId id) -> OwningSlice; +auto BytesToSongId(const std::string& bytes) -> SongId; + +} // namespace database diff --git a/src/database/include/song.hpp b/src/database/include/song.hpp new file mode 100644 index 00000000..79b2160a --- /dev/null +++ b/src/database/include/song.hpp @@ -0,0 +1,76 @@ +#pragma once + +#include <stdint.h> +#include <cstdint> +#include <optional> +#include <string> + +#include "leveldb/db.h" +#include "span.hpp" + +namespace database { + +typedef uint32_t SongId; + +enum Encoding { ENC_UNSUPPORTED, ENC_MP3 }; + +struct SongTags { + Encoding encoding; + std::optional<std::string> title; + std::optional<std::string> artist; + std::optional<std::string> album; + auto Hash() const -> uint64_t; +}; + +auto ReadAndParseTags(const std::string& path, SongTags* out) -> bool; + +class SongData { + private: + const SongId id_; + const std::string filepath_; + const uint64_t tags_hash_; + const uint32_t play_count_; + const bool is_tombstoned_; + + public: + SongData(SongId id, const std::string& path, uint64_t hash) + : id_(id), + filepath_(path), + tags_hash_(hash), + play_count_(0), + is_tombstoned_(false) {} + SongData(SongId id, + const std::string& path, + uint64_t hash, + uint32_t play_count, + bool is_tombstoned) + : id_(id), + filepath_(path), + tags_hash_(hash), + play_count_(play_count), + is_tombstoned_(is_tombstoned) {} + + auto id() const -> SongId { return id_; } + auto filepath() const -> std::string { return filepath_; } + auto play_count() const -> uint32_t { return play_count_; } + auto tags_hash() const -> uint64_t { return tags_hash_; } + auto is_tombstoned() const -> bool { return is_tombstoned_; } + + auto UpdateHash(uint64_t new_hash) const -> SongData; + auto Entomb() const -> SongData; + auto Exhume(const std::string& new_path) const -> SongData; +}; + +class Song { + public: + Song(SongData data, SongTags tags) : data_(data), tags_(tags) {} + + auto data() -> const SongData& { return data_; } + auto tags() -> const SongTags& { return tags_; } + + private: + const SongData data_; + const SongTags tags_; +}; + +} // namespace database diff --git a/src/database/include/tag_processor.hpp b/src/database/include/tag_processor.hpp deleted file mode 100644 index eda88225..00000000 --- a/src/database/include/tag_processor.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include <string> - -namespace database { - -struct FileInfo { - bool is_playable; - std::string artist; - std::string album; - std::string title; -}; - -auto GetInfo(const std::string& path, FileInfo* out) -> bool; - -} // namespace database |
