]> git.ipfire.org Git - pakfire.git/commitdiff
transaction: Merge requests into the transaction
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 22 Sep 2023 15:41:18 +0000 (15:41 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 22 Sep 2023 15:41:18 +0000 (15:41 +0000)
It makes a lot more sense to have one large object that wraps the
solving process around libsolv instead of having multiple and passing
things around.

This is the first step to move things over and allow more flexibility
when performing depenedency resolution.

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
17 files changed:
Makefile.am
src/_pakfire/package.c
src/_pakfire/pakfire.c
src/libpakfire/build.c
src/libpakfire/include/pakfire/package.h
src/libpakfire/include/pakfire/problem.h
src/libpakfire/include/pakfire/request.h [deleted file]
src/libpakfire/include/pakfire/transaction.h
src/libpakfire/include/pakfire/ui.h
src/libpakfire/libpakfire.sym
src/libpakfire/package.c
src/libpakfire/pakfire.c
src/libpakfire/problem.c
src/libpakfire/request.c [deleted file]
src/libpakfire/solution.c
src/libpakfire/transaction.c
src/libpakfire/ui.c

index c0ae72b586fa57845ef42959d8443ddd7c81d376..1225ea9e734a03aa519f0350b63e580eba32c26c 100644 (file)
@@ -247,7 +247,6 @@ libpakfire_la_SOURCES = \
        src/libpakfire/pwd.c \
        src/libpakfire/repo.c \
        src/libpakfire/repolist.c \
-       src/libpakfire/request.c \
        src/libpakfire/scriptlet.c \
        src/libpakfire/snapshot.c \
        src/libpakfire/solution.c \
@@ -289,7 +288,6 @@ pkginclude_HEADERS += \
        src/libpakfire/include/pakfire/pwd.h \
        src/libpakfire/include/pakfire/repo.h \
        src/libpakfire/include/pakfire/repolist.h \
-       src/libpakfire/include/pakfire/request.h \
        src/libpakfire/include/pakfire/scriptlet.h \
        src/libpakfire/include/pakfire/snapshot.h \
        src/libpakfire/include/pakfire/solution.h \
index cf369f2f76eea4c238dc697b587e753d4cc313d0..8b5aa0942b9b060487efa20cf90a627e106c4061 100644 (file)
@@ -772,7 +772,7 @@ static PyObject* Package_installcheck(PackageObject* self) {
        int r;
 
        // Perform the installcheck
-       r = pakfire_package_installcheck(self->package, &problem);
+       r = pakfire_package_installcheck(self->package, &problem, 0);
 
        // Success!
        if (r == 0)
index ce16c3c3925b5c17f13e3a859b2f47ced3c29510..258b3ed3ddb7eb0319eeb57d065a80de60881eec 100644 (file)
@@ -34,7 +34,6 @@
 #include <pakfire/key.h>
 #include <pakfire/repo.h>
 #include <pakfire/repolist.h>
-#include <pakfire/request.h>
 #include <pakfire/transaction.h>
 #include <pakfire/util.h>
 
@@ -462,15 +461,15 @@ static PyObject* Pakfire_install(PakfireObject* self, PyObject* args, PyObject*
 
        // Do not install recommended packages
        if (without_recommended)
-               solver_flags |= PAKFIRE_REQUEST_WITHOUT_RECOMMENDED;
+               solver_flags |= PAKFIRE_TRANSACTION_WITHOUT_RECOMMENDED;
 
        // Can the solver uninstall packages?
        if (allow_uninstall)
-               solver_flags |= PAKFIRE_REQUEST_ALLOW_UNINSTALL;
+               solver_flags |= PAKFIRE_TRANSACTION_ALLOW_UNINSTALL;
 
        // Can the solver downgrade packages?
        if (allow_downgrade)
-               solver_flags |= PAKFIRE_REQUEST_ALLOW_DOWNGRADE;
+               solver_flags |= PAKFIRE_TRANSACTION_ALLOW_DOWNGRADE;
 
        Py_BEGIN_ALLOW_THREADS
 
@@ -525,7 +524,7 @@ static PyObject* Pakfire_erase(PakfireObject* self, PyObject* args, PyObject* kw
                transaction_flags |= PAKFIRE_TRANSACTION_DRY_RUN;
 
        if (keep_dependencies)
-               flags |= PAKFIRE_REQUEST_KEEP_DEPS;
+               flags |= PAKFIRE_JOB_KEEP_DEPS;
 
        Py_BEGIN_ALLOW_THREADS
 
@@ -582,15 +581,15 @@ static PyObject* Pakfire_update(PakfireObject* self, PyObject* args, PyObject* k
        }
 
        if (dryrun)
-               transaction_flags = PAKFIRE_TRANSACTION_DRY_RUN;
+               transaction_flags |= PAKFIRE_TRANSACTION_DRY_RUN;
 
        // Can the solver uninstall packages?
        if (allow_uninstall)
-               solver_flags |= PAKFIRE_REQUEST_ALLOW_UNINSTALL;
+               solver_flags |= PAKFIRE_TRANSACTION_ALLOW_UNINSTALL;
 
        // Can the solver downgrade packages?
        if (allow_downgrade)
-               solver_flags |= PAKFIRE_REQUEST_ALLOW_DOWNGRADE;
+               solver_flags |= PAKFIRE_TRANSACTION_ALLOW_DOWNGRADE;
 
        Py_BEGIN_ALLOW_THREADS
 
@@ -1379,7 +1378,7 @@ static PyObject* Pakfire_sync(PakfireObject* self, PyObject* args, PyObject* kwa
                return NULL;
 
        if (keep_orphaned)
-               flags |= PAKFIRE_REQUEST_KEEP_ORPHANED;
+               flags |= PAKFIRE_JOB_KEEP_ORPHANED;
 
        Py_BEGIN_ALLOW_THREADS
 
index 47986a73f3748de6e2723664bf04c7ea2c5afe82..e470ac56c7bced2ea5484bd6f5ebc353869b1bec 100644 (file)
 #include <pakfire/private.h>
 #include <pakfire/problem.h>
 #include <pakfire/repo.h>
-#include <pakfire/request.h>
 #include <pakfire/scriptlet.h>
 #include <pakfire/snapshot.h>
 #include <pakfire/solution.h>
 #include <pakfire/string.h>
+#include <pakfire/transaction.h>
 #include <pakfire/util.h>
 
 #define CCACHE_DIR "/var/cache/ccache"
@@ -1874,29 +1874,29 @@ ERROR:
 
 static int pakfire_build_install_package(struct pakfire* pakfire,
                struct pakfire_package* pkg, void* p) {
-       struct pakfire_request* request = (struct pakfire_request*)p;
+       struct pakfire_transaction* transaction = (struct pakfire_transaction*)p;
 
-       return pakfire_request_add_package(request, PAKFIRE_REQ_INSTALL, pkg,
-               PAKFIRE_REQUEST_ESSENTIAL);
+       return pakfire_transaction_request_package(transaction,
+               PAKFIRE_JOB_INSTALL, pkg, PAKFIRE_JOB_ESSENTIAL);
 }
 
 static int pakfire_build_install_test(struct pakfire_build* build) {
-       struct pakfire_request* request = NULL;
+       struct pakfire_transaction* transaction = NULL;
        struct pakfire_problem* problem = NULL;
        struct pakfire_solution* solution = NULL;
        const char* s = NULL;
        int r;
 
-       // Create a new request
-       r = pakfire_request_create(&request, build->pakfire, 0);
+       // Create a new transaction
+       r = pakfire_transaction_create(&transaction, build->pakfire, 0);
        if (r)
                goto ERROR;
 
        // Add all packages
-       r = pakfire_packagelist_walk(build->packages, pakfire_build_install_package, request);
+       r = pakfire_packagelist_walk(build->packages, pakfire_build_install_package, transaction);
 
        // Solve the request
-       r = pakfire_request_solve(request, 0);
+       r = pakfire_transaction_solve(transaction, 0, NULL);
        switch (r) {
                // All okay
                case 0:
@@ -1908,7 +1908,7 @@ static int pakfire_build_install_test(struct pakfire_build* build) {
 
                        // Walk through all problems
                        for (;;) {
-                               r = pakfire_request_next_problem(request, &problem);
+                               r = pakfire_transaction_next_problem(transaction, &problem);
                                if (r)
                                        goto ERROR;
 
@@ -1952,8 +1952,6 @@ static int pakfire_build_install_test(struct pakfire_build* build) {
 ERROR:
        if (r)
                ERROR(build->pakfire, "Install test failed: %m\n");
-       if (request)
-               pakfire_request_unref(request);
        if (problem)
                pakfire_problem_unref(problem);
        if (solution)
@@ -2057,37 +2055,37 @@ ERROR:
 
 static int pakfire_build_install_source_package(
                struct pakfire_build* build, struct pakfire_package* package) {
-       struct pakfire_request* request = NULL;
        struct pakfire_transaction* transaction = NULL;
+       char* problems = NULL;
        int r;
 
-       // Create a new request
-       r = pakfire_request_create(&request, build->pakfire, 0);
+       // Create a new transaction
+       r = pakfire_transaction_create(&transaction, build->pakfire, 0);
        if (r)
                goto ERROR;
 
-       // Add the package
-       r = pakfire_request_add_package(request, PAKFIRE_REQ_INSTALL, package,
-               PAKFIRE_REQUEST_ESSENTIAL);
-       if (r)
-               goto ERROR;
-
-       // Install all essential packages
+       // Request to install all essential packages
        for (const char** p = PAKFIRE_BUILD_PACKAGES; *p; p++) {
-               r = pakfire_request_add(request, PAKFIRE_REQ_INSTALL, *p, PAKFIRE_REQUEST_ESSENTIAL);
+               r = pakfire_transaction_request(transaction,
+                       PAKFIRE_JOB_INSTALL, *p, PAKFIRE_JOB_ESSENTIAL);
                if (r)
                        goto ERROR;
        }
 
-       // Solve the request
-       r = pakfire_request_solve(request, 0);
+       // Add the source package
+       r = pakfire_transaction_request_package(transaction,
+               PAKFIRE_JOB_INSTALL, package, PAKFIRE_JOB_ESSENTIAL);
        if (r)
                goto ERROR;
 
-       // Fetch the transaction
-       r = pakfire_request_get_transaction(request, &transaction);
-       if (r)
+       // Solve the transaction
+       r = pakfire_transaction_solve(transaction, 0, &problems);
+       if (r) {
+               if (problems)
+                       ERROR(build->pakfire, "Could not install the source package:\n%s\n", problems);
+
                goto ERROR;
+       }
 
        // Set how many packages have been changed
        const size_t changes = pakfire_transaction_count(transaction);
@@ -2107,8 +2105,8 @@ static int pakfire_build_install_source_package(
 ERROR:
        if (transaction)
                pakfire_transaction_unref(transaction);
-       if (request)
-               pakfire_request_unref(request);
+       if (problems)
+               free(problems);
 
        return r;
 }
@@ -2220,9 +2218,9 @@ ERROR:
 
 static int pakfire_build_mkimage_install_deps(struct pakfire_build* build,
                const char* type) {
-       struct pakfire_request* request = NULL;
        struct pakfire_transaction* transaction = NULL;
        char requires[NAME_MAX];
+       char* problems = NULL;
        int r;
 
        // Format requires
@@ -2230,32 +2228,25 @@ static int pakfire_build_mkimage_install_deps(struct pakfire_build* build,
        if (r)
                goto ERROR;
 
-       // Create a new request
-       r = pakfire_request_create(&request, build->pakfire, 0);
+       // Create a new transaction
+       r = pakfire_transaction_create(&transaction, build->pakfire, 0);
        if (r) {
-               ERROR(build->pakfire, "Could not create request: %m\n");
+               ERROR(build->pakfire, "Could not create transaction: %m\n");
                goto ERROR;
        }
 
        // Add requires to the request
-       r = pakfire_request_add(request, PAKFIRE_REQ_INSTALL, requires,
-               PAKFIRE_REQUEST_ESSENTIAL);
+       r = pakfire_transaction_request(transaction,
+                       PAKFIRE_JOB_INSTALL, requires, PAKFIRE_JOB_ESSENTIAL);
        if (r) {
-               ERROR(build->pakfire, "Could not add '%s' to the request: %m\n", requires);
+               ERROR(build->pakfire, "Could not add '%s' to the transaction: %m\n", requires);
                goto ERROR;
        }
 
        // Solve the request
-       r = pakfire_request_solve(request, 0);
+       r = pakfire_transaction_solve(transaction, 0, &problems);
        if (r) {
-               ERROR(build->pakfire, "Could not solve the request\n");
-               goto ERROR;
-       }
-
-       // Fetch the transaction
-       r = pakfire_request_get_transaction(request, &transaction);
-       if (r) {
-               ERROR(build->pakfire, "Could not fetch the transaction: %m\n");
+               ERROR(build->pakfire, "Could not solve the request:\n%s\n", problems);
                goto ERROR;
        }
 
@@ -2265,47 +2256,40 @@ static int pakfire_build_mkimage_install_deps(struct pakfire_build* build,
                goto ERROR;
 
 ERROR:
-       if (request)
-               pakfire_request_unref(request);
        if (transaction)
                pakfire_transaction_unref(transaction);
+       if (problems)
+               free(problems);
 
        return r;
 }
 
 static int pakfire_build_collect_packages(struct pakfire_build* build, const char* path) {
-       struct pakfire_request* request = NULL;
        struct pakfire_transaction* transaction = NULL;
+       char* problems = NULL;
        char* p = NULL;
        int r;
 
-       // Create a new request
-       r = pakfire_request_create(&request, build->pakfire, 0);
+       // Create a new transaction
+       r = pakfire_transaction_create(&transaction, build->pakfire, 0);
        if (r) {
-               ERROR(build->pakfire, "Could not create request: %m\n");
+               ERROR(build->pakfire, "Could not create transaction: %m\n");
                goto ERROR;
        }
 
        // XXX
        // Install the base system
-       r = pakfire_request_add(request, PAKFIRE_REQ_INSTALL, "ipfire-release",
-               PAKFIRE_REQUEST_ESSENTIAL);
+       r = pakfire_transaction_request(transaction,
+                       PAKFIRE_JOB_INSTALL, "ipfire-release", PAKFIRE_JOB_ESSENTIAL);
        if (r) {
                ERROR(build->pakfire, "Could not install 'ipfire-release': %m\n");
                goto ERROR;
        }
 
-       // Solve the request
-       r = pakfire_request_solve(request, 0);
-       if (r) {
-               ERROR(build->pakfire, "Could not solve request\n");
-               goto ERROR;
-       }
-
-       // Get the transaction
-       r = pakfire_request_get_transaction(request, &transaction);
+       // Solve the transaction
+       r = pakfire_transaction_solve(transaction, 0, &problems);
        if (r) {
-               ERROR(build->pakfire, "Could not fetch transaction: %m\n");
+               ERROR(build->pakfire, "Could not solve request:\n%s\n", problems);
                goto ERROR;
        }
 
@@ -2346,8 +2330,8 @@ static int pakfire_build_collect_packages(struct pakfire_build* build, const cha
 ERROR:
        if (transaction)
                pakfire_transaction_unref(transaction);
-       if (request)
-               pakfire_request_unref(request);
+       if (problems)
+               free(problems);
        if (p)
                free(p);
 
index eb73988435ff4e46fbd7071c897f2e6fb9e12253..3558d7dcebb6751f6a76cbd80e48a649762edbce 100644 (file)
@@ -146,7 +146,7 @@ enum pakfire_package_dump_flags {
 };
 
 // Installcheck
-int pakfire_package_installcheck(struct pakfire_package* pkg, char** problem);
+int pakfire_package_installcheck(struct pakfire_package* pkg, char** problem, int flags);
 
 #ifdef PAKFIRE_PRIVATE
 
index b9f7e6844e025af9d0c9c68ac9edc08a9df79951..6232d3835f733c1f0a0d23ec7e4c557ff6407f3b 100644 (file)
@@ -30,17 +30,17 @@ 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);
-
 int pakfire_problem_next_solution(
        struct pakfire_problem* problem, struct pakfire_solution** solution);
 
 #ifdef PAKFIRE_PRIVATE
 
-#include <pakfire/request.h>
+#include <pakfire/transaction.h>
 
 int pakfire_problem_create(struct pakfire_problem** problem, struct pakfire* pakfire,
-       struct pakfire_request* request, Id id);
+       struct pakfire_transaction* transaction, Id id);
+
+struct pakfire_transaction* pakfire_problem_get_transaction(struct pakfire_problem* problem);
 
 struct pakfire* pakfire_problem_get_pakfire(struct pakfire_problem* problem);
 Id pakfire_problem_get_id(struct pakfire_problem* problem);
diff --git a/src/libpakfire/include/pakfire/request.h b/src/libpakfire/include/pakfire/request.h
deleted file mode 100644 (file)
index 2a206a2..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/*#############################################################################
-#                                                                             #
-# Pakfire - The IPFire package management system                              #
-# Copyright (C) 2013 Pakfire development team                                 #
-#                                                                             #
-# This program is free software: you can redistribute it and/or modify        #
-# it under the terms of the GNU General Public License as published by        #
-# the Free Software Foundation, either version 3 of the License, or           #
-# (at your option) any later version.                                         #
-#                                                                             #
-# This program is distributed in the hope that it will be useful,             #
-# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
-# GNU General Public License for more details.                                #
-#                                                                             #
-# You should have received a copy of the GNU General Public License           #
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
-#                                                                             #
-#############################################################################*/
-
-#ifndef PAKFIRE_REQUEST_H
-#define PAKFIRE_REQUEST_H
-
-enum pakfire_request_flags {
-       PAKFIRE_REQUEST_WITHOUT_RECOMMENDED = 1 << 0,
-       PAKFIRE_REQUEST_ALLOW_UNINSTALL     = 1 << 1,
-       PAKFIRE_REQUEST_ALLOW_DOWNGRADE     = 1 << 2,
-};
-
-enum pakfire_request_job_flags {
-       PAKFIRE_REQUEST_KEEP_DEPS           = 1 << 0,
-       PAKFIRE_REQUEST_KEEP_ORPHANED       = 1 << 1,
-       PAKFIRE_REQUEST_ESSENTIAL           = 1 << 2,
-};
-
-#ifdef PAKFIRE_PRIVATE
-
-#include <solv/solver.h>
-
-#include <pakfire/package.h>
-#include <pakfire/problem.h>
-#include <pakfire/solution.h>
-#include <pakfire/transaction.h>
-
-struct pakfire_request;
-
-enum pakfire_request_action {
-       PAKFIRE_REQ_INSTALL,
-       PAKFIRE_REQ_ERASE,
-       PAKFIRE_REQ_UPDATE,
-       PAKFIRE_REQ_UPDATE_ALL,
-       PAKFIRE_REQ_SYNC,
-       PAKFIRE_REQ_LOCK,
-       PAKFIRE_REQ_VERIFY,
-};
-
-enum pakfire_request_solve_flags {
-       PAKFIRE_REQ_SOLVE_INTERACTIVE,
-};
-
-int pakfire_request_create(struct pakfire_request** request, struct pakfire* pakfire, int flags);
-
-struct pakfire_request* pakfire_request_ref(struct pakfire_request* request);
-struct pakfire_request* pakfire_request_unref(struct pakfire_request* request);
-
-int pakfire_request_solve(struct pakfire_request* request, int flags);
-
-int pakfire_request_add(struct pakfire_request* request,
-       const enum pakfire_request_action action, const char* what, int flags);
-int pakfire_request_add_package(struct pakfire_request* request,
-       const enum pakfire_request_action action, struct pakfire_package* package, int flags);
-
-int pakfire_request_take_solution(struct pakfire_request* request,
-       struct pakfire_solution* solution);
-
-Solver* pakfire_request_get_solver(struct pakfire_request* request);
-
-char* pakfire_request_get_problem_string(struct pakfire_request* request);
-
-int pakfire_request_next_problem(
-       struct pakfire_request* request, struct pakfire_problem** problem);
-
-int pakfire_request_get_transaction(struct pakfire_request* request,
-       struct pakfire_transaction** transaction);
-
-#endif
-
-#endif /* PAKFIRE_REQUEST_H */
index 3f21d07934bd231fe8ab27014d52a98d75cba5a5..651c545e4e504bf44ab1b1048c890d22ba056e96 100644 (file)
 
 struct pakfire_transaction;
 
+#include <pakfire/pakfire.h>
+#include <pakfire/problem.h>
+
 enum pakfire_transaction_flags {
-       PAKFIRE_TRANSACTION_DRY_RUN     = (1 << 0),
+       // XXX DRY_RUN has to be removed
+       PAKFIRE_TRANSACTION_DRY_RUN             = 1 << 0,
+       PAKFIRE_TRANSACTION_WITHOUT_RECOMMENDED = 1 << 1,
+       PAKFIRE_TRANSACTION_ALLOW_UNINSTALL     = 1 << 2,
+       PAKFIRE_TRANSACTION_ALLOW_DOWNGRADE     = 1 << 3,
+};
+
+enum pakfire_job_action {
+       PAKFIRE_JOB_INSTALL,
+       PAKFIRE_JOB_ERASE,
+       PAKFIRE_JOB_UPDATE,
+       PAKFIRE_JOB_UPDATE_ALL,
+       PAKFIRE_JOB_SYNC,
+       PAKFIRE_JOB_LOCK,
+       PAKFIRE_JOB_VERIFY,
+};
+
+enum pakfire_job_flags {
+       PAKFIRE_JOB_KEEP_DEPS           = 1 << 0,
+       PAKFIRE_JOB_KEEP_ORPHANED       = 1 << 1,
+       PAKFIRE_JOB_ESSENTIAL           = 1 << 2,
+       PAKFIRE_JOB_BEST                = 1 << 3,
 };
 
+int pakfire_transaction_create(struct pakfire_transaction** transaction,
+       struct pakfire* pakfire, int flags);
+
 struct pakfire_transaction* pakfire_transaction_ref(struct pakfire_transaction* transaction);
 struct pakfire_transaction* pakfire_transaction_unref(struct pakfire_transaction* transaction);
 
+// Callbacks
+void pakfire_transaction_set_status_callback(
+       struct pakfire_transaction* transaction, pakfire_status_callback callback, void* data);
+
+int pakfire_transaction_solve(struct pakfire_transaction* transaction, int flags, char** problems);
+
+int pakfire_transaction_request(struct pakfire_transaction* transaction,
+       const enum pakfire_job_action action, const char* what, int flags);
+int pakfire_transaction_request_package(struct pakfire_transaction* transaction,
+       const enum pakfire_job_action action, struct pakfire_package* package, int flags);
+
 size_t pakfire_transaction_count(struct pakfire_transaction* transaction);
 char* pakfire_transaction_dump(struct pakfire_transaction* transaction, size_t width);
 
@@ -45,9 +83,20 @@ int pakfire_transaction_download(struct pakfire_transaction* transaction);
 #include <solv/solver.h>
 
 #include <pakfire/key.h>
+#include <pakfire/solution.h>
 
-int pakfire_transaction_create(struct pakfire_transaction** transaction,
-       struct pakfire* pakfire, Solver* solver);
+// XXX needs removal
+enum pakfire_request_solve_flags {
+       PAKFIRE_REQ_SOLVE_INTERACTIVE,
+};
+
+Solver* pakfire_transaction_get_solver(struct pakfire_transaction* transaction);
+
+int pakfire_transaction_next_problem(
+       struct pakfire_transaction* transaction, struct pakfire_problem** problem);
+
+int pakfire_transaction_take_solution(struct pakfire_transaction* transaction,
+       struct pakfire_solution* solution);
 
 int pakfire_transaction_compose_repo(struct pakfire_transaction* transaction,
        struct pakfire_key* key, const char* path);
index 7bb955873631b620dd121a3ec05fde9b0deeab22..c319930a60dab31886455b4912f01d25fea66990 100644 (file)
@@ -23,9 +23,9 @@
 
 #ifdef PAKFIRE_PRIVATE
 
-#include <pakfire/request.h>
+#include <pakfire/transaction.h>
 
-int pakfire_ui_pick_solution(struct pakfire* pakfire, struct pakfire_request* request);
+int pakfire_ui_pick_solution(struct pakfire* pakfire, struct pakfire_transaction* transaction);
 
 #endif
 
index 7c0f96fc6c72ba454fdb14945df0098eec64574a..ed4255889688ed4cf865382b5c6f30fefda5492f 100644 (file)
@@ -279,7 +279,10 @@ global:
        pakfire_transaction_download;
        pakfire_transaction_dump;
        pakfire_transaction_ref;
+       pakfire_transaction_request;
+       pakfire_transaction_request_package;
        pakfire_transaction_run;
+       pakfire_transaction_set_status_callback;
        pakfire_transaction_unref;
 
 local:
index d2281c351659f40d5696342dc52064ccd8058af4..0209e596f9065becbf90a029a6e2b1eef4e49a65 100644 (file)
@@ -44,8 +44,8 @@
 #include <pakfire/pakfire.h>
 #include <pakfire/private.h>
 #include <pakfire/repo.h>
-#include <pakfire/request.h>
 #include <pakfire/string.h>
+#include <pakfire/transaction.h>
 #include <pakfire/util.h>
 
 struct pakfire_package {
@@ -2462,38 +2462,42 @@ ERROR:
        return md;
 }
 
-PAKFIRE_EXPORT int pakfire_package_installcheck(struct pakfire_package* pkg, char** problem) {
-       struct pakfire_request* request = NULL;
+PAKFIRE_EXPORT int pakfire_package_installcheck(struct pakfire_package* pkg,
+               char** problem, int flags) {
+       struct pakfire_transaction* transaction = NULL;
+       char* p = NULL;
        int r;
 
        const char* nevra = pakfire_package_get_string(pkg, PAKFIRE_PKG_NEVRA);
 
-       // Create a new request
-       r = pakfire_request_create(&request, pkg->pakfire, 0);
+       // Create a new transaction
+       r = pakfire_transaction_create(&transaction, pkg->pakfire, flags);
        if (r)
                goto ERROR;
 
        // Install the package
-       r = pakfire_request_add_package(request, PAKFIRE_REQ_INSTALL, pkg, 0);
+       r = pakfire_transaction_request_package(transaction,
+               PAKFIRE_JOB_INSTALL, pkg, PAKFIRE_JOB_ESSENTIAL);
        if (r) {
                ERROR(pkg->pakfire, "Could not add package %s to the request\n", nevra);
                goto ERROR;
        }
 
-       // Solve the request
-       r = pakfire_request_solve(request, 0);
+       // Solve the transaction
+       r = pakfire_transaction_solve(transaction, 0, &p);
        if (r) {
-               DEBUG(pkg->pakfire, "Could not install %s:\n", nevra);
+               DEBUG(pkg->pakfire, "Could not install %s:\n%s\n", nevra, p);
 
-               // Fetch the problem
-               *problem = pakfire_request_get_problem_string(request);
-               if (*problem)
-                       DEBUG(pkg->pakfire, "%s\n", *problem);
+               // Copy the problem string
+               if (p)
+                       *problem = strdup(p);
        }
 
 ERROR:
-       if (request)
-               pakfire_request_unref(request);
+       if (p)
+               free(p);
+       if (transaction)
+               pakfire_transaction_unref(transaction);
 
        return r;
 }
index a3c74f20cfc0f04134b2cfbdadff0202121999cc..2b1691dff36d8da74e27694e05589e41013ea9f6 100644 (file)
@@ -57,7 +57,6 @@
 #include <pakfire/private.h>
 #include <pakfire/pwd.h>
 #include <pakfire/repo.h>
-#include <pakfire/request.h>
 #include <pakfire/string.h>
 #include <pakfire/transaction.h>
 #include <pakfire/ui.h>
@@ -1899,14 +1898,13 @@ static int pakfire_perform_transaction(
                struct pakfire* pakfire,
                int transaction_flags,
                int solver_flags,
-               const enum pakfire_request_action action,
+               const enum pakfire_job_action action,
                const char** packages,
                const char** locks,
                int job_flags,
                int* changed,
                pakfire_status_callback status_callback,
                void* status_callback_data) {
-       struct pakfire_request* request = NULL;
        struct pakfire_transaction* transaction = NULL;
        int r = 1;
 
@@ -1921,15 +1919,20 @@ static int pakfire_perform_transaction(
        if (r)
                goto ERROR;
 
-       // Create a new request
-       r = pakfire_request_create(&request, pakfire, solver_flags);
+       // Create a new transaction
+       r = pakfire_transaction_create(&transaction, pakfire, solver_flags);
        if (r)
                goto ERROR;
 
+       // Set status callback
+       if (status_callback)
+               pakfire_transaction_set_status_callback(
+                       transaction, status_callback, status_callback_data);
+
        // Lock anything that should be locked
        if (locks) {
                for (const char** lock = locks; *lock; lock++) {
-                       r = pakfire_request_add(request, PAKFIRE_REQ_LOCK, *lock, 0);
+                       r = pakfire_transaction_request(transaction, PAKFIRE_JOB_LOCK, *lock, 0);
                        if (r) {
                                ERROR(pakfire, "Could not lock '%s': %m\n", *lock);
                                goto ERROR;
@@ -1939,20 +1942,15 @@ static int pakfire_perform_transaction(
 
        // Perform action on all packages
        for (const char** package = packages; *package; package++) {
-               r = pakfire_request_add(request, action, *package, job_flags);
+               r = pakfire_transaction_request(transaction, action, *package, job_flags);
                if (r) {
                        ERROR(pakfire, "Could not find '%s': %m\n", *package);
                        goto ERROR;
                }
        }
 
-       // Solve the request
-       r = pakfire_request_solve(request, PAKFIRE_REQ_SOLVE_INTERACTIVE);
-       if (r)
-               goto ERROR;
-
-       // Fetch the transaction
-       r = pakfire_request_get_transaction(request, &transaction);
+       // Solve the transaction
+       r = pakfire_transaction_solve(transaction, PAKFIRE_REQ_SOLVE_INTERACTIVE, NULL);
        if (r)
                goto ERROR;
 
@@ -1960,11 +1958,6 @@ static int pakfire_perform_transaction(
        if (changed)
                *changed = pakfire_transaction_count(transaction);
 
-       // Set status callback
-       if (status_callback)
-               pakfire_transaction_set_status_callback(
-                       transaction, status_callback, status_callback_data);
-
        // Run the transaction
        r = pakfire_transaction_run(transaction, transaction_flags);
        if (r)
@@ -1979,8 +1972,6 @@ ERROR:
 
        if (transaction)
                pakfire_transaction_unref(transaction);
-       if (request)
-               pakfire_request_unref(request);
 
        return r;
 }
@@ -1999,7 +1990,7 @@ PAKFIRE_EXPORT int pakfire_install(
                pakfire,
                transaction_flags,
                solver_flags,
-               PAKFIRE_REQ_INSTALL,
+               PAKFIRE_JOB_INSTALL,
                packages,
                locks,
                flags,
@@ -2022,7 +2013,7 @@ PAKFIRE_EXPORT int pakfire_erase(
                pakfire,
                transaction_flags,
                solver_flags,
-               PAKFIRE_REQ_ERASE,
+               PAKFIRE_JOB_ERASE,
                packages,
                locks,
                flags,
@@ -2032,9 +2023,8 @@ PAKFIRE_EXPORT int pakfire_erase(
 }
 
 static int pakfire_perform_transaction_simple(struct pakfire* pakfire, int solver_flags,
-               const enum pakfire_request_action action, int job_flags, int* changed,
+               const enum pakfire_job_action action, int job_flags, int* changed,
                pakfire_status_callback status_callback, void* status_callback_data) {
-       struct pakfire_request* request = NULL;
        struct pakfire_transaction* transaction = NULL;
        int r = 1;
 
@@ -2043,23 +2033,23 @@ static int pakfire_perform_transaction_simple(struct pakfire* pakfire, int solve
        if (r)
                goto ERROR;
 
-       // Create a new request
-       r = pakfire_request_create(&request, pakfire, solver_flags);
+       // Create a new transaction
+       r = pakfire_transaction_create(&transaction, pakfire, solver_flags);
        if (r)
                goto ERROR;
 
-       // Perform action
-       r = pakfire_request_add(request, action, NULL, job_flags);
-       if (r)
-               goto ERROR;
+       // Set status callback
+       if (status_callback)
+               pakfire_transaction_set_status_callback(
+                       transaction, status_callback, status_callback_data);
 
-       // Solve the request
-       r = pakfire_request_solve(request, PAKFIRE_REQ_SOLVE_INTERACTIVE);
+       // Perform action
+       r = pakfire_transaction_request(transaction, action, NULL, job_flags);
        if (r)
                goto ERROR;
 
-       // Fetch the transaction
-       r = pakfire_request_get_transaction(request, &transaction);
+       // Solve the transaction
+       r = pakfire_transaction_solve(transaction, PAKFIRE_REQ_SOLVE_INTERACTIVE, NULL);
        if (r)
                goto ERROR;
 
@@ -2067,11 +2057,6 @@ static int pakfire_perform_transaction_simple(struct pakfire* pakfire, int solve
        if (changed)
                *changed = pakfire_transaction_count(transaction);
 
-       // Set status callback
-       if (status_callback)
-               pakfire_transaction_set_status_callback(
-                       transaction, status_callback, status_callback_data);
-
        // Run the transaction
        r = pakfire_transaction_run(transaction, 0);
        if (r)
@@ -2086,8 +2071,6 @@ ERROR:
 
        if (transaction)
                pakfire_transaction_unref(transaction);
-       if (request)
-               pakfire_request_unref(request);
 
        return r;
 }
@@ -2106,16 +2089,16 @@ PAKFIRE_EXPORT int pakfire_update(
        // XXX add locks
        if (!packages)
                return pakfire_perform_transaction_simple(
-                       pakfire, solver_flags, PAKFIRE_REQ_UPDATE_ALL, flags, changed,
+                       pakfire, solver_flags, PAKFIRE_JOB_UPDATE_ALL, flags, changed,
                        status_callback, status_callback_data);
 
        return pakfire_perform_transaction(pakfire, transaction_flags, solver_flags,
-               PAKFIRE_REQ_UPDATE, packages, locks, flags, changed,
+               PAKFIRE_JOB_UPDATE, packages, locks, flags, changed,
                status_callback, status_callback_data);
 }
 
 static int pakfire_verify(struct pakfire* pakfire, int *changed) {
-       return pakfire_perform_transaction_simple(pakfire, 0, PAKFIRE_REQ_VERIFY,
+       return pakfire_perform_transaction_simple(pakfire, 0, PAKFIRE_JOB_VERIFY,
                0, changed, NULL, NULL);
 }
 
@@ -2173,5 +2156,5 @@ ERROR:
 PAKFIRE_EXPORT int pakfire_sync(struct pakfire* pakfire, int solver_flags, int flags,
                int* changed, pakfire_status_callback status_callback, void* status_callback_data) {
        return pakfire_perform_transaction_simple(pakfire, solver_flags,
-               PAKFIRE_REQ_SYNC, flags, changed, status_callback, status_callback_data);
+               PAKFIRE_JOB_SYNC, flags, changed, status_callback, status_callback_data);
 }
index 67d403f1e81248c40860948e133696f2f762be18..8da224b1ce7efda3ca766edbb55748287eaa31e9 100644 (file)
 #include <pakfire/pakfire.h>
 #include <pakfire/private.h>
 #include <pakfire/problem.h>
-#include <pakfire/request.h>
 #include <pakfire/solution.h>
+#include <pakfire/transaction.h>
 #include <pakfire/util.h>
 
 struct pakfire_problem {
        struct pakfire* pakfire;
        int nrefs;
 
-       struct pakfire_request* request;
+       struct pakfire_transaction* transaction;
        Id id;
        char* string;
 };
 
 static char* pakfire_problem_make_string(struct pakfire_problem* problem) {
-       Solver* solver = pakfire_request_get_solver(problem->request);
+       Solver* solver = pakfire_transaction_get_solver(problem->transaction);
        Pool* pool = solver->pool;
 
        // Get the problem rule
@@ -187,8 +187,8 @@ static char* pakfire_problem_make_string(struct pakfire_problem* problem) {
        return s;
 }
 
-PAKFIRE_EXPORT int pakfire_problem_create(struct pakfire_problem** problem,
-               struct pakfire* pakfire, struct pakfire_request* request, Id id) {
+int pakfire_problem_create(struct pakfire_problem** problem,
+               struct pakfire* pakfire, struct pakfire_transaction* transaction, Id id) {
        struct pakfire_problem* p = calloc(1, sizeof(*p));
        if (!p)
                return 1;
@@ -196,7 +196,7 @@ PAKFIRE_EXPORT int pakfire_problem_create(struct pakfire_problem** problem,
        p->pakfire = pakfire_ref(pakfire);
        p->nrefs = 1;
 
-       p->request = pakfire_request_ref(request);
+       p->transaction = pakfire_transaction_ref(transaction);
        p->id = id;
 
        *problem = p;
@@ -210,11 +210,10 @@ PAKFIRE_EXPORT struct pakfire_problem* pakfire_problem_ref(struct pakfire_proble
 }
 
 static void pakfire_problem_free(struct pakfire_problem* problem) {
-       pakfire_request_unref(problem->request);
-
+       if (problem->transaction)
+               pakfire_transaction_unref(problem->transaction);
        if (problem->string)
                free(problem->string);
-
        pakfire_unref(problem->pakfire);
        free(problem);
 }
@@ -242,13 +241,13 @@ Id pakfire_problem_get_id(struct pakfire_problem* problem) {
        return problem->id;
 }
 
-PAKFIRE_EXPORT struct pakfire_request* pakfire_problem_get_request(struct pakfire_problem* problem) {
-       return pakfire_request_ref(problem->request);
+struct pakfire_transaction* pakfire_problem_get_transaction(struct pakfire_problem* problem) {
+       return pakfire_transaction_ref(problem->transaction);
 }
 
 PAKFIRE_EXPORT int pakfire_problem_next_solution(
                struct pakfire_problem* problem, struct pakfire_solution** solution) {
-       Solver* solver = pakfire_request_get_solver(problem->request);
+       Solver* solver = pakfire_transaction_get_solver(problem->transaction);
        Id id = 0;
 
        // Check input
diff --git a/src/libpakfire/request.c b/src/libpakfire/request.c
deleted file mode 100644 (file)
index a0edf56..0000000
+++ /dev/null
@@ -1,462 +0,0 @@
-/*#############################################################################
-#                                                                             #
-# Pakfire - The IPFire package management system                              #
-# Copyright (C) 2013 Pakfire development team                                 #
-#                                                                             #
-# This program is free software: you can redistribute it and/or modify        #
-# it under the terms of the GNU General Public License as published by        #
-# the Free Software Foundation, either version 3 of the License, or           #
-# (at your option) any later version.                                         #
-#                                                                             #
-# This program is distributed in the hope that it will be useful,             #
-# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
-# GNU General Public License for more details.                                #
-#                                                                             #
-# You should have received a copy of the GNU General Public License           #
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
-#                                                                             #
-#############################################################################*/
-
-#include <ctype.h>
-#include <errno.h>
-#include <linux/limits.h>
-#include <stdlib.h>
-
-#include <solv/queue.h>
-#include <solv/selection.h>
-#include <solv/solver.h>
-#include <solv/transaction.h>
-
-#ifdef ENABLE_DEBUG
-# include <solv/solverdebug.h>
-#endif
-
-#include <pakfire/archive.h>
-#include <pakfire/dependencies.h>
-#include <pakfire/logging.h>
-#include <pakfire/package.h>
-#include <pakfire/pakfire.h>
-#include <pakfire/problem.h>
-#include <pakfire/request.h>
-#include <pakfire/string.h>
-#include <pakfire/transaction.h>
-#include <pakfire/ui.h>
-#include <pakfire/util.h>
-
-struct pakfire_request {
-       struct pakfire* pakfire;
-       int nrefs;
-
-       Solver* solver;
-       Queue jobs;
-};
-
-static void pakfire_request_free(struct pakfire_request* request) {
-       if (request->solver)
-               solver_free(request->solver);
-       queue_free(&request->jobs);
-
-       pakfire_unref(request->pakfire);
-       free(request);
-}
-
-static int setup_solver(struct pakfire_request* request, int flags) {
-       // Obey policy when searching for the best solvable
-       solver_set_flag(request->solver, SOLVER_FLAG_BEST_OBEY_POLICY, 1);
-
-       // Automatically update when installation is requested
-       solver_set_flag(request->solver, SOLVER_FLAG_INSTALL_ALSO_UPDATES, 1);
-
-       // Can the solver downgrade packages?
-       if (flags & PAKFIRE_REQUEST_ALLOW_DOWNGRADE)
-               solver_set_flag(request->solver, SOLVER_FLAG_ALLOW_DOWNGRADE, 1);
-
-       // Can the solver uninstall packages?
-       if (flags & PAKFIRE_REQUEST_ALLOW_UNINSTALL)
-               solver_set_flag(request->solver, SOLVER_FLAG_ALLOW_UNINSTALL, 1);
-
-       // Do not install any recommended packages
-       if (flags & PAKFIRE_REQUEST_WITHOUT_RECOMMENDED)
-               solver_set_flag(request->solver, SOLVER_FLAG_IGNORE_RECOMMENDED, 1);
-
-       return 0;
-}
-
-int pakfire_request_create(struct pakfire_request** request,
-               struct pakfire* pakfire, int flags) {
-       Pool* pool = pakfire_get_solv_pool(pakfire);
-       int r = 1;
-
-       // Cannot create a solver when no installed repository has been set
-       if (!pool->installed)
-               return -EINVAL;
-
-       // Allocate request
-       struct pakfire_request* req = calloc(1, sizeof(*req));
-       if (!req)
-               return ENOMEM;
-
-       req->pakfire = pakfire_ref(pakfire);
-       req->nrefs = 1;
-
-       // Allocate a job queue
-       queue_init(&req->jobs);
-
-       // Allocate solver
-       req->solver = solver_create(pool);
-       if (!req->solver) {
-               ERROR(pakfire, "Could not allocate solver: %m\n");
-               goto ERROR;
-       }
-
-       // Set up solver
-       r = setup_solver(req, flags);
-       if (r)
-               goto ERROR;
-
-       *request = req;
-       return 0;
-
-ERROR:
-       pakfire_request_free(req);
-       return r;
-}
-
-struct pakfire_request* pakfire_request_ref(struct pakfire_request* request) {
-       request->nrefs++;
-
-       return request;
-}
-
-struct pakfire_request* pakfire_request_unref(struct pakfire_request* request) {
-       if (--request->nrefs > 0)
-               return request;
-
-       pakfire_request_free(request);
-       return NULL;
-}
-
-Solver* pakfire_request_get_solver(struct pakfire_request* request) {
-       return request->solver;
-}
-
-static int pakfire_request_pick_solution(struct pakfire_request* request) {
-       // XXX TODO this is just a dummy
-       return pakfire_ui_pick_solution(request->pakfire, request);
-}
-
-int pakfire_request_solve(struct pakfire_request* request, int flags) {
-       int solved = 0;
-       int r;
-
-       // Prepare pool
-       pakfire_pool_internalize(request->pakfire);
-
-#ifdef ENABLE_DEBUG
-       Pool* pool = pakfire_get_solv_pool(request->pakfire);
-
-       const char* selection = pool_selection2str(pool, &request->jobs, 0);
-       if (selection) {
-               DEBUG(request->pakfire, "Solving: %s\n", selection);
-       }
-#endif
-
-       // Save time when we starting solving
-       clock_t solving_start = clock();
-
-RETRY:
-       r = solver_solve(request->solver, &request->jobs);
-       switch (r) {
-               // Solved!
-               case 0:
-                       // Mark as solved
-                       solved = 1;
-                       break;
-
-               // Not Solved
-               default:
-#ifdef ENABLE_DEBUG
-                       // Print all solutions
-                       solver_printallsolutions(request->solver);
-#endif
-
-                       // Ask the user to pick a solution
-                       if (flags & PAKFIRE_REQ_SOLVE_INTERACTIVE) {
-                               r = pakfire_request_pick_solution(request);
-                               if (r)
-                                       return r;
-
-                               // Retry solving
-                               goto RETRY;
-
-                       } else {
-                               char* s = pakfire_request_get_problem_string(request);
-                               if (s)
-                                       ERROR(request->pakfire, "%s\n", s);
-                       }
-                       break;
-       }
-
-       // Save time when we finished solving
-       clock_t solving_end = clock();
-
-       DEBUG(request->pakfire, "Solved request in %.4fms\n",
-               (double)(solving_end - solving_start) * 1000 / CLOCKS_PER_SEC);
-
-#ifdef ENABLE_DEBUG
-       if (solved)
-               solver_printdecisions(request->solver);
-#endif
-
-       // Return zero if solved, otherwise return non-zero
-       if (solved)
-               return 0;
-
-       return 2;
-}
-
-static int pakfire_request_is_file(const char* what) {
-       return pakfire_string_endswith(what, ".pfm");
-}
-
-static int __pakfire_request_add(struct pakfire_request* request,
-               const enum pakfire_request_action action, const Id type, const Id id, int flags) {
-       Id job = ID_NULL;
-
-       // Check if type/ID is not set for actions that don't support it
-       switch (action) {
-               case PAKFIRE_REQ_INSTALL:
-               case PAKFIRE_REQ_ERASE:
-               case PAKFIRE_REQ_UPDATE:
-               case PAKFIRE_REQ_LOCK:
-                       break;
-
-               default:
-                       if (type || id) {
-                               errno = EINVAL;
-                               return 1;
-                       }
-       }
-
-       // Essential jobs
-       if (flags & PAKFIRE_REQUEST_ESSENTIAL)
-               job |= SOLVER_ESSENTIAL;
-
-       // Select the correct action
-       switch (action) {
-               case PAKFIRE_REQ_INSTALL:
-                       job |= SOLVER_INSTALL;
-                       break;
-
-               case PAKFIRE_REQ_ERASE:
-                       job |= SOLVER_ERASE;
-
-                       // Should we keep any dependencies?
-                       if (!(flags & PAKFIRE_REQUEST_KEEP_DEPS))
-                               job |= SOLVER_CLEANDEPS;
-                       break;
-
-               case PAKFIRE_REQ_UPDATE:
-                       job |= SOLVER_UPDATE;
-                       break;
-
-               case PAKFIRE_REQ_UPDATE_ALL:
-                       job |= SOLVER_UPDATE|SOLVER_SOLVABLE_ALL;
-                       break;
-
-               case PAKFIRE_REQ_SYNC:
-                       job |= SOLVER_DISTUPGRADE|SOLVER_SOLVABLE_ALL;
-
-                       // Drop orphans?
-                       if (!(flags & PAKFIRE_REQUEST_KEEP_ORPHANED))
-                               queue_push2(&request->jobs, SOLVER_DROP_ORPHANED, 0);
-                       break;
-
-               case PAKFIRE_REQ_LOCK:
-                       job |= SOLVER_LOCK;
-                       break;
-
-               case PAKFIRE_REQ_VERIFY:
-                       job |= SOLVER_VERIFY|SOLVER_SOLVABLE_ALL;
-                       break;
-       }
-
-       // Add it to the job queue
-       queue_push2(&request->jobs, job|type, id);
-
-       return 0;
-}
-
-static int pakfire_request_add_job(struct pakfire_request* request,
-               const enum pakfire_request_action action, const char* what, int extra_flags) {
-       Pool* pool = pakfire_get_solv_pool(request->pakfire);
-
-       // Make the pool ready
-       pakfire_pool_internalize(request->pakfire);
-
-       Queue jobs;
-       queue_init(&jobs);
-
-       int flags =
-               // Select packages by name
-               SELECTION_NAME|
-               // Select packages by what they provide
-               SELECTION_PROVIDES|
-               // Process globbing patterns
-               SELECTION_GLOB|
-               // Select packages by their canonical name
-               SELECTION_CANON|
-               // Process .arch
-               SELECTION_DOTARCH|
-               // Process -release
-               SELECTION_REL;
-
-       // Process filelists?
-       if (*what == '/')
-               flags |= SELECTION_FILELIST;
-
-       // Select all packages
-       selection_make(pool, &jobs, what, flags);
-
-       // Did we find anything?
-       if (jobs.count == 0) {
-               Id id = pakfire_str2dep(request->pakfire, what);
-               if (!id)
-                       return 1;
-
-               queue_push2(&jobs, SOLVER_SOLVABLE_PROVIDES, id);
-       }
-
-       DEBUG(request->pakfire, "Found %d match(es) for '%s'\n", jobs.count / 2, what);
-
-       // Set action and global flags
-       for (int i = 0; i < jobs.count; i += 2)
-               __pakfire_request_add(request, action, jobs.elements[i], jobs.elements[i+1], extra_flags);
-
-       queue_free(&jobs);
-
-       return 0;
-}
-
-int pakfire_request_add(struct pakfire_request* request,
-               const enum pakfire_request_action action, const char* what, int flags) {
-       struct pakfire_package* package = NULL;
-       int r;
-
-       // Remove leading whitespace
-       if (what) {
-               while (*what && isspace(*what))
-                       what++;
-       }
-
-       if (!what) {
-               r = __pakfire_request_add(request, action, ID_NULL, ID_NULL, flags);
-               if (r)
-                       goto ERROR;
-
-       // Check if we got given a URL or some file
-       } else if (pakfire_string_is_url(what) || pakfire_request_is_file(what)) {
-               // Add them to the commandline repository
-               r = pakfire_commandline_add(request->pakfire, what, &package);
-               if (r)
-                       goto ERROR;
-
-               // Then add the package
-               r = pakfire_request_add_package(request, action, package, flags);
-               if (r)
-                       goto ERROR;
-
-       // Otherwise try adding this as a job
-       } else {
-               r = pakfire_request_add_job(request, action, what, flags);
-               if (r)
-                       goto ERROR;
-       }
-
-ERROR:
-       if (package)
-               pakfire_package_unref(package);
-
-       return r;
-}
-
-int pakfire_request_add_package(struct pakfire_request* request,
-               const enum pakfire_request_action action, struct pakfire_package* package, int flags) {
-       // Get the solvable ID
-       Id id = pakfire_package_id(package);
-
-       // Add it to the job queue
-       return __pakfire_request_add(request, action, SOLVER_SOLVABLE, id, flags);
-}
-
-char* pakfire_request_get_problem_string(struct pakfire_request* request) {
-       struct pakfire_problem* problem = NULL;
-       char* s = NULL;
-       int r;
-
-       for (;;) {
-               r = pakfire_request_next_problem(request, &problem);
-               if (r || !problem)
-                       break;
-
-               const char* p = pakfire_problem_to_string(problem);
-
-               r = asprintf(&s, "%s%s\n", (s) ? s : "", p);
-               if (r < 0)
-                       return NULL;
-       }
-
-       return s;
-}
-
-int pakfire_request_next_problem(
-               struct pakfire_request* request, struct pakfire_problem** problem) {
-       Id id = 0;
-
-       // Check input
-       if (!problem) {
-               errno = EINVAL;
-               return 1;
-       }
-
-       // Fetch the ID of the previous problem
-       if (*problem) {
-               id = pakfire_problem_get_id(*problem);
-
-               // Free the previous problem
-               pakfire_problem_unref(*problem);
-               *problem = NULL;
-       }
-
-       // Fetch the ID of the next problem
-       id = solver_next_problem(request->solver, id);
-       if (!id)
-               return 0;
-
-       // Create problem
-       return pakfire_problem_create(problem, request->pakfire, request, id);
-}
-
-int pakfire_request_take_solution(struct pakfire_request* request,
-               struct pakfire_solution* solution) {
-       struct pakfire_problem* problem = pakfire_solution_get_problem(solution);
-
-       // Fetch IDs
-       Id problem_id = pakfire_problem_get_id(problem);
-       Id solution_id = pakfire_solution_get_id(solution);
-
-       // Feed the solution into the solver
-       solver_take_solution(request->solver, problem_id, solution_id, &request->jobs);
-
-       pakfire_problem_unref(problem);
-       return 0;
-}
-
-int pakfire_request_get_transaction(struct pakfire_request* request,
-               struct pakfire_transaction** transaction) {
-       // XXX Check if we have solved successfully
-
-       // Create the transaction
-       return pakfire_transaction_create(transaction, request->pakfire, request->solver);
-}
index cad749a34988134ad24fb643613958bc1b2e3374..7eaac79ca0fdd4bfc2b97b2c87ac7475f808e819 100644 (file)
@@ -27,9 +27,9 @@
 #include <pakfire/logging.h>
 #include <pakfire/private.h>
 #include <pakfire/problem.h>
-#include <pakfire/request.h>
 #include <pakfire/solution.h>
 #include <pakfire/string.h>
+#include <pakfire/transaction.h>
 #include <pakfire/util.h>
 
 struct pakfire_solution {
@@ -94,8 +94,8 @@ Id pakfire_solution_get_id(struct pakfire_solution* solution) {
 }
 
 static char* pakfire_solution_make_string(struct pakfire_solution* solution) {
-       struct pakfire_request* request = pakfire_problem_get_request(solution->problem);
-       Solver* solver = pakfire_request_get_solver(request);
+       struct pakfire_transaction* transaction = pakfire_problem_get_transaction(solution->problem);
+       Solver* solver = pakfire_transaction_get_solver(transaction);
        Pool* pool = solver->pool;
 
        // Fetch the problem ID
@@ -104,7 +104,7 @@ static char* pakfire_solution_make_string(struct pakfire_solution* solution) {
        // How many elements do we have?
        unsigned int count = solver_solutionelement_count(solver, problem_id, solution->id);
        if (!count) {
-               pakfire_request_unref(request);
+               pakfire_transaction_unref(transaction);
                return NULL;
        }
 
@@ -188,7 +188,8 @@ static char* pakfire_solution_make_string(struct pakfire_solution* solution) {
        s = pakfire_string_join(elements, "\n");
 
 ERROR:
-       pakfire_request_unref(request);
+       if (transaction)
+               pakfire_transaction_unref(transaction);
 
        // Free all elements
        for (char** element = elements; *element; element++)
index a56ebae3b6e0ce11c3403c9319a50f9e5ab69a70..eb751942b01720b53aa166496338c17c8c9c539f 100644 (file)
 #                                                                             #
 #############################################################################*/
 
+#include <ctype.h>
 #include <errno.h>
 #include <stdlib.h>
 
+#include <solv/selection.h>
 #include <solv/transaction.h>
 #include <solv/solverdebug.h>
 
 #include <pakfire/archive.h>
 #include <pakfire/db.h>
+#include <pakfire/dependencies.h>
 #include <pakfire/digest.h>
 #include <pakfire/downloader.h>
 #include <pakfire/file.h>
@@ -46,6 +49,18 @@ struct pakfire_transaction {
        struct pakfire* pakfire;
        int nrefs;
 
+       // Flags
+       int flags;
+
+       // The solver
+       Solver* solver;
+       enum pakfire_transaction_solver_status {
+               SOLVER_STATUS_UNKNOWN,
+       } solver_status;
+
+       // The jobs to solve
+       Queue jobs;
+
        Transaction* transaction;
        char** userinstalled;
 
@@ -156,34 +171,37 @@ static void pakfire_transaction_free(struct pakfire_transaction* transaction) {
                        free(*userinstalled);
                free(transaction->userinstalled);
        }
-       transaction_free(transaction->transaction);
 
+       if (transaction->transaction)
+               transaction_free(transaction->transaction);
+
+       if (transaction->solver)
+               solver_free(transaction->solver);
        pakfire_unref(transaction->pakfire);
        free(transaction);
 }
 
-static int pakfire_transaction_import_transaction(
-               struct pakfire_transaction* transaction, Solver* solver) {
+static int pakfire_transaction_import_transaction(struct pakfire_transaction* transaction) {
        int r;
 
        // Clone the transaction to keep a copy of it
-       Transaction* t = solver_create_transaction(solver);
-       if (!t)
+       transaction->transaction = solver_create_transaction(transaction->solver);
+       if (!transaction->transaction) {
+               ERROR(transaction->pakfire, "Could not create transaction from solver: %m\n");
                return 1;
-
-       transaction->transaction = t;
+       }
 
        // Order the transaction
-       transaction_order(t, 0);
+       transaction_order(transaction->transaction, 0);
 
        // Log the transaction
-       transaction_print(t);
+       transaction_print(transaction->transaction);
 
        // Free any previous content
        pakfire_transaction_free_archives_and_packages(transaction);
 
        // How many steps?
-       transaction->num = t->steps.count;
+       transaction->num = transaction->transaction->steps.count;
 
        // Allocate space for packages
        transaction->packages = calloc(transaction->num, sizeof(*transaction->packages));
@@ -198,7 +216,7 @@ static int pakfire_transaction_import_transaction(
        // Create all packages
        for (unsigned int i = 0; i < transaction->num; i++) {
                r = pakfire_package_create_from_solvable(&transaction->packages[i],
-                       transaction->pakfire, t->steps.elements[i]);
+                       transaction->pakfire, transaction->transaction->steps.elements[i]);
                if (r)
                        return r;
        }
@@ -206,8 +224,7 @@ static int pakfire_transaction_import_transaction(
        return 0;
 }
 
-static int pakfire_transaction_import_userinstalled(
-               struct pakfire_transaction* t, Solver* solver) {
+static int pakfire_transaction_import_userinstalled(struct pakfire_transaction* transaction) {
        Queue userinstalled;
        const char* package = NULL;
        int r = 0;
@@ -215,34 +232,34 @@ static int pakfire_transaction_import_userinstalled(
        queue_init(&userinstalled);
 
        // Cleanup previous content
-       if (t->userinstalled) {
-               pakfire_strings_free(t->userinstalled);
-               t->userinstalled = NULL;
+       if (transaction->userinstalled) {
+               pakfire_strings_free(transaction->userinstalled);
+               transaction->userinstalled = NULL;
        }
 
        // Fetch a list of all packages that are installed by the user
-       solver_get_userinstalled(solver, &userinstalled, GET_USERINSTALLED_NAMES);
+       solver_get_userinstalled(transaction->solver, &userinstalled, GET_USERINSTALLED_NAMES);
 
        // Skip everything if the queue is empty
        if (!userinstalled.count)
                goto OUT;
 
-       t->userinstalled = calloc(userinstalled.count + 1, sizeof(*t->userinstalled));
-       if (!t->userinstalled) {
-               ERROR(t->pakfire, "Could not allocate userinstalled: %m\n");
+       transaction->userinstalled = calloc(userinstalled.count + 1, sizeof(*transaction->userinstalled));
+       if (!transaction->userinstalled) {
+               ERROR(transaction->pakfire, "Could not allocate userinstalled: %m\n");
                r = -errno;
                goto ERROR;
        }
 
-       Pool* pool = pakfire_get_solv_pool(t->pakfire);
+       Pool* pool = pakfire_get_solv_pool(transaction->pakfire);
 
        // Store the names of all userinstalled packages
        for (int i = 0; i < userinstalled.count; i++) {
                package = pool_id2str(pool, userinstalled.elements[i]);
 
-               t->userinstalled[i] = strdup(package);
+               transaction->userinstalled[i] = strdup(package);
 
-               if (!t->userinstalled[i]) {
+               if (!transaction->userinstalled[i]) {
                        r = -errno;
                        goto ERROR;
                }
@@ -252,9 +269,9 @@ static int pakfire_transaction_import_userinstalled(
        r = 0;
 
 ERROR:
-       if (t->userinstalled) {
-               pakfire_strings_free(t->userinstalled);
-               t->userinstalled = NULL;
+       if (transaction->userinstalled) {
+               pakfire_strings_free(transaction->userinstalled);
+               transaction->userinstalled = NULL;
        }
 
 OUT:
@@ -263,11 +280,50 @@ OUT:
        return r;
 }
 
-int pakfire_transaction_create(struct pakfire_transaction** transaction,
-               struct pakfire* pakfire, Solver* solver) {
+static void pakfire_transaction_default_status_callback(
+               struct pakfire* pakfire, void* data, int progress, const char* status) {
+       // XXX perform some default action...
+}
+
+static int pakfire_transaction_setup_solver(struct pakfire_transaction* transaction) {
+       Pool* pool = pakfire_get_solv_pool(transaction->pakfire);
+
+       // Allocate a new solver
+       transaction->solver = solver_create(pool);
+       if (!transaction->solver) {
+               ERROR(transaction->pakfire, "Could not allocate solver: %m\n");
+               return -errno;
+       }
+
+       // Obey policy when searching for the best solvable
+       solver_set_flag(transaction->solver, SOLVER_FLAG_BEST_OBEY_POLICY, 1);
+
+       // Automatically update when installation is requested
+       solver_set_flag(transaction->solver, SOLVER_FLAG_INSTALL_ALSO_UPDATES, 1);
+
+       // Can the solver downgrade packages?
+       if (transaction->flags & PAKFIRE_TRANSACTION_ALLOW_DOWNGRADE)
+               solver_set_flag(transaction->solver, SOLVER_FLAG_ALLOW_DOWNGRADE, 1);
+
+       // Can the solver uninstall packages?
+       if (transaction->flags & PAKFIRE_TRANSACTION_ALLOW_UNINSTALL)
+               solver_set_flag(transaction->solver, SOLVER_FLAG_ALLOW_UNINSTALL, 1);
+
+       // Do not install any recommended packages
+       if (transaction->flags & PAKFIRE_TRANSACTION_WITHOUT_RECOMMENDED)
+               solver_set_flag(transaction->solver, SOLVER_FLAG_IGNORE_RECOMMENDED, 1);
+
+       return 0;
+}
+
+PAKFIRE_EXPORT int pakfire_transaction_create(struct pakfire_transaction** transaction,
+               struct pakfire* pakfire, int flags) {
+       int r;
+
+       // Allocate the transaction
        struct pakfire_transaction* t = calloc(1, sizeof(*t));
        if (!t)
-               return ENOMEM;
+               return -errno;
 
        // Store reference to Pakfire
        t->pakfire = pakfire_ref(pakfire);
@@ -275,22 +331,28 @@ int pakfire_transaction_create(struct pakfire_transaction** transaction,
        // Initialize the reference counter
        t->nrefs = 1;
 
-       // Import transaction
-       int r = pakfire_transaction_import_transaction(t, solver);
-       if (r)
-               goto ERROR;
+       // Store flags
+       t->flags = flags;
 
-       // Import userinstalled
-       r = pakfire_transaction_import_userinstalled(t, solver);
+       // Set the default status callback
+       t->callbacks.status = pakfire_transaction_default_status_callback;
+
+       // Setup the solver
+       r = pakfire_transaction_setup_solver(t);
        if (r)
                goto ERROR;
 
+       // Allocate a job queue
+       queue_init(&t->jobs);
+
+       // Return the transaction
        *transaction = t;
+
        return 0;
 
 ERROR:
        pakfire_transaction_free(t);
-       return 1;
+       return r;
 }
 
 PAKFIRE_EXPORT struct pakfire_transaction* pakfire_transaction_ref(
@@ -309,8 +371,8 @@ PAKFIRE_EXPORT struct pakfire_transaction* pakfire_transaction_unref(
        return NULL;
 }
 
-void pakfire_transaction_set_status_callback(struct pakfire_transaction* transaction,
-               pakfire_status_callback callback, void* data) {
+PAKFIRE_EXPORT void pakfire_transaction_set_status_callback(
+               struct pakfire_transaction* transaction, pakfire_status_callback callback, void* data) {
        transaction->callbacks.status = callback;
        transaction->callbacks.status_data = data;
 }
@@ -351,6 +413,362 @@ static void pakfire_transaction_status(struct pakfire_transaction* transaction,
                free(buffer);
 }
 
+static char* pakfire_transaction_get_problem_string(struct pakfire_transaction* transaction) {
+       struct pakfire_problem* problem = NULL;
+       const char* p = NULL;
+       char* s = NULL;
+       int r;
+
+       for (;;) {
+               r = pakfire_transaction_next_problem(transaction, &problem);
+               if (r || !problem)
+                       break;
+
+               p = pakfire_problem_to_string(problem);
+               if (!p)
+                       goto ERROR;
+
+               r = asprintf(&s, "%s%s\n", (s) ? s : "", p);
+               if (r < 0)
+                       goto ERROR;
+       }
+
+       return s;
+
+ERROR:
+       if (s)
+               free(s);
+
+       return NULL;
+}
+
+Solver* pakfire_transaction_get_solver(struct pakfire_transaction* transaction) {
+       return transaction->solver;
+}
+
+PAKFIRE_EXPORT int pakfire_transaction_solve(struct pakfire_transaction* transaction,
+               int flags, char** problems) {
+       int solved = 0;
+       int r;
+
+       // XXX halt if the request has already been solved
+
+       // Prepare pool
+       pakfire_pool_internalize(transaction->pakfire);
+
+#ifdef ENABLE_DEBUG
+       Pool* pool = pakfire_get_solv_pool(transaction->pakfire);
+
+       const char* selection = pool_selection2str(pool, &transaction->jobs, 0);
+       if (selection)
+               DEBUG(transaction->pakfire, "Solving: %s\n", selection);
+#endif
+
+RETRY:
+       // Save time when we starting solving
+       clock_t solving_start = clock();
+
+       r = solver_solve(transaction->solver, &transaction->jobs);
+
+       // Save time when we finished solving
+       clock_t solving_end = clock();
+
+       DEBUG(transaction->pakfire, "Solved request in %.4fms\n",
+               (double)(solving_end - solving_start) * 1000 / CLOCKS_PER_SEC);
+
+       switch (r) {
+               // Solved!
+               case 0:
+                       // Mark as solved
+                       solved = 1;
+
+                       // Import the transaction
+                       r = pakfire_transaction_import_transaction(transaction);
+                       if (r)
+                               goto ERROR;
+
+                       // Import userinstalled packages
+                       r = pakfire_transaction_import_userinstalled(transaction);
+                       if (r)
+                               goto ERROR;
+
+                       break;
+
+               // Not Solved
+               default:
+#ifdef ENABLE_DEBUG
+                       // Print all solutions
+                       solver_printallsolutions(transaction->solver);
+#endif
+
+                       // Return the problems as string
+                       if (problems)
+                               *problems = pakfire_transaction_get_problem_string(transaction);
+
+                       // Ask the user to pick a solution
+                       if (flags & PAKFIRE_REQ_SOLVE_INTERACTIVE) {
+                               r = pakfire_ui_pick_solution(transaction->pakfire, transaction);
+                               if (r)
+                                       return r;
+
+                               // Retry solving
+                               goto RETRY;
+
+                       } else {
+                               char* s = pakfire_transaction_get_problem_string(transaction);
+                               if (s)
+                                       ERROR(transaction->pakfire, "%s\n", s);
+                       }
+                       break;
+       }
+
+#ifdef ENABLE_DEBUG
+       if (solved)
+               solver_printdecisions(transaction->solver);
+#endif
+
+       // Return zero if solved, otherwise return non-zero
+       if (solved)
+               return 0;
+
+       return 2;
+
+ERROR:
+       return r;
+}
+
+static int pakfire_transaction_is_file(const char* what) {
+       return pakfire_string_endswith(what, ".pfm");
+}
+
+static int __pakfire_transaction_add(struct pakfire_transaction* transaction,
+               const enum pakfire_job_action action, const Id type, const Id id, int flags) {
+       Id job = ID_NULL;
+
+       // Check if type/ID is not set for actions that don't support it
+       switch (action) {
+               case PAKFIRE_JOB_INSTALL:
+               case PAKFIRE_JOB_ERASE:
+               case PAKFIRE_JOB_UPDATE:
+               case PAKFIRE_JOB_LOCK:
+                       break;
+
+               default:
+                       if (type || id)
+                               return -EINVAL;
+       }
+
+       // Essential jobs
+       if (flags & PAKFIRE_JOB_ESSENTIAL)
+               job |= SOLVER_ESSENTIAL;
+
+       // Install the best package only?
+       if (flags & PAKFIRE_JOB_BEST)
+               job |= SOLVER_FORCEBEST;
+
+       // Select the correct action
+       switch (action) {
+               case PAKFIRE_JOB_INSTALL:
+                       job |= SOLVER_INSTALL;
+                       break;
+
+               case PAKFIRE_JOB_ERASE:
+                       job |= SOLVER_ERASE;
+
+                       // Should we keep any dependencies?
+                       if (!(flags & PAKFIRE_JOB_KEEP_DEPS))
+                               job |= SOLVER_CLEANDEPS;
+                       break;
+
+               case PAKFIRE_JOB_UPDATE:
+                       job |= SOLVER_UPDATE;
+                       break;
+
+               case PAKFIRE_JOB_UPDATE_ALL:
+                       job |= SOLVER_UPDATE|SOLVER_SOLVABLE_ALL;
+                       break;
+
+               case PAKFIRE_JOB_SYNC:
+                       job |= SOLVER_DISTUPGRADE|SOLVER_SOLVABLE_ALL;
+
+                       // Drop orphans?
+                       if (!(flags & PAKFIRE_JOB_KEEP_ORPHANED))
+                               queue_push2(&transaction->jobs, SOLVER_DROP_ORPHANED, 0);
+                       break;
+
+               case PAKFIRE_JOB_LOCK:
+                       job |= SOLVER_LOCK;
+                       break;
+
+               case PAKFIRE_JOB_VERIFY:
+                       job |= SOLVER_VERIFY|SOLVER_SOLVABLE_ALL;
+                       break;
+       }
+
+       // Add it to the job queue
+       queue_push2(&transaction->jobs, job|type, id);
+
+       return 0;
+}
+
+static int pakfire_transaction_add_job(struct pakfire_transaction* transaction,
+               const enum pakfire_job_action action, const char* what, int extra_flags) {
+       Queue jobs;
+       int r;
+
+       Pool* pool = pakfire_get_solv_pool(transaction->pakfire);
+
+       // Make the pool ready
+       pakfire_pool_internalize(transaction->pakfire);
+
+       // Initialize jobs
+       queue_init(&jobs);
+
+       int flags =
+               // Select packages by name
+               SELECTION_NAME|
+               // Select packages by what they provide
+               SELECTION_PROVIDES|
+               // Process globbing patterns
+               SELECTION_GLOB|
+               // Select packages by their canonical name
+               SELECTION_CANON|
+               // Process .arch
+               SELECTION_DOTARCH|
+               // Process -release
+               SELECTION_REL;
+
+       // Process filelists?
+       if (*what == '/')
+               flags |= SELECTION_FILELIST;
+
+       // Select all packages
+       selection_make(pool, &jobs, what, flags);
+
+       // Did we find anything?
+       if (jobs.count == 0) {
+               Id id = pakfire_str2dep(transaction->pakfire, what);
+               if (!id) {
+                       r = -errno;
+                       goto ERROR;
+               }
+
+               queue_push2(&jobs, SOLVER_SOLVABLE_PROVIDES, id);
+       }
+
+       DEBUG(transaction->pakfire, "Found %d match(es) for '%s'\n", jobs.count / 2, what);
+
+       // Set action and global flags
+       for (int i = 0; i < jobs.count; i += 2) {
+               r = __pakfire_transaction_add(transaction, action,
+                       jobs.elements[i], jobs.elements[i+1], extra_flags);
+               if (r)
+                       goto ERROR;
+       }
+
+       // Success
+       r = 0;
+
+ERROR:
+       queue_free(&jobs);
+
+       return r;
+}
+
+PAKFIRE_EXPORT int pakfire_transaction_request(struct pakfire_transaction* transaction,
+               const enum pakfire_job_action action, const char* what, int flags) {
+       struct pakfire_package* package = NULL;
+       int r;
+
+       // Remove leading whitespace
+       if (what) {
+               while (*what && isspace(*what))
+                       what++;
+       }
+
+       if (!what) {
+               r = __pakfire_transaction_add(transaction, action, ID_NULL, ID_NULL, flags);
+               if (r)
+                       goto ERROR;
+
+       // Check if we got given a URL or some file
+       } else if (pakfire_string_is_url(what) || pakfire_transaction_is_file(what)) {
+               // Add them to the commandline repository
+               r = pakfire_commandline_add(transaction->pakfire, what, &package);
+               if (r)
+                       goto ERROR;
+
+               // Then add the package
+               r = pakfire_transaction_request_package(transaction, action, package, flags);
+               if (r)
+                       goto ERROR;
+
+       // Otherwise try adding this as a job
+       } else {
+               r = pakfire_transaction_add_job(transaction, action, what, flags);
+               if (r)
+                       goto ERROR;
+       }
+
+ERROR:
+       if (package)
+               pakfire_package_unref(package);
+
+       return r;
+}
+
+PAKFIRE_EXPORT int pakfire_transaction_request_package(struct pakfire_transaction* transaction,
+               const enum pakfire_job_action action, struct pakfire_package* package, int flags) {
+       // Get the solvable ID
+       Id id = pakfire_package_id(package);
+
+       // Add it to the job queue
+       return __pakfire_transaction_add(transaction, action, SOLVER_SOLVABLE, id, flags);
+}
+
+int pakfire_transaction_next_problem(
+               struct pakfire_transaction* transaction, struct pakfire_problem** problem) {
+       Id id = 0;
+
+       // Check input
+       if (!problem) {
+               errno = EINVAL;
+               return 1;
+       }
+
+       // Fetch the ID of the previous problem
+       if (*problem) {
+               id = pakfire_problem_get_id(*problem);
+
+               // Free the previous problem
+               pakfire_problem_unref(*problem);
+               *problem = NULL;
+       }
+
+       // Fetch the ID of the next problem
+       id = solver_next_problem(transaction->solver, id);
+       if (!id)
+               return 0;
+
+       // Create problem
+       return pakfire_problem_create(problem, transaction->pakfire, transaction, id);
+}
+
+int pakfire_transaction_take_solution(struct pakfire_transaction* transaction,
+               struct pakfire_solution* solution) {
+       struct pakfire_problem* problem = pakfire_solution_get_problem(solution);
+
+       // Fetch IDs
+       Id problem_id = pakfire_problem_get_id(problem);
+       Id solution_id = pakfire_solution_get_id(solution);
+
+       // Feed the solution into the solver
+       solver_take_solution(transaction->solver, problem_id, solution_id, &transaction->jobs);
+
+       pakfire_problem_unref(problem);
+       return 0;
+}
+
 PAKFIRE_EXPORT size_t pakfire_transaction_count(struct pakfire_transaction* transaction) {
        return transaction->num;
 }
@@ -1443,6 +1861,9 @@ PAKFIRE_EXPORT int pakfire_transaction_run(
                struct pakfire_transaction* transaction, int flags) {
        int r;
 
+       // XXX automatically solve
+       // XXX automatically download
+
        // Skip running an empty transaction
        if (!transaction->num) {
                DEBUG(transaction->pakfire, "Empty transaction. Skipping...\n");
index ca9223189cf10da449f615fc11f9846a52cab6f8..b8c9f095f71fa427e608b90bda60f68b3848c353 100644 (file)
@@ -25,7 +25,7 @@
 #include <pakfire/i18n.h>
 #include <pakfire/pakfire.h>
 #include <pakfire/problem.h>
-#include <pakfire/request.h>
+#include <pakfire/transaction.h>
 #include <pakfire/ui.h>
 
 static int pakfire_ui_is_interactive(struct pakfire* pakfire) {
@@ -112,7 +112,7 @@ static struct pakfire_solution** pakfire_ui_append_solution(
        return list;
 }
 
-int pakfire_ui_pick_solution(struct pakfire* pakfire, struct pakfire_request* request) {
+int pakfire_ui_pick_solution(struct pakfire* pakfire, struct pakfire_transaction* transaction) {
        struct pakfire_problem* problem = NULL;
        struct pakfire_solution** solutions = NULL;
        struct pakfire_solution* solution = NULL;
@@ -124,7 +124,7 @@ int pakfire_ui_pick_solution(struct pakfire* pakfire, struct pakfire_request* re
 
        // Print all problems
        for (;;) {
-               r = pakfire_request_next_problem(request, &problem);
+               r = pakfire_transaction_next_problem(transaction, &problem);
                if (r)
                        goto ERROR;
 
@@ -175,7 +175,7 @@ int pakfire_ui_pick_solution(struct pakfire* pakfire, struct pakfire_request* re
                goto ERROR;
 
        // Fetch selected solution into the solver
-       r = pakfire_request_take_solution(request, solutions[choice - 1]);
+       r = pakfire_transaction_take_solution(transaction, solutions[choice - 1]);
        if (r)
                goto ERROR;