reapack

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

commit c69f154041ca827a3154707e833e254778f9b978
parent d1b7958963fb6348a6e86538110c69deb0e52121
Author: cfillion <cfillion@users.noreply.github.com>
Date:   Sun, 14 Feb 2016 04:05:02 -0500

store unparsed version numbers in the registry

In case another parsing bug is discovered, the fix will be able to take
effect right away.

Diffstat:
Msrc/database.cpp | 11-----------
Msrc/database.hpp | 3---
Msrc/registry.cpp | 35+++++++++++++++++------------------
Msrc/registry.hpp | 2+-
Msrc/version.cpp | 13++++++++++++-
Msrc/version.hpp | 6+++++-
Mtest/registry.cpp | 1+
Mtest/version.cpp | 14++++++++++++++
8 files changed, 50 insertions(+), 35 deletions(-)

diff --git a/src/database.cpp b/src/database.cpp @@ -127,12 +127,6 @@ void Statement::bind(const int index, const int integer) throw m_db->lastError(); } -void Statement::bind(const int index, const uint64_t integer) -{ - if(sqlite3_bind_int64(m_stmt, index, (sqlite3_int64)integer)) - throw m_db->lastError(); -} - void Statement::exec() { exec([=] { return false; }); @@ -162,11 +156,6 @@ int Statement::intColumn(const int index) const return sqlite3_column_int(m_stmt, index); } -uint64_t Statement::uint64Column(const int index) const -{ - return (uint64_t)sqlite3_column_int64(m_stmt, index); -} - string Statement::stringColumn(const int index) const { char *col = (char *)sqlite3_column_text(m_stmt, index); diff --git a/src/database.hpp b/src/database.hpp @@ -18,7 +18,6 @@ #ifndef REAPACK_DATABASE_HPP #define REAPACK_DATABASE_HPP -#include <cstdint> #include <functional> #include <string> #include <vector> @@ -58,12 +57,10 @@ public: void bind(int index, const std::string &text); void bind(int index, int integer); - void bind(int index, uint64_t integer); void exec(); void exec(const ExecCallback &); int intColumn(int index) const; - uint64_t uint64Column(int index) const; std::string stringColumn(int index) const; private: diff --git a/src/registry.cpp b/src/registry.cpp @@ -34,7 +34,7 @@ Registry::Registry(const Path &path) // entry queries m_insertEntry = m_db.prepare( - "INSERT INTO entries VALUES(NULL, ?, ?, ?, ?, ?, NULL);" + "INSERT INTO entries VALUES(NULL, ?, ?, ?, ?, ?);" ); m_updateEntry = m_db.prepare( @@ -48,24 +48,20 @@ Registry::Registry(const Path &path) ); m_allEntries = m_db.prepare( - "SELECT id, remote, category, package, type " + "SELECT id, remote, category, package, type, version " "FROM entries WHERE remote = ?" ); m_forgetEntry = m_db.prepare("DELETE FROM entries WHERE id = ?"); - m_setMainFile = m_db.prepare( - "UPDATE entries SET mainFile = (" - " SELECT id FROM files WHERE path = ?" - ") WHERE id = ?" - ); // file queries m_getFiles = m_db.prepare("SELECT path FROM files WHERE entry = ?"); m_getMainFile = m_db.prepare( - "SELECT path FROM files WHERE id = (" - " SELECT mainFile FROM entries WHERE id = ? LIMIT 1" - ") LIMIT 1" + "SELECT path FROM files WHERE main = 1 AND entry = ? LIMIT 1" + ); + m_setMainFile = m_db.prepare( + "UPDATE files SET main = 1 WHERE path = ? AND entry = ?" ); - m_insertFile = m_db.prepare("INSERT INTO files VALUES(NULL, ?, ?)"); + m_insertFile = m_db.prepare("INSERT INTO files VALUES(NULL, ?, ?, NULL)"); m_clearFiles = m_db.prepare( "DELETE FROM files WHERE entry = (" " SELECT id FROM entries WHERE remote = ? AND category = ? AND package = ?" @@ -93,8 +89,7 @@ void Registry::migrate() " category TEXT NOT NULL," " package TEXT NOT NULL," " type INTEGER NOT NULL," - " version INTEGER NOT NULL," - " mainFile INTEGER," + " version TEXT NOT NULL," " UNIQUE(remote, category, package)" ");" @@ -102,6 +97,7 @@ void Registry::migrate() " id INTEGER PRIMARY KEY," " entry INTEGER NOT NULL," " path TEXT UNIQUE NOT NULL," + " main INTEGER DEFAULT 0," " FOREIGN KEY(entry) REFERENCES entries(id)" ");" ); @@ -133,9 +129,10 @@ auto Registry::push(const Version *ver, vector<Path> *conflicts) -> Entry int entryId = getEntry(ver->package()).id; + // register version if(entryId) { m_updateEntry->bind(1, pkg->type()); - m_updateEntry->bind(2, ver->code()); + m_updateEntry->bind(2, ver->name()); m_updateEntry->bind(3, entryId); m_updateEntry->exec(); } @@ -144,12 +141,13 @@ auto Registry::push(const Version *ver, vector<Path> *conflicts) -> Entry m_insertEntry->bind(2, cat->name()); m_insertEntry->bind(3, pkg->name()); m_insertEntry->bind(4, pkg->type()); - m_insertEntry->bind(5, ver->code()); + m_insertEntry->bind(5, ver->name()); m_insertEntry->exec(); entryId = m_db.lastInsertId(); } + // register files for(const Path &path : ver->files()) { m_insertFile->bind(1, entryId); m_insertFile->bind(2, path.join('/')); @@ -206,7 +204,7 @@ auto Registry::getEntry(const Package *pkg) const -> Entry string category; string package; Package::Type type = Package::UnknownType; - uint64_t version = 0; + Version::Code version = 0; const Category *cat = pkg->category(); const RemoteIndex *ri = cat->index(); @@ -223,7 +221,7 @@ auto Registry::getEntry(const Package *pkg) const -> Entry category = m_findEntry->stringColumn(col++); package = m_findEntry->stringColumn(col++); type = static_cast<Package::Type>(m_findEntry->intColumn(col++)); - version = m_findEntry->uint64Column(col++); + Version::parse(m_findEntry->stringColumn(col++), &version); return false; }); @@ -245,7 +243,8 @@ auto Registry::getEntries(const Remote &remote) const -> vector<Entry> const string &package = m_allEntries->stringColumn(col++); const Package::Type type = static_cast<Package::Type>(m_allEntries->intColumn(col++)); - const uint64_t version = m_allEntries->uint64Column(col++); + Version::Code version = 0; + Version::parse(m_allEntries->stringColumn(col++), &version); list.push_back({id, remote, category, package, type, version}); diff --git a/src/registry.hpp b/src/registry.hpp @@ -46,7 +46,7 @@ public: std::string category; std::string package; Package::Type type; - uint64_t version; + Version::Code version; }; struct QueryResult { diff --git a/src/version.cpp b/src/version.cpp @@ -26,6 +26,17 @@ using namespace std; +bool Version::parse(const std::string &str, Code *out) +{ + try { + *out = Version(str, nullptr).code(); + return true; + } + catch(const reapack_error &) { + return false; + } +} + Version::Version(const std::string &str, Package *pkg) : m_name(str), m_code(0), m_time(), m_package(pkg), m_mainSource(nullptr) { @@ -49,7 +60,7 @@ Version::Version(const std::string &str, Package *pkg) if(match.size() > 4) throw reapack_error("version component overflow"); - m_code += stoi(match) * (uint64_t)pow(10000, size - index - 1); + m_code += stoi(match) * (Code)pow(10000, size - index - 1); } } diff --git a/src/version.hpp b/src/version.hpp @@ -29,6 +29,10 @@ class Package; class Version { public: + typedef uint64_t Code; + + static bool parse(const std::string &in, Code *out); + Version(const std::string &, Package * = nullptr); ~Version(); @@ -61,7 +65,7 @@ public: private: std::string m_name; - uint64_t m_code; + Code m_code; std::tm m_time; const Package *m_package; diff --git a/test/registry.cpp b/test/registry.cpp @@ -103,6 +103,7 @@ TEST_CASE("query all packages", M) { REQUIRE(entries[0].category == "Category Name"); REQUIRE(entries[0].package == "Hello"); REQUIRE(entries[0].type == Package::ScriptType); + REQUIRE(entries[0].version == Version("1.0").code()); } TEST_CASE("forget registry entry", M) { diff --git a/test/version.cpp b/test/version.cpp @@ -98,6 +98,20 @@ TEST_CASE("version with 5 components", M) { } } +TEST_CASE("public version parser", M) { + Version::Code code = 0; + + REQUIRE(Version::parse("1.0", &code)); + REQUIRE(code == UINT64_C(1000000000000)); + + REQUIRE_FALSE(Version::parse("hello", &code)); + REQUIRE(code == UINT64_C(1000000000000)); + + code = 0; + REQUIRE_FALSE(Version::parse("hello", &code)); + REQUIRE(code == UINT64_C(0)); +} + TEST_CASE("version full name", M) { SECTION("no package") { Version ver("1.0");