Refactor to optimize deserialization of base-data
* Break backwards compatibility * Allow to deserialize only base-data of packages and build actions to potentially speed up showing tables * Speed up package search in many cases by only deserializing base-data (unless details are actually wanted)
This commit is contained in:
parent
ae44624989
commit
68d67f543f
|
@ -1 +1 @@
|
||||||
Subproject commit 2f5eb32a33130c4deb139118ebbd2dfa634d69bd
|
Subproject commit 9a9bed0f462244192e7f8524077c0daef64047c6
|
|
@ -200,6 +200,29 @@ void Config::packages(std::string_view dbName, std::string_view dbArch, const st
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Config::packages(std::string_view dbName, std::string_view dbArch, const std::string &packageName, const DatabaseVisitor &databaseVisitor,
|
||||||
|
const PackageVisitorBase &visitor)
|
||||||
|
{
|
||||||
|
// don't allow to iterate though all packages
|
||||||
|
if (packageName.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto basePackage = std::make_shared<PackageBase>();
|
||||||
|
for (auto &db : databases) {
|
||||||
|
if ((!dbName.empty() && dbName != db.name) || (!dbArch.empty() && dbArch != db.arch) || (databaseVisitor && databaseVisitor(db))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!basePackage) {
|
||||||
|
basePackage = std::make_shared<PackageBase>();
|
||||||
|
} else {
|
||||||
|
basePackage->clear();
|
||||||
|
}
|
||||||
|
if (const auto id = db.findBasePackageWithID(packageName, *basePackage)) {
|
||||||
|
visitor(db, id, std::move(basePackage));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Config::packagesByName(const DatabaseVisitor &databaseVisitor, const PackageVisitorByName &visitor)
|
void Config::packagesByName(const DatabaseVisitor &databaseVisitor, const PackageVisitorByName &visitor)
|
||||||
{
|
{
|
||||||
for (auto &db : databases) {
|
for (auto &db : databases) {
|
||||||
|
@ -211,6 +234,17 @@ void Config::packagesByName(const DatabaseVisitor &databaseVisitor, const Packag
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Config::packagesByName(const DatabaseVisitor &databaseVisitor, const PackageVisitorByNameBase &visitor)
|
||||||
|
{
|
||||||
|
for (auto &db : databases) {
|
||||||
|
if (databaseVisitor && databaseVisitor(db)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
db.allPackagesByName(
|
||||||
|
[&](std::string_view packageName, const std::function<StorageID(PackageBase&)> &getPackage) { return visitor(db, packageName, getPackage); });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Config::providingPackages(const Dependency &dependency, bool reverse, const DatabaseVisitor &databaseVisitor, const PackageVisitorConst &visitor)
|
void Config::providingPackages(const Dependency &dependency, bool reverse, const DatabaseVisitor &databaseVisitor, const PackageVisitorConst &visitor)
|
||||||
{
|
{
|
||||||
for (auto &db : databases) {
|
for (auto &db : databases) {
|
||||||
|
|
|
@ -107,10 +107,12 @@ constexpr bool operator&(BuildOrderOptions lhs, BuildOrderOptions rhs)
|
||||||
|
|
||||||
struct LIBPKG_EXPORT Config : public Lockable, public ReflectiveRapidJSON::BinarySerializable<Config> {
|
struct LIBPKG_EXPORT Config : public Lockable, public ReflectiveRapidJSON::BinarySerializable<Config> {
|
||||||
using DatabaseVisitor = std::function<bool(Database &)>;
|
using DatabaseVisitor = std::function<bool(Database &)>;
|
||||||
|
using PackageVisitorBase = std::function<bool(Database &, StorageID, std::shared_ptr<PackageBase> &&)>; // package is invalidated/reused unless moved from!!!
|
||||||
using PackageVisitorMove
|
using PackageVisitorMove
|
||||||
= std::function<bool(Database &, StorageID, std::shared_ptr<Package> &&)>; // package is invalidated/reused unless moved from!!!
|
= std::function<bool(Database &, StorageID, std::shared_ptr<Package> &&)>; // package is invalidated/reused unless moved from!!!
|
||||||
using PackageVisitorConst = std::function<bool(Database &, StorageID, const std::shared_ptr<Package> &)>;
|
using PackageVisitorConst = std::function<bool(Database &, StorageID, const std::shared_ptr<Package> &)>;
|
||||||
using PackageVisitorByName = std::function<bool(Database &, std::string_view, const std::function<PackageSpec(void)> &)>;
|
using PackageVisitorByName = std::function<bool(Database &, std::string_view, const std::function<PackageSpec(void)> &)>;
|
||||||
|
using PackageVisitorByNameBase = std::function<bool(Database &, std::string_view, const std::function<StorageID(PackageBase&)> &)>;
|
||||||
|
|
||||||
explicit Config();
|
explicit Config();
|
||||||
~Config();
|
~Config();
|
||||||
|
@ -164,7 +166,10 @@ struct LIBPKG_EXPORT Config : public Lockable, public ReflectiveRapidJSON::Binar
|
||||||
// package iteration
|
// package iteration
|
||||||
void packages(std::string_view dbName, std::string_view dbArch, const std::string &packageName, const DatabaseVisitor &databaseVisitor,
|
void packages(std::string_view dbName, std::string_view dbArch, const std::string &packageName, const DatabaseVisitor &databaseVisitor,
|
||||||
const PackageVisitorConst &visitor);
|
const PackageVisitorConst &visitor);
|
||||||
|
void packages(std::string_view dbName, std::string_view dbArch, const std::string &packageName, const DatabaseVisitor &databaseVisitor,
|
||||||
|
const PackageVisitorBase &visitor);
|
||||||
void packagesByName(const DatabaseVisitor &databaseVisitor, const PackageVisitorByName &visitor);
|
void packagesByName(const DatabaseVisitor &databaseVisitor, const PackageVisitorByName &visitor);
|
||||||
|
void packagesByName(const DatabaseVisitor &databaseVisitor, const PackageVisitorByNameBase &visitor);
|
||||||
void providingPackages(const Dependency &dependency, bool reverse, const DatabaseVisitor &databaseVisitor, const PackageVisitorConst &visitor);
|
void providingPackages(const Dependency &dependency, bool reverse, const DatabaseVisitor &databaseVisitor, const PackageVisitorConst &visitor);
|
||||||
void providingPackages(const std::string &libraryName, bool reverse, const DatabaseVisitor &databaseVisitor, const PackageVisitorConst &visitor);
|
void providingPackages(const std::string &libraryName, bool reverse, const DatabaseVisitor &databaseVisitor, const PackageVisitorConst &visitor);
|
||||||
|
|
||||||
|
|
|
@ -299,12 +299,33 @@ void Database::allPackages(const PackageVisitorMove &visitor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Database::allPackages(const PackageVisitorBase &visitor)
|
||||||
|
{
|
||||||
|
auto txn = m_storage->packages.getROTransaction();
|
||||||
|
for (auto i = txn.begin<std::shared_ptr, PackageBase>(); i != txn.end(); ++i) {
|
||||||
|
if (visitor(i.getID(), std::move(i.getPointer()))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void LibPkg::Database::allPackagesByName(const PackageVisitorByName &visitor)
|
void LibPkg::Database::allPackagesByName(const PackageVisitorByName &visitor)
|
||||||
{
|
{
|
||||||
auto txn = m_storage->packages.getROTransaction();
|
auto txn = m_storage->packages.getROTransaction();
|
||||||
for (auto i = txn.begin_idx<0, std::shared_ptr>(); i != txn.end(); ++i) {
|
for (auto i = txn.begin_idx<0, std::shared_ptr>(); i != txn.end(); ++i) {
|
||||||
const auto packageName = i.getKey().get<string_view>();
|
const auto packageName = i.getKey().get<string_view>();
|
||||||
if (visitor(packageName, [this, &txn, &i]() { return m_storage->packageCache.retrieve(*m_storage, &txn, i.value()); })) {
|
if (visitor(packageName, [this, &txn, &i] { return m_storage->packageCache.retrieve(*m_storage, &txn, i.value()); })) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LibPkg::Database::allPackagesByName(const PackageVisitorByNameBase &visitor)
|
||||||
|
{
|
||||||
|
auto txn = m_storage->packages.getROTransaction();
|
||||||
|
for (auto i = txn.begin_idx<0, std::shared_ptr>(); i != txn.end(); ++i) {
|
||||||
|
const auto packageName = i.getKey().get<string_view>();
|
||||||
|
if (visitor(packageName, [&txn, &i] (PackageBase &pkg) { return txn.get(i.value(), pkg); })) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -393,6 +414,12 @@ PackageSpec Database::findPackageWithID(const std::string &packageName)
|
||||||
return m_storage->packageCache.retrieve(*m_storage, packageName);
|
return m_storage->packageCache.retrieve(*m_storage, packageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StorageID Database::findBasePackageWithID(const std::string &packageName, PackageBase &basePackage)
|
||||||
|
{
|
||||||
|
auto txn = m_storage->packages.getROTransaction();
|
||||||
|
return txn.get<0, PackageBase>(packageName, basePackage);
|
||||||
|
}
|
||||||
|
|
||||||
void Database::removePackage(const std::string &packageName)
|
void Database::removePackage(const std::string &packageName)
|
||||||
{
|
{
|
||||||
const auto lock = std::unique_lock(m_storage->updateMutex);
|
const auto lock = std::unique_lock(m_storage->updateMutex);
|
||||||
|
@ -504,7 +531,7 @@ std::unordered_map<PackageSpec, UnresolvedDependencies> Database::detectUnresolv
|
||||||
// add packages to list of unresolved packages
|
// add packages to list of unresolved packages
|
||||||
for (const auto &affectedPackageID : requiredDep.relevantPackages) {
|
for (const auto &affectedPackageID : requiredDep.relevantPackages) {
|
||||||
const auto affectedPackage = findPackage(affectedPackageID);
|
const auto affectedPackage = findPackage(affectedPackageID);
|
||||||
unresolvedPackages[PackageSpec(affectedPackageID, affectedPackage)].deps.emplace_back(requiredDep);
|
unresolvedPackages[GenericPackageSpec(affectedPackageID, affectedPackage)].deps.emplace_back(requiredDep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -545,7 +572,7 @@ std::unordered_map<PackageSpec, UnresolvedDependencies> Database::detectUnresolv
|
||||||
// add packages to list of unresolved packages
|
// add packages to list of unresolved packages
|
||||||
for (const auto &affectedPackageID : requiredLib.relevantPackages) {
|
for (const auto &affectedPackageID : requiredLib.relevantPackages) {
|
||||||
const auto affectedPackage = findPackage(affectedPackageID);
|
const auto affectedPackage = findPackage(affectedPackageID);
|
||||||
unresolvedPackages[PackageSpec(affectedPackageID, affectedPackage)].libs.emplace_back(requiredLib.name);
|
unresolvedPackages[GenericPackageSpec(affectedPackageID, affectedPackage)].libs.emplace_back(requiredLib.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -801,7 +828,7 @@ PackageUpdater::~PackageUpdater()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
LibPkg::PackageSpec LibPkg::PackageUpdater::findPackageWithID(const std::string &packageName)
|
PackageSpec LibPkg::PackageUpdater::findPackageWithID(const std::string &packageName)
|
||||||
{
|
{
|
||||||
return m_database.m_storage->packageCache.retrieve(*m_database.m_storage, &m_d->packagesTxn, packageName);
|
return m_database.m_storage->packageCache.retrieve(*m_database.m_storage, &m_d->packagesTxn, packageName);
|
||||||
}
|
}
|
||||||
|
@ -901,14 +928,14 @@ void push<LibPkg::PackageSearchResult>(
|
||||||
push(pkg->timestamp, "timestamp", obj, allocator);
|
push(pkg->timestamp, "timestamp", obj, allocator);
|
||||||
push(pkg->version, "version", obj, allocator);
|
push(pkg->version, "version", obj, allocator);
|
||||||
push(pkg->description, "description", obj, allocator);
|
push(pkg->description, "description", obj, allocator);
|
||||||
if (const auto &pkgInfo = pkg->packageInfo) {
|
if (!pkg->arch.empty()) {
|
||||||
push(pkgInfo->arch, "arch", obj, allocator);
|
push(pkg->arch, "arch", obj, allocator);
|
||||||
push(pkgInfo->buildDate, "buildDate", obj, allocator);
|
}
|
||||||
|
if (!pkg->buildDate.isNull()) {
|
||||||
|
push(pkg->buildDate, "buildDate", obj, allocator);
|
||||||
}
|
}
|
||||||
if (!pkg->archs.empty()) {
|
if (!pkg->archs.empty()) {
|
||||||
push(pkg->archs, "archs", obj, allocator);
|
push(pkg->archs, "archs", obj, allocator);
|
||||||
} else if (const auto &srcInfo = pkg->sourceInfo) {
|
|
||||||
push(srcInfo->archs, "archs", obj, allocator);
|
|
||||||
}
|
}
|
||||||
if (const auto *const dbInfo = std::get_if<LibPkg::DatabaseInfo>(&reflectable.db)) {
|
if (const auto *const dbInfo = std::get_if<LibPkg::DatabaseInfo>(&reflectable.db)) {
|
||||||
if (!dbInfo->name.empty()) {
|
if (!dbInfo->name.empty()) {
|
||||||
|
@ -946,18 +973,42 @@ void pull<LibPkg::PackageSearchResult>(LibPkg::PackageSearchResult &reflectable,
|
||||||
ReflectiveRapidJSON::JsonReflector::pull(pkg->timestamp, "timestamp", obj, errors);
|
ReflectiveRapidJSON::JsonReflector::pull(pkg->timestamp, "timestamp", obj, errors);
|
||||||
ReflectiveRapidJSON::JsonReflector::pull(pkg->version, "version", obj, errors);
|
ReflectiveRapidJSON::JsonReflector::pull(pkg->version, "version", obj, errors);
|
||||||
ReflectiveRapidJSON::JsonReflector::pull(pkg->description, "description", obj, errors);
|
ReflectiveRapidJSON::JsonReflector::pull(pkg->description, "description", obj, errors);
|
||||||
auto &pkgInfo = pkg->packageInfo;
|
ReflectiveRapidJSON::JsonReflector::pull(pkg->arch, "arch", obj, errors);
|
||||||
if (!pkgInfo) {
|
ReflectiveRapidJSON::JsonReflector::pull(pkg->buildDate, "buildDate", obj, errors);
|
||||||
pkgInfo = make_unique<LibPkg::PackageInfo>();
|
|
||||||
}
|
|
||||||
ReflectiveRapidJSON::JsonReflector::pull(pkgInfo->arch, "arch", obj, errors);
|
|
||||||
ReflectiveRapidJSON::JsonReflector::pull(pkgInfo->buildDate, "buildDate", obj, errors);
|
|
||||||
ReflectiveRapidJSON::JsonReflector::pull(pkg->archs, "archs", obj, errors);
|
ReflectiveRapidJSON::JsonReflector::pull(pkg->archs, "archs", obj, errors);
|
||||||
auto &dbInfo = reflectable.db.emplace<LibPkg::DatabaseInfo>();
|
auto &dbInfo = reflectable.db.emplace<LibPkg::DatabaseInfo>();
|
||||||
ReflectiveRapidJSON::JsonReflector::pull(dbInfo.name, "db", obj, errors);
|
ReflectiveRapidJSON::JsonReflector::pull(dbInfo.name, "db", obj, errors);
|
||||||
ReflectiveRapidJSON::JsonReflector::pull(dbInfo.arch, "dbArch", obj, errors);
|
ReflectiveRapidJSON::JsonReflector::pull(dbInfo.arch, "dbArch", obj, errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void push<LibPkg::PackageBaseSearchResult>(
|
||||||
|
const LibPkg::PackageBaseSearchResult &reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
|
||||||
|
{
|
||||||
|
// serialize PackageBaseSearchResult object in accordance with PackageSearchResult
|
||||||
|
value.SetObject();
|
||||||
|
auto obj = value.GetObject();
|
||||||
|
if (auto &pkg = reflectable.pkg) {
|
||||||
|
push(*pkg, obj, allocator);
|
||||||
|
}
|
||||||
|
if (const auto &db = reflectable.db) {
|
||||||
|
push(db->name, "db", obj, allocator);
|
||||||
|
if (!db->arch.empty()) {
|
||||||
|
push(db->arch, "dbArch", obj, allocator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void pull<LibPkg::PackageBaseSearchResult>(LibPkg::PackageBaseSearchResult &reflectable,
|
||||||
|
const RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors)
|
||||||
|
{
|
||||||
|
CPP_UTILITIES_UNUSED(reflectable)
|
||||||
|
CPP_UTILITIES_UNUSED(value)
|
||||||
|
CPP_UTILITIES_UNUSED(errors)
|
||||||
|
throw std::logic_error("Attempt to deserialize LibPkg::PackageBaseSearchResult");
|
||||||
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
void push<LibPkg::AtomicDateTime>(
|
void push<LibPkg::AtomicDateTime>(
|
||||||
const LibPkg::AtomicDateTime &reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
|
const LibPkg::AtomicDateTime &reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
|
||||||
|
|
|
@ -42,6 +42,20 @@ struct LIBPKG_EXPORT PackageSearchResult {
|
||||||
StorageID id;
|
StorageID id;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct LIBPKG_EXPORT PackageBaseSearchResult {
|
||||||
|
PackageBaseSearchResult() = default;
|
||||||
|
PackageBaseSearchResult(const Database &database, const PackageBase &package, StorageID id);
|
||||||
|
|
||||||
|
/// \brief The related database.
|
||||||
|
/// \remarks
|
||||||
|
/// - The find functions always uses Database* and it is guaranteed to be never nullptr.
|
||||||
|
/// - The deserialization functions always use DatabaseInfo and the values might be empty if the source was empty.
|
||||||
|
/// - The serialization functions can cope with both alternatives.
|
||||||
|
const Database *db = nullptr;
|
||||||
|
const PackageBase *pkg = nullptr;
|
||||||
|
StorageID id = 0;
|
||||||
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief The DatabaseUsage enum specifies the usage of a database within pacman.
|
* \brief The DatabaseUsage enum specifies the usage of a database within pacman.
|
||||||
*/
|
*/
|
||||||
|
@ -131,9 +145,11 @@ struct AtomicDateTime : public std::atomic<CppUtilities::DateTime> {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LIBPKG_EXPORT Database : public ReflectiveRapidJSON::JsonSerializable<Database>, public ReflectiveRapidJSON::BinarySerializable<Database> {
|
struct LIBPKG_EXPORT Database : public ReflectiveRapidJSON::JsonSerializable<Database>, public ReflectiveRapidJSON::BinarySerializable<Database> {
|
||||||
|
using PackageVisitorBase = std::function<bool(StorageID, std::shared_ptr<PackageBase> &&)>; // package is invalidated/reused unless moved from!!!
|
||||||
using PackageVisitorMove = std::function<bool(StorageID, std::shared_ptr<Package> &&)>; // package is invalidated/reused unless moved from!!!
|
using PackageVisitorMove = std::function<bool(StorageID, std::shared_ptr<Package> &&)>; // package is invalidated/reused unless moved from!!!
|
||||||
using PackageVisitorConst = std::function<bool(StorageID, const std::shared_ptr<Package> &)>;
|
using PackageVisitorConst = std::function<bool(StorageID, const std::shared_ptr<Package> &)>;
|
||||||
using PackageVisitorByName = std::function<bool(std::string_view, const std::function<PackageSpec(void)> &)>;
|
using PackageVisitorByName = std::function<bool(std::string_view, const std::function<PackageSpec(void)> &)>;
|
||||||
|
using PackageVisitorByNameBase = std::function<bool(std::string_view, const std::function<StorageID(PackageBase&)> &)>;
|
||||||
|
|
||||||
friend struct PackageUpdater;
|
friend struct PackageUpdater;
|
||||||
|
|
||||||
|
@ -153,7 +169,9 @@ struct LIBPKG_EXPORT Database : public ReflectiveRapidJSON::JsonSerializable<Dat
|
||||||
static bool isFileRelevant(const char *filePath, const char *fileName, mode_t);
|
static bool isFileRelevant(const char *filePath, const char *fileName, mode_t);
|
||||||
std::vector<std::shared_ptr<Package>> findPackages(const std::function<bool(const Database &, const Package &)> &pred);
|
std::vector<std::shared_ptr<Package>> findPackages(const std::function<bool(const Database &, const Package &)> &pred);
|
||||||
void allPackages(const PackageVisitorMove &visitor);
|
void allPackages(const PackageVisitorMove &visitor);
|
||||||
|
void allPackages(const PackageVisitorBase &visitor);
|
||||||
void allPackagesByName(const PackageVisitorByName &visitor);
|
void allPackagesByName(const PackageVisitorByName &visitor);
|
||||||
|
void allPackagesByName(const PackageVisitorByNameBase &visitor);
|
||||||
std::size_t packageCount() const;
|
std::size_t packageCount() const;
|
||||||
void providingPackages(const Dependency &dependency, bool reverse, const PackageVisitorConst &visitor);
|
void providingPackages(const Dependency &dependency, bool reverse, const PackageVisitorConst &visitor);
|
||||||
void providingPackages(const std::string &libraryName, bool reverse, const PackageVisitorConst &visitor);
|
void providingPackages(const std::string &libraryName, bool reverse, const PackageVisitorConst &visitor);
|
||||||
|
@ -162,6 +180,7 @@ struct LIBPKG_EXPORT Database : public ReflectiveRapidJSON::JsonSerializable<Dat
|
||||||
std::shared_ptr<Package> findPackage(StorageID packageID);
|
std::shared_ptr<Package> findPackage(StorageID packageID);
|
||||||
std::shared_ptr<Package> findPackage(const std::string &packageName);
|
std::shared_ptr<Package> findPackage(const std::string &packageName);
|
||||||
PackageSpec findPackageWithID(const std::string &packageName);
|
PackageSpec findPackageWithID(const std::string &packageName);
|
||||||
|
StorageID findBasePackageWithID(const std::string &packageName, PackageBase &basePackage);
|
||||||
void removePackage(const std::string &packageName);
|
void removePackage(const std::string &packageName);
|
||||||
StorageID updatePackage(const std::shared_ptr<Package> &package);
|
StorageID updatePackage(const std::shared_ptr<Package> &package);
|
||||||
StorageID forceUpdatePackage(const std::shared_ptr<Package> &package);
|
StorageID forceUpdatePackage(const std::shared_ptr<Package> &package);
|
||||||
|
@ -233,6 +252,13 @@ inline bool PackageSearchResult::operator==(const PackageSearchResult &other) co
|
||||||
return ((!*db1 && !*db2) || (*db1 && *db2 && (**db1).name == (**db2).name)) && pkg == other.pkg;
|
return ((!*db1 && !*db2) || (*db1 && *db2 && (**db1).name == (**db2).name)) && pkg == other.pkg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline PackageBaseSearchResult::PackageBaseSearchResult(const Database &database, const PackageBase &package, StorageID id)
|
||||||
|
: db(&database)
|
||||||
|
, pkg(&package)
|
||||||
|
, id(id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace LibPkg
|
} // namespace LibPkg
|
||||||
|
|
||||||
namespace std {
|
namespace std {
|
||||||
|
@ -247,7 +273,7 @@ template <> struct hash<LibPkg::PackageSearchResult> {
|
||||||
} else if (const auto *const db = std::get<LibPkg::Database *>(res.db)) {
|
} else if (const auto *const db = std::get<LibPkg::Database *>(res.db)) {
|
||||||
dbName = &db->name;
|
dbName = &db->name;
|
||||||
}
|
}
|
||||||
return ((hash<string>()(dbName ? *dbName : string()) ^ (hash<std::shared_ptr<LibPkg::Package>>()(res.pkg) << 1)) >> 1);
|
return ((hash<string>()(dbName ? *dbName : string()) ^ (hash<std::shared_ptr<LibPkg::PackageBase>>()(res.pkg) << 1)) >> 1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -265,6 +291,14 @@ template <>
|
||||||
LIBPKG_EXPORT void pull<LibPkg::PackageSearchResult>(LibPkg::PackageSearchResult &reflectable,
|
LIBPKG_EXPORT void pull<LibPkg::PackageSearchResult>(LibPkg::PackageSearchResult &reflectable,
|
||||||
const RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors);
|
const RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors);
|
||||||
|
|
||||||
|
// declare custom (de)serialization for PackageBaseSearchResult
|
||||||
|
template <>
|
||||||
|
LIBPKG_EXPORT void push<LibPkg::PackageBaseSearchResult>(
|
||||||
|
const LibPkg::PackageBaseSearchResult &reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator);
|
||||||
|
template <>
|
||||||
|
LIBPKG_EXPORT void pull<LibPkg::PackageBaseSearchResult>(LibPkg::PackageBaseSearchResult &reflectable,
|
||||||
|
const RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors);
|
||||||
|
|
||||||
// declare custom (de)serialization for AtomicDateTime
|
// declare custom (de)serialization for AtomicDateTime
|
||||||
template <>
|
template <>
|
||||||
LIBPKG_EXPORT void push<LibPkg::AtomicDateTime>(
|
LIBPKG_EXPORT void push<LibPkg::AtomicDateTime>(
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
#ifndef LIBPKG_DATA_MRU_LIST_H
|
||||||
|
#define LIBPKG_DATA_MRU_LIST_H
|
||||||
|
|
||||||
|
#include <boost/multi_index/hashed_index.hpp>
|
||||||
|
#include <boost/multi_index/identity.hpp>
|
||||||
|
#include <boost/multi_index/sequenced_index.hpp>
|
||||||
|
#include <boost/multi_index_container.hpp>
|
||||||
|
|
||||||
|
namespace LibPkg {
|
||||||
|
|
||||||
|
template <typename Item> class MostRecentUseList {
|
||||||
|
using ItemList = boost::multi_index::multi_index_container<Item,
|
||||||
|
boost::multi_index::indexed_by<boost::multi_index::sequenced<>, boost::multi_index::hashed_unique<boost::multi_index::identity<Item>>>>;
|
||||||
|
|
||||||
|
public:
|
||||||
|
using item_type = Item;
|
||||||
|
using iterator = typename ItemList::iterator;
|
||||||
|
|
||||||
|
explicit MostRecentUseList(std::size_t limit = 1000)
|
||||||
|
: m_limit(limit)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void insert(const item_type &item)
|
||||||
|
{
|
||||||
|
auto [i, newItem] = std::pair<iterator, bool>(m_itemList.push_front(item));
|
||||||
|
if (!newItem) {
|
||||||
|
m_itemList.relocate(m_itemList.begin(), i);
|
||||||
|
} else if (m_itemList.size() > m_limit) {
|
||||||
|
m_itemList.pop_back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator begin()
|
||||||
|
{
|
||||||
|
return m_itemList.begin();
|
||||||
|
}
|
||||||
|
iterator end()
|
||||||
|
{
|
||||||
|
return m_itemList.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
ItemList m_itemList;
|
||||||
|
std::size_t m_limit;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace LibPkg
|
||||||
|
|
||||||
|
#endif // LIBPKG_DATA_MRU_LIST_H
|
|
@ -163,7 +163,7 @@ ostream &operator<<(ostream &o, const PackageVersionPartComparison &res)
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
PackageVersionComparison Package::compareVersion(const Package &other) const
|
PackageVersionComparison PackageBase::compareVersion(const PackageBase &other) const
|
||||||
{
|
{
|
||||||
return PackageVersion::fromString(version).compare(PackageVersion::fromString(other.version));
|
return PackageVersion::fromString(version).compare(PackageVersion::fromString(other.version));
|
||||||
}
|
}
|
||||||
|
@ -331,7 +331,7 @@ string LibPkg::Package::computeFileName(const char *extension) const
|
||||||
return argsToString(name, '-', version, '-', packageInfo->arch, '.', extension);
|
return argsToString(name, '-', version, '-', packageInfo->arch, '.', extension);
|
||||||
}
|
}
|
||||||
|
|
||||||
string LibPkg::Package::computeRegularPackageName() const
|
string LibPkg::PackageBase::computeRegularPackageName() const
|
||||||
{
|
{
|
||||||
if (name == "mingw-w64-headers" || name == "mingw-w64-crt") {
|
if (name == "mingw-w64-headers" || name == "mingw-w64-crt") {
|
||||||
return string();
|
return string();
|
||||||
|
@ -352,6 +352,17 @@ string LibPkg::Package::computeRegularPackageName() const
|
||||||
return string();
|
return string();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PackageBase::clear()
|
||||||
|
{
|
||||||
|
origin = PackageOrigin::Default;
|
||||||
|
timestamp = buildDate = DateTime();
|
||||||
|
name.clear();
|
||||||
|
version.clear();
|
||||||
|
arch.clear();
|
||||||
|
archs.clear();
|
||||||
|
description.clear();
|
||||||
|
}
|
||||||
|
|
||||||
bool Package::addDepsAndProvidesFromOtherPackage(const Package &otherPackage, bool force)
|
bool Package::addDepsAndProvidesFromOtherPackage(const Package &otherPackage, bool force)
|
||||||
{
|
{
|
||||||
if (&otherPackage == this) {
|
if (&otherPackage == this) {
|
||||||
|
@ -369,7 +380,7 @@ bool Package::addDepsAndProvidesFromOtherPackage(const Package &otherPackage, bo
|
||||||
|
|
||||||
// add package info from other package if this package has none at all
|
// add package info from other package if this package has none at all
|
||||||
if (!packageInfo && otherPackage.packageInfo) {
|
if (!packageInfo && otherPackage.packageInfo) {
|
||||||
packageInfo = make_unique<PackageInfo>(*(otherPackage.packageInfo));
|
packageInfo = std::make_optional<PackageInfo>(*(otherPackage.packageInfo));
|
||||||
}
|
}
|
||||||
// add source info from other package; at least add missing make and check dependencies
|
// add source info from other package; at least add missing make and check dependencies
|
||||||
if (!sourceInfo) {
|
if (!sourceInfo) {
|
||||||
|
@ -552,36 +563,112 @@ namespace ReflectiveRapidJSON {
|
||||||
|
|
||||||
namespace JsonReflector {
|
namespace JsonReflector {
|
||||||
|
|
||||||
template <>
|
template <typename PackageSpecType, Traits::EnableIf<Traits::IsSpecializationOf<PackageSpecType, LibPkg::GenericPackageSpec>> * = nullptr>
|
||||||
LIBPKG_EXPORT void push<LibPkg::PackageSpec>(
|
static void internalPush(
|
||||||
const LibPkg::PackageSpec &reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
|
const PackageSpecType &reflectable, ::RAPIDJSON_NAMESPACE::Value::Object &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
|
||||||
{
|
{
|
||||||
// just serialize the package (and ignore the ID)
|
// just serialize the package (and ignore the ID)
|
||||||
push(reflectable.pkg, value, allocator);
|
if (reflectable.pkg) {
|
||||||
|
push(*reflectable.pkg, value, allocator);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <typename PackageSpecType, Traits::EnableIf<Traits::IsSpecializationOf<PackageSpecType, LibPkg::GenericPackageSpec>> * = nullptr>
|
||||||
LIBPKG_EXPORT void pull<LibPkg::PackageSpec>(LibPkg::PackageSpec &reflectable,
|
static void internalPull(
|
||||||
const RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors)
|
PackageSpecType &reflectable, const ::RAPIDJSON_NAMESPACE::GenericValue<::RAPIDJSON_NAMESPACE::UTF8<char>>::ConstObject &value, JsonDeserializationErrors *errors)
|
||||||
{
|
{
|
||||||
// allow the package being specified with ID or directly
|
|
||||||
if (!value.IsObject()) {
|
|
||||||
if (errors) {
|
|
||||||
errors->reportTypeMismatch<LibPkg::PackageSpec>(value.GetType());
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// find member
|
// find member
|
||||||
if (const auto pkg = value.FindMember("pkg"); pkg != value.MemberEnd()) {
|
if (const auto pkg = value.FindMember("pkg"); pkg != value.MemberEnd()) {
|
||||||
pull(reflectable.pkg, pkg->value, errors);
|
reflectable.pkg = std::make_shared<typename decltype(reflectable.pkg)::element_type>();
|
||||||
|
pull(*reflectable.pkg, pkg->value, errors);
|
||||||
if (const auto id = value.FindMember("id"); id != value.MemberEnd()) {
|
if (const auto id = value.FindMember("id"); id != value.MemberEnd()) {
|
||||||
pull(reflectable.id, id->value, errors);
|
pull(reflectable.id, id->value, errors);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
pull(reflectable.pkg, value, errors);
|
reflectable.pkg = std::make_shared<typename decltype(reflectable.pkg)::element_type>();
|
||||||
|
pull(*reflectable.pkg, value, errors);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
LIBPKG_EXPORT void push<LibPkg::PackageSpec>(const LibPkg::PackageSpec &reflectable, ::RAPIDJSON_NAMESPACE::Value::Object &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
|
||||||
|
{
|
||||||
|
internalPush(reflectable, value, allocator);
|
||||||
|
}
|
||||||
|
template <>
|
||||||
|
LIBPKG_EXPORT void push<LibPkg::GenericPackageSpec<LibPkg::PackageBase>>(const LibPkg::GenericPackageSpec<LibPkg::PackageBase> &reflectable, ::RAPIDJSON_NAMESPACE::Value::Object &value,
|
||||||
|
RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
|
||||||
|
{
|
||||||
|
internalPush(reflectable, value, allocator);
|
||||||
|
}
|
||||||
|
template <>
|
||||||
|
LIBPKG_EXPORT void pull<LibPkg::PackageSpec>(LibPkg::PackageSpec &reflectable,const ::RAPIDJSON_NAMESPACE::GenericValue<::RAPIDJSON_NAMESPACE::UTF8<char>>::ConstObject &value,
|
||||||
|
JsonDeserializationErrors *errors)
|
||||||
|
{
|
||||||
|
internalPull(reflectable, value, errors);
|
||||||
|
}
|
||||||
|
template <>
|
||||||
|
LIBPKG_EXPORT void pull<LibPkg::GenericPackageSpec<LibPkg::PackageBase>>(LibPkg::GenericPackageSpec<LibPkg::PackageBase> &reflectable,
|
||||||
|
const ::RAPIDJSON_NAMESPACE::GenericValue<::RAPIDJSON_NAMESPACE::UTF8<char>>::ConstObject &value, JsonDeserializationErrors *errors)
|
||||||
|
{
|
||||||
|
internalPull(reflectable, value, errors);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace JsonReflector
|
} // namespace JsonReflector
|
||||||
|
|
||||||
|
namespace BinaryReflector {
|
||||||
|
|
||||||
|
template <typename PackageSpecType, Traits::EnableIf<Traits::IsSpecializationOf<PackageSpecType, LibPkg::GenericPackageSpec>> * = nullptr>
|
||||||
|
BinaryVersion internalReadCustomType(BinaryDeserializer &deserializer, PackageSpecType &reflectable, BinaryVersion version)
|
||||||
|
{
|
||||||
|
// read version
|
||||||
|
using V = Versioning<::ReflectiveRapidJSON::BinarySerializable<PackageSpecType>>;
|
||||||
|
if constexpr (V::enabled) {
|
||||||
|
V::assertVersion(version = deserializer.readVariableLengthUIntBE(), "LibPkg::GenericPackageSpec");
|
||||||
|
}
|
||||||
|
// read members
|
||||||
|
deserializer.read(reflectable.id, version);
|
||||||
|
deserializer.read(reflectable.pkg, version);
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename PackageSpecType, Traits::EnableIf<Traits::IsSpecializationOf<PackageSpecType, LibPkg::GenericPackageSpec>> * = nullptr>
|
||||||
|
void internalWriteCustomType(BinarySerializer &serializer, const PackageSpecType &reflectable, BinaryVersion version)
|
||||||
|
{
|
||||||
|
// write version
|
||||||
|
using V = Versioning<::ReflectiveRapidJSON::BinarySerializable<PackageSpecType>>;
|
||||||
|
if constexpr (V::enabled) {
|
||||||
|
serializer.writeVariableLengthUIntBE(V::applyDefault(version));
|
||||||
|
}
|
||||||
|
// write members
|
||||||
|
serializer.write(reflectable.id, version);
|
||||||
|
serializer.write(reflectable.pkg, version);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
LIBPKG_EXPORT BinaryVersion readCustomType<LibPkg::PackageSpec>(BinaryDeserializer &deserializer, LibPkg::PackageSpec &reflectable, BinaryVersion version)
|
||||||
|
{
|
||||||
|
return internalReadCustomType(deserializer, reflectable, version);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
LIBPKG_EXPORT BinaryVersion readCustomType<LibPkg::GenericPackageSpec<LibPkg::PackageBase>>(BinaryDeserializer &deserializer, LibPkg::GenericPackageSpec<LibPkg::PackageBase> &reflectable, BinaryVersion version)
|
||||||
|
{
|
||||||
|
return internalReadCustomType(deserializer, reflectable, version);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
LIBPKG_EXPORT void writeCustomType<LibPkg::PackageSpec>(BinarySerializer &serializer, const LibPkg::PackageSpec &reflectable, BinaryVersion version)
|
||||||
|
{
|
||||||
|
internalWriteCustomType(serializer, reflectable, version);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
LIBPKG_EXPORT void writeCustomType<LibPkg::GenericPackageSpec<LibPkg::PackageBase>>(BinarySerializer &serializer, const LibPkg::GenericPackageSpec<LibPkg::PackageBase> &reflectable, BinaryVersion version)
|
||||||
|
{
|
||||||
|
internalWriteCustomType(serializer, reflectable, version);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace BinaryReflector
|
||||||
|
|
||||||
} // namespace ReflectiveRapidJSON
|
} // namespace ReflectiveRapidJSON
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <optional>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
@ -201,6 +202,7 @@ LIBPKG_EXPORT std::ostream &operator<<(std::ostream &o, const std::vector<Depend
|
||||||
struct SourceFile : public ReflectiveRapidJSON::JsonSerializable<SourceFile>, public ReflectiveRapidJSON::BinarySerializable<SourceFile> {
|
struct SourceFile : public ReflectiveRapidJSON::JsonSerializable<SourceFile>, public ReflectiveRapidJSON::BinarySerializable<SourceFile> {
|
||||||
std::string path;
|
std::string path;
|
||||||
std::string contents;
|
std::string contents;
|
||||||
|
bool operator==(const SourceFile &) const = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LIBPKG_EXPORT SourceInfo : public ReflectiveRapidJSON::JsonSerializable<SourceInfo>,
|
struct LIBPKG_EXPORT SourceInfo : public ReflectiveRapidJSON::JsonSerializable<SourceInfo>,
|
||||||
|
@ -219,6 +221,7 @@ struct LIBPKG_EXPORT SourceInfo : public ReflectiveRapidJSON::JsonSerializable<S
|
||||||
std::string url;
|
std::string url;
|
||||||
std::vector<SourceFile> sources;
|
std::vector<SourceFile> sources;
|
||||||
std::string directory;
|
std::string directory;
|
||||||
|
bool operator==(const SourceInfo &other) const = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LIBPKG_EXPORT PackageInfo : public ReflectiveRapidJSON::JsonSerializable<PackageInfo>,
|
struct LIBPKG_EXPORT PackageInfo : public ReflectiveRapidJSON::JsonSerializable<PackageInfo>,
|
||||||
|
@ -232,6 +235,7 @@ struct LIBPKG_EXPORT PackageInfo : public ReflectiveRapidJSON::JsonSerializable<
|
||||||
std::string pgpSignature;
|
std::string pgpSignature;
|
||||||
std::string arch; // arch of concrete binary package
|
std::string arch; // arch of concrete binary package
|
||||||
std::uint32_t size = 0;
|
std::uint32_t size = 0;
|
||||||
|
bool operator==(const PackageInfo &other) const = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LIBPKG_EXPORT InstallInfo : public ReflectiveRapidJSON::JsonSerializable<InstallInfo>,
|
struct LIBPKG_EXPORT InstallInfo : public ReflectiveRapidJSON::JsonSerializable<InstallInfo>,
|
||||||
|
@ -241,6 +245,7 @@ struct LIBPKG_EXPORT InstallInfo : public ReflectiveRapidJSON::JsonSerializable<
|
||||||
std::vector<std::string> backupFiles;
|
std::vector<std::string> backupFiles;
|
||||||
InstallStatus installStatus = InstallStatus::Unknown;
|
InstallStatus installStatus = InstallStatus::Unknown;
|
||||||
PackageValidation validationMethods = PackageValidation::None;
|
PackageValidation validationMethods = PackageValidation::None;
|
||||||
|
bool operator==(const InstallInfo &other) const = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -333,22 +338,25 @@ struct Package;
|
||||||
* \brief The PackageSpec struct holds a reference to a package.
|
* \brief The PackageSpec struct holds a reference to a package.
|
||||||
* \remarks If id is non-zero, the package is part of a database using that ID.
|
* \remarks If id is non-zero, the package is part of a database using that ID.
|
||||||
*/
|
*/
|
||||||
struct LIBPKG_EXPORT PackageSpec : public ReflectiveRapidJSON::JsonSerializable<PackageSpec>,
|
template <typename PackageType = Package>
|
||||||
public ReflectiveRapidJSON::BinarySerializable<PackageSpec> {
|
struct LIBPKG_EXPORT GenericPackageSpec : public ReflectiveRapidJSON::JsonSerializable<GenericPackageSpec<PackageType>>,
|
||||||
explicit PackageSpec(StorageID id = 0, const std::shared_ptr<Package> &pkg = nullptr);
|
public ReflectiveRapidJSON::BinarySerializable<GenericPackageSpec<PackageType>> {
|
||||||
bool operator==(const PackageSpec &other) const;
|
explicit GenericPackageSpec(StorageID id = 0, const std::shared_ptr<PackageType> &pkg = nullptr);
|
||||||
|
bool operator==(const GenericPackageSpec &other) const;
|
||||||
|
|
||||||
StorageID id;
|
StorageID id;
|
||||||
std::shared_ptr<Package> pkg;
|
std::shared_ptr<PackageType> pkg;
|
||||||
};
|
};
|
||||||
|
using PackageSpec = GenericPackageSpec<>;
|
||||||
|
|
||||||
inline PackageSpec::PackageSpec(StorageID id, const std::shared_ptr<Package> &pkg)
|
template <typename PackageType>
|
||||||
|
inline GenericPackageSpec<PackageType>::GenericPackageSpec(StorageID id, const std::shared_ptr<PackageType> &pkg)
|
||||||
: id(id)
|
: id(id)
|
||||||
, pkg(pkg)
|
, pkg(pkg)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool PackageSpec::operator==(const PackageSpec &other) const
|
template <typename PackageType> inline bool GenericPackageSpec<PackageType>::operator==(const GenericPackageSpec &other) const
|
||||||
{
|
{
|
||||||
return id ? id == other.id : pkg == other.pkg;
|
return id ? id == other.id : pkg == other.pkg;
|
||||||
}
|
}
|
||||||
|
@ -357,8 +365,8 @@ inline bool PackageSpec::operator==(const PackageSpec &other) const
|
||||||
|
|
||||||
namespace std {
|
namespace std {
|
||||||
|
|
||||||
template <> struct hash<LibPkg::PackageSpec> {
|
template <typename PackageType> struct hash<LibPkg::GenericPackageSpec<PackageType>> {
|
||||||
std::size_t operator()(const LibPkg::PackageSpec &spec) const
|
std::size_t operator()(const LibPkg::GenericPackageSpec<PackageType> &spec) const
|
||||||
{
|
{
|
||||||
using std::hash;
|
using std::hash;
|
||||||
return spec.id ? hash<decltype(spec.id)>()(spec.id) : hash<decltype(spec.pkg)>()(spec.pkg);
|
return spec.id ? hash<decltype(spec.id)>()(spec.id) : hash<decltype(spec.pkg)>()(spec.pkg);
|
||||||
|
@ -369,19 +377,38 @@ template <> struct hash<LibPkg::PackageSpec> {
|
||||||
|
|
||||||
namespace LibPkg {
|
namespace LibPkg {
|
||||||
|
|
||||||
struct LIBPKG_EXPORT Package : public ReflectiveRapidJSON::JsonSerializable<Package>, public ReflectiveRapidJSON::BinarySerializable<Package, 1> {
|
struct LIBPKG_EXPORT PackageBase : public ReflectiveRapidJSON::JsonSerializable<PackageBase>,
|
||||||
|
public ReflectiveRapidJSON::BinarySerializable<PackageBase, 1> {
|
||||||
|
PackageBase() = default;
|
||||||
|
PackageBase(const PackageBase &other) = default;
|
||||||
|
PackageBase(PackageBase &&other) = default;
|
||||||
|
PackageBase &operator=(PackageBase &&other) = default;
|
||||||
|
|
||||||
|
bool isSame(const PackageBase &other) const;
|
||||||
|
PackageVersionComparison compareVersion(const PackageBase &other) const;
|
||||||
|
std::string computeRegularPackageName() const;
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
PackageOrigin origin = PackageOrigin::Default;
|
||||||
|
CppUtilities::DateTime timestamp, buildDate;
|
||||||
|
std::string name;
|
||||||
|
std::string version;
|
||||||
|
std::string arch;
|
||||||
|
std::vector<std::string> archs; // set if a split package overrides the base archs; if empty, archs from sourceInfo apply
|
||||||
|
std::string description;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LIBPKG_EXPORT Package : public PackageBase,
|
||||||
|
public ReflectiveRapidJSON::JsonSerializable<Package>,
|
||||||
|
public ReflectiveRapidJSON::BinarySerializable<Package, 1> {
|
||||||
Package() = default;
|
Package() = default;
|
||||||
Package(const Package &other);
|
Package(const Package &other) = default;
|
||||||
Package(Package &&other) = default;
|
Package(Package &&other) = default;
|
||||||
//Package &operator=(const Package &other);
|
|
||||||
Package &operator=(Package &&other) = default;
|
Package &operator=(Package &&other) = default;
|
||||||
bool providesDependency(const Dependency &dependency) const;
|
bool providesDependency(const Dependency &dependency) const;
|
||||||
static void exportProvides(
|
static void exportProvides(
|
||||||
const std::shared_ptr<Package> &package, DependencySet &destinationProvides, std::unordered_set<std::string> &destinationLibProvides);
|
const std::shared_ptr<Package> &package, DependencySet &destinationProvides, std::unordered_set<std::string> &destinationLibProvides);
|
||||||
bool isSame(const Package &other) const;
|
|
||||||
PackageVersionComparison compareVersion(const Package &other) const;
|
|
||||||
std::string computeFileName(const char *extension = "pkg.tar.zst") const;
|
std::string computeFileName(const char *extension = "pkg.tar.zst") const;
|
||||||
std::string computeRegularPackageName() const;
|
|
||||||
PackageNameData decomposeName() const;
|
PackageNameData decomposeName() const;
|
||||||
void addInfoFromPkgInfoFile(const std::string &info);
|
void addInfoFromPkgInfoFile(const std::string &info);
|
||||||
void addDepsAndProvidesFromContainedDirectory(std::string_view directoryPath);
|
void addDepsAndProvidesFromContainedDirectory(std::string_view directoryPath);
|
||||||
|
@ -391,24 +418,26 @@ struct LIBPKG_EXPORT Package : public ReflectiveRapidJSON::JsonSerializable<Pack
|
||||||
std::vector<std::string> processDllsReferencedByImportLibs(std::set<std::string> &&dllsReferencedByImportLibs);
|
std::vector<std::string> processDllsReferencedByImportLibs(std::set<std::string> &&dllsReferencedByImportLibs);
|
||||||
bool addDepsAndProvidesFromOtherPackage(const Package &otherPackage, bool force = false);
|
bool addDepsAndProvidesFromOtherPackage(const Package &otherPackage, bool force = false);
|
||||||
bool isArchAny() const;
|
bool isArchAny() const;
|
||||||
|
using ReflectiveRapidJSON::JsonSerializable<Package>::fromJson;
|
||||||
|
using ReflectiveRapidJSON::JsonSerializable<Package>::toJson;
|
||||||
|
using ReflectiveRapidJSON::JsonSerializable<Package>::toJsonDocument;
|
||||||
|
using ReflectiveRapidJSON::BinarySerializable<Package, 1>::toBinary;
|
||||||
|
using ReflectiveRapidJSON::BinarySerializable<Package, 1>::restoreFromBinary;
|
||||||
|
using ReflectiveRapidJSON::BinarySerializable<Package, 1>::fromBinary;
|
||||||
|
|
||||||
static bool isPkgInfoFileOrBinary(const char *filePath, const char *fileName, mode_t mode);
|
static bool isPkgInfoFileOrBinary(const char *filePath, const char *fileName, mode_t mode);
|
||||||
static bool isLicense(const char *filePath, const char *fileName, mode_t mode);
|
static bool isLicense(const char *filePath, const char *fileName, mode_t mode);
|
||||||
|
|
||||||
static std::vector<PackageSpec> fromInfo(const std::string &info, bool isPackageInfo = false);
|
static std::vector<GenericPackageSpec<Package>> fromInfo(const std::string &info, bool isPackageInfo = false);
|
||||||
static std::shared_ptr<Package> fromDescription(const std::vector<std::string> &descriptionParts);
|
static std::shared_ptr<Package> fromDescription(const std::vector<std::string> &descriptionParts);
|
||||||
static void fromDatabaseFile(const std::string &archivePath, const std::function<bool(const std::shared_ptr<Package> &)> &visitor);
|
static void fromDatabaseFile(const std::string &archivePath, const std::function<bool(const std::shared_ptr<Package> &)> &visitor);
|
||||||
static std::shared_ptr<Package> fromPkgFile(const std::string &path);
|
static std::shared_ptr<Package> fromPkgFile(const std::string &path);
|
||||||
static std::tuple<std::string_view, std::string_view, std::string_view> fileNameComponents(std::string_view fileName);
|
static std::tuple<std::string_view, std::string_view, std::string_view> fileNameComponents(std::string_view fileName);
|
||||||
static std::shared_ptr<Package> fromPkgFileName(std::string_view fileName);
|
static std::shared_ptr<Package> fromPkgFileName(std::string_view fileName);
|
||||||
static std::vector<PackageSpec> fromAurRpcJson(const char *jsonData, std::size_t jsonSize, PackageOrigin origin = PackageOrigin::AurRpcInfo);
|
static std::vector<GenericPackageSpec<Package>> fromAurRpcJson(
|
||||||
|
const char *jsonData, std::size_t jsonSize, PackageOrigin origin = PackageOrigin::AurRpcInfo);
|
||||||
|
|
||||||
PackageOrigin origin = PackageOrigin::Default;
|
using PackageBase::version;
|
||||||
CppUtilities::DateTime timestamp;
|
|
||||||
std::string name;
|
|
||||||
std::string version;
|
|
||||||
std::vector<std::string> archs; // set if a split package overrides the base archs; if empty, archs from sourceInfo apply
|
|
||||||
std::string description;
|
|
||||||
std::string upstreamUrl;
|
std::string upstreamUrl;
|
||||||
std::vector<std::string> licenses;
|
std::vector<std::string> licenses;
|
||||||
std::vector<std::string> groups;
|
std::vector<std::string> groups;
|
||||||
|
@ -419,32 +448,12 @@ struct LIBPKG_EXPORT Package : public ReflectiveRapidJSON::JsonSerializable<Pack
|
||||||
std::vector<Dependency> replaces;
|
std::vector<Dependency> replaces;
|
||||||
std::set<std::string> libprovides;
|
std::set<std::string> libprovides;
|
||||||
std::set<std::string> libdepends;
|
std::set<std::string> libdepends;
|
||||||
std::shared_ptr<SourceInfo> sourceInfo;
|
std::optional<SourceInfo> sourceInfo;
|
||||||
std::unique_ptr<PackageInfo> packageInfo;
|
std::optional<PackageInfo> packageInfo;
|
||||||
std::unique_ptr<InstallInfo> installInfo;
|
std::optional<InstallInfo> installInfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline Package::Package(const Package &other)
|
inline bool PackageBase::isSame(const PackageBase &other) const
|
||||||
: origin(other.origin)
|
|
||||||
, timestamp(other.timestamp)
|
|
||||||
, name(other.name)
|
|
||||||
, version(other.version)
|
|
||||||
, description(other.description)
|
|
||||||
, upstreamUrl(other.upstreamUrl)
|
|
||||||
, licenses(other.licenses)
|
|
||||||
, groups(other.groups)
|
|
||||||
, dependencies(other.dependencies)
|
|
||||||
, optionalDependencies(other.optionalDependencies)
|
|
||||||
, conflicts(other.conflicts)
|
|
||||||
, provides(other.provides)
|
|
||||||
, replaces(other.replaces)
|
|
||||||
, sourceInfo(other.sourceInfo)
|
|
||||||
, packageInfo()
|
|
||||||
, installInfo()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool Package::isSame(const Package &other) const
|
|
||||||
{
|
{
|
||||||
return name == other.name && version == other.version;
|
return name == other.name && version == other.version;
|
||||||
}
|
}
|
||||||
|
@ -502,17 +511,6 @@ namespace ReflectiveRapidJSON {
|
||||||
|
|
||||||
REFLECTIVE_RAPIDJSON_TREAT_AS_MULTI_MAP_OR_HASH(LibPkg::DependencySet);
|
REFLECTIVE_RAPIDJSON_TREAT_AS_MULTI_MAP_OR_HASH(LibPkg::DependencySet);
|
||||||
|
|
||||||
namespace JsonReflector {
|
|
||||||
|
|
||||||
// declare custom (de)serialization for LibPkg::PackageSpec
|
|
||||||
template <>
|
|
||||||
LIBPKG_EXPORT void push<LibPkg::PackageSpec>(
|
|
||||||
const LibPkg::PackageSpec &reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator);
|
|
||||||
template <>
|
|
||||||
LIBPKG_EXPORT void pull<LibPkg::PackageSpec>(LibPkg::PackageSpec &reflectable,
|
|
||||||
const RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors);
|
|
||||||
|
|
||||||
} // namespace JsonReflector
|
|
||||||
} // namespace ReflectiveRapidJSON
|
} // namespace ReflectiveRapidJSON
|
||||||
|
|
||||||
#endif // LIBPKG_DATA_PACKAGE_H
|
#endif // LIBPKG_DATA_PACKAGE_H
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
namespace LibPkg {
|
namespace LibPkg {
|
||||||
|
|
||||||
using PackageStorage = LMDBSafe::TypedDBI<Package, LMDBSafe::index_on<Package, std::string, &Package::name>>;
|
using PackageStorage = LMDBSafe::TypedDBI<Package, LMDBSafe::index_on_base_member<Package, std::string, PackageBase, &PackageBase::name>>;
|
||||||
using DependencyStorage = LMDBSafe::TypedDBI<DatabaseDependency, LMDBSafe::index_on<Dependency, std::string, &DatabaseDependency::name>>;
|
using DependencyStorage = LMDBSafe::TypedDBI<DatabaseDependency, LMDBSafe::index_on<Dependency, std::string, &DatabaseDependency::name>>;
|
||||||
using LibraryDependencyStorage
|
using LibraryDependencyStorage
|
||||||
= LMDBSafe::TypedDBI<DatabaseLibraryDependency, LMDBSafe::index_on<DatabaseLibraryDependency, std::string, &DatabaseLibraryDependency::name>>;
|
= LMDBSafe::TypedDBI<DatabaseLibraryDependency, LMDBSafe::index_on<DatabaseLibraryDependency, std::string, &DatabaseLibraryDependency::name>>;
|
||||||
|
|
|
@ -193,13 +193,13 @@ PackageVersion PackageVersion::fromString(const char *versionString, size_t vers
|
||||||
#define valueString std::string_view(value, valueSize)
|
#define valueString std::string_view(value, valueSize)
|
||||||
#define ensure_pkg_info \
|
#define ensure_pkg_info \
|
||||||
if (!package.packageInfo) \
|
if (!package.packageInfo) \
|
||||||
package.packageInfo = make_unique<PackageInfo>()
|
package.packageInfo = make_optional<PackageInfo>()
|
||||||
#define ensure_install_info \
|
#define ensure_install_info \
|
||||||
if (!package.installInfo) \
|
if (!package.installInfo) \
|
||||||
package.installInfo = make_unique<InstallInfo>()
|
package.installInfo = make_optional<InstallInfo>()
|
||||||
|
|
||||||
void addPackageInfo(
|
static void addPackageInfo(Package &package, PackageVersion &version, const char *field, size_t fieldSize, const char *value, size_t valueSize,
|
||||||
Package &package, PackageVersion &version, const char *field, size_t fieldSize, const char *value, size_t valueSize, bool isPackageInfo)
|
bool isPackageInfo, std::size_t packageCount)
|
||||||
{
|
{
|
||||||
if_field("pkgbase")
|
if_field("pkgbase")
|
||||||
{
|
{
|
||||||
|
@ -235,7 +235,7 @@ void addPackageInfo(
|
||||||
// add as binary arch when parsing PKGINFO
|
// add as binary arch when parsing PKGINFO
|
||||||
ensure_pkg_info;
|
ensure_pkg_info;
|
||||||
package.packageInfo->arch = valueString;
|
package.packageInfo->arch = valueString;
|
||||||
} else if (package.sourceInfo.use_count() <= 1) {
|
} else if (!packageCount) {
|
||||||
// add to sourceInfo when still parsing base info
|
// add to sourceInfo when still parsing base info
|
||||||
package.sourceInfo->archs.emplace_back(value, valueSize);
|
package.sourceInfo->archs.emplace_back(value, valueSize);
|
||||||
} else {
|
} else {
|
||||||
|
@ -451,11 +451,12 @@ static void addVersionInfo(Package &package, PackageVersion &version, bool isPac
|
||||||
static void parsePkgInfo(const std::string &info, const std::function<Package *(Package &)> &nextPackage, bool isPackageInfo)
|
static void parsePkgInfo(const std::string &info, const std::function<Package *(Package &)> &nextPackage, bool isPackageInfo)
|
||||||
{
|
{
|
||||||
// define variables to store intermediate results while still parsing package base
|
// define variables to store intermediate results while still parsing package base
|
||||||
PackageVersion version;
|
auto version = PackageVersion();
|
||||||
Package basePackage;
|
auto packageCount = std::size_t();
|
||||||
|
auto basePackage = Package();
|
||||||
basePackage.origin = isPackageInfo ? PackageOrigin::PackageInfo : PackageOrigin::SourceInfo;
|
basePackage.origin = isPackageInfo ? PackageOrigin::PackageInfo : PackageOrigin::SourceInfo;
|
||||||
basePackage.sourceInfo = make_shared<SourceInfo>();
|
basePackage.sourceInfo = std::make_optional<SourceInfo>();
|
||||||
std::string &packageBase = basePackage.sourceInfo->name;
|
auto &packageBase = basePackage.sourceInfo->name;
|
||||||
|
|
||||||
// states
|
// states
|
||||||
enum {
|
enum {
|
||||||
|
@ -560,17 +561,18 @@ static void parsePkgInfo(const std::string &info, const std::function<Package *(
|
||||||
}
|
}
|
||||||
// find next package
|
// find next package
|
||||||
currentPackage = nextPackage(basePackage);
|
currentPackage = nextPackage(basePackage);
|
||||||
|
++packageCount;
|
||||||
}
|
}
|
||||||
// -> add field to ...
|
// -> add field to ...
|
||||||
try {
|
try {
|
||||||
if (currentPackage) {
|
if (currentPackage) {
|
||||||
// ... concrete package info if there's already a concrete package
|
// ... concrete package info if there's already a concrete package
|
||||||
addPackageInfo(*currentPackage, version, currentFieldName, currentFieldNameSize, currentFieldValue, currentFieldValueSize,
|
addPackageInfo(*currentPackage, version, currentFieldName, currentFieldNameSize, currentFieldValue, currentFieldValueSize,
|
||||||
isPackageInfo);
|
isPackageInfo, packageCount);
|
||||||
} else {
|
} else {
|
||||||
// ... base info if still parsing general info
|
// ... base info if still parsing general info
|
||||||
addPackageInfo(
|
addPackageInfo(basePackage, version, currentFieldName, currentFieldNameSize, currentFieldValue, currentFieldValueSize,
|
||||||
basePackage, version, currentFieldName, currentFieldNameSize, currentFieldValue, currentFieldValueSize, isPackageInfo);
|
isPackageInfo, packageCount);
|
||||||
}
|
}
|
||||||
} catch (const ConversionException &) {
|
} catch (const ConversionException &) {
|
||||||
// FIXME: error handling
|
// FIXME: error handling
|
||||||
|
@ -624,8 +626,8 @@ std::shared_ptr<Package> Package::fromDescription(const std::vector<std::string>
|
||||||
{
|
{
|
||||||
auto package = std::make_shared<Package>();
|
auto package = std::make_shared<Package>();
|
||||||
package->origin = PackageOrigin::Database;
|
package->origin = PackageOrigin::Database;
|
||||||
package->sourceInfo = make_shared<SourceInfo>();
|
package->sourceInfo = std::make_optional<SourceInfo>();
|
||||||
package->packageInfo = make_unique<PackageInfo>();
|
package->packageInfo = std::make_optional<PackageInfo>();
|
||||||
for (const auto &desc : descriptionParts) {
|
for (const auto &desc : descriptionParts) {
|
||||||
// states
|
// states
|
||||||
enum {
|
enum {
|
||||||
|
@ -890,7 +892,7 @@ std::shared_ptr<Package> Package::fromPkgFile(const string &path)
|
||||||
throw runtime_error("Package " % path + " does not contain a valid .PKGINFO");
|
throw runtime_error("Package " % path + " does not contain a valid .PKGINFO");
|
||||||
}
|
}
|
||||||
if (!package->packageInfo) {
|
if (!package->packageInfo) {
|
||||||
package->packageInfo = make_unique<PackageInfo>();
|
package->packageInfo = std::make_optional<PackageInfo>();
|
||||||
}
|
}
|
||||||
package->packageInfo->fileName = fileName(path);
|
package->packageInfo->fileName = fileName(path);
|
||||||
package->addDepsAndProvidesFromOtherPackage(tmpPackageForLibraryDeps, true);
|
package->addDepsAndProvidesFromOtherPackage(tmpPackageForLibraryDeps, true);
|
||||||
|
@ -933,7 +935,7 @@ std::shared_ptr<Package> Package::fromPkgFileName(std::string_view fileName)
|
||||||
pkg->name = name;
|
pkg->name = name;
|
||||||
pkg->version = version;
|
pkg->version = version;
|
||||||
pkg->provides.emplace_back(pkg->name, pkg->version);
|
pkg->provides.emplace_back(pkg->name, pkg->version);
|
||||||
pkg->packageInfo = make_unique<PackageInfo>();
|
pkg->packageInfo = std::make_optional<PackageInfo>();
|
||||||
pkg->packageInfo->fileName = fileName;
|
pkg->packageInfo->fileName = fileName;
|
||||||
pkg->packageInfo->arch = arch;
|
pkg->packageInfo->arch = arch;
|
||||||
return pkg;
|
return pkg;
|
||||||
|
@ -948,8 +950,9 @@ std::vector<PackageSpec> Package::fromAurRpcJson(const char *jsonData, std::size
|
||||||
packages.reserve(rpcMultiInfo.results.size());
|
packages.reserve(rpcMultiInfo.results.size());
|
||||||
|
|
||||||
for (auto &result : rpcMultiInfo.results) {
|
for (auto &result : rpcMultiInfo.results) {
|
||||||
auto package = std::make_shared<Package>();
|
auto &spec = packages.emplace_back();
|
||||||
auto sourceInfo = std::make_shared<SourceInfo>();
|
auto *package = &*(spec.pkg = std::make_shared<Package>());
|
||||||
|
auto &sourceInfo = package->sourceInfo = std::make_optional<SourceInfo>();
|
||||||
package->origin = origin;
|
package->origin = origin;
|
||||||
package->name = std::move(result.Name);
|
package->name = std::move(result.Name);
|
||||||
package->version = std::move(result.Version);
|
package->version = std::move(result.Version);
|
||||||
|
@ -979,8 +982,6 @@ std::vector<PackageSpec> Package::fromAurRpcJson(const char *jsonData, std::size
|
||||||
sourceInfo->firstSubmitted = DateTime::fromTimeStampGmt(result.FirstSubmitted);
|
sourceInfo->firstSubmitted = DateTime::fromTimeStampGmt(result.FirstSubmitted);
|
||||||
sourceInfo->lastModified = DateTime::fromTimeStampGmt(result.LastModified);
|
sourceInfo->lastModified = DateTime::fromTimeStampGmt(result.LastModified);
|
||||||
sourceInfo->url = std::move(result.URLPath);
|
sourceInfo->url = std::move(result.URLPath);
|
||||||
package->sourceInfo = std::move(sourceInfo);
|
|
||||||
packages.emplace_back(0, std::move(package));
|
|
||||||
}
|
}
|
||||||
return packages;
|
return packages;
|
||||||
}
|
}
|
||||||
|
|
|
@ -274,7 +274,7 @@ void DataTests::testComputingFileName()
|
||||||
pkg.name = "test";
|
pkg.name = "test";
|
||||||
pkg.version = "1.2-3";
|
pkg.version = "1.2-3";
|
||||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("packageInfo required for computing filename", string(), pkg.computeFileName());
|
CPPUNIT_ASSERT_EQUAL_MESSAGE("packageInfo required for computing filename", string(), pkg.computeFileName());
|
||||||
pkg.packageInfo = make_unique<PackageInfo>();
|
pkg.packageInfo = std::make_optional<PackageInfo>();
|
||||||
pkg.packageInfo->arch = "x86_64";
|
pkg.packageInfo->arch = "x86_64";
|
||||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("file name computed from name, version and arch", "test-1.2-3-x86_64.pkg.tar.zst"s, pkg.computeFileName());
|
CPPUNIT_ASSERT_EQUAL_MESSAGE("file name computed from name, version and arch", "test-1.2-3-x86_64.pkg.tar.zst"s, pkg.computeFileName());
|
||||||
pkg.packageInfo->fileName = "explicitly-specified-filename";
|
pkg.packageInfo->fileName = "explicitly-specified-filename";
|
||||||
|
@ -349,8 +349,8 @@ void DataTests::testComputingBuildOrder()
|
||||||
CPPUNIT_ASSERT_EQUAL(0_st, res.ignored.size());
|
CPPUNIT_ASSERT_EQUAL(0_st, res.ignored.size());
|
||||||
|
|
||||||
// ignore cycle if not interested in that particular package
|
// ignore cycle if not interested in that particular package
|
||||||
m_pkg2->packageInfo = std::make_unique<PackageInfo>();
|
m_pkg2->packageInfo = std::make_optional<PackageInfo>();
|
||||||
tar->packageInfo = std::make_unique<PackageInfo>();
|
tar->packageInfo = std::make_optional<PackageInfo>();
|
||||||
tar->dependencies.clear();
|
tar->dependencies.clear();
|
||||||
tar->dependencies.emplace_back("bar");
|
tar->dependencies.emplace_back("bar");
|
||||||
db.forceUpdatePackage(tar);
|
db.forceUpdatePackage(tar);
|
||||||
|
|
|
@ -4,6 +4,15 @@
|
||||||
#include "../parser/config.h"
|
#include "../parser/config.h"
|
||||||
#include "../parser/package.h"
|
#include "../parser/package.h"
|
||||||
|
|
||||||
|
namespace CppUtilities {
|
||||||
|
inline std::ostream &operator<<(std::ostream &out, const LibPkg::SourceInfo &sourceInfo)
|
||||||
|
{
|
||||||
|
const auto buff = sourceInfo.toJson();
|
||||||
|
out.write(buff.GetString(), ReflectiveRapidJSON::JsonReflector::rapidJsonSize(buff.GetSize()));
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
} // namespace CppUtilities
|
||||||
|
|
||||||
#include <c++utilities/conversion/stringbuilder.h>
|
#include <c++utilities/conversion/stringbuilder.h>
|
||||||
#include <c++utilities/conversion/stringconversion.h>
|
#include <c++utilities/conversion/stringconversion.h>
|
||||||
#include <c++utilities/io/misc.h>
|
#include <c++utilities/io/misc.h>
|
||||||
|
@ -194,8 +203,8 @@ void ParserTests::testParsingPlainSrcInfo()
|
||||||
CPPUNIT_ASSERT_MESSAGE("no regular dependencies"s, pkg1.dependencies.empty());
|
CPPUNIT_ASSERT_MESSAGE("no regular dependencies"s, pkg1.dependencies.empty());
|
||||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("optional dependencies"s,
|
CPPUNIT_ASSERT_EQUAL_MESSAGE("optional dependencies"s,
|
||||||
vector<Dependency>{ Dependency("c++utilities-doc"s, string(), DependencyMode::Any, "API documentation"s) }, pkg1.optionalDependencies);
|
vector<Dependency>{ Dependency("c++utilities-doc"s, string(), DependencyMode::Any, "API documentation"s) }, pkg1.optionalDependencies);
|
||||||
CPPUNIT_ASSERT_MESSAGE("source info present", pkg1.sourceInfo != nullptr);
|
CPPUNIT_ASSERT_MESSAGE("source info present", pkg1.sourceInfo.has_value());
|
||||||
CPPUNIT_ASSERT_MESSAGE("no package info present", pkg1.packageInfo == nullptr);
|
CPPUNIT_ASSERT_MESSAGE("no package info present", !pkg1.packageInfo.has_value());
|
||||||
CPPUNIT_ASSERT_EQUAL_MESSAGE(
|
CPPUNIT_ASSERT_EQUAL_MESSAGE(
|
||||||
"make dependencies"s, vector<Dependency>{ Dependency("cmake"s, "3.0"s, DependencyMode::GreatherEqual) }, pkg1.sourceInfo->makeDependencies);
|
"make dependencies"s, vector<Dependency>{ Dependency("cmake"s, "3.0"s, DependencyMode::GreatherEqual) }, pkg1.sourceInfo->makeDependencies);
|
||||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("check dependencies"s, vector<Dependency>{ Dependency("cppunit"s) }, pkg1.sourceInfo->checkDependencies);
|
CPPUNIT_ASSERT_EQUAL_MESSAGE("check dependencies"s, vector<Dependency>{ Dependency("cppunit"s) }, pkg1.sourceInfo->checkDependencies);
|
||||||
|
@ -225,10 +234,10 @@ void ParserTests::testParsingSplitPackageSrcInfo()
|
||||||
Dependency("mingw-w64-icu"s),
|
Dependency("mingw-w64-icu"s),
|
||||||
};
|
};
|
||||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("dependencies (2)"s, dependencies2, pkg2.dependencies);
|
CPPUNIT_ASSERT_EQUAL_MESSAGE("dependencies (2)"s, dependencies2, pkg2.dependencies);
|
||||||
CPPUNIT_ASSERT_MESSAGE("source info present (1)", pkg1.sourceInfo != nullptr);
|
CPPUNIT_ASSERT_MESSAGE("source info present (1)", pkg1.sourceInfo.has_value());
|
||||||
CPPUNIT_ASSERT_MESSAGE("source info present (2)", pkg2.sourceInfo != nullptr);
|
CPPUNIT_ASSERT_MESSAGE("source info present (2)", pkg2.sourceInfo.has_value());
|
||||||
CPPUNIT_ASSERT_MESSAGE("no package info present (1)", pkg1.packageInfo == nullptr);
|
CPPUNIT_ASSERT_MESSAGE("no package info present (1)", !pkg1.packageInfo.has_value());
|
||||||
CPPUNIT_ASSERT_MESSAGE("no package info present (2)", pkg2.packageInfo == nullptr);
|
CPPUNIT_ASSERT_MESSAGE("no package info present (2)", !pkg2.packageInfo.has_value());
|
||||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("pkgbase (1)"s, "mingw-w64-harfbuzz"s, pkg1.sourceInfo->name);
|
CPPUNIT_ASSERT_EQUAL_MESSAGE("pkgbase (1)"s, "mingw-w64-harfbuzz"s, pkg1.sourceInfo->name);
|
||||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("pkgbase (2)"s, "mingw-w64-harfbuzz"s, pkg2.sourceInfo->name);
|
CPPUNIT_ASSERT_EQUAL_MESSAGE("pkgbase (2)"s, "mingw-w64-harfbuzz"s, pkg2.sourceInfo->name);
|
||||||
const vector<string> archs = { "any"s };
|
const vector<string> archs = { "any"s };
|
||||||
|
@ -243,8 +252,9 @@ void ParserTests::testParsingSplitPackageSrcInfoWithDifferentArchs()
|
||||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("3 (split) packages present"s, 3ul, packages.size());
|
CPPUNIT_ASSERT_EQUAL_MESSAGE("3 (split) packages present"s, 3ul, packages.size());
|
||||||
|
|
||||||
const auto &jre = packages[0].pkg, &jdk = packages[1].pkg, &doc = packages[2].pkg;
|
const auto &jre = packages[0].pkg, &jdk = packages[1].pkg, &doc = packages[2].pkg;
|
||||||
CPPUNIT_ASSERT_MESSAGE("source info present", jdk->sourceInfo);
|
CPPUNIT_ASSERT_MESSAGE("source info present (jdk)", jdk->sourceInfo.has_value());
|
||||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("jre has same source info as base", jdk->sourceInfo, jre->sourceInfo);
|
CPPUNIT_ASSERT_MESSAGE("source info present (jre)", jre->sourceInfo.has_value());
|
||||||
|
CPPUNIT_ASSERT_EQUAL_MESSAGE("jre has same source info as base", jdk->sourceInfo->archs, jre->sourceInfo->archs);
|
||||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("jdk-doc has same source info as base", jdk->sourceInfo, doc->sourceInfo);
|
CPPUNIT_ASSERT_EQUAL_MESSAGE("jdk-doc has same source info as base", jdk->sourceInfo, doc->sourceInfo);
|
||||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("jre name", "jre"s, jre->name);
|
CPPUNIT_ASSERT_EQUAL_MESSAGE("jre name", "jre"s, jre->name);
|
||||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("jdk name", "jdk"s, jdk->name);
|
CPPUNIT_ASSERT_EQUAL_MESSAGE("jdk name", "jdk"s, jdk->name);
|
||||||
|
|
|
@ -55,7 +55,7 @@ struct LIBREPOMGR_EXPORT PackageBuildData : public ReflectiveRapidJSON::JsonSeri
|
||||||
std::vector<std::shared_ptr<LibPkg::Package>> existingPackages;
|
std::vector<std::shared_ptr<LibPkg::Package>> existingPackages;
|
||||||
std::string sourceDirectory;
|
std::string sourceDirectory;
|
||||||
std::string originalSourceDirectory;
|
std::string originalSourceDirectory;
|
||||||
std::shared_ptr<LibPkg::SourceInfo> sourceInfo;
|
std::optional<LibPkg::SourceInfo> sourceInfo;
|
||||||
std::vector<LibPkg::PackageSpec> packages;
|
std::vector<LibPkg::PackageSpec> packages;
|
||||||
std::vector<std::string> warnings;
|
std::vector<std::string> warnings;
|
||||||
std::string error;
|
std::string error;
|
||||||
|
@ -154,7 +154,14 @@ struct LIBREPOMGR_EXPORT BuildActionMessages : public ReflectiveRapidJSON::JsonS
|
||||||
class BuildProcessSession;
|
class BuildProcessSession;
|
||||||
struct ServiceSetup;
|
struct ServiceSetup;
|
||||||
|
|
||||||
struct LIBREPOMGR_EXPORT BuildAction : public std::enable_shared_from_this<BuildAction>,
|
struct LIBREPOMGR_EXPORT BuildActionBase : public ReflectiveRapidJSON::JsonSerializable<BuildActionBase>,
|
||||||
|
public ReflectiveRapidJSON::BinarySerializable<BuildActionBase, 1> {
|
||||||
|
using IdType = BuildActionIdType;
|
||||||
|
static constexpr IdType invalidId = std::numeric_limits<BuildActionBase::IdType>::max();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LIBREPOMGR_EXPORT BuildAction : public BuildActionBase,
|
||||||
|
public std::enable_shared_from_this<BuildAction>,
|
||||||
public ReflectiveRapidJSON::JsonSerializable<BuildAction>,
|
public ReflectiveRapidJSON::JsonSerializable<BuildAction>,
|
||||||
public ReflectiveRapidJSON::BinarySerializable<BuildAction, 1> {
|
public ReflectiveRapidJSON::BinarySerializable<BuildAction, 1> {
|
||||||
friend InternalBuildAction;
|
friend InternalBuildAction;
|
||||||
|
@ -168,9 +175,6 @@ struct LIBREPOMGR_EXPORT BuildAction : public std::enable_shared_from_this<Build
|
||||||
friend void WebAPI::Routes::postCloneBuildActions(const WebAPI::Params ¶ms, WebAPI::ResponseHandler &&handler);
|
friend void WebAPI::Routes::postCloneBuildActions(const WebAPI::Params ¶ms, WebAPI::ResponseHandler &&handler);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using IdType = BuildActionIdType;
|
|
||||||
static constexpr IdType invalidId = std::numeric_limits<BuildAction::IdType>::max();
|
|
||||||
|
|
||||||
explicit BuildAction(IdType id = invalidId, ServiceSetup *setup = nullptr) noexcept;
|
explicit BuildAction(IdType id = invalidId, ServiceSetup *setup = nullptr) noexcept;
|
||||||
BuildAction &operator=(BuildAction &&other);
|
BuildAction &operator=(BuildAction &&other);
|
||||||
~BuildAction();
|
~BuildAction();
|
||||||
|
@ -198,6 +202,12 @@ public:
|
||||||
void streamFile(const WebAPI::Params ¶ms, const std::string &filePath, boost::beast::string_view fileMimeType,
|
void streamFile(const WebAPI::Params ¶ms, const std::string &filePath, boost::beast::string_view fileMimeType,
|
||||||
boost::beast::string_view contentDisposition = boost::beast::string_view());
|
boost::beast::string_view contentDisposition = boost::beast::string_view());
|
||||||
ServiceSetup *setup();
|
ServiceSetup *setup();
|
||||||
|
using ReflectiveRapidJSON::JsonSerializable<BuildAction>::fromJson;
|
||||||
|
using ReflectiveRapidJSON::JsonSerializable<BuildAction>::toJson;
|
||||||
|
using ReflectiveRapidJSON::JsonSerializable<BuildAction>::toJsonDocument;
|
||||||
|
using ReflectiveRapidJSON::BinarySerializable<BuildAction, 1>::toBinary;
|
||||||
|
using ReflectiveRapidJSON::BinarySerializable<BuildAction, 1>::restoreFromBinary;
|
||||||
|
using ReflectiveRapidJSON::BinarySerializable<BuildAction, 1>::fromBinary;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
private:
|
private:
|
||||||
|
@ -207,28 +217,26 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
IdType id;
|
IdType id;
|
||||||
|
BuildActionType type = BuildActionType::Invalid;
|
||||||
std::string taskName;
|
std::string taskName;
|
||||||
std::string templateName;
|
std::string templateName;
|
||||||
std::string directory;
|
|
||||||
std::vector<std::string> packageNames;
|
|
||||||
std::vector<std::string> sourceDbs, destinationDbs;
|
|
||||||
std::unordered_map<std::string, std::string> settings;
|
|
||||||
BuildActionFlagType flags = noBuildActionFlags;
|
|
||||||
BuildActionType type = BuildActionType::Invalid;
|
|
||||||
|
|
||||||
// only the following member variables are supposed to change after the build action has been added
|
|
||||||
// to the overall list of build actions
|
|
||||||
BuildActionStatus status = BuildActionStatus::Created;
|
BuildActionStatus status = BuildActionStatus::Created;
|
||||||
BuildActionResult result = BuildActionResult::None;
|
BuildActionResult result = BuildActionResult::None;
|
||||||
std::variant<std::string, std::vector<std::string>, LibPkg::LicenseResult, LibPkg::PackageUpdates, BuildPreparation, BuildProgress,
|
|
||||||
PackageMovementResult, std::unordered_map<std::string, std::vector<RepositoryProblem>>, BuildActionMessages>
|
|
||||||
resultData;
|
|
||||||
std::vector<std::string> logfiles;
|
|
||||||
std::vector<std::string> artefacts;
|
|
||||||
CppUtilities::DateTime created = CppUtilities::DateTime::gmtNow();
|
CppUtilities::DateTime created = CppUtilities::DateTime::gmtNow();
|
||||||
CppUtilities::DateTime started;
|
CppUtilities::DateTime started;
|
||||||
CppUtilities::DateTime finished;
|
CppUtilities::DateTime finished;
|
||||||
std::vector<IdType> startAfter;
|
std::vector<IdType> startAfter;
|
||||||
|
std::string directory;
|
||||||
|
std::vector<std::string> sourceDbs, destinationDbs;
|
||||||
|
std::vector<std::string> packageNames;
|
||||||
|
BuildActionFlagType flags = noBuildActionFlags;
|
||||||
|
std::unordered_map<std::string, std::string> settings;
|
||||||
|
|
||||||
|
std::vector<std::string> logfiles;
|
||||||
|
std::vector<std::string> artefacts;
|
||||||
|
std::variant<std::string, std::vector<std::string>, LibPkg::LicenseResult, LibPkg::PackageUpdates, BuildPreparation, BuildProgress,
|
||||||
|
PackageMovementResult, std::unordered_map<std::string, std::vector<RepositoryProblem>>, BuildActionMessages>
|
||||||
|
resultData;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LogContext m_log;
|
LogContext m_log;
|
||||||
|
|
|
@ -350,7 +350,7 @@ void PrepareBuild::addResultFromSrcInfo(WebClient::AurSnapshotQuerySession &mult
|
||||||
auto snapshotResult = WebClient::AurSnapshotResult{ .packageName = packageName, .packages = LibPkg::Package::fromInfo(srcInfo, false) };
|
auto snapshotResult = WebClient::AurSnapshotResult{ .packageName = packageName, .packages = LibPkg::Package::fromInfo(srcInfo, false) };
|
||||||
if (snapshotResult.packages.empty() || snapshotResult.packages.front().pkg->name.empty()) {
|
if (snapshotResult.packages.empty() || snapshotResult.packages.front().pkg->name.empty()) {
|
||||||
snapshotResult.error = "Unable to parse .SRCINFO: no package name present";
|
snapshotResult.error = "Unable to parse .SRCINFO: no package name present";
|
||||||
} else if (!(snapshotResult.sourceInfo = snapshotResult.packages.front().pkg->sourceInfo)) {
|
} else if (!snapshotResult.packages.front().pkg->sourceInfo.has_value()) {
|
||||||
snapshotResult.error = "Unable to parse .SRCINFO: no source info present";
|
snapshotResult.error = "Unable to parse .SRCINFO: no source info present";
|
||||||
}
|
}
|
||||||
multiSession.addResponse(std::move(snapshotResult));
|
multiSession.addResponse(std::move(snapshotResult));
|
||||||
|
@ -822,7 +822,9 @@ void PrepareBuild::computeDependencies(WebClient::AurSnapshotQuerySession::Conta
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
auto &buildData = m_buildDataByPackage[response.packageName];
|
auto &buildData = m_buildDataByPackage[response.packageName];
|
||||||
buildData.sourceInfo = move(response.sourceInfo);
|
if (!response.packages.empty() && response.packages.front().pkg) {
|
||||||
|
buildData.sourceInfo = response.packages.front().pkg->sourceInfo;
|
||||||
|
}
|
||||||
buildData.packages = move(response.packages);
|
buildData.packages = move(response.packages);
|
||||||
buildData.error = move(response.error);
|
buildData.error = move(response.error);
|
||||||
buildData.hasSource = buildData.sourceInfo && !buildData.packages.empty() && buildData.error.empty();
|
buildData.hasSource = buildData.sourceInfo && !buildData.packages.empty() && buildData.error.empty();
|
||||||
|
|
|
@ -228,10 +228,10 @@ bool ReloadLibraryDependencies::addRelevantPackage(LibPkg::StorageID packageID,
|
||||||
relevantPkg.info.name = package->name;
|
relevantPkg.info.name = package->name;
|
||||||
// -> assign certain fields which are used by addDepsAndProvidesFromOtherPackage() to check whether the packages are matching
|
// -> assign certain fields which are used by addDepsAndProvidesFromOtherPackage() to check whether the packages are matching
|
||||||
relevantPkg.info.version = package->version;
|
relevantPkg.info.version = package->version;
|
||||||
relevantPkg.info.packageInfo = std::make_unique<LibPkg::PackageInfo>();
|
relevantPkg.info.packageInfo = std::make_optional<LibPkg::PackageInfo>();
|
||||||
relevantPkg.info.packageInfo->buildDate = package->packageInfo->buildDate;
|
relevantPkg.info.packageInfo->buildDate = package->packageInfo->buildDate;
|
||||||
// -> gather source info such as make and check dependencies as well
|
// -> gather source info such as make and check dependencies as well
|
||||||
relevantPkg.info.sourceInfo = std::make_shared<LibPkg::SourceInfo>();
|
relevantPkg.info.sourceInfo = std::make_optional<LibPkg::SourceInfo>();
|
||||||
++m_remainingPackages;
|
++m_remainingPackages;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,8 @@ void UpdateCheck::run()
|
||||||
|
|
||||||
if (m_fromAur && !m_packageLookupDone
|
if (m_fromAur && !m_packageLookupDone
|
||||||
&& WebClient::queryAurPackagesForDatabase(m_buildAction->log(), m_setup, m_setup.building.ioContext,
|
&& WebClient::queryAurPackagesForDatabase(m_buildAction->log(), m_setup, m_setup.building.ioContext,
|
||||||
&std::get<std::shared_lock<std::shared_mutex>>(configReadLock), **m_destinationDbs.begin(), [this](std::vector<LibPkg::PackageSpec> &&) {
|
&std::get<std::shared_lock<std::shared_mutex>>(configReadLock), **m_destinationDbs.begin(),
|
||||||
|
[this](std::vector<LibPkg::PackageSpec> &&) {
|
||||||
m_packageLookupDone = true;
|
m_packageLookupDone = true;
|
||||||
run();
|
run();
|
||||||
})) {
|
})) {
|
||||||
|
|
|
@ -44,7 +44,7 @@ struct LIBREPOMGR_EXPORT ServiceSetup : public LibPkg::Lockable {
|
||||||
std::string pacmanConfigFilePath = "/etc/pacman.conf";
|
std::string pacmanConfigFilePath = "/etc/pacman.conf";
|
||||||
std::filesystem::path initialWorkingDirectory;
|
std::filesystem::path initialWorkingDirectory;
|
||||||
std::string workingDirectory = "workingdir";
|
std::string workingDirectory = "workingdir";
|
||||||
std::string dbPath = "libpkg.db";
|
std::string dbPath = "libpkg-1.db";
|
||||||
std::uint32_t maxDbs = 512;
|
std::uint32_t maxDbs = 512;
|
||||||
std::size_t packageCacheLimit = 1000;
|
std::size_t packageCacheLimit = 1000;
|
||||||
|
|
||||||
|
@ -130,7 +130,7 @@ struct LIBREPOMGR_EXPORT ServiceSetup : public LibPkg::Lockable {
|
||||||
// never changed after startup
|
// never changed after startup
|
||||||
unsigned short threadCount = 4;
|
unsigned short threadCount = 4;
|
||||||
boost::asio::io_context ioContext;
|
boost::asio::io_context ioContext;
|
||||||
std::string dbPath = "librepomgr.db";
|
std::string dbPath = "librepomgr-1.db";
|
||||||
|
|
||||||
void initStorage(const char *path);
|
void initStorage(const char *path);
|
||||||
bool hasStorage() const;
|
bool hasStorage() const;
|
||||||
|
|
|
@ -227,15 +227,18 @@ void getPackages(const Params ¶ms, ResponseHandler &&handler)
|
||||||
const auto dbIterator = dbs.find(db.name);
|
const auto dbIterator = dbs.find(db.name);
|
||||||
return dbIterator == dbs.end() || dbIterator->second.find(db.arch) == dbIterator->second.end();
|
return dbIterator == dbs.end() || dbIterator->second.find(db.arch) == dbIterator->second.end();
|
||||||
});
|
});
|
||||||
const auto pushPackage = details
|
const auto pushPackage = LibPkg::Config::PackageVisitorBase([&array, &document, &limit](Database &db, LibPkg::StorageID id, const std::shared_ptr<PackageBase> &pkg) {
|
||||||
? LibPkg::Config::PackageVisitorConst([&array, &document, &limit](Database &, LibPkg::StorageID, const std::shared_ptr<Package> &pkg) {
|
ReflectiveRapidJSON::JsonReflector::push(LibPkg::PackageBaseSearchResult(db, *pkg, id), array, document.GetAllocator());
|
||||||
ReflectiveRapidJSON::JsonReflector::push(pkg, array, document.GetAllocator());
|
|
||||||
return array.Size() >= limit;
|
|
||||||
})
|
|
||||||
: ([&array, &document, &limit](Database &db, LibPkg::StorageID id, const std::shared_ptr<Package> &pkg) {
|
|
||||||
ReflectiveRapidJSON::JsonReflector::push(LibPkg::PackageSearchResult(db, pkg, id), array, document.GetAllocator());
|
|
||||||
return array.Size() >= limit;
|
return array.Size() >= limit;
|
||||||
});
|
});
|
||||||
|
const auto pushBasePackage = [&array, &document, &limit](Database &db, LibPkg::StorageID id, const PackageBase &pkg) {
|
||||||
|
ReflectiveRapidJSON::JsonReflector::push(LibPkg::PackageBaseSearchResult(db, pkg, id), array, document.GetAllocator());
|
||||||
|
return array.Size() >= limit;
|
||||||
|
};
|
||||||
|
const auto pushPackageDetails = !details ? LibPkg::Config::PackageVisitorConst() : [&array, &document, &limit](Database &, LibPkg::StorageID, const std::shared_ptr<Package> &pkg) {
|
||||||
|
ReflectiveRapidJSON::JsonReflector::push(pkg, array, document.GetAllocator());
|
||||||
|
return array.Size() >= limit;
|
||||||
|
};
|
||||||
|
|
||||||
auto aurPackages = std::vector<PackageSearchResult>();
|
auto aurPackages = std::vector<PackageSearchResult>();
|
||||||
auto neededAurPackages = std::vector<std::string>();
|
auto neededAurPackages = std::vector<std::string>();
|
||||||
|
@ -261,21 +264,28 @@ void getPackages(const Params ¶ms, ResponseHandler &&handler)
|
||||||
--limit;
|
--limit;
|
||||||
}
|
}
|
||||||
if (!isDbAur && (!dbs.empty() || !onlyFromAur)) {
|
if (!isDbAur && (!dbs.empty() || !onlyFromAur)) {
|
||||||
params.setup.config.packages(dbName, dbArch, packageNameStr, visitDb, pushPackage);
|
if (details) {
|
||||||
|
params.setup.config.packages(dbName, dbArch, packageNameStr, visitDb, pushPackageDetails);
|
||||||
|
} else {
|
||||||
|
params.setup.config.packages(dbName, dbArch, packageNameStr, visitDb, pushPackage);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Mode::NameContains:
|
case Mode::NameContains: {
|
||||||
|
auto basePackage = PackageBase();
|
||||||
params.setup.config.packagesByName(
|
params.setup.config.packagesByName(
|
||||||
visitDb, [&](LibPkg::Database &db, std::string_view packageName, const std::function<PackageSpec(void)> &getPackage) {
|
visitDb, [&](LibPkg::Database &db, std::string_view packageName, const std::function<StorageID(PackageBase&)> &getPackage) {
|
||||||
if (packageName.find(name) != std::string_view::npos) {
|
if (packageName.find(name) != std::string_view::npos) {
|
||||||
const auto [packageID, package] = getPackage();
|
const auto packageID = getPackage(basePackage);
|
||||||
if (!package) {
|
if (!packageID) {
|
||||||
cerr << Phrases::ErrorMessage << "Broken index in db \"" << db.name << "\": package \"" << packageName
|
cerr << Phrases::ErrorMessage << "Broken index in db \"" << db.name << "\": package \"" << packageName
|
||||||
<< "\" does not exist" << std::endl;
|
<< "\" does not exist" << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return pushPackage(db, packageID, package);
|
const auto stopSearch = pushBasePackage(db, packageID, basePackage);
|
||||||
|
basePackage.clear();
|
||||||
|
return stopSearch;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
@ -283,19 +293,23 @@ void getPackages(const Params ¶ms, ResponseHandler &&handler)
|
||||||
neededAurPackages.emplace_back(std::move(name));
|
neededAurPackages.emplace_back(std::move(name));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Mode::Regex:
|
}
|
||||||
|
case Mode::Regex: {
|
||||||
try {
|
try {
|
||||||
const auto regex = std::regex(name.data(), name.size());
|
const auto regex = std::regex(name.data(), name.size());
|
||||||
|
auto basePackage = PackageBase();
|
||||||
params.setup.config.packagesByName(
|
params.setup.config.packagesByName(
|
||||||
visitDb, [&](LibPkg::Database &db, std::string_view packageName, const std::function<PackageSpec(void)> &getPackage) {
|
visitDb, [&](LibPkg::Database &db, std::string_view packageName, const std::function<StorageID(PackageBase&)> &getPackage) {
|
||||||
if (std::regex_match(packageName.begin(), packageName.end(), regex)) {
|
if (std::regex_match(packageName.begin(), packageName.end(), regex)) {
|
||||||
const auto [packageID, package] = getPackage();
|
const auto packageID = getPackage(basePackage);
|
||||||
if (!package) {
|
if (!packageID) {
|
||||||
cerr << Phrases::ErrorMessage << "Broken index in db \"" << db.name << "\": package \"" << packageName
|
cerr << Phrases::ErrorMessage << "Broken index in db \"" << db.name << "\": package \"" << packageName
|
||||||
<< "\" does not exist" << std::endl;
|
<< "\" does not exist" << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return pushPackage(db, packageID, package);
|
const auto stopSearch = pushBasePackage(db, packageID, basePackage);
|
||||||
|
basePackage.clear();
|
||||||
|
return stopSearch;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
@ -303,6 +317,7 @@ void getPackages(const Params ¶ms, ResponseHandler &&handler)
|
||||||
throw BadRequest(argsToString("regex is invalid: ", e.what()));
|
throw BadRequest(argsToString("regex is invalid: ", e.what()));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case Mode::Provides:
|
case Mode::Provides:
|
||||||
case Mode::Depends:
|
case Mode::Depends:
|
||||||
params.setup.config.providingPackages(Dependency::fromString(name), mode == Mode::Depends, visitDb, pushPackage);
|
params.setup.config.providingPackages(Dependency::fromString(name), mode == Mode::Depends, visitDb, pushPackage);
|
||||||
|
|
|
@ -282,7 +282,7 @@ void queryAurSnapshots(LogContext &log, ServiceSetup &setup, const std::vector<A
|
||||||
}
|
}
|
||||||
if (result.packages.empty() || result.packages.front().pkg->name.empty()) {
|
if (result.packages.empty() || result.packages.front().pkg->name.empty()) {
|
||||||
result.error = "Unable to parse .SRCINFO: no package name present";
|
result.error = "Unable to parse .SRCINFO: no package name present";
|
||||||
} else if (!(result.sourceInfo = result.packages.front().pkg->sourceInfo)) {
|
} else if (!result.packages.front().pkg->sourceInfo.has_value()) {
|
||||||
result.error = "Unable to parse .SRCINFO: no source info present";
|
result.error = "Unable to parse .SRCINFO: no source info present";
|
||||||
}
|
}
|
||||||
multiSession->addResponse(move(result));
|
multiSession->addResponse(move(result));
|
||||||
|
|
|
@ -19,7 +19,6 @@ namespace WebClient {
|
||||||
struct AurSnapshotResult {
|
struct AurSnapshotResult {
|
||||||
std::string packageName;
|
std::string packageName;
|
||||||
std::string errorOutput;
|
std::string errorOutput;
|
||||||
std::shared_ptr<LibPkg::SourceInfo> sourceInfo;
|
|
||||||
std::vector<LibPkg::PackageSpec> packages;
|
std::vector<LibPkg::PackageSpec> packages;
|
||||||
std::string error;
|
std::string error;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue