"build_host TEXT, "
"build_time INTEGER, "
"installed INTEGER, "
- "reason TEXT, "
+ "userinstalled INTEGER, "
"repository TEXT"
")");
if (r)
}
int pakfire_db_add_package(struct pakfire_db* db,
- PakfirePackage pkg, PakfireArchive archive) {
+ PakfirePackage pkg, PakfireArchive archive, int userinstalled) {
sqlite3_stmt* stmt = NULL;
int r;
const char* sql = "INSERT INTO packages(name, evr, arch, groups, filename, size, "
"inst_size, hash1, license, summary, description, uuid, vendor, build_host, "
- "build_time, installed, repository, reason) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, "
- "?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP, ?, ?)";
+ "build_time, installed, repository, userinstalled) "
+ "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP, ?, ?)";
// Prepare the statement
r = sqlite3_prepare_v2(db->handle, sql, strlen(sql), &stmt, NULL);
goto ROLLBACK;
}
- // XXX TODO Bind reason
- r = sqlite3_bind_null(stmt, 17);
- if (r)
+ // installed by the user?
+ r = sqlite3_bind_int(stmt, 17, userinstalled);
+ if (r) {
+ ERROR(db->pakfire, "Could not bind userinstalled: %s\n", sqlite3_errmsg(db->handle));
goto ROLLBACK;
+ }
// Run query
do {
ssize_t pakfire_db_packages(struct pakfire_db* db);
-int pakfire_db_add_package(struct pakfire_db* db, PakfirePackage pkg, PakfireArchive archive);
+int pakfire_db_add_package(struct pakfire_db* db, PakfirePackage pkg,
+ PakfireArchive archive, int userinstalled);
int pakfire_db_remove_package(struct pakfire_db* db, PakfirePackage pkg);
int pakfire_db_load(struct pakfire_db* db, PakfireRepo repo);
#ifdef PAKFIRE_PRIVATE
+#include <solv/queue.h>
#include <solv/transaction.h>
#include <pakfire/types.h>
-int pakfire_transaction_create(struct pakfire_transaction** transaction, Pakfire pakfire, Transaction* trans);
+int pakfire_transaction_create(struct pakfire_transaction** transaction, Pakfire pakfire,
+ Transaction* trans, Queue* userinstalled);
#endif
}
PAKFIRE_EXPORT struct pakfire_transaction* pakfire_request_get_transaction(struct pakfire_request* request) {
+ struct pakfire_transaction* transaction;
+ Queue userinstalled;
+
+ // Return nothing if no transaction was created
if (!request->transaction)
return NULL;
- struct pakfire_transaction* transaction;
- int r = pakfire_transaction_create(&transaction, request->pakfire, request->transaction);
- if (r)
- return NULL;
+ queue_init(&userinstalled);
+
+ // Fetch a list of all packages that are installed by the user
+ solver_get_userinstalled(request->solver, &userinstalled, GET_USERINSTALLED_NAMES);
+
+ // Create a new transaction
+ int r = pakfire_transaction_create(&transaction, request->pakfire,
+ request->transaction, &userinstalled);
+ if (r) {
+ transaction = NULL;
+ goto ERROR;
+ }
+
+ERROR:
+ queue_free(&userinstalled);
return transaction;
}
int nrefs;
Transaction* transaction;
+ const char** userinstalled;
PakfireArchive* archives;
PakfirePackage* packages;
static void pakfire_transaction_free(struct pakfire_transaction* transaction) {
pakfire_transaction_free_archives_and_packages(transaction);
+ if (transaction->userinstalled)
+ free(transaction->userinstalled);
transaction_free(transaction->transaction);
pakfire_unref(transaction->pakfire);
return 0;
}
+static int pakfire_transaction_import_userinstalled(
+ struct pakfire_transaction* t, Queue* userinstalled) {
+ if (t->userinstalled) {
+ free(t->userinstalled);
+ t->userinstalled = NULL;
+ }
+
+ // Skip everything if the queue is empty
+ if (!userinstalled || !userinstalled->count)
+ return 0;
+
+ t->userinstalled = calloc(userinstalled->count, sizeof(*t->userinstalled));
+ if (!t->userinstalled) {
+ ERROR(t->pakfire, "Could not allocate userinstalled\n");
+ return 1;
+ }
+
+ Pool* pool = pakfire_get_solv_pool(t->pakfire);
+
+ // Store the names of all userinstalled packages
+ for (int i = 0; i < userinstalled->count; i++)
+ t->userinstalled[i] = pool_id2str(pool, userinstalled->elements[i]);
+
+ return 0;
+}
+
int pakfire_transaction_create(struct pakfire_transaction** transaction,
- Pakfire pakfire, Transaction* trans) {
+ Pakfire pakfire, Transaction* trans, Queue* userinstalled) {
struct pakfire_transaction* t = calloc(1, sizeof(*t));
if (!t)
return ENOMEM;
if (r)
goto ERROR;
+ // Import userinstalled
+ r = pakfire_transaction_import_userinstalled(t, userinstalled);
+ if (r)
+ goto ERROR;
+
*transaction = t;
return 0;
return NULL;
}
+static int pakfire_transaction_package_is_userinstalled(
+ struct pakfire_transaction* transaction, PakfirePackage pkg) {
+ // No packages on the list
+ if (!transaction->userinstalled)
+ return 0;
+
+ const char* name = pakfire_package_get_name(pkg);
+
+ // Check if the package is on the list
+ for (const char** elem = transaction->userinstalled; *elem; elem++) {
+ if (strcmp(name, *elem) == 0)
+ return 1;
+ }
+
+ // Not found
+ return 0;
+}
+
static int pakfire_transaction_run_step(struct pakfire_transaction* transaction,
struct pakfire_db* db, const pakfire_action_type_t action, PakfirePackage pkg, PakfireArchive archive) {
if (!pkg) {
break;
}
- r = pakfire_db_add_package(db, pkg, archive);
+ r = pakfire_db_add_package(db, pkg, archive,
+ pakfire_transaction_package_is_userinstalled(transaction, pkg));
if (r)
break;
if (r)
break;
- r = pakfire_db_add_package(db, pkg, archive);
+ r = pakfire_db_add_package(db, pkg, archive,
+ pakfire_transaction_package_is_userinstalled(transaction, pkg));
if (r)
break;