make resolve-dependencies write result back
authorKlaus Kaempf <kkaempf@suse.de>
Tue, 7 Feb 2006 17:11:40 +0000 (17:11 +0000)
committerKlaus Kaempf <kkaempf@suse.de>
Tue, 7 Feb 2006 17:11:40 +0000 (17:11 +0000)
zmd/backend/resolve-dependencies.cc
zmd/backend/transactions.cc
zmd/backend/transactions.h

index d2e42615c7811c76938dbcc008f55bad54186933..4c2e389b56d02865b67ebbdb9619c89660b0abf7 100644 (file)
@@ -1,11 +1,13 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
 
+#include <string>
+
 #include "zypp/ZYpp.h"
 #include "zypp/ZYppFactory.h"
 #include "zypp/base/Logger.h"
 #include "zypp/base/Exception.h"
 
-using std::endl;
+using namespace std;
 using namespace zypp;
 
 #include <sqlite3.h>
@@ -13,12 +15,41 @@ using namespace zypp;
 #include "dbsource/DbSources.h"
 
 #include "transactions.h"
+#include "zypp/solver/detail/ResolverInfo.h"
+
+using solver::detail::ResolverInfo_Ptr;
+
+static void
+append_dep_info (ResolverInfo_Ptr info, void *user_data)
+{
+    string *dep_failure_info = (string *)user_data;
+    bool debug = false;
+
+    if (info == NULL) {
+       ERR << "append_dep_info(NULL)" << endl;
+       return;
+    }
+
+    if (getenv ("RCD_DEBUG_DEPS"))
+        debug = true;
+
+    if (debug || info->important()) {
+       dep_failure_info->append( "\n" );
+       if (debug && info->error())
+           dep_failure_info->append( "ERR " );
+       if (debug && info->important())
+           dep_failure_info->append( "IMP " );
+       dep_failure_info->append( info->message() );
+    }
+    return;
+}
+
 
 int
 main (int argc, char **argv)
 {
     if (argc != 2) {
-       ERR << "usage: " << argv[0] << " <database>" << endl;
+       ERR << "usage: " << argv[0] << " <database> [verify]" << endl;
        return 1;
     }
 
@@ -50,7 +81,31 @@ main (int argc, char **argv)
     if (!read_transactions (God->pool(), db.db(), dbs))
        return 1;
 
-    God->resolver()->resolvePool();
+    bool success;
+    if (argc == 3) {
+       success = God->resolver()->verifySystem();
+    }
+    else {
+       success = God->resolver()->resolvePool();
+    }
+    MIL << "Solver " << (success?"was":"NOT") << " successful" << endl;
+
+    solver::detail::ResolverContext_Ptr context = God->resolver()->context();
+    if (context == NULL) {
+       ERR << "No context ?!" << endl;
+       return 1;
+    }
+    if (success) {
+       success = write_transactions (God->pool(), db.db(), context);
+    }
+    else {
+       string dep_failure_info( "Unresolved dependencies:\n" );
+
+       context->foreachInfo (PoolItem_Ref(), -1, append_dep_info, &dep_failure_info);
+
+       cout << dep_failure_info;
+       cout.flush();
+    }
 
-    return 0;
+    return (success ? 0 : 1);
 }
index fb6f6b1015923ddb05f5fe5a569b3dfa33ff16d9..836f9e15351d294559a5b5004a560dd4d240cc2f 100644 (file)
@@ -17,6 +17,9 @@
 #include "zypp/ResFilters.h"
 #include "zypp/CapFilters.h"
 
+#include "zypp/solver/detail/ResolverContext.h"
+#include "zypp/solver/detail/ResolverInfo.h"
+
 using std::endl;
 using namespace zypp;
 
@@ -32,6 +35,10 @@ typedef enum {
 
 using namespace std;
 using namespace zypp;
+using solver::detail::ResolverInfo_Ptr;
+using solver::detail::ResolverContext_Ptr;
+
+typedef std::set<PoolItem_Ref> PoolItemSet;
 
 //-----------------------------------------------------------------------------
 
@@ -44,7 +51,7 @@ read_transactions (const ResPool & pool, sqlite3 *db, const DbSources & sources)
     const char  *sql = "SELECT action, id FROM transactions";
     int rc = sqlite3_prepare (db, sql, -1, &handle, NULL);
     if (rc != SQLITE_OK) {
-       ERR << "Can not prepare transaction insertion clause: " << sqlite3_errmsg (db) << endl;
+       ERR << "Can not prepare transaction selection clause: " << sqlite3_errmsg (db) << endl;
         return false;
     }
 
@@ -97,5 +104,100 @@ read_transactions (const ResPool & pool, sqlite3 *db, const DbSources & sources)
     return true;
 }
 
+//-----------------------------------------------------------------------------
+
+static void
+insert_item( PoolItem_Ref item, const ResStatus & status, void *data)
+{
+    PoolItemSet *pis = (PoolItemSet *)data;
+    pis->insert( item );
+}
+
+static void
+insert_item_pair (PoolItem_Ref install, const ResStatus & status1, PoolItem_Ref remove, const ResStatus & status2, void *data)
+{
+    PoolItemSet *pis = (PoolItemSet *)data;
+    pis->insert( install );            // only the install
+}
+
+
+
+static void
+dep_get_package_info_cb (ResolverInfo_Ptr info, void *user_data)
+{
+    string *msg = (string *)user_data;
+
+    msg->append( info->message() );
+    msg->append( "|" );
+
+} /* dep_get_package_info_cb */
+
+
+static string
+dep_get_package_info (ResolverContext_Ptr context, PoolItem_Ref item)
+{
+    string info;
+
+    context->foreachInfo (item, RESOLVER_INFO_PRIORITY_USER, dep_get_package_info_cb, &info);
+
+    return info;
+} /* dep_get_package_info */
+
+
+bool
+write_resobject_set( sqlite3_stmt *handle, const PoolItemSet & objects, PackageOpType op_type, ResolverContext_Ptr context)
+{
+    int rc = SQLITE_DONE;
+
+    for (PoolItemSet::const_iterator iter = objects.begin(); iter != objects.end(); ++iter) {
+
+       string details = dep_get_package_info( context, *iter );
+
+        sqlite3_bind_int (handle, 1, (int) op_type);
+        sqlite3_bind_int (handle, 2, iter->resolvable()->zmdid());
+        sqlite3_bind_text (handle, 3, details.c_str(), -1, SQLITE_STATIC);
+
+        rc = sqlite3_step (handle);
+        sqlite3_reset (handle);
+    }
+    return (rc == SQLITE_DONE);
+}
+
+
+bool
+write_transactions (const ResPool & pool, sqlite3 *db, ResolverContext_Ptr context)
+{
+    MIL << "write_transactions" << endl;
+
+    sqlite3_stmt *handle = NULL;
+    const char *sql = "INSERT INTO transactions (action, id, details) VALUES (?, ?, ?)";
+    int rc = sqlite3_prepare (db, sql, -1, &handle, NULL);
+    if (rc != SQLITE_OK) {
+       ERR << "Can not prepare transaction insertion clause: " << sqlite3_errmsg (db) << endl;
+        return false;
+    }
+    PoolItemSet install_set;
+    PoolItemSet remove_set;
+
+    context->foreachInstall( insert_item, &install_set);
+    context->foreachUninstall( insert_item, &remove_set);
+    context->foreachUpgrade( insert_item_pair, &install_set);
+
+    bool result;
+    result = write_resobject_set (handle, install_set, PACKAGE_OP_INSTALL, context);
+    if (!result) {
+       ERR << "Error writing transaction install set: " << sqlite3_errmsg (db) << endl;
+    }
+    result = write_resobject_set (handle, remove_set, PACKAGE_OP_REMOVE, context);
+    if (!result) {
+       ERR << "Error writing transaction remove set: " << sqlite3_errmsg (db) << endl;
+    }
+
+    sqlite3_finalize (handle);
+
+    return result;
+}
+
+
 
 
index cd0d5454e879d8fd0b468d35ae42a08ccea02b02..9c9f2fa175a076e26065fd985a002cdaed538c3e 100644 (file)
@@ -2,7 +2,8 @@
 
 #include "dbsource/DbSources.h"
 #include "zypp/ResPool.h"
+#include "zypp/solver/detail/ResolverContext.h"
 #include <sqlite3.h>
 
 extern bool read_transactions (const zypp::ResPool & pool, sqlite3 *db, const DbSources & sources);
-extern bool write_transactions (const zypp::ResPool & pool, sqlite3 *db, const DbSources & sources);
+extern bool write_transactions (const zypp::ResPool & pool, sqlite3 *db, zypp::solver::detail::ResolverContext_Ptr context);