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:
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");