]> git.ipfire.org Git - pakfire.git/commitdiff
problems: Refactor fetching solutions
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 2 Jul 2021 16:21:35 +0000 (16:21 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 2 Jul 2021 16:21:35 +0000 (16:21 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/_pakfire/problem.c
src/libpakfire/include/pakfire/problem.h
src/libpakfire/problem.c

index 120569c1a9a8c6c735c5fced39df523daaf4fe42..66a123a48c2e5945a52e0ac652c29032c54dbdfe 100644 (file)
@@ -82,18 +82,37 @@ static PyObject* Problem_string(ProblemObject* self) {
 }
 
 static PyObject* Problem_get_solutions(ProblemObject* self) {
+       struct pakfire_solution** solutions = NULL;
+
+       // Fetch all solutions
+       int r = pakfire_problem_get_solutions(self->problem, &solutions);
+       if (r) {
+               PyErr_SetFromErrno(PyExc_OSError);
+               return NULL;
+       }
+
        PyObject* list = PyList_New(0);
+       if (!list)
+               return NULL;
+
+       // Return the empty list if there are no solutions
+       if (!solutions)
+               return list;
+
+       for (struct pakfire_solution** solution = solutions; *solution; solution++) {
+               PyObject* s = new_solution(*solution);
+               if (!s)
+                       goto ERROR;
 
-       struct pakfire_solution* solution = pakfire_problem_get_solutions(self->problem);
-       while (solution) {
-               PyObject* s = new_solution(solution);
                PyList_Append(list, s);
                Py_DECREF(s);
-
-               solution = pakfire_solution_next(solution);
        }
 
        return list;
+
+ERROR:
+       Py_DECREF(list);
+       return NULL;
 }
 
 static struct PyMethodDef Problem_methods[] = {
index c391918ee632906edb1ba449d56787345ddfd12b..1f880b45710b53afc18342c709cf0e64069c3153 100644 (file)
@@ -32,7 +32,8 @@ struct pakfire_problem* pakfire_problem_unref(struct pakfire_problem* problem);
 const char* pakfire_problem_to_string(struct pakfire_problem* problem);
 
 struct pakfire_request* pakfire_problem_get_request(struct pakfire_problem* problem);
-struct pakfire_solution* pakfire_problem_get_solutions(struct pakfire_problem* problem);
+int pakfire_problem_get_solutions(struct pakfire_problem* problem,
+       struct pakfire_solution*** solutions);
 
 #ifdef PAKFIRE_PRIVATE
 
index e929509030ed3fe7138e270e75d9bcecb7cdd793..9a00b2841f7b31eba8b9b194b2bd5c96c985ec9f 100644 (file)
@@ -262,20 +262,48 @@ PAKFIRE_EXPORT struct pakfire_request* pakfire_problem_get_request(struct pakfir
        return pakfire_request_ref(problem->request);
 }
 
-PAKFIRE_EXPORT struct pakfire_solution* pakfire_problem_get_solutions(struct pakfire_problem* problem) {
-       struct pakfire_solution* s = NULL;
-       struct pakfire_solution* ret = NULL;
+PAKFIRE_EXPORT int pakfire_problem_get_solutions(struct pakfire_problem* problem,
+               struct pakfire_solution*** solutions) {
        Solver* solver = pakfire_request_get_solver(problem->request);
+       int r;
 
-       Id solution = 0;
-       while ((solution = solver_next_solution(solver, problem->id, solution)) != 0) {
-               pakfire_solution_create(&s, problem, solution);
+       // How many solutions are there?
+       unsigned int count = solver_solution_count(solver, problem->id);
+       if (!count) {
+               *solutions = NULL;
+               return 0;
+       }
+
+       // Allocate a solutions array
+       *solutions = calloc(count + 1, sizeof(**solutions));
+       if (!*solutions)
+               return 1;
+
+       struct pakfire_solution* solution = NULL;
+
+       Id s = 0;
+       for (unsigned int i = 0; i < count; i++) {
+               s = solver_next_solution(solver, problem->id, s);
+               if (!s)
+                       break;
+
+               // Create a new solution object
+               r = pakfire_solution_create(&solution, problem, s);
+               if (r)
+                       goto ERROR;
+
+               // Append solution to array
+               (*solutions)[i] = solution;
+       }
+
+       return 0;
 
-               if (ret)
-                       pakfire_solution_append(ret, s);
-               else
-                       ret = s;
+ERROR:
+       if (*solutions) {
+               for (struct pakfire_solution** solution = *solutions; *solution; solution++)
+                       pakfire_solution_unref(*solution);
+               free(*solutions);
        }
 
-       return ret;
+       return r;
 }