reapack

Package manager for REAPER
Log | Files | Refs | Submodules | README | LICENSE

commit 644aa3eac196f790b983f69c5b43198b951873e6
parent 2a812b5c4995cd2444ab912a11668a5c278203a9
Author: cfillion <cfillion@users.noreply.github.com>
Date:   Fri,  2 Jun 2017 00:21:51 -0400

api: create GetOwner function

Diffstat:
Msrc/api.cpp | 35+++++++++++++++++++++++++++++++----
Msrc/api.hpp | 7+++++--
Msrc/main.cpp | 2++
Msrc/reapack.hpp | 1-
Msrc/registry.cpp | 29++++++++++++++++++++++++++---
Msrc/registry.hpp | 2++
Mtest/registry.cpp | 12+++++++++++-
7 files changed, 77 insertions(+), 11 deletions(-)

diff --git a/src/api.cpp b/src/api.cpp @@ -21,7 +21,9 @@ #include <reaper_plugin_functions.h> +#include "errors.hpp" #include "reapack.hpp" +#include "registry.hpp" #include "remote.hpp" #include "version.hpp" @@ -66,9 +68,7 @@ void APIDef::unregister(const char *key, void *ptr) namespace name { \ static type cImpl(BOOST_PP_SEQ_FOR_EACH_I(ARGS, _, args)) __VA_ARGS__ \ void *reascriptImpl(void **argv, int argc) { \ - if(argc == BOOST_PP_SEQ_SIZE(args)) \ - return (void *)(intptr_t)cImpl(BOOST_PP_SEQ_FOR_EACH_I(PARAMS, _, args)); \ - return nullptr; \ + return (void *)(intptr_t)cImpl(BOOST_PP_SEQ_FOR_EACH_I(PARAMS, _, args)); \ } \ static const char *definition = #type "\0" \ BOOST_PP_SEQ_FOR_EACH_I(DEFARGS, ARG_TYPE, args) "\0" \ @@ -80,6 +80,12 @@ void APIDef::unregister(const char *key, void *ptr) "APIdef_" API_PREFIX #name, (void *)name::definition, \ } +DEFINE_API(bool, AboutPackage, ((int, id)), + "Show the about dialog of the given package. Returns true on success.", +{ + return false; +}); + DEFINE_API(bool, AboutRepository, ((const char*, repoName)), "Show the about dialog of the given repository. Returns true on success.", { @@ -93,7 +99,7 @@ DEFINE_API(bool, AboutRepository, ((const char*, repoName)), DEFINE_API(bool, CompareVersions, ((const char*, ver1))((const char*, ver2)) ((int*, resultOut))((char*, errorOut))((int, errorOut_sz)), - "Compare version numbers. Returns 0 if both versions are equal," + "Returns 0 if both versions are equal," " a positive value if ver1 is higher than ver2" " and a negative value otherwise.", { @@ -112,3 +118,24 @@ DEFINE_API(bool, CompareVersions, ((const char*, ver1))((const char*, ver2)) return false; }); + +DEFINE_API(int, GetOwner, ((const char*, fn))((char*, errorOut))((int, errorOut_sz)), + "Returns ID of the package owning the given file or 0 on error.", +{ + try { + const Registry reg(Path::prefixRoot(Path::REGISTRY)); + const int owner = (int)reg.getOwner(Path(fn)); + + if(!owner && errorOut) + snprintf(errorOut, errorOut_sz, "file is not owned by any package"); + + return owner; + } + catch(const reapack_error &e) + { + if(errorOut) + snprintf(errorOut, errorOut_sz, "%s", e.what()); + + return 0; + } +}); diff --git a/src/api.hpp b/src/api.hpp @@ -42,11 +42,14 @@ private: const APIFunc *m_func; }; + namespace API { + extern ReaPack *reapack; + + extern APIFunc AboutPackage; extern APIFunc AboutRepository; extern APIFunc CompareVersions; - - extern ReaPack *reapack; + extern APIFunc GetOwner; }; #endif diff --git a/src/main.cpp b/src/main.cpp @@ -160,8 +160,10 @@ static void setupActions() static void setupAPI() { + reapack->setupAPI(&API::AboutPackage); reapack->setupAPI(&API::AboutRepository); reapack->setupAPI(&API::CompareVersions); + reapack->setupAPI(&API::GetOwner); } extern "C" REAPER_PLUGIN_DLL_EXPORT int REAPER_PLUGIN_ENTRYPOINT( diff --git a/src/reapack.hpp b/src/reapack.hpp @@ -19,7 +19,6 @@ #define REAPACK_REAPACK_HPP #include "path.hpp" -#include "registry.hpp" #include <functional> #include <map> diff --git a/src/registry.cpp b/src/registry.cpp @@ -57,6 +57,9 @@ Registry::Registry(const Path &path) m_forgetEntry = m_db.prepare("DELETE FROM entries WHERE id = ?"); // file queries + m_getOwner = m_db.prepare( + "SELECT entry FROM files WHERE path = ? LIMIT 1" + ); m_getFiles = m_db.prepare( "SELECT path, main, type FROM files WHERE entry = ? ORDER BY path" ); @@ -260,9 +263,13 @@ auto Registry::getFiles(const Entry &entry) const -> vector<File> m_getFiles->bind(1, entry.id); m_getFiles->exec([&] { - File file{m_getFiles->stringColumn(0)}; - file.sections = static_cast<int>(m_getFiles->intColumn(1)); - file.type = static_cast<Package::Type>(m_getFiles->intColumn(2)); + int col = 0; + + File file{ + m_getFiles->stringColumn(col++), + static_cast<int>(m_getFiles->intColumn(col++)), + static_cast<Package::Type>(m_getFiles->intColumn(col++)), + }; if(!file.type) // < v1.0rc2 file.type = entry.type; @@ -288,6 +295,22 @@ auto Registry::getMainFiles(const Entry &entry) const -> vector<File> return mainFiles; } +int64_t Registry::getOwner(const Path &path) const +{ + Entry entry{}; + + m_getOwner->bind(1, path.join('/')); + + int64_t id = 0; + + m_getOwner->exec([&] { + id = m_getOwner->intColumn(0); + return false; + }); + + return id; +} + void Registry::forget(const Entry &entry) { m_forgetFiles->bind(1, entry.id); diff --git a/src/registry.hpp b/src/registry.hpp @@ -57,6 +57,7 @@ public: std::vector<Entry> getEntries(const std::string &) const; std::vector<File> getFiles(const Entry &) const; std::vector<File> getMainFiles(const Entry &) const; + int64_t getOwner(const Path &) const; Entry push(const Version *, std::vector<Path> *conflicts = nullptr); void setPinned(const Entry &, bool pinned); void forget(const Entry &); @@ -78,6 +79,7 @@ private: Statement *m_allEntries; Statement *m_forgetEntry; + Statement *m_getOwner; Statement *m_getFiles; Statement *m_insertFile; Statement *m_clearFiles; diff --git a/test/registry.cpp b/test/registry.cpp @@ -168,7 +168,7 @@ TEST_CASE("get main files", M) { MAKE_PACKAGE Registry reg; - REQUIRE((reg.getMainFiles({})).empty()); + REQUIRE(reg.getMainFiles({}).empty()); Source *main1 = new Source({}, "url", &ver); main1->setSections(Source::MIDIEditorSection); @@ -205,3 +205,13 @@ TEST_CASE("pin registry entry", M) { reg.setPinned(entry, false); REQUIRE_FALSE(reg.getEntry(&pkg).pinned); } + +TEST_CASE("get file owner", M) { + MAKE_PACKAGE + + Registry reg; + REQUIRE(reg.getOwner({}) == 0); + + const Registry::Entry &entry = reg.push(&ver); + REQUIRE(reg.getOwner(src->targetPath()) == entry.id); +}