Allow dumping package databases

This commit is contained in:
Martchus 2023-12-16 22:13:44 +01:00
parent 00b737e334
commit 141d8fa3f5
7 changed files with 66 additions and 1 deletions

View File

@ -71,6 +71,15 @@ void LibPkg::Config::rebuildDb()
aur.rebuildDb();
}
void Config::dumpDb(const std::optional<std::regex> &filterRegex)
{
assert(m_storage != nullptr);
for (auto &db : databases) {
db.dumpDb(filterRegex);
}
aur.dumpDb(filterRegex);
}
std::size_t Config::cachedPackages() const
{
return m_storage ? m_storage->packageCache().size() : 0;

View File

@ -13,6 +13,7 @@
#include <cstring>
#include <memory>
#include <set>
#include <regex>
namespace LibPkg {
@ -123,6 +124,7 @@ struct LIBPKG_EXPORT Config : public Lockable, public ReflectiveRapidJSON::Binar
// storage and caching
void initStorage(const char *path = "libpkg.db", std::uint32_t maxDbs = 0);
void rebuildDb();
void dumpDb(const std::optional<std::regex> &filterRegex);
std::size_t cachedPackages() const;
void setPackageCacheLimit(std::size_t limit);
std::unique_ptr<StorageDistribution> &storage();

View File

@ -104,6 +104,28 @@ void LibPkg::Database::rebuildDb()
txn.commit();
}
void Database::dumpDb(const std::optional<std::regex> &filterRegex)
{
std::cout << "db: " << name << '@' << arch << '\n';
auto txn = m_storage->packages.getROTransaction();
auto end = txn.end();
std::cout << "packages (" << txn.size() << "):\n";
for (auto i = txn.begin(); i != end; ++i) {
if (const auto &value = i.value(); !filterRegex.has_value() || std::regex_match(value.name, filterRegex.value())) {
const auto key = i.getKey().get<LMDBSafe::IDType>();
std::cout << key << ':' << ' ' << value.name << '\n';
}
}
std::cout << "index (" << txn.size<0>() << "):\n";
for (auto i = txn.begin<0>(); i != end; ++i) {
if (const auto key = i.getKey().get<std::string_view>(); !filterRegex.has_value() || std::regex_match(key.cbegin(), key.cend(), filterRegex.value())) {
const auto value = i.getID();
std::cout << key << ':' << ' ' << value << '\n';
}
}
std::cout << '\n';
}
void LibPkg::Database::deducePathsFromLocalDirs()
{
if (localDbDir.empty()) {

View File

@ -13,6 +13,7 @@
#include <atomic>
#include <filesystem>
#include <optional>
#include <regex>
#include <unordered_set>
namespace LibPkg {
@ -161,6 +162,7 @@ struct LIBPKG_EXPORT Database : public ReflectiveRapidJSON::JsonSerializable<Dat
void initStorage(StorageDistribution &storage);
void rebuildDb();
void dumpDb(const std::optional<std::regex> &filterRegex);
void deducePathsFromLocalDirs();
void resetConfiguration(bool keepLocalPaths = false);
void clearPackages();

View File

@ -46,6 +46,7 @@
#include <filesystem>
#include <fstream>
#include <string_view>
#include <regex>
#include <unordered_set>
using namespace std;
@ -885,6 +886,25 @@ int ServiceSetup::fixDb()
return EXIT_SUCCESS;
}
int ServiceSetup::dumpDb(std::string_view filterRegex)
{
#ifndef CPP_UTILITIES_DEBUG_BUILD
try {
#endif
loadConfigFiles(true);
config.dumpDb(filterRegex.empty() ? std::nullopt : std::optional(std::regex(filterRegex.begin(), filterRegex.end())));
#ifndef CPP_UTILITIES_DEBUG_BUILD
} catch (const std::exception &e) {
cerr << Phrases::ErrorMessage << "Exception occurred: " << Phrases::End << " " << e.what() << Phrases::EndFlush;
return EXIT_FAILURE + 5;
} catch (...) {
cerr << Phrases::ErrorMessage << "Unknown error occurred." << Phrases::EndFlush;
return EXIT_FAILURE + 5;
}
#endif
return EXIT_SUCCESS;
}
void ServiceSetup::Locks::clear()
{
auto log = LogContext();

View File

@ -61,6 +61,7 @@ struct LIBREPOMGR_EXPORT ServiceSetup : public LibPkg::Lockable {
void initStorage();
int run();
int fixDb();
int dumpDb(std::string_view filterRegex);
ServiceStatus computeStatus();
// variables relevant for the web server; only changed when (re)loading config

View File

@ -41,9 +41,18 @@ int main(int argc, const char *argv[])
}
exitCode = setup.fixDb();
});
OperationArgument dumpDb("dump-db", '\0', "dumps package database entries");
ConfigValueArgument filterRegexArg("filter-regex", 'r', "dump only packages which name matches the specified regex", { "regex" });
dumpDb.setSubArguments({ &filterRegexArg, &configFileArg });
dumpDb.setCallback([&setup, &exitCode, &filterRegexArg, &configFileArg](const ArgumentOccurrence &) {
if (const auto configFilePath = configFileArg.firstValue()) {
setup.configFilePath = configFilePath;
}
exitCode = setup.dumpDb(filterRegexArg.isPresent() ? std::string_view(filterRegexArg.firstValue()) : std::string_view());
});
HelpArgument helpArg(parser);
NoColorArgument noColorArg;
parser.setMainArguments({ &runArg, &fixDb, &noColorArg, &helpArg });
parser.setMainArguments({ &runArg, &fixDb, &dumpDb, &noColorArg, &helpArg });
parser.setDefaultArgument(&runArg);
parser.parseArgs(argc, argv);
return exitCode;