From 644d266028bf1709233d56171eb6b7dbfd3cd1bd Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Tue, 28 Feb 2023 15:53:15 +0000 Subject: [PATCH] search: Consolidate using Dataiterator and add file search Signed-off-by: Michael Tremer --- src/_pakfire/pakfire.c | 21 +++- src/libpakfire/include/pakfire/pakfire.h | 2 +- src/libpakfire/pakfire.c | 117 +++++++++++++++-------- 3 files changed, 94 insertions(+), 46 deletions(-) diff --git a/src/_pakfire/pakfire.c b/src/_pakfire/pakfire.c index 114197bd..556ce119 100644 --- a/src/_pakfire/pakfire.c +++ b/src/_pakfire/pakfire.c @@ -768,6 +768,8 @@ static PyObject* Pakfire_search(PakfireObject* self, PyObject* args, PyObject* k const char* pattern = NULL; int name_only = 0; int flags = 0; + PyObject* ret = NULL; + int r; if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|$p", kwlist, &pattern, &name_only)) return NULL; @@ -776,16 +778,25 @@ static PyObject* Pakfire_search(PakfireObject* self, PyObject* args, PyObject* k if (name_only) flags |= PAKFIRE_SEARCH_NAME_ONLY; - int r = pakfire_search(self->pakfire, pattern, flags, &list); + r = pakfire_packagelist_create(&list, self->pakfire); if (r) { PyErr_SetFromErrno(PyExc_OSError); - return NULL; + goto ERROR; } - PyObject* obj = PyList_FromPackageList(list); - pakfire_packagelist_unref(list); + r = pakfire_search(self->pakfire, pattern, flags, list); + if (r) { + PyErr_SetFromErrno(PyExc_OSError); + goto ERROR; + } - return obj; + ret = PyList_FromPackageList(list); + +ERROR: + if (list) + pakfire_packagelist_unref(list); + + return ret; } static PyObject* Pakfire_version_compare(PakfireObject* self, PyObject* args) { diff --git a/src/libpakfire/include/pakfire/pakfire.h b/src/libpakfire/include/pakfire/pakfire.h index 54693ae0..c58b16ba 100644 --- a/src/libpakfire/include/pakfire/pakfire.h +++ b/src/libpakfire/include/pakfire/pakfire.h @@ -88,7 +88,7 @@ enum pakfire_search_flags { }; int pakfire_search(struct pakfire* pakfire, const char* what, int flags, - struct pakfire_packagelist** list); + struct pakfire_packagelist* list); // Logging diff --git a/src/libpakfire/pakfire.c b/src/libpakfire/pakfire.c index 59d99e33..1e6f2bb5 100644 --- a/src/libpakfire/pakfire.c +++ b/src/libpakfire/pakfire.c @@ -1446,6 +1446,52 @@ ERROR: return r; } +static int __pakfire_search(struct pakfire* pakfire, struct pakfire_packagelist* list, + const Id* keys, const char* what, int flags) { + Dataiterator di; + Queue matches; + int r; + + // Get the pool ready + pakfire_pool_internalize(pakfire); + + // Initialize the result queue + queue_init(&matches); + + // Setup the data interator + dataiterator_init(&di, pakfire->pool, 0, 0, 0, what, flags); + + // Search through these keys and add matches to the queue + for (const Id* key = keys; *key; key++) { + dataiterator_set_keyname(&di, *key); + dataiterator_set_search(&di, 0, 0); + + while (dataiterator_step(&di)) + queue_pushunique(&matches, di.solvid); + } + + // Import matches into the package list + r = pakfire_packagelist_import_solvables(list, &matches); + if (r) + goto ERROR; + +ERROR: + dataiterator_free(&di); + queue_free(&matches); + + return r; +} + +static int pakfire_search_filelist(struct pakfire* pakfire, const char* what, int flags, + struct pakfire_packagelist* list) { + const Id keys[] = { + SOLVABLE_FILELIST, + ID_NULL, + }; + + return __pakfire_search(pakfire, list, keys, what, SEARCH_FILES|SEARCH_GLOB); +} + static int pakfire_search_dep(struct pakfire* pakfire, Id type, const char* what, int flags, struct pakfire_packagelist* list) { int r; @@ -1479,7 +1525,27 @@ ERROR: PAKFIRE_EXPORT int pakfire_whatprovides(struct pakfire* pakfire, const char* what, int flags, struct pakfire_packagelist* list) { - return pakfire_search_dep(pakfire, SOLVABLE_PROVIDES, what, flags, list); + int r; + + // Check for valid input + if (!what || !list) { + errno = EINVAL; + return 1; + } + + // Search for all packages that match this dependency + r = pakfire_search_dep(pakfire, SOLVABLE_PROVIDES, what, flags, list); + if (r) + return r; + + // Search the filelist + if (*what == '/') { + r = pakfire_search_filelist(pakfire, what, flags, list); + if (r) + return r; + } + + return 0; } PAKFIRE_EXPORT int pakfire_whatrequires(struct pakfire* pakfire, const char* what, int flags, @@ -1488,20 +1554,7 @@ PAKFIRE_EXPORT int pakfire_whatrequires(struct pakfire* pakfire, const char* wha } PAKFIRE_EXPORT int pakfire_search(struct pakfire* pakfire, const char* what, int flags, - struct pakfire_packagelist** list) { - Queue matches; - Dataiterator di; - int r; - - // Get the pool ready - pakfire_pool_internalize(pakfire); - - // Initialize the result queue - queue_init(&matches); - - // Setup the data interator - dataiterator_init(&di, pakfire->pool, 0, 0, 0, what, SEARCH_SUBSTRING|SEARCH_NOCASE); - + struct pakfire_packagelist* list) { const Id keys[] = { SOLVABLE_NAME, SOLVABLE_SUMMARY, @@ -1509,32 +1562,16 @@ PAKFIRE_EXPORT int pakfire_search(struct pakfire* pakfire, const char* what, int ID_NULL }; - // Search through these keys and add matches to the queue - for (const Id* key = keys; *key; key++) { - dataiterator_set_keyname(&di, *key); - dataiterator_set_search(&di, 0, 0); - - while (dataiterator_step(&di)) - queue_pushunique(&matches, di.solvid); - - // Stop after name - if (flags & PAKFIRE_SEARCH_NAME_ONLY) - break; - } - - // Convert matches to package list - r = pakfire_packagelist_create_from_queue(list, pakfire, &matches); - if (r) - goto ERROR; - - // Sort the result - pakfire_packagelist_sort(*list); - -ERROR: - dataiterator_free(&di); - queue_free(&matches); + const Id keys_name_only[] = { + SOLVABLE_NAME, + ID_NULL + }; - return r; + return __pakfire_search(pakfire, + list, + (flags & PAKFIRE_SEARCH_NAME_ONLY) ? keys_name_only : keys, + what, + SEARCH_SUBSTRING|SEARCH_NOCASE); } // Logging -- 2.47.3