fork of Klaus dbsource, will be used as cache soon or later
authorDuncan Mac-Vicar P <dmacvicar@suse.de>
Thu, 22 Jun 2006 14:14:22 +0000 (14:14 +0000)
committerDuncan Mac-Vicar P <dmacvicar@suse.de>
Thu, 22 Jun 2006 14:14:22 +0000 (14:14 +0000)
as we redesign the sources.

25 files changed:
configure.ac
zypp/source/Makefile.am
zypp/source/sqlite-source/Makefile.am [new file with mode: 0644]
zypp/source/sqlite-source/SqliteAccess.cc [new file with mode: 0644]
zypp/source/sqlite-source/SqliteAccess.h [new file with mode: 0644]
zypp/source/sqlite-source/SqliteAtomImpl.cc [new file with mode: 0644]
zypp/source/sqlite-source/SqliteAtomImpl.h [new file with mode: 0644]
zypp/source/sqlite-source/SqliteLanguageImpl.cc [new file with mode: 0644]
zypp/source/sqlite-source/SqliteLanguageImpl.h [new file with mode: 0644]
zypp/source/sqlite-source/SqliteMessageImpl.cc [new file with mode: 0644]
zypp/source/sqlite-source/SqliteMessageImpl.h [new file with mode: 0644]
zypp/source/sqlite-source/SqlitePackageImpl.cc [new file with mode: 0644]
zypp/source/sqlite-source/SqlitePackageImpl.h [new file with mode: 0644]
zypp/source/sqlite-source/SqlitePatchImpl.cc [new file with mode: 0644]
zypp/source/sqlite-source/SqlitePatchImpl.h [new file with mode: 0644]
zypp/source/sqlite-source/SqlitePatternImpl.cc [new file with mode: 0644]
zypp/source/sqlite-source/SqlitePatternImpl.h [new file with mode: 0644]
zypp/source/sqlite-source/SqliteProductImpl.cc [new file with mode: 0644]
zypp/source/sqlite-source/SqliteProductImpl.h [new file with mode: 0644]
zypp/source/sqlite-source/SqliteScriptImpl.cc [new file with mode: 0644]
zypp/source/sqlite-source/SqliteScriptImpl.h [new file with mode: 0644]
zypp/source/sqlite-source/SqliteSourceImpl.cc [new file with mode: 0644]
zypp/source/sqlite-source/SqliteSourceImpl.h [new file with mode: 0644]
zypp/source/sqlite-source/SqliteSources.cc [new file with mode: 0644]
zypp/source/sqlite-source/SqliteSources.h [new file with mode: 0644]

index ac7e4e3..3d5cf32 100644 (file)
@@ -246,7 +246,8 @@ AC_OUTPUT(   po/Makefile.in\
        zypp/source/plaindir/Makefile   \
        zypp/source/susetags/Makefile   \
        zypp/source/yum/Makefile        \
-       zypp/media/Makefile             \
+       zypp/source/sqlite-source/Makefile \
+  zypp/media/Makefile          \
        zypp/media/proxyinfo/Makefile   \
        zypp/ui/Makefile                \
        zypp/url/Makefile               \
index 786c956..952d039 100644 (file)
@@ -1,7 +1,7 @@
 ## Process this file with automake to produce Makefile.in
 ## ##################################################
 
-SUBDIRS = plaindir susetags yum
+SUBDIRS = plaindir susetags yum sqlite-source
 
 INCLUDES =                                     \
        -DZYPP_BASE_LOGGER_LOGGROUP=\"source\"
@@ -14,7 +14,8 @@ sourceinclude_HEADERS =       \
        SourceImpl.h    \
        Builtin.h       \
        PackageDelta.h  \
-       MediaSet.h
+       MediaSet.h \
+       SourceCreateContext.h
 
 noinst_LTLIBRARIES =   lib@PACKAGE@_source.la
 
@@ -29,6 +30,7 @@ lib@PACKAGE@_source_la_SOURCES = \
 lib@PACKAGE@_source_la_LIBADD = \
                plaindir/lib@PACKAGE@_source_plaindir.la        \
                susetags/lib@PACKAGE@_source_susetags.la        \
-               yum/lib@PACKAGE@_source_yum.la
+               yum/lib@PACKAGE@_source_yum.la \
+               sqlite-source/lib@PACKAGE@_source_sqlite.la
 
 ## ##################################################
diff --git a/zypp/source/sqlite-source/Makefile.am b/zypp/source/sqlite-source/Makefile.am
new file mode 100644 (file)
index 0000000..e1e2b88
--- /dev/null
@@ -0,0 +1,42 @@
+#
+# Makefile.am for zmd/backend/dbsource
+#
+
+INCLUDES =                                     \
+       -I$(top_srcdir) $(ZYPP_CFLAGS) -Wall    \
+       -DG_LOG_DOMAIN=\"sqlite-source\"                \
+       -DZYPP_BASE_LOGGER_LOGGROUP=\"sqlite-source\"
+
+sourceincludedir = $(pkgincludedir)/source
+
+pkginclude_HEADERS =                           \
+       SqliteSources.h                         \
+       SqliteAccess.h
+
+sourceinclude_HEADERS =                                \
+       SqliteSourceImpl.h                              \
+       SqlitePackageImpl.h                             \
+       SqliteAtomImpl.h                                \
+       SqliteScriptImpl.h                              \
+       SqliteMessageImpl.h                             \
+       SqliteLanguageImpl.h                    \
+       SqlitePatchImpl.h                               \
+       SqlitePatternImpl.h                             \
+       SqliteProductImpl.h
+
+noinst_LTLIBRARIES =   lib@PACKAGE@_source_sqlite.la
+
+lib@PACKAGE@_source_sqlite_la_SOURCES =                        \
+       SqliteSourceImpl.cc                             \
+       SqlitePackageImpl.cc                    \
+       SqliteAtomImpl.cc                               \
+       SqliteScriptImpl.cc                             \
+       SqliteMessageImpl.cc                    \
+       SqliteLanguageImpl.cc                   \
+       SqlitePatchImpl.cc                              \
+       SqlitePatternImpl.cc                    \
+       SqliteProductImpl.cc                    \
+       SqliteSources.cc                                \
+       SqliteAccess.cc 
+
+lib@PACKAGE@_source_sqlite_la_LBADD = -lsqlite3
diff --git a/zypp/source/sqlite-source/SqliteAccess.cc b/zypp/source/sqlite-source/SqliteAccess.cc
new file mode 100644 (file)
index 0000000..b3817c6
--- /dev/null
@@ -0,0 +1,1158 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file zmd/backend/dbsource/SqliteAccess.cc
+ *
+*/
+
+#include <iostream>
+#include <fstream>
+
+#include "zypp/base/Logger.h"
+#include "zypp/ZYppFactory.h"
+#include "zypp/Source.h"
+#include "SqliteAccess.h"
+
+IMPL_PTR_TYPE(SqliteAccess);
+
+#undef ZYPP_BASE_LOGGER_LOGGROUP
+#define ZYPP_BASE_LOGGER_LOGGROUP "SqliteAccess"
+
+using namespace std;
+using namespace zypp;
+
+
+static struct archrc {
+       char *arch;
+       RCArch rc;
+    } archtable[] = {
+       { "noarch",     RC_ARCH_NOARCH },
+       { "i386",       RC_ARCH_I386 },
+       { "i486",       RC_ARCH_I486 },
+       { "i586",       RC_ARCH_I586 },
+       { "i686",       RC_ARCH_I686 },
+       { "x86_64",     RC_ARCH_X86_64 },
+       { "ia32e",      RC_ARCH_IA32E },
+       { "athlon",     RC_ARCH_ATHLON },
+       { "ppc",        RC_ARCH_PPC },
+       { "ppc64",      RC_ARCH_PPC64 },
+       { "s390",       RC_ARCH_S390 },
+       { "s390x",      RC_ARCH_S390X },
+       { "ia64",       RC_ARCH_IA64 },
+       { "sparc",      RC_ARCH_SPARC },
+       { "sparc64",    RC_ARCH_SPARC64 },
+       { NULL,         RC_ARCH_UNKNOWN }
+    };
+
+
+//----------------------------------------------------------------------------
+
+// check if source is local for zypp
+
+static bool
+source_is_local( Source_Ref source )
+{
+    return false;
+
+    if (!source) return true;
+
+    string scheme = source.url().getScheme();
+//    DBG << "Source url '" << src.url() << "', scheme '" << scheme << "'" << endl;
+    return (scheme == "cd"
+       || scheme == "dvd"
+       || scheme == "file"
+       || scheme == "dir"
+       || scheme == "hd"
+       || scheme == "iso"
+       || scheme == "smb"
+       || scheme == "nfs");
+}
+
+//----------------------------------------------------------------------------
+
+// Convert ZYPP relation operator to ZMD RCResolvableRelation
+
+RCResolvableRelation
+SqliteAccess::Rel2Rc (Rel op)
+{
+
+   /* This enum is here so that gdb can give us pretty strings */
+
+    switch (op.inSwitch()) {
+       case Rel::EQ_e:    return RC_RELATION_EQUAL; break;
+       case Rel::NE_e:    return RC_RELATION_NOT_EQUAL; break;
+       case Rel::LT_e:    return RC_RELATION_LESS; break;
+       case Rel::LE_e:    return RC_RELATION_LESS_EQUAL; break;
+       case Rel::GT_e:    return RC_RELATION_GREATER; break;
+       case Rel::GE_e:    return RC_RELATION_GREATER_EQUAL; break;
+       case Rel::ANY_e:   return RC_RELATION_ANY; break;
+       case Rel::NONE_e:  return RC_RELATION_NONE; break;
+    }
+    return RC_RELATION_INVALID;
+}
+
+
+Rel
+SqliteAccess::Rc2Rel (RCResolvableRelation rel)
+{
+    switch (rel) {
+       case RC_RELATION_INVALID:       return Rel::NONE; break;
+       case RC_RELATION_ANY:           return Rel::ANY; break;
+       case RC_RELATION_EQUAL:         return Rel::EQ; break;
+       case RC_RELATION_LESS:          return Rel::LT; break;
+       case RC_RELATION_LESS_EQUAL:    return Rel::LE; break;
+       case RC_RELATION_GREATER:       return Rel::GT; break;
+       case RC_RELATION_GREATER_EQUAL: return Rel::GE; break;
+       case RC_RELATION_NOT_EQUAL:     return Rel::NE; break;
+       case RC_RELATION_NONE:          return Rel::ANY; break;
+    }
+    return Rel::NONE;
+}
+
+//----------------------------------------------------------------------------
+
+// convert ZYPP architecture string to ZMD int
+
+RCArch
+SqliteAccess::Arch2Rc (const Arch & arch)
+{
+    string arch_str = arch.asString();
+    struct archrc *aptr = archtable;
+    while (aptr->arch != NULL) {
+       if (arch_str == aptr->arch)
+           break;
+       aptr++;
+    }
+
+    return aptr->rc;
+}
+
+Arch
+SqliteAccess::Rc2Arch (RCArch rc)
+{
+    if (rc == RC_ARCH_UNKNOWN)
+       return Arch();
+
+    struct archrc *aptr = archtable;
+    while (aptr->arch != NULL) {
+       if (aptr->rc == rc) {
+           return Arch (aptr->arch);
+       }
+       aptr++;
+    }
+    WAR << "SqliteAccess::Rc2Arch(" << rc << ") unknown" << endl;
+    return Arch ();
+}
+
+
+// convert description Text (list<string>) to a single string
+static string
+desc2str (const Text t)
+{
+    static string s;           // static so we can use sqlite STATIC below
+    s.clear();
+    string::size_type authors = t.find ("Authors:");           // strip off 'Authors:'
+    if (authors != string::npos) {
+       do {
+           --authors;
+       } while (t[authors] == ' ' || t[authors] == '\n');
+    }
+    s = string (t, 0, authors);
+    return s;
+}
+
+//----------------------------------------------------------------------------
+// convert ZYPP Resolvable kind to ZMD RCDependencyTarget
+
+static RCDependencyTarget
+kind2target( Resolvable::Kind kind )
+{
+    if (kind == ResTraits<Package>::kind)       return RC_DEP_TARGET_PACKAGE;
+    else if (kind == ResTraits<Script>::kind)   return RC_DEP_TARGET_SCRIPT;
+    else if (kind == ResTraits<Message>::kind)  return RC_DEP_TARGET_MESSAGE;
+    else if (kind == ResTraits<Patch>::kind)    return RC_DEP_TARGET_PATCH;
+    else if (kind == ResTraits<Selection>::kind) return RC_DEP_TARGET_SELECTION;
+    else if (kind == ResTraits<Pattern>::kind)  return RC_DEP_TARGET_PATTERN;
+    else if (kind == ResTraits<Product>::kind)  return RC_DEP_TARGET_PRODUCT;
+    else if (kind == ResTraits<Language>::kind)         return RC_DEP_TARGET_LANGUAGE;
+    else if (kind == ResTraits<Atom>::kind)     return RC_DEP_TARGET_ATOM;
+    else if (kind == ResTraits<SrcPackage>::kind) return RC_DEP_TARGET_SRC;
+    else if (kind == ResTraits<SystemResObject>::kind) return RC_DEP_TARGET_SYSTEM;
+
+    WAR << "Unknown resolvable kind " << kind << endl;
+    return RC_DEP_TARGET_UNKNOWN;
+}
+
+//----------------------------------------------------------------------------
+// convert ZYPP ResStatus to ZMD RCResolvableStatus
+
+static RCResolvableStatus
+resstatus2rcstatus( ResStatus status )
+{
+    if (status.isEstablishedUneeded()) return RC_RES_STATUS_UNNEEDED;
+    else if (status.isEstablishedSatisfied()) return RC_RES_STATUS_SATISFIED;
+    else if (status.isEstablishedIncomplete()) return RC_RES_STATUS_BROKEN;
+    return RC_RES_STATUS_UNDETERMINED;
+}
+
+//----------------------------------------------------------------------------
+
+  /** Ctor */
+SqliteAccess::SqliteAccess( const std::string & dbfile_r )
+    : _dbfile( dbfile_r )
+    , _db( NULL )
+    , _insert_res_handle( NULL )
+    , _insert_pkg_handle( NULL )
+    , _insert_message_handle( NULL )
+    , _insert_script_handle( NULL )
+    , _insert_patch_handle( NULL )
+    , _insert_pattern_handle( NULL )
+    , _insert_product_handle( NULL )
+    , _insert_dep_handle( NULL )
+{
+    MIL << "SqliteAccess::SqliteAccess(" << dbfile_r << ")" << endl;
+}
+
+
+  /** Dtor */
+SqliteAccess::~SqliteAccess( )
+{
+    closeDb();
+}
+
+
+std::ostream &
+SqliteAccess::dumpOn( std::ostream & str ) const
+{
+    str << "SqliteAccess(" << _dbfile << ")" << endl;
+    return str;
+}
+
+
+//----------------------------------------------------------------------------
+
+static sqlite3_stmt *
+prepare_handle( sqlite3 *db, const string & query )
+{
+    int rc;
+    sqlite3_stmt *handle = NULL;
+
+    rc = sqlite3_prepare (db, query.c_str(), -1, &handle, NULL);
+
+    if (rc != SQLITE_OK) {
+       ERR << "Can not prepare '" << query << "': " << sqlite3_errmsg (db) << endl;
+        handle = NULL;
+    }
+
+    return handle;
+}
+
+
+static sqlite3_stmt *
+prepare_res_insert (sqlite3 *db)
+{
+    string query (
+       //                        1     2        3        4      5
+        "INSERT INTO resolvables (name, version, release, epoch, arch,"
+       //                        6               7
+        "                         installed_size, catalog,"
+       //                        8          9      10      11        12       13
+        "                         installed, local, status, category, license, kind) "
+        "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
+
+    return prepare_handle( db, query );
+}
+
+
+static sqlite3_stmt *
+prepare_message_insert (sqlite3 *db)
+{
+    string query (
+       //                            1
+        "INSERT INTO message_details (resolvable_id, "
+       //                            2
+        "                             content) "
+        "VALUES (?, ?)"
+       "");
+
+    return prepare_handle( db, query );
+}
+
+
+static sqlite3_stmt *
+prepare_script_insert (sqlite3 *db)
+{
+    string query (
+       //                            1
+        "INSERT INTO script_details (resolvable_id, "
+       //                            2          3
+        "                             do_script, undo_script) "
+        "VALUES (?, ?, ?)"
+       "");
+
+    return prepare_handle( db, query );
+}
+
+
+static sqlite3_stmt *
+prepare_pkg_insert (sqlite3 *db)
+{
+    string query (
+       //                            1              2          3
+        "INSERT INTO package_details (resolvable_id, rpm_group, summary, "
+       //                            4            5            6                 7
+        "                             description, package_url, package_filename, signature_filename,"
+       //                            8          9             10
+        "                             file_size, install_only, media_nr) "
+        "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
+       "");
+
+    return prepare_handle( db, query );
+}
+
+
+static sqlite3_stmt *
+prepare_patch_insert (sqlite3 *db)
+{
+    string query (
+       //                          1              2
+        "INSERT INTO patch_details (resolvable_id, patch_id, "
+       //                          3
+        "                           creation_time,"
+       //                          4       5        6
+        "                           reboot, restart, interactive,"
+       //                          7        8
+        "                           summary, description) "
+        "VALUES (?, ?, ?, ?, ?, ?, ?, ?)"
+       "");
+
+    return prepare_handle( db, query );
+}
+
+
+static sqlite3_stmt *
+prepare_pattern_insert (sqlite3 *db)
+{
+    string query (
+       //                            1
+        "INSERT INTO pattern_details (resolvable_id, "
+       //                            2        3
+        "                             summary, description) "
+        "VALUES (?, ?, ?)"
+       "");
+
+    return prepare_handle( db, query );
+}
+
+
+static sqlite3_stmt *
+prepare_product_insert (sqlite3 *db)
+{
+    string query (
+       //                            1
+        "INSERT INTO product_details (resolvable_id, "
+       //                            2        3
+        "                             summary, description) "
+        "VALUES (?, ?, ?)"
+       "");
+
+    return prepare_handle( db, query );
+}
+
+
+static sqlite3_stmt *
+prepare_dep_insert (sqlite3 *db)
+{
+    string query (
+       "INSERT INTO dependencies "
+       //  1              2         3     4        5        6      7     8         9
+       "  (resolvable_id, dep_type, name, version, release, epoch, arch, relation, dep_target) "
+       "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");
+
+    return prepare_handle( db, query );
+}
+
+
+bool
+SqliteAccess::prepareWrite(void)
+{
+    XXX << "SqliteAccess::prepareWrite()" << endl;
+
+    sqlite3_exec (_db, "PRAGMA synchronous = 0", NULL, NULL, NULL);
+
+    bool result = false;
+
+    _insert_res_handle = prepare_res_insert (_db);
+    if (_insert_res_handle == NULL) {
+       goto cleanup;
+    }
+
+    _insert_pkg_handle = prepare_pkg_insert (_db);
+    if (_insert_pkg_handle == NULL) {
+       goto cleanup;
+    }
+
+    _insert_message_handle = prepare_message_insert (_db);
+    if (_insert_message_handle == NULL) {
+       goto cleanup;
+    }
+
+    _insert_script_handle = prepare_script_insert (_db);
+    if (_insert_script_handle == NULL) {
+       goto cleanup;
+    }
+
+    _insert_patch_handle = prepare_patch_insert (_db);
+    if (_insert_patch_handle == NULL) {
+       goto cleanup;
+    }
+
+    _insert_pattern_handle = prepare_pattern_insert (_db);
+    if (_insert_pattern_handle == NULL) {
+       goto cleanup;
+    }
+
+    _insert_product_handle = prepare_product_insert (_db);
+    if (_insert_product_handle == NULL) {
+       goto cleanup;
+    }
+
+    _insert_dep_handle = prepare_dep_insert (_db);
+    if (_insert_dep_handle == NULL) {
+       goto cleanup;
+    }
+
+    result = true;
+
+ cleanup:
+    if (result == false) {
+       closeDb();
+    }
+
+    return result;
+}
+
+
+//----------------------------------------------------------------------------
+
+bool
+SqliteAccess::openDb( bool for_writing )
+{
+    XXX << "SqliteAccess::openDb(" << (for_writing?"write":"read") << ")" << endl;
+
+    if (_db) {
+       WAR << "Db already open" << endl;
+       return true;
+    }
+
+    int rc = sqlite3_open (_dbfile.c_str(), &_db);
+    if (rc != SQLITE_OK
+       || _db == NULL)
+    {
+       ERR << "Can not open SQL database: " << sqlite3_errmsg (_db) << endl;
+       cerr << "Can't open " << _dbfile << endl;
+       return false;
+    }
+
+    if (for_writing) {
+       if (!prepareWrite()) {
+           cerr << "Can't prepare sql access handles" << endl;
+           return false;
+       }
+    }
+
+    sqlite3_exec (_db, "BEGIN", NULL, NULL, NULL);
+
+    return true;
+}
+
+
+static void
+close_handle( sqlite3_stmt **handle )
+{
+    if (*handle) {
+       sqlite3_finalize (*handle);
+       *handle = NULL;
+    }
+    return;
+}
+
+
+void
+SqliteAccess::closeDb(void)
+{
+    XXX << "SqliteAccess::closeDb()" << endl;
+
+    commit();
+
+    close_handle( &_insert_res_handle );
+    close_handle( &_insert_pkg_handle );
+    close_handle( &_insert_message_handle );
+    close_handle( &_insert_script_handle );
+    close_handle( &_insert_patch_handle );
+    close_handle( &_insert_pattern_handle );
+    close_handle( &_insert_product_handle );
+    close_handle( &_insert_dep_handle );
+
+    if (_db) {
+       sqlite3_close (_db);
+       _db = NULL;
+    }
+    return;
+}
+
+
+void
+SqliteAccess::commit(void)
+{
+    if (_db)
+       sqlite3_exec (_db, "COMMIT", NULL, NULL, NULL);
+}
+
+//----------------------------------------------------------------------------
+// dependency
+
+void
+SqliteAccess::writeDependency( sqlite_int64 res_id, RCDependencyType type, const zypp::CapSet & capabilities)
+{
+    XXX << "SqliteAccess::writeDependency(" << res_id << ", " << type << ", ...)" << endl;
+
+    int rc;
+    sqlite3_stmt *handle = _insert_dep_handle;
+
+    if (capabilities.empty())
+       return;
+
+    for (zypp::CapSet::const_iterator iter = capabilities.begin(); iter != capabilities.end(); ++iter) {
+       XXX << "Cap " << *iter << endl;
+       RCDependencyTarget refers = kind2target( iter->refers() );
+       if (refers == RC_DEP_TARGET_UNKNOWN) continue;
+
+       sqlite3_bind_int64( handle, 1, res_id);                                         // who issues the dependency
+       sqlite3_bind_int( handle, 2, type);                                             // type (provides, requires, ...)
+       sqlite3_bind_text( handle, 3, iter->index().c_str(), -1, SQLITE_STATIC );       // tag
+
+       Edition edition = iter->edition();
+
+       if (iter->op() != Rel::NONE                                                     // operator and edition given ?
+           && iter->op() != Rel::ANY
+           && edition != Edition::noedition)
+       {
+           sqlite3_bind_text( handle, 4, edition.version().c_str(), -1, SQLITE_STATIC );       // version
+           sqlite3_bind_text( handle, 5, edition.release().c_str(), -1, SQLITE_STATIC );       // release
+           Edition::epoch_t epoch = edition.epoch();
+           if (epoch != Edition::noepoch) {
+               sqlite3_bind_int( handle, 6, epoch);                                            // epoch
+           }
+           else {
+               sqlite3_bind_int( handle, 6, 0);
+           }
+           sqlite3_bind_int( handle, 7, -1);                                                   // arch
+           sqlite3_bind_int( handle, 8, Rel2Rc( iter->op() ));                                 // operation (==, <, <=, ...)
+       }
+       else {
+           // no operation or edition given
+           sqlite3_bind_text( handle, 4, NULL, -1, SQLITE_STATIC );
+           sqlite3_bind_text( handle, 5, NULL, -1, SQLITE_STATIC );
+           sqlite3_bind_int( handle, 6, 0);
+           sqlite3_bind_int( handle, 7, -1);                           // arch
+           sqlite3_bind_int( handle, 8, RC_RELATION_NONE );
+       }
+
+       sqlite3_bind_int( handle, 9, refers );                                  // resolvable kind the dependency refers to
+
+       rc = sqlite3_step( handle);
+       sqlite3_reset( handle);
+
+       if (rc != SQLITE_DONE) {
+           ERR << "Error adding package to SQL: " << sqlite3_errmsg (_db) << endl;
+       }
+    }
+    return;
+}
+
+
+void
+SqliteAccess::writeDependencies(sqlite_int64 id, Resolvable::constPtr res)
+{
+    XXX << "SqliteAccess::writeDependencies(" << id << ", " << *res << ")" << endl;
+
+    writeDependency( id, RC_DEP_TYPE_REQUIRE,   res->dep (Dep::REQUIRES));
+    writeDependency( id, RC_DEP_TYPE_PROVIDE,   res->dep (Dep::PROVIDES));
+    writeDependency( id, RC_DEP_TYPE_CONFLICT,  res->dep (Dep::CONFLICTS));
+    writeDependency( id, RC_DEP_TYPE_OBSOLETE,  res->dep (Dep::OBSOLETES));
+    writeDependency( id, RC_DEP_TYPE_PREREQUIRE, res->dep (Dep::PREREQUIRES));
+    writeDependency( id, RC_DEP_TYPE_FRESHEN,   res->dep (Dep::FRESHENS));
+    writeDependency( id, RC_DEP_TYPE_RECOMMEND,  res->dep (Dep::RECOMMENDS));
+    writeDependency( id, RC_DEP_TYPE_SUGGEST,   res->dep (Dep::SUGGESTS));
+    writeDependency( id, RC_DEP_TYPE_SUPPLEMENT, res->dep (Dep::SUPPLEMENTS));
+    writeDependency( id, RC_DEP_TYPE_ENHANCE,   res->dep (Dep::ENHANCES));
+}
+
+
+//----------------------------------------------------------------------------
+// package
+
+sqlite_int64
+SqliteAccess::writePackage( sqlite_int64 id, Package::constPtr pkg, Ownership owner )
+{
+    XXX <<  "SqliteAccess::writePackage(" << id << ", " << *pkg << ")" << endl;
+    int rc;
+    sqlite3_stmt *handle = _insert_pkg_handle;
+
+    sqlite3_bind_int64( handle, 1, id);
+    sqlite3_bind_text( handle, 2, pkg->group().c_str(), -1, SQLITE_STATIC );
+    sqlite3_bind_text( handle, 3, pkg->summary().c_str(), -1, SQLITE_STATIC );
+    sqlite3_bind_text( handle, 4, desc2str(pkg->description()).c_str(), -1, SQLITE_STATIC );
+
+    const char *package_url = pkg->location().asString().c_str();
+    if (package_url[0] == '.' && package_url[1] == '/') package_url += 2;              // strip leading "./"
+
+    const char *url = package_url;
+    const char *filename = NULL;
+
+    switch( owner ) {
+       case ZYPP_OWNED:
+           filename = "";
+       break;
+       case ZMD_OWNED:
+       break;
+       case LOCAL_FILE:
+           url = NULL;
+           filename = package_url;
+       break;
+       default:
+           ERR << "Unknown ownership" << endl;
+       break;
+    }
+
+    sqlite3_bind_text( handle, 5, url, -1, SQLITE_STATIC );
+    sqlite3_bind_text( handle, 6, filename, -1, SQLITE_STATIC );
+
+    sqlite3_bind_text( handle, 7, NULL, -1, SQLITE_STATIC );                   // signature_filename
+    sqlite3_bind_int( handle, 8, pkg->size() );
+    sqlite3_bind_int( handle, 9, pkg->installOnly() ? 1 : 0 );
+    sqlite3_bind_int( handle, 10, pkg->sourceMediaNr() );
+
+    rc = sqlite3_step( handle);
+    sqlite3_reset( handle);
+
+    if (rc != SQLITE_DONE) {
+       ERR << "Error adding package to SQL: " << sqlite3_errmsg (_db) << endl;
+       return -1;
+    }
+    sqlite_int64 rowid = sqlite3_last_insert_rowid (_db);
+
+    return rowid;
+}
+
+
+//----------------------------------------------------------------------------
+// message
+
+sqlite_int64
+SqliteAccess::writeMessage (sqlite_int64 id, Message::constPtr message )
+{
+    XXX <<  "SqliteAccess::writeMessage(" << id << ", " << *message << ")" << endl;
+    int rc;
+    sqlite3_stmt *handle = _insert_message_handle;
+
+    sqlite3_bind_int64( handle, 1, id);
+    sqlite3_bind_text( handle, 2, message->text().asString().c_str(), -1, SQLITE_STATIC );
+
+    rc = sqlite3_step( handle);
+    sqlite3_reset( handle);
+
+    if (rc != SQLITE_DONE) {
+       ERR << "Error adding message to SQL: " << sqlite3_errmsg (_db) << endl;
+       return -1;
+    }
+    sqlite_int64 rowid = sqlite3_last_insert_rowid (_db);
+
+    return rowid;
+}
+
+
+//----------------------------------------------------------------------------
+// script
+
+static string
+readFromPath( const Pathname & p )
+{
+    string result;
+    string line;
+    try {
+       ifstream infile( p.asString().c_str() );
+       while (getline( infile, line )) {
+           result += line;
+           result += "\n";
+       }
+    }
+    catch( const Exception & excpt_r ) {
+       ZYPP_CAUGHT( excpt_r );
+    }
+    return result;
+}
+
+sqlite_int64
+SqliteAccess::writeScript (sqlite_int64 id, Script::constPtr script)
+{
+    XXX <<  "SqliteAccess::writeScript(" << id << ", " << *script << ")" << endl;
+    int rc;
+    sqlite3_stmt *handle = _insert_script_handle;
+
+    sqlite3_bind_int64( handle, 1, id);
+    string do_script( readFromPath( script->do_script() ) );
+    string undo_script( readFromPath( script->undo_script() ) );
+    sqlite3_bind_text( handle, 2, do_script.c_str(), -1, SQLITE_STATIC );
+    sqlite3_bind_text( handle, 3, undo_script.c_str(), -1, SQLITE_STATIC );
+
+    rc = sqlite3_step( handle);
+    sqlite3_reset( handle);
+
+    if (rc != SQLITE_DONE) {
+       ERR << "Error adding message to SQL: " << sqlite3_errmsg (_db) << endl;
+       return -1;
+    }
+    sqlite_int64 rowid = sqlite3_last_insert_rowid (_db);
+
+    return rowid;
+}
+
+
+//----------------------------------------------------------------------------
+// patch
+
+sqlite_int64
+SqliteAccess::writePatch (sqlite_int64 id, Patch::constPtr patch )
+{
+    XXX <<  "SqliteAccess::writePatch(" << id << ", " << *patch << ")" << endl;
+    int rc;
+    sqlite3_stmt *handle = _insert_patch_handle;
+
+    sqlite3_bind_int64( handle, 1, id );
+    sqlite3_bind_text( handle, 2, patch->id().c_str(), -1, SQLITE_STATIC );
+    sqlite3_bind_int64( handle, 3, patch->timestamp() );
+    sqlite3_bind_int( handle, 4, patch->reboot_needed() ? 1 : 0 );
+    sqlite3_bind_int( handle, 5, patch->affects_pkg_manager() ? 1 : 0 );
+    sqlite3_bind_int( handle, 6, patch->interactive() ? 1 : 0 );
+    sqlite3_bind_text( handle, 7, patch->summary().c_str(), -1, SQLITE_STATIC );
+    sqlite3_bind_text( handle, 8, desc2str(patch->description()).c_str(), -1, SQLITE_STATIC );
+
+    rc = sqlite3_step( handle);
+    sqlite3_reset( handle);
+
+    if (rc != SQLITE_DONE) {
+       ERR << "Error adding patch to SQL: " << sqlite3_errmsg (_db) << endl;
+       return -1;
+    }
+    sqlite_int64 rowid = sqlite3_last_insert_rowid (_db);
+
+    return rowid;
+}
+
+
+//----------------------------------------------------------------------------
+// pattern
+
+sqlite_int64
+SqliteAccess::writePattern (sqlite_int64 id, Pattern::constPtr pattern )
+{
+    XXX <<  "SqliteAccess::writePattern(" << id << ", " << *pattern << ")" << endl;
+    int rc;
+    sqlite3_stmt *handle = _insert_pattern_handle;
+
+    sqlite3_bind_int64( handle, 1, id);
+    sqlite3_bind_text( handle, 2, pattern->summary().c_str(), -1, SQLITE_STATIC );
+    sqlite3_bind_text( handle, 3, desc2str(pattern->description()).c_str(), -1, SQLITE_STATIC );
+
+    rc = sqlite3_step( handle);
+    sqlite3_reset( handle);
+
+    if (rc != SQLITE_DONE) {
+       ERR << "Error adding pattern to SQL: " << sqlite3_errmsg (_db) << endl;
+       return -1;
+    }
+    sqlite_int64 rowid = sqlite3_last_insert_rowid (_db);
+
+    return rowid;
+}
+
+
+//----------------------------------------------------------------------------
+// product
+
+sqlite_int64
+SqliteAccess::writeProduct (sqlite_int64 id, Product::constPtr product )
+{
+    XXX <<  "SqliteAccess::writeProduct(" << id << ", " << *product << ")" << endl;
+    int rc;
+    sqlite3_stmt *handle = _insert_product_handle;
+
+    sqlite3_bind_int64( handle, 1, id);
+    sqlite3_bind_text( handle, 2, product->summary().c_str(), -1, SQLITE_STATIC );
+    sqlite3_bind_text( handle, 3, desc2str(product->description()).c_str(), -1, SQLITE_STATIC );
+
+    rc = sqlite3_step( handle);
+    sqlite3_reset( handle);
+
+    if (rc != SQLITE_DONE) {
+       ERR << "Error adding product to SQL: " << sqlite3_errmsg (_db) << endl;
+       return -1;
+    }
+    sqlite_int64 rowid = sqlite3_last_insert_rowid (_db);
+
+    return rowid;
+}
+
+
+//----------------------------------------------------------------------------
+// resolvable
+
+// write ResObject to resolvables table
+//  return rowid (> 0) on success
+//  return < 0 on failure
+//  return == 0 if this kind of resolvable is to be skipped
+
+sqlite_int64
+SqliteAccess::writeResObject( ResObject::constPtr obj, ResStatus status, const char *catalog, Ownership owner )
+{
+    XXX << "SqliteAccess::writeResObject (" << *obj << ", " << status << ")" << endl;
+
+    if (obj->kind() == ResTraits<SystemResObject>::kind)
+       return 0;
+
+    Resolvable::constPtr res = obj;
+    Package::constPtr pkg = asKind<Package>(res);
+    Message::constPtr message = asKind<Message>(res);
+    Script::constPtr script = asKind<Script>(res);
+    Patch::constPtr patch = asKind<Patch>(res);
+    Pattern::constPtr pattern = asKind<Pattern>(res);
+    Product::constPtr product = asKind<Product>(res);
+
+    zypp::License license;
+
+    int rc;
+    sqlite3_stmt *handle = _insert_res_handle;
+
+    // write NVRAD and all the rest
+
+    sqlite3_bind_text( handle, 1, obj->name().c_str(), -1, SQLITE_STATIC );
+    Edition ed = obj->edition();
+    sqlite3_bind_text( handle, 2, ed.version().c_str(), -1, SQLITE_STATIC );
+    sqlite3_bind_text( handle, 3, ed.release().c_str(), -1, SQLITE_STATIC );
+    if (ed.epoch() == Edition::noepoch) {
+       sqlite3_bind_int( handle, 4, 0);
+    } else {
+       sqlite3_bind_int( handle, 4, ed.epoch());
+    }
+    sqlite3_bind_int( handle, 5, Arch2Rc (obj->arch()) );
+
+    sqlite3_bind_int64( handle, 6, obj->size() );
+    if (catalog != NULL)
+       sqlite3_bind_text( handle, 7, catalog, -1, SQLITE_STATIC );
+    else
+       sqlite3_bind_text( handle, 7, obj->source().alias().c_str(), -1, SQLITE_STATIC );
+
+    sqlite3_bind_int( handle,  8, status.isInstalled() ? 1 : 0);
+
+    Source_Ref src( obj->source() );
+    if (source_is_local( src ))
+    {
+       sqlite3_bind_int( handle, 9, 1 );                                       //local_package
+    }
+    else {
+       sqlite3_bind_int( handle, 9, 0 );
+    }
+    sqlite3_bind_int( handle, 10, resstatus2rcstatus( status ) );
+
+    if (pkg != NULL) {
+       license = pkg->licenseToConfirm();
+       if (license.empty()) {
+           sqlite3_bind_text( handle, 12, NULL, -1, SQLITE_STATIC );
+       }
+       else {
+           sqlite3_bind_text( handle, 12, license.c_str(), -1, SQLITE_STATIC );
+       }
+    }
+    else if (patch != NULL) {
+       sqlite3_bind_text( handle, 11, patch->category().c_str(), -1, SQLITE_STATIC );
+    }
+    else if (product != NULL) {
+       sqlite3_bind_text( handle, 11, product->category().c_str(), -1, SQLITE_STATIC );
+       license = product->licenseToConfirm();
+       if (license.empty()) {
+           sqlite3_bind_text( handle, 12, NULL, -1, SQLITE_STATIC );
+       }
+       else {
+           sqlite3_bind_text( handle, 12, license.c_str(), -1, SQLITE_STATIC );
+       }
+    }
+
+    sqlite3_bind_int( handle, 13, kind2target( obj->kind() ) );
+
+    rc = sqlite3_step( handle );
+    sqlite3_reset( handle );
+
+    if (rc != SQLITE_DONE) {
+       ERR << "Error adding package to SQL: " << sqlite3_errmsg (_db) << endl;
+       return -1;
+    }
+    sqlite_int64 rowid = sqlite3_last_insert_rowid (_db);
+
+    // now write the respective _details table
+
+    if (pkg != NULL) writePackage( rowid, pkg, owner );
+    else if (message != NULL) writeMessage( rowid, message );
+    else if (script != NULL) writeScript( rowid, script );
+    else if (patch != NULL) writePatch( rowid, patch );
+    else if (pattern != NULL) writePattern( rowid, pattern );
+    else if (product != NULL) writeProduct( rowid, product );
+
+    writeDependencies (rowid, obj);
+
+    return rowid;
+}
+
+
+//----------------------------------------------------------------------------
+/** check if catalog exists */
+bool
+SqliteAccess::haveCatalog( const std::string & catalog )
+{
+    string query ("SELECT * FROM catalogs WHERE id = ? ");
+
+    sqlite3_stmt *handle = prepare_handle( _db, query );
+    if (handle == NULL) {
+       return false;
+    }
+
+    sqlite3_bind_text( handle, 1, catalog.c_str(), -1, SQLITE_STATIC );
+
+    int rc = sqlite3_step( handle);
+    if (rc == SQLITE_ROW) {
+       DBG << "Found catalog" << endl;
+    }
+    else if (rc != SQLITE_DONE) {
+       ERR << "rc " << rc << ": " << sqlite3_errmsg (_db) << endl;
+    }
+    sqlite3_reset( handle);
+
+    return (rc == SQLITE_ROW);
+}
+
+
+/** insert catalog */
+bool
+SqliteAccess::insertCatalog( const std::string & catalog, const string & name, const string & alias, const string & description )
+{
+    string query ("INSERT INTO catalogs(id,name,alias,description) VALUES (?,?,?,?) ");
+
+    sqlite3_stmt *handle = prepare_handle( _db, query );
+    if (handle == NULL) {
+       return false;
+    }
+
+    sqlite3_bind_text( handle, 1, catalog.c_str(), -1, SQLITE_STATIC );
+    sqlite3_bind_text( handle, 2, name.c_str(), -1, SQLITE_STATIC );
+    sqlite3_bind_text( handle, 3, alias.c_str(), -1, SQLITE_STATIC );
+    sqlite3_bind_text( handle, 4, description.c_str(), -1, SQLITE_STATIC );
+
+    int rc = sqlite3_step( handle);
+    if (rc != SQLITE_DONE) {
+       ERR << "rc " << rc << "Error writing catalog: " << sqlite3_errmsg (_db) << endl;
+    }
+    sqlite3_reset( handle);
+
+    return (rc == SQLITE_DONE);
+}
+
+
+/** update catalog */
+bool
+SqliteAccess::updateCatalog( const std::string & catalog, const string & name, const string & alias, const string & description )
+{
+
+    DBG << "updateCatalog(" << catalog << ", " << name << ", " << alias << ", " << description << ")" << endl;
+
+    //                    0    1     2
+    string query ("SELECT name,alias,description FROM catalogs WHERE id = ? ");
+
+    sqlite3_stmt *sel_handle = prepare_handle( _db, query );
+    if (sel_handle == NULL) {
+       ERR << "Can't prepare SELECT query: " << sqlite3_errmsg (_db) << endl;
+       return false;
+    }
+
+    sqlite3_bind_text( sel_handle, 1, catalog.c_str(), -1, SQLITE_STATIC );
+
+    int rc = sqlite3_step( sel_handle);
+    if (rc == SQLITE_ROW) {
+       DBG << "Found catalog" << endl;
+    }
+    else if (rc != SQLITE_DONE) {
+       ERR << "rc " << rc << ": " << sqlite3_errmsg (_db) << endl;
+    }
+
+    if (rc != SQLITE_ROW) {
+       sqlite3_reset( sel_handle );
+       return false;
+    }
+
+    string c_name, c_alias, c_description;
+
+    // now set the c_* string to either the original or the updated (if non-empty) values
+
+    const char *text;
+    if (name.empty()) {
+       text = (const char *) sqlite3_column_text( sel_handle, 0 );
+       if (text != NULL)
+           c_name = text;
+    }
+    else {
+       c_name = name;
+    }
+
+    if (alias.empty()) {
+       text = (const char *) sqlite3_column_text( sel_handle, 1 );
+       if (text != NULL)
+           c_alias = text;
+    }
+    else {
+       c_alias = alias;
+    }
+
+    if (description.empty()) {
+       text = (const char *) sqlite3_column_text( sel_handle, 2 );
+       if (text != NULL)
+           c_description = text;
+    }
+    else {
+       c_description = description;
+    }
+
+    //                                  1          2                3            4
+    query = "UPDATE catalogs SET name = ?, alias = ?, description = ? WHERE id = ?";
+    sqlite3_stmt *upd_handle = prepare_handle( _db, query );
+    if (upd_handle == NULL) {
+       ERR << "Can't prepare UPDATE query: " << sqlite3_errmsg (_db) << endl;
+       return false;
+    }
+
+    sqlite3_bind_text( upd_handle, 1, c_name.c_str(), -1, SQLITE_STATIC );
+    sqlite3_bind_text( upd_handle, 2, c_alias.c_str(), -1, SQLITE_STATIC );
+    sqlite3_bind_text( upd_handle, 3, c_description.c_str(), -1, SQLITE_STATIC );
+    sqlite3_bind_text( upd_handle, 4, catalog.c_str(), -1, SQLITE_STATIC );
+
+    rc = sqlite3_step( upd_handle );
+    if (rc != SQLITE_DONE) {
+       ERR << "rc " << rc << "Error writing catalog: " << sqlite3_errmsg (_db) << endl;
+    }
+
+    sqlite3_reset( sel_handle );
+    sqlite3_reset( upd_handle );
+
+    return (rc == SQLITE_DONE);
+}
+
+
+/** remove catalog, remove all resolvables of this catalog */
+bool
+SqliteAccess::removeCatalog( const std::string & catalog )
+{
+    string query ("DELETE FROM catalogs where id = ? ");
+
+    sqlite3_stmt *handle = prepare_handle( _db, query );
+    if (handle == NULL) {
+       return false;
+    }
+
+    sqlite3_bind_text( handle, 1, catalog.c_str(), -1, SQLITE_STATIC );
+
+    int rc = sqlite3_step( handle);
+    if (rc != SQLITE_DONE) {
+       ERR << "rc " << rc << ", Error removing catalog: " << sqlite3_errmsg (_db) << endl;
+    }
+    sqlite3_reset( handle);
+
+    return (rc == SQLITE_DONE);
+}
+
+
+//----------------------------------------------------------------------------
+// store
+
+void
+SqliteAccess::writeStore( const zypp::ResStore & store, ResStatus status, const char *catalog, Ownership owner )
+{
+    XXX << "SqliteAccess::writeStore()" << endl;
+
+    if (store.empty()) {
+       ERR << "Store is empty." << endl;
+       return;
+    }
+
+    Arch sysarch = getZYpp()->architecture();
+
+    int count = 0;
+    sqlite_int64 rowid = 0;
+    for (ResStore::const_iterator iter = store.begin(); iter != store.end(); ++iter) {
+       ResObject::constPtr obj = *iter;
+       if (!obj) {
+           WAR << "Huh ? No object ?" << endl;
+           continue;
+       }
+
+       if (obj->kind() != ResTraits<SrcPackage>::kind          // don't write src/nosrc packages
+            && ( status == ResStatus::installed                        // installed ones are ok
+               || obj->kind() == ResTraits<Atom>::kind         //  and atoms because we need them for multi-arch patch requirements
+               || obj->arch().compatibleWith( sysarch ) ) )    //   and architecturally compatible ones
+       {
+           rowid = writeResObject( obj, status, catalog, owner );
+           if (rowid < 0)
+               break;
+           if (rowid > 0)              // rowid == 0 means 'skip'
+               ++count;
+       }
+       else {
+           DBG << "Not writing " << *obj << endl;
+       }
+    }
+
+    MIL << "Wrote " << count << " resolvables to database, last rowid " << rowid << endl;
+    return;
+}
+
+//----------------------------------------------------------------------------
+// pool
+
+void
+SqliteAccess::writePool( const zypp::ResPool & pool, const char *catalog )
+{
+    XXX << "SqliteAccess::writePool()" << endl;
+
+    if (pool.empty()) {
+       ERR << "Pool is empty" << endl;
+       return;
+    }
+
+    int count = 0;
+    sqlite_int64 rowid = 0;
+    for (ResPool::const_iterator iter = pool.begin(); iter != pool.end(); ++iter) {
+       rowid = writeResObject( iter->resolvable(), iter->status(), catalog );
+       if (rowid < 0)
+           break;
+       if (rowid > 0)                  // rowid == 0 means 'skip'
+           ++count;
+    }
+
+    MIL << "Wrote " << count << " resolvables to database" << endl;
+    return;
+}
+
+
diff --git a/zypp/source/sqlite-source/SqliteAccess.h b/zypp/source/sqlite-source/SqliteAccess.h
new file mode 100644 (file)
index 0000000..63c503d
--- /dev/null
@@ -0,0 +1,221 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file zmd/backend/dbsource/SqliteAccess.h
+ *
+*/
+#ifndef ZMD_BACKEND_DBSOURCE_DBACCESS_H
+#define ZMD_BACKEND_DBSOURCE_DBACCESS_H
+
+#include <iosfwd>
+#include <string>
+
+#include <sqlite3.h>
+
+#include <zypp/base/PtrTypes.h>
+
+#include <zypp/ResStatus.h>
+#include <zypp/ResStore.h>
+#include <zypp/Resolvable.h>
+#include <zypp/Package.h>
+#include <zypp/Message.h>
+#include <zypp/Script.h>
+#include <zypp/Patch.h>
+#include <zypp/Selection.h>
+#include <zypp/Pattern.h>
+#include <zypp/Product.h>
+#include <zypp/Pathname.h>
+#include <zypp/ResPool.h>
+#include <zypp/CapSet.h>
+#include <zypp/Dep.h>
+#include <zypp/Rel.h>
+#include <zypp/Arch.h>
+
+DEFINE_PTR_TYPE(SqliteAccess);
+
+typedef std::list<zypp::ResObject::constPtr> ResObjectList;
+typedef std::map<sqlite_int64, zypp::ResObject::constPtr> IdMap;
+
+//-----------------------------------------------------------------------------
+// filling of package_url and package_filename in package_details table
+
+typedef enum {
+  ZYPP_OWNED,          // fill _url, set _filename "" (empty)
+  ZMD_OWNED,           // fill _url, leave _filename NULL
+  LOCAL_FILE           // leave _url NULL, fill _filename
+} Ownership;
+
+//-----------------------------------------------------------------------------
+// relations
+
+#define RELATION_ANY 0
+#define RELATION_EQUAL (1 << 0)
+#define RELATION_LESS (1 << 1)
+#define RELATION_GREATER (1 << 2)
+#define RELATION_NONE (1 << 3)
+
+typedef enum {
+       RC_RELATION_INVALID            = -1,
+       RC_RELATION_ANY                = RELATION_ANY,
+       RC_RELATION_EQUAL              = RELATION_EQUAL,
+       RC_RELATION_LESS               = RELATION_LESS,
+       RC_RELATION_LESS_EQUAL         = RELATION_LESS | RELATION_EQUAL,
+       RC_RELATION_GREATER            = RELATION_GREATER,
+       RC_RELATION_GREATER_EQUAL      = RELATION_GREATER | RELATION_EQUAL,
+       RC_RELATION_NOT_EQUAL          = RELATION_LESS | RELATION_GREATER,
+       RC_RELATION_NONE               = RELATION_NONE,
+} RCResolvableRelation;
+
+//-----------------------------------------------------------------------------
+// architectures
+
+typedef enum {
+    RC_ARCH_UNKNOWN = -1,
+    RC_ARCH_NOARCH = 0,
+    RC_ARCH_I386,
+    RC_ARCH_I486,
+    RC_ARCH_I586,
+    RC_ARCH_I686,
+    RC_ARCH_X86_64,
+    RC_ARCH_IA32E,
+    RC_ARCH_ATHLON,
+    RC_ARCH_PPC,
+    RC_ARCH_PPC64,
+    RC_ARCH_S390,
+    RC_ARCH_S390X,
+    RC_ARCH_IA64,
+    RC_ARCH_SPARC,
+    RC_ARCH_SPARC64,
+} RCArch;
+
+//-----------------------------------------------------------------------------
+// dependencies
+
+typedef enum {
+       RC_DEP_TYPE_REQUIRE = 0,
+       RC_DEP_TYPE_PROVIDE,                    // 1
+       RC_DEP_TYPE_CONFLICT,                   // 2
+       RC_DEP_TYPE_OBSOLETE,                   // 3
+       RC_DEP_TYPE_PREREQUIRE,                 // 4
+       RC_DEP_TYPE_FRESHEN,                    // 5
+       RC_DEP_TYPE_RECOMMEND,                  // 6
+       RC_DEP_TYPE_SUGGEST,                    // 7
+       RC_DEP_TYPE_SUPPLEMENT,                 // 8
+       RC_DEP_TYPE_ENHANCE                     // 9
+} RCDependencyType;
+
+//-----------------------------------------------------------------------------
+// kinds (dependencies.dep_target
+
+typedef enum {
+       RC_DEP_TARGET_PACKAGE = 0,
+       RC_DEP_TARGET_SCRIPT,                   // 1
+       RC_DEP_TARGET_MESSAGE,                  // 2
+       RC_DEP_TARGET_PATCH,                    // 3
+       RC_DEP_TARGET_PATTERN,                  // 4
+       RC_DEP_TARGET_PRODUCT,                  // 5
+       RC_DEP_TARGET_SELECTION,                // 6
+       RC_DEP_TARGET_LANGUAGE,                 // 7
+       RC_DEP_TARGET_ATOM,                     // 8
+       RC_DEP_TARGET_SRC,                      // 9
+       RC_DEP_TARGET_SYSTEM,                   // 10 SystemResObject
+       RC_DEP_TARGET_UNKNOWN=42                // 42
+} RCDependencyTarget;
+
+//-----------------------------------------------------------------------------
+// status (mostly for patches)
+//   to be evaluated together with resolvables.installed
+
+typedef enum {
+       RC_RES_STATUS_UNDETERMINED = 0,
+       RC_RES_STATUS_UNNEEDED,                 // not needed
+       RC_RES_STATUS_SATISFIED,                // needed, dependencies complete
+       RC_RES_STATUS_BROKEN                    // needed, dependencies incomplete
+} RCResolvableStatus;
+
+///////////////////////////////////////////////////////////////////
+//
+//     CLASS NAME : SqliteAccess
+//
+/**
+*/
+
+class SqliteAccess : public zypp::base::ReferenceCounted, public zypp::base::NonCopyable
+{
+  private:
+    std::string _dbfile;
+
+    sqlite3 *_db;
+    sqlite3_stmt *_insert_res_handle;
+    sqlite3_stmt *_insert_pkg_handle;
+    sqlite3_stmt *_insert_message_handle;
+    sqlite3_stmt *_insert_script_handle;
+    sqlite3_stmt *_insert_patch_handle;
+    sqlite3_stmt *_insert_pattern_handle;
+    sqlite3_stmt *_insert_product_handle;
+    sqlite3_stmt *_insert_dep_handle;
+
+    void commit();
+
+    sqlite_int64 writeResObject( zypp::ResObject::constPtr obj, zypp::ResStatus status, const char *catalog = NULL, Ownership owner = ZYPP_OWNED );
+
+    sqlite_int64 writePackage( sqlite_int64 id, zypp::Package::constPtr package, Ownership owner = ZYPP_OWNED );
+    sqlite_int64 writeMessage( sqlite_int64 id, zypp::Message::constPtr message );
+    sqlite_int64 writeScript( sqlite_int64 id, zypp::Script::constPtr script );
+    sqlite_int64 writePatch( sqlite_int64 id, zypp::Patch::constPtr patch );
+    sqlite_int64 writePattern( sqlite_int64 id, zypp::Pattern::constPtr pattern );
+    sqlite_int64 writeProduct( sqlite_int64 id, zypp::Product::constPtr product );
+
+    void writeDependencies( sqlite_int64 id, zypp::Resolvable::constPtr res);
+    void writeDependency( sqlite_int64 pkg_id, RCDependencyType type, const zypp::CapSet & capabilities);
+
+    bool prepareWrite( void );
+
+public:
+    /** Ctor */
+    SqliteAccess( const std::string & dbfile_r );
+    /** Dtor */
+    ~SqliteAccess( );
+
+    static RCResolvableRelation Rel2Rc (zypp::Rel op);
+    static zypp::Rel Rc2Rel (RCResolvableRelation rel);
+    static RCArch Arch2Rc (const zypp::Arch & arch);
+    static zypp::Arch Rc2Arch (RCArch rc);
+
+    sqlite3 *db() const { return _db; }
+    bool openDb( bool for_writing );
+    void closeDb( void );
+
+    /** check if catalog exists */
+    bool haveCatalog( const std::string & catalog );
+    /** insert catalog */
+    bool insertCatalog( const std::string & catalog, const std::string & name, const std::string & alias, const std::string & description );
+    /** remove catalog, remove all resolvables of this catalog */
+    bool removeCatalog( const std::string & catalog );
+    /** update catalog, update all non-empty parameters (name, alias, description) */
+    bool updateCatalog( const std::string & catalog, const std::string & name, const std::string & alias, const std::string & description );
+
+    /** write resolvables from store to db */
+    void writeStore( const zypp::ResStore & resolvables, zypp::ResStatus status, const char *catalog = NULL, Ownership owner = ZYPP_OWNED );
+    /** write resolvables from pool to db */
+    void writePool( const zypp::ResPool & pool, const char *catalog = NULL );
+
+private:
+    friend std::ostream & operator<<( std::ostream & str, const SqliteAccess & obj );
+    /** Stream output. */
+    std::ostream & dumpOn( std::ostream & str ) const;
+
+};
+///////////////////////////////////////////////////////////////////
+
+/** \relates SqliteAccess Stream output. */
+inline std::ostream & operator<<( std::ostream & str, const SqliteAccess & obj )
+{ return obj.dumpOn( str ); }
+
+
+#endif // ZMD_BACKEND_DBSOURCE_DBACCESS_H
diff --git a/zypp/source/sqlite-source/SqliteAtomImpl.cc b/zypp/source/sqlite-source/SqliteAtomImpl.cc
new file mode 100644 (file)
index 0000000..5ea28e9
--- /dev/null
@@ -0,0 +1,49 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file zmd/backend/dbsource/SqliteAtomImpl.h
+ *
+*/
+
+#include "SqliteAtomImpl.h"
+#include "zypp/source/SourceImpl.h"
+#include "zypp/TranslatedText.h"
+#include "zypp/base/String.h"
+#include "zypp/base/Logger.h"
+
+using namespace std;
+using namespace zypp::detail;
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////
+//
+//        CLASS NAME : SqliteAtomImpl
+//
+///////////////////////////////////////////////////////////////////
+
+/** Default ctor
+*/
+SqliteAtomImpl::SqliteAtomImpl (Source_Ref source_r, ZmdId zmdid)
+    : _source( source_r )
+    , _zmdid( zmdid )
+{
+}
+
+Source_Ref
+SqliteAtomImpl::source() const
+{ return _source; }
+
+ZmdId SqliteAtomImpl::zmdid() const
+{ return _zmdid; }
+
+  /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
diff --git a/zypp/source/sqlite-source/SqliteAtomImpl.h b/zypp/source/sqlite-source/SqliteAtomImpl.h
new file mode 100644 (file)
index 0000000..453c8e2
--- /dev/null
@@ -0,0 +1,49 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file zmd/backend/dbsource/SqliteAtomImpl.h
+ *
+*/
+#ifndef ZMD_BACKEND_DBSOURCE_DBATOMIMPL_H
+#define ZMD_BACKEND_DBSOURCE_DBATOMIMPL_H
+
+#include "zypp/detail/AtomImpl.h"
+#include "zypp/Source.h"
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////
+//
+//        CLASS NAME : SqliteAtomImpl
+//
+/** Class representing a package
+*/
+class SqliteAtomImpl : public detail::AtomImplIf
+{
+public:
+
+       /** Default ctor
+       */
+       SqliteAtomImpl( Source_Ref source_r, ZmdId zmdid );
+
+       /** */
+       virtual Source_Ref source() const;
+        /** */
+       virtual ZmdId zmdid() const;
+
+protected:
+       Source_Ref _source;
+       ZmdId _zmdid;
+
+ };
+  /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
+#endif // ZMD_BACKEND_DBSOURCE_DBATOMIMPL_H
diff --git a/zypp/source/sqlite-source/SqliteLanguageImpl.cc b/zypp/source/sqlite-source/SqliteLanguageImpl.cc
new file mode 100644 (file)
index 0000000..9443a92
--- /dev/null
@@ -0,0 +1,49 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file zmd/backend/dbsource/SqliteLanguageImpl.h
+ *
+*/
+
+#include "SqliteLanguageImpl.h"
+#include "zypp/source/SourceImpl.h"
+#include "zypp/TranslatedText.h"
+#include "zypp/base/String.h"
+#include "zypp/base/Logger.h"
+
+using namespace std;
+using namespace zypp::detail;
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////
+//
+//        CLASS NAME : SqliteLanguageImpl
+//
+///////////////////////////////////////////////////////////////////
+
+/** Default ctor
+*/
+SqliteLanguageImpl::SqliteLanguageImpl (Source_Ref source_r, ZmdId zmdid)
+    : _source( source_r )
+    , _zmdid( zmdid )
+{
+}
+
+Source_Ref
+SqliteLanguageImpl::source() const
+{ return _source; }
+
+ZmdId SqliteLanguageImpl::zmdid() const
+{ return _zmdid; }
+
+  /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
diff --git a/zypp/source/sqlite-source/SqliteLanguageImpl.h b/zypp/source/sqlite-source/SqliteLanguageImpl.h
new file mode 100644 (file)
index 0000000..639d138
--- /dev/null
@@ -0,0 +1,49 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file zmd/backend/dbsource/SqliteLanguageImpl.h
+ *
+*/
+#ifndef ZMD_BACKEND_DBSOURCE_DBLANGUAGEIMPL_H
+#define ZMD_BACKEND_DBSOURCE_DBLANGUAGEIMPL_H
+
+#include "zypp/Language.h"
+#include "zypp/Source.h"
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////
+//
+//        CLASS NAME : SqliteLanguageImpl
+//
+/** Class representing a package
+*/
+class SqliteLanguageImpl : public detail::LanguageImplIf
+{
+public:
+
+       /** Default ctor
+       */
+       SqliteLanguageImpl( Source_Ref source_r, ZmdId zmdid );
+
+       /** */
+       virtual Source_Ref source() const;
+        /** */
+       virtual ZmdId zmdid() const;
+
+protected:
+       Source_Ref _source;
+       ZmdId _zmdid;
+
+ };
+  /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
+#endif // ZMD_BACKEND_DBSOURCE_DBLANGUAGEIMPL_H
diff --git a/zypp/source/sqlite-source/SqliteMessageImpl.cc b/zypp/source/sqlite-source/SqliteMessageImpl.cc
new file mode 100644 (file)
index 0000000..eda96c4
--- /dev/null
@@ -0,0 +1,57 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file zmd/backend/dbsource/SqliteMessageImpl.h
+ *
+*/
+
+#include "SqliteMessageImpl.h"
+#include "zypp/source/SourceImpl.h"
+#include "zypp/TranslatedText.h"
+#include "zypp/base/String.h"
+#include "zypp/base/Logger.h"
+
+using namespace std;
+using namespace zypp::detail;
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////
+//
+//        CLASS NAME : SqliteMessageImpl
+//
+///////////////////////////////////////////////////////////////////
+
+/** Default ctor
+*/
+SqliteMessageImpl::SqliteMessageImpl (Source_Ref source_r, TranslatedText text, ZmdId zmdid)
+    : _source( source_r )
+    , _text( text )
+    , _zmdid( zmdid )
+{
+}
+
+Source_Ref
+SqliteMessageImpl::source() const
+{ return _source; }
+
+TranslatedText SqliteMessageImpl::text() const
+{ return _text; }
+
+ByteCount SqliteMessageImpl::size() const
+{ return _text.asString().size(); }
+
+
+ZmdId SqliteMessageImpl::zmdid() const
+{ return _zmdid; }
+
+  /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
diff --git a/zypp/source/sqlite-source/SqliteMessageImpl.h b/zypp/source/sqlite-source/SqliteMessageImpl.h
new file mode 100644 (file)
index 0000000..55f4972
--- /dev/null
@@ -0,0 +1,52 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file zmd/backend/dbsource/SqliteMessageImpl.h
+ *
+*/
+#ifndef ZMD_BACKEND_DBSOURCE_DBMESSAGEIMPL_H
+#define ZMD_BACKEND_DBSOURCE_DBMESSAGEIMPL_H
+
+#include "zypp/detail/MessageImpl.h"
+#include "zypp/Source.h"
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////
+//
+//        CLASS NAME : SqliteMessageImpl
+//
+/** Class representing a package
+*/
+class SqliteMessageImpl : public detail::MessageImplIf
+{
+public:
+
+       /** Default ctor
+       */
+       SqliteMessageImpl( Source_Ref source_r, TranslatedText text, ZmdId zmdid );
+
+       /** */
+       virtual Source_Ref source() const;
+       virtual TranslatedText text() const;
+       virtual ByteCount size() const;
+        /** */
+       virtual ZmdId zmdid() const;
+
+protected:
+       Source_Ref _source;
+       TranslatedText _text;
+       ZmdId _zmdid;
+
+ };
+  /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
+#endif // ZMD_BACKEND_DBSOURCE_DBMESSAGEIMPL_H
diff --git a/zypp/source/sqlite-source/SqlitePackageImpl.cc b/zypp/source/sqlite-source/SqlitePackageImpl.cc
new file mode 100644 (file)
index 0000000..ab48eb9
--- /dev/null
@@ -0,0 +1,127 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file zmd/backend/dbsource/SqlitePackageImpl.h
+ *
+*/
+
+#include "SqlitePackageImpl.h"
+#include "zypp/source/SourceImpl.h"
+#include "zypp/TranslatedText.h"
+#include "zypp/base/String.h"
+#include "zypp/base/Logger.h"
+
+using namespace std;
+using namespace zypp::detail;
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////
+//
+//        CLASS NAME : SqlitePackageImpl
+//
+///////////////////////////////////////////////////////////////////
+
+/** Default ctor
+*/
+SqlitePackageImpl::SqlitePackageImpl (Source_Ref source_r)
+    : _source (source_r)
+    , _install_only(false)
+    , _size_installed(0)
+    , _size_archive(0)
+{
+}
+
+/**
+ * read package specific data from handle
+ * (see SqliteSourceImpl, create_package_handle(), the handle is for the package_details table)
+ * throw() on error
+ */
+
+void
+SqlitePackageImpl::readHandle( sqlite_int64 id, sqlite3_stmt *handle )
+{
+    _zmdid = id;
+
+    // 1-5: nvra, see SqliteSourceImpl
+    _size_installed = sqlite3_column_int( handle, 6 );
+    // 7: catalog
+    // 8: installed
+    // 9: local
+    const char * text = ((const char *) sqlite3_column_text( handle, 10 ));
+    if (text != NULL)
+       _group = text;
+    _size_archive = sqlite3_column_int( handle, 11 );
+    text = (const char *) sqlite3_column_text( handle, 12 );
+    if (text != NULL)
+       _summary = TranslatedText( string( text ) );
+    text = (const char *) sqlite3_column_text( handle, 13 );
+    if (text != NULL)
+       _description = TranslatedText( string( text ) );
+    text = (const char *) sqlite3_column_text( handle, 15 );   // package_filename
+    if (text != NULL
+       && *text != 0)
+    {
+       _location = Pathname( text );                           // if set, use this (zmd owned source)
+    }
+    else {
+       text = (const char *)sqlite3_column_text( handle, 14 ); // else use package_url
+       if (text == NULL)
+           ERR << "package_url NULL for id " << id << endl;
+       else
+           _location = Pathname( text );
+    }
+    _install_only = (sqlite3_column_int( handle, 16 ) != 0);
+    _media_nr = sqlite3_column_int( handle, 17 );
+
+    return;
+}
+
+
+Source_Ref
+SqlitePackageImpl::source() const
+{ return _source; }
+
+/** Package summary */
+TranslatedText SqlitePackageImpl::summary() const
+{ return _summary; }
+
+/** Package description */
+TranslatedText SqlitePackageImpl::description() const
+{ return _description; }
+
+PackageGroup SqlitePackageImpl::group() const
+{ return _group; }
+
+Pathname SqlitePackageImpl::location() const
+{ return _location; }
+
+ByteCount SqlitePackageImpl::size() const
+{ return _size_installed; }
+
+ZmdId SqlitePackageImpl::zmdid() const
+{ return _zmdid; }
+
+/** */
+ByteCount SqlitePackageImpl::archivesize() const
+{ return _size_archive; }
+
+bool SqlitePackageImpl::installOnly() const
+{ return _install_only; }
+
+unsigned SqlitePackageImpl::sourceMediaNr() const
+{ return _media_nr; }
+
+Vendor SqlitePackageImpl::vendor() const
+{ return "suse"; }
+
+  /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
diff --git a/zypp/source/sqlite-source/SqlitePackageImpl.h b/zypp/source/sqlite-source/SqlitePackageImpl.h
new file mode 100644 (file)
index 0000000..b988b89
--- /dev/null
@@ -0,0 +1,78 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file zmd/backend/dbsource/SqlitePackageImpl.h
+ *
+*/
+#ifndef ZMD_BACKEND_DBSOURCE_DBPACKAGEIMPL_H
+#define ZMD_BACKEND_DBSOURCE_DBPACKAGEIMPL_H
+
+#include "zypp/detail/PackageImpl.h"
+#include "zypp/Source.h"
+#include <sqlite3.h>
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////
+//
+//        CLASS NAME : SqlitePackageImpl
+//
+/** Class representing a package
+*/
+class SqlitePackageImpl : public detail::PackageImplIf
+{
+public:
+
+       /** Default ctor
+       */
+       SqlitePackageImpl( Source_Ref source_r );
+       void readHandle( sqlite_int64 id, sqlite3_stmt *handle );
+
+       /** Package summary */
+       virtual TranslatedText summary() const;
+       /** Package description */
+       virtual TranslatedText description() const;
+       virtual ByteCount size() const;
+       /** */
+       virtual PackageGroup group() const;
+       /** */
+       virtual ByteCount archivesize() const;
+       /** */
+       virtual Pathname location() const;
+       /** */
+       virtual bool installOnly() const;
+       /** */
+       virtual Source_Ref source() const;
+        /** */
+       virtual ZmdId zmdid() const;
+        /** */
+       virtual unsigned sourceMediaNr() const;
+
+       virtual Vendor vendor() const;
+
+protected:
+       Source_Ref _source;
+       TranslatedText _summary;
+       TranslatedText _description;
+       PackageGroup _group;
+       Pathname _location;
+       bool _install_only;
+       ZmdId _zmdid;
+       unsigned _media_nr;
+
+       ByteCount _size_installed;
+       ByteCount _size_archive;
+
+
+ };
+  /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
+#endif // ZMD_BACKEND_DBSOURCE_DBPACKAGEIMPL_H
diff --git a/zypp/source/sqlite-source/SqlitePatchImpl.cc b/zypp/source/sqlite-source/SqlitePatchImpl.cc
new file mode 100644 (file)
index 0000000..6e231f4
--- /dev/null
@@ -0,0 +1,116 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file zmd/backend/dbsource/SqlitePatchImpl.cc
+ *
+*/
+
+#include "SqlitePatchImpl.h"
+#include "zypp/source/SourceImpl.h"
+#include "zypp/TranslatedText.h"
+#include "zypp/base/String.h"
+#include "zypp/base/Logger.h"
+
+using namespace std;
+using namespace zypp::detail;
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////
+//
+//        CLASS NAME : SqlitePatchImpl
+//
+///////////////////////////////////////////////////////////////////
+
+/** Default ctor
+*/
+SqlitePatchImpl::SqlitePatchImpl (Source_Ref source_r)
+    : _source (source_r)
+    , _reboot_needed( false )
+    , _affects_pkg_manager( false )
+    , _interactive( false )
+{
+}
+
+/**
+ * read patch specific data from handle
+ * (see SqliteSourceImpl, create_patch_handle(), the handle is for the patch_details table)
+ * throw() on error
+
+
+       //      6               7
+       "       installed_size, catalog,"
+       //      8          9      10        11
+       "       installed, local, patch_id, status,"
+       //      12             13        14
+       "       creation_time, category, reboot,"
+       //      15       16
+       "       restart, interactive"
+ */
+
+void
+SqlitePatchImpl::readHandle( sqlite_int64 id, sqlite3_stmt *handle )
+{
+    _zmdid = id;
+
+    // 1-5: nvra, see SqliteSourceImpl
+    _size_installed = sqlite3_column_int( handle, 6 );
+    // 7: catalog
+    // 8: installed
+    // 9: local
+    const char * text = ((const char *) sqlite3_column_text( handle, 10 ));
+    if (text != NULL)
+       _id = text;
+    // 11: status (will re recomputed anyways)
+    _timestamp = sqlite3_column_int64( handle, 12 );
+    text = (const char *) sqlite3_column_text( handle, 13 );
+    if (text != NULL)
+       _category = text;
+
+    _reboot_needed = (sqlite3_column_int( handle, 14 ) != 0);
+    _affects_pkg_manager = (sqlite3_column_int( handle, 15 ) != 0);
+    _interactive = (sqlite3_column_int( handle, 16 ) != 0);
+
+    return;
+}
+
+
+Source_Ref
+SqlitePatchImpl::source() const
+{ return _source; }
+
+ZmdId SqlitePatchImpl::zmdid() const
+{ return _zmdid; }
+
+ByteCount SqlitePatchImpl::size() const
+{ return _size_installed; }
+
+/** Patch ID */
+std::string SqlitePatchImpl::id() const
+{ return _id; }
+/** Patch time stamp */
+Date SqlitePatchImpl::timestamp() const
+{ return _timestamp; }
+/** Patch category (recommended, security,...) */
+std::string SqlitePatchImpl::category() const
+{ return _category; }
+/** Does the system need to reboot to finish the update process? */
+bool SqlitePatchImpl::reboot_needed() const
+{ return _reboot_needed; }
+/** Does the patch affect the package manager itself? */
+bool SqlitePatchImpl::affects_pkg_manager() const
+{ return _affects_pkg_manager; }
+/** Is the patch installation interactive? (does it need user input?) */
+bool SqlitePatchImpl::interactive() const
+{ return _interactive; }
+
+  /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
diff --git a/zypp/source/sqlite-source/SqlitePatchImpl.h b/zypp/source/sqlite-source/SqlitePatchImpl.h
new file mode 100644 (file)
index 0000000..465397a
--- /dev/null
@@ -0,0 +1,89 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file zmd/backend/dbsource/SqlitePatchImpl.h
+ *
+*/
+#ifndef ZMD_BACKEND_DBSOURCE_DBPATCHIMPL_H
+#define ZMD_BACKEND_DBSOURCE_DBPATCHIMPL_H
+
+#include "zypp/detail/PatchImpl.h"
+#include "zypp/Source.h"
+#include <sqlite3.h>
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////
+//
+//        CLASS NAME : SqlitePatchImpl
+//
+/** Class representing a package
+*/
+class SqlitePatchImpl : public detail::PatchImplIf
+{
+public:
+
+       /** Default ctor
+       */
+       SqlitePatchImpl( Source_Ref source_r );
+       void readHandle( sqlite_int64 id, sqlite3_stmt *handle );
+
+       /** */
+       virtual Source_Ref source() const;
+        /** */
+       virtual ZmdId zmdid() const;
+
+      /** Patch ID */
+      virtual std::string id() const;
+      /** Patch time stamp */
+      virtual Date timestamp() const;
+      /** Patch category (recommended, security,...) */
+      virtual std::string category() const;
+      /** Does the system need to reboot to finish the update process? */
+      virtual bool reboot_needed() const;
+      /** Does the patch affect the package manager itself? */
+      virtual bool affects_pkg_manager() const;
+      /** */
+      virtual ByteCount size() const;
+
+      /** Is the patch installation interactive? (does it need user input?) */
+      virtual bool interactive() const;
+
+      /** The list of all atoms building the patch */
+      virtual AtomList all_atoms() const
+      { return AtomList(); }
+      /** The list of those atoms which have not been installed */
+      virtual AtomList not_installed_atoms() const
+      { return AtomList(); }
+
+// TODO check necessarity of functions below
+      virtual void mark_atoms_to_freshen(bool freshen)
+      { return; }
+      virtual bool any_atom_selected() const
+      { return false; }
+
+protected:
+       Source_Ref _source;
+       ZmdId _zmdid;
+       std::string _id;
+       Date _timestamp;
+       std::string _category;
+       bool _reboot_needed;
+       bool _affects_pkg_manager;
+       bool _interactive;
+       ByteCount _size_installed;
+       ByteCount _size_archive;
+
+
+ };
+  /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
+#endif // ZMD_BACKEND_DBSOURCE_DBPATCHIMPL_H
diff --git a/zypp/source/sqlite-source/SqlitePatternImpl.cc b/zypp/source/sqlite-source/SqlitePatternImpl.cc
new file mode 100644 (file)
index 0000000..24ddca7
--- /dev/null
@@ -0,0 +1,96 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file zmd/backend/dbsource/SqlitePatternImpl.h
+ *
+*/
+
+#include "SqlitePatternImpl.h"
+#include "zypp/source/SourceImpl.h"
+#include "zypp/TranslatedText.h"
+#include "zypp/base/String.h"
+#include "zypp/base/Logger.h"
+
+using namespace std;
+using namespace zypp::detail;
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////
+//
+//        CLASS NAME : SqlitePatternImpl
+//
+///////////////////////////////////////////////////////////////////
+
+/** Default ctor
+*/
+SqlitePatternImpl::SqlitePatternImpl (Source_Ref source_r)
+    : _source (source_r)
+    , _zmdid(0)
+    , _default(false)
+    , _visible(false)
+{
+}
+
+/**
+ * read package specific data from handle
+ * throw() on error
+ */
+
+void
+SqlitePatternImpl::readHandle( sqlite_int64 id, sqlite3_stmt *handle )
+{
+    _zmdid = id;
+
+    // 1-5: nvra, see SqliteSourceImpl
+
+    // 6: status (don't care, its recomputed anyways)
+
+    return;
+}
+
+
+Source_Ref
+SqlitePatternImpl::source() const
+{ return _source; }
+
+/** Pattern summary */
+TranslatedText SqlitePatternImpl::summary() const
+{ return _summary; }
+
+/** Pattern description */
+TranslatedText SqlitePatternImpl::description() const
+{ return _description; }
+
+bool SqlitePatternImpl::isDefault() const
+{ return _default; }
+
+bool SqlitePatternImpl::userVisible() const
+{ return _visible; }
+
+TranslatedText SqlitePatternImpl::category() const
+{ return _category; }
+
+Pathname SqlitePatternImpl::icon() const
+{ return _icon; }
+
+Pathname SqlitePatternImpl::script() const
+{ return _script; }
+      
+Label SqlitePatternImpl::order() const
+{ return _order; }
+
+ZmdId SqlitePatternImpl::zmdid() const
+{ return _zmdid; }
+
+
+  /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
diff --git a/zypp/source/sqlite-source/SqlitePatternImpl.h b/zypp/source/sqlite-source/SqlitePatternImpl.h
new file mode 100644 (file)
index 0000000..99c5a5f
--- /dev/null
@@ -0,0 +1,74 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file zmd/backend/dbsource/SqlitePatternImpl.h
+ *
+*/
+#ifndef ZMD_BACKEND_DBSOURCE_DBPATTERNIMPL_H
+#define ZMD_BACKEND_DBSOURCE_DBPATTERNIMPL_H
+
+#include "zypp/detail/PatternImpl.h"
+#include "zypp/Source.h"
+#include <sqlite3.h>
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////
+//
+//        CLASS NAME : SqlitePatternImpl
+//
+/** Class representing a package
+*/
+class SqlitePatternImpl : public detail::PatternImplIf
+{
+public:
+
+       /** Default ctor
+       */
+       SqlitePatternImpl( Source_Ref source_r );
+       void readHandle( sqlite_int64 id, sqlite3_stmt *handle );
+
+       /** Pattern summary */
+       virtual TranslatedText summary() const;
+       /** Pattern description */
+       virtual TranslatedText description() const;
+
+       virtual bool isDefault() const;
+
+       virtual bool userVisible() const;
+
+       virtual TranslatedText category() const;
+
+       virtual Pathname icon() const;
+
+       virtual Pathname script() const;
+      
+       virtual Label order() const;
+       /** */
+       virtual Source_Ref source() const;
+        /** */
+       virtual ZmdId zmdid() const;
+
+protected:
+       Source_Ref _source;
+       TranslatedText _summary;
+       TranslatedText _description;
+       ZmdId _zmdid;
+       bool _default;
+       bool _visible;
+       TranslatedText _category;
+       Pathname _icon;
+       Pathname _script;
+       Label _order;
+ };
+  /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
+#endif // ZMD_BACKEND_DBSOURCE_DBPATTERNIMPL_H
diff --git a/zypp/source/sqlite-source/SqliteProductImpl.cc b/zypp/source/sqlite-source/SqliteProductImpl.cc
new file mode 100644 (file)
index 0000000..492fe21
--- /dev/null
@@ -0,0 +1,95 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file zmd/backend/dbsource/SqliteProductImpl.h
+ *
+*/
+
+#include "SqliteProductImpl.h"
+#include "zypp/source/SourceImpl.h"
+#include "zypp/TranslatedText.h"
+#include "zypp/base/String.h"
+#include "zypp/base/Logger.h"
+
+using namespace std;
+using namespace zypp::detail;
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////
+//
+//        CLASS NAME : SqliteProductImpl
+//
+///////////////////////////////////////////////////////////////////
+
+/** Default ctor
+*/
+SqliteProductImpl::SqliteProductImpl (Source_Ref source_r)
+    : _source (source_r)
+    , _zmdid(0)
+{
+}
+
+/**
+ * read package specific data from handle
+ * throw() on error
+ */
+
+void
+SqliteProductImpl::readHandle( sqlite_int64 id, sqlite3_stmt *handle )
+{
+    _zmdid = id;
+
+    // 1-5: nvra, see SqliteSourceImpl
+    // 6: status (don't care, its recomputed anyways)
+    // 7: category
+    const char * text = ((const char *) sqlite3_column_text( handle, 7 ));
+    if (text != NULL)
+       _category = text;
+
+    return;
+}
+
+
+Source_Ref
+SqliteProductImpl::source() const
+{ return _source; }
+
+ZmdId SqliteProductImpl::zmdid() const
+{ return _zmdid; }
+
+/** Product summary */
+TranslatedText SqliteProductImpl::summary() const
+{ return _summary; }
+
+/** Product description */
+TranslatedText SqliteProductImpl::description() const
+{ return _description; }
+
+/** Get the category of the product - addon or base*/
+std::string SqliteProductImpl::category() const
+{ return _category; }
+
+/** Get the vendor of the product */
+Label SqliteProductImpl::vendor() const
+{ return _vendor; }
+
+/** Get the name of the product to be presented to user */
+Label SqliteProductImpl::displayName( const Locale & locale_r ) const
+{ return _displayName; }
+
+/** */
+Url SqliteProductImpl::releaseNotesUrl() const
+{ return _releaseNotesUrl; }
+
+
+  /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
diff --git a/zypp/source/sqlite-source/SqliteProductImpl.h b/zypp/source/sqlite-source/SqliteProductImpl.h
new file mode 100644 (file)
index 0000000..9bc795f
--- /dev/null
@@ -0,0 +1,68 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file zmd/backend/dbsource/SqliteProductImpl.h
+ *
+*/
+#ifndef ZMD_BACKEND_DBSOURCE_DBPRODUCTIMPL_H
+#define ZMD_BACKEND_DBSOURCE_DBPRODUCTIMPL_H
+
+#include "zypp/detail/ProductImpl.h"
+#include "zypp/Source.h"
+#include <sqlite3.h>
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////
+//
+//        CLASS NAME : SqliteProductImpl
+//
+/** Class representing a package
+*/
+class SqliteProductImpl : public detail::ProductImplIf
+{
+public:
+
+       /** Default ctor
+       */
+       SqliteProductImpl( Source_Ref source_r );
+       void readHandle( sqlite_int64 id, sqlite3_stmt *handle );
+
+       /** Product summary */
+       virtual TranslatedText summary() const;
+       /** Product description */
+       virtual TranslatedText description() const;
+       /** Get the category of the product - addon or base*/
+       virtual std::string category() const;
+       /** Get the vendor of the product */
+       virtual Label vendor() const;
+       /** Get the name of the product to be presented to user */
+       virtual Label displayName( const Locale & locale_r = Locale() ) const;
+       /** */
+       virtual Url releaseNotesUrl() const;
+       /** */
+       virtual Source_Ref source() const;
+        /** */
+       virtual ZmdId zmdid() const;
+
+protected:
+       TranslatedText _summary;
+       TranslatedText _description;
+       Source_Ref _source;
+       ZmdId _zmdid;
+       std::string _category;
+       Label _vendor;
+       Label _displayName;
+       Url _releaseNotesUrl;
+ };
+  /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
+#endif // ZMD_BACKEND_DBSOURCE_DBPRODUCTIMPL_H
diff --git a/zypp/source/sqlite-source/SqliteScriptImpl.cc b/zypp/source/sqlite-source/SqliteScriptImpl.cc
new file mode 100644 (file)
index 0000000..040fb4c
--- /dev/null
@@ -0,0 +1,85 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file zmd/backend/dbsource/SqliteScriptImpl.h
+ *
+*/
+
+#include <fstream>
+
+#include "SqliteScriptImpl.h"
+#include "zypp/source/SourceImpl.h"
+#include "zypp/TranslatedText.h"
+#include "zypp/base/String.h"
+#include "zypp/base/Logger.h"
+
+using namespace std;
+using namespace zypp::detail;
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////
+//
+//        CLASS NAME : SqliteScriptImpl
+//
+///////////////////////////////////////////////////////////////////
+
+/** Default ctor
+*/
+SqliteScriptImpl::SqliteScriptImpl (Source_Ref source_r, std::string do_script, std::string undo_script, ZmdId zmdid)
+    : _source( source_r )
+    , _do_script( do_script )
+    , _undo_script( undo_script )
+    , _zmdid( zmdid )
+{
+}
+
+Source_Ref
+SqliteScriptImpl::source() const
+{ return _source; }
+
+Pathname
+SqliteScriptImpl::do_script() const
+{
+    if (_do_script.empty()) {
+       return Pathname();
+    }
+    _tmp_file = filesystem::TmpFile();
+    Pathname path = _tmp_file.path();
+    ofstream st( path.asString().c_str() );
+    st << _do_script << endl;
+    return path;
+}
+
+Pathname
+SqliteScriptImpl::undo_script() const
+{
+    if (_undo_script.empty()) {
+       return Pathname();
+    }
+    _tmp_file = filesystem::TmpFile();
+    Pathname path = _tmp_file.path();
+    ofstream st( path.asString().c_str() );
+    st << _undo_script << endl;
+    return path;
+}
+
+bool
+SqliteScriptImpl::undo_available() const
+{
+    return !_undo_script.empty();
+}
+
+ZmdId SqliteScriptImpl::zmdid() const
+{ return _zmdid; }
+
+  /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
diff --git a/zypp/source/sqlite-source/SqliteScriptImpl.h b/zypp/source/sqlite-source/SqliteScriptImpl.h
new file mode 100644 (file)
index 0000000..5175acb
--- /dev/null
@@ -0,0 +1,57 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file zmd/backend/dbsource/SqliteScriptImpl.h
+ *
+*/
+#ifndef ZMD_BACKEND_DBSOURCE_DBSCRIPTIMPL_H
+#define ZMD_BACKEND_DBSOURCE_DBSCRIPTIMPL_H
+
+#include "zypp/detail/ScriptImpl.h"
+#include "zypp/TmpPath.h"
+#include "zypp/Source.h"
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////
+//
+//        CLASS NAME : SqliteScriptImpl
+//
+/** Class representing a package
+*/
+class SqliteScriptImpl : public detail::ScriptImplIf
+{
+public:
+
+       /** Default ctor
+       */
+       SqliteScriptImpl( Source_Ref source_r, std::string do_script, std::string undo_script, ZmdId zmdid );
+
+       /** */
+       virtual Source_Ref source() const;
+       virtual Pathname do_script() const;
+       virtual Pathname undo_script() const;
+       virtual bool undo_available() const;
+
+        /** */
+       virtual ZmdId zmdid() const;
+
+protected:
+       Source_Ref _source;
+       std::string _do_script;
+       std::string _undo_script;
+       ZmdId _zmdid;
+
+       mutable filesystem::TmpFile _tmp_file;
+ };
+  /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
+#endif // ZMD_BACKEND_DBSOURCE_DBSCRIPTIMPL_H
diff --git a/zypp/source/sqlite-source/SqliteSourceImpl.cc b/zypp/source/sqlite-source/SqliteSourceImpl.cc
new file mode 100644 (file)
index 0000000..bf106ad
--- /dev/null
@@ -0,0 +1,882 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* SqliteSourceImpl.cc
+ *
+ * Copyright (C) 2000-2002 Ximian, Inc.
+ * Copyright (C) 2005 SUSE Linux Products GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include "SqliteSourceImpl.h"
+
+#include "SqlitePackageImpl.h"
+#include "SqliteAtomImpl.h"
+#include "SqliteMessageImpl.h"
+#include "SqliteScriptImpl.h"
+#include "SqliteLanguageImpl.h"
+#include "SqlitePatchImpl.h"
+#include "SqlitePatternImpl.h"
+#include "SqliteProductImpl.h"
+
+#include "zypp/source/SourceImpl.h"
+#include "zypp/base/Logger.h"
+#include "zypp/base/Exception.h"
+#include "zypp/CapFactory.h"
+
+using namespace std;
+using namespace zypp;
+
+//---------------------------------------------------------------------------
+
+SqliteSourceImpl::SqliteSourceImpl()
+    : _db (NULL)
+    , _idmap (NULL)
+{
+}
+
+
+void
+SqliteSourceImpl::factoryInit()
+{
+    MIL << "SqliteSourceImpl::factoryInit()" << endl;
+
+    try {
+       media::MediaManager media_mgr;
+       MIL << "Adding no media verifier" << endl;
+       media::MediaAccessId _media = _media_set->getMediaAccessId(1);
+       media_mgr.delVerifier( _media);
+       media_mgr.addVerifier( _media, media::MediaVerifierRef( new media::NoVerifier()));
+    }
+    catch (const Exception & excpt_r)
+    {
+#warning FIXME: If media data is not set, verifier is not set. Should the media be refused instead?
+       ZYPP_CAUGHT(excpt_r);
+       WAR << "Verifier not found" << endl;
+    }
+    return;
+}
+
+void
+SqliteSourceImpl::attachDatabase( sqlite3 *db)
+{
+    _db = db;
+}
+
+void
+SqliteSourceImpl::attachIdMap (IdMap *idmap)
+{
+  _idmap = idmap;
+}
+
+void
+SqliteSourceImpl::attachZyppSource(zypp::Source_Ref source)
+{
+  _zyppsource = source;
+}
+
+//-----------------------------------------------------------------------------
+
+static sqlite3_stmt *
+create_dependency_handle (sqlite3 *db)
+{
+    const char *query;
+    int rc;
+    sqlite3_stmt *handle = NULL;
+
+    query =
+       //      0         1     2        3        4      5     6         7
+       "SELECT dep_type, name, version, release, epoch, arch, relation, dep_target "
+       "FROM dependencies "
+       "WHERE resolvable_id = ?";
+
+    rc = sqlite3_prepare ( db, query, -1, &handle, NULL);
+    if (rc != SQLITE_OK) {
+       ERR << "Can not prepare dependency selection clause: " << sqlite3_errmsg ( db) << endl;
+       sqlite3_finalize (handle);
+       return NULL;
+    }
+
+    return handle;
+}
+
+
+static sqlite3_stmt *
+create_resolvables_handle (sqlite3 *db)
+{
+    const char *query;
+    int rc;
+    sqlite3_stmt *handle = NULL;
+
+    query =
+       //      0   1     2        3        4      5
+       "SELECT id, name, version, release, epoch, arch, "
+       //      6               7        8          9      10
+       "       installed_size, catalog, installed, local, kind "
+       "FROM resolvables "
+       "WHERE catalog = ? AND kind = ?";
+
+    rc = sqlite3_prepare ( db, query, -1, &handle, NULL);
+    if (rc != SQLITE_OK) {
+       ERR << "Can not prepare resolvables selection clause: " << sqlite3_errmsg ( db) << endl;
+       sqlite3_finalize (handle);
+       return NULL;
+    }
+
+    return handle;
+}
+
+
+static sqlite3_stmt *
+create_message_handle (sqlite3 *db)
+{
+    const char *query;
+    int rc;
+    sqlite3_stmt *handle = NULL;
+
+    query =
+       //      0   1     2        3        4      5
+       "SELECT id, name, version, release, epoch, arch, "
+       //      6               7
+       "       installed_size, catalog,"
+       //      8          9      10
+       "       installed, local, content "
+       "FROM messages "
+       "WHERE catalog = ?";
+
+    rc = sqlite3_prepare ( db, query, -1, &handle, NULL);
+    if (rc != SQLITE_OK) {
+       ERR << "Can not prepare messages selection clause: " << sqlite3_errmsg ( db) << endl;
+       sqlite3_finalize (handle);
+       return NULL;
+    }
+
+    return handle;
+}
+
+
+static sqlite3_stmt *
+create_script_handle (sqlite3 *db)
+{
+    const char *query;
+    int rc;
+    sqlite3_stmt *handle = NULL;
+
+    query =
+       //      0   1     2        3        4      5
+       "SELECT id, name, version, release, epoch, arch, "
+       //      6               7
+       "       installed_size, catalog,"
+       //      8          9      10         11
+       "       installed, local, do_script, undo_script "
+       "FROM scripts "
+       "WHERE catalog = ?";
+
+    rc = sqlite3_prepare ( db, query, -1, &handle, NULL);
+    if (rc != SQLITE_OK) {
+       ERR << "Can not prepare scripts selection clause: " << sqlite3_errmsg ( db) << endl;
+       sqlite3_finalize (handle);
+       return NULL;
+    }
+
+    return handle;
+}
+
+
+static sqlite3_stmt *
+create_package_handle (sqlite3 *db)
+{
+    const char *query;
+    int rc;
+    sqlite3_stmt *handle = NULL;
+
+    query =
+       //      0   1     2        3        4      5
+       "SELECT id, name, version, release, epoch, arch, "
+       //      6               7
+       "       installed_size, catalog,"
+       //      8          9      10         11
+       "       installed, local, rpm_group, file_size,"
+       //      12       13           14           15
+       "       summary, description, package_url, package_filename,"
+       //      16            17
+       "       install_only, media_nr "
+       "FROM packages "
+       "WHERE catalog = ?";
+
+    rc = sqlite3_prepare ( db, query, -1, &handle, NULL);
+    if (rc != SQLITE_OK) {
+       ERR << "Can not prepare packages selection clause: " << sqlite3_errmsg ( db) << endl;
+       sqlite3_finalize (handle);
+       return NULL;
+    }
+
+    return handle;
+}
+
+
+static sqlite3_stmt *
+create_patch_handle (sqlite3 *db)
+{
+    const char *query;
+    int rc;
+    sqlite3_stmt *handle = NULL;
+
+    query =
+       //      0   1     2        3        4      5
+       "SELECT id, name, version, release, epoch, arch, "
+       //      6               7
+       "       installed_size, catalog,"
+       //      8          9      10        11
+       "       installed, local, patch_id, status,"
+       //      12             13        14
+       "       creation_time, category, reboot,"
+       //      15       16
+       "       restart, interactive "
+       "FROM patches "
+       "WHERE catalog = ?";
+
+    rc = sqlite3_prepare ( db, query, -1, &handle, NULL);
+    if (rc != SQLITE_OK) {
+       ERR << "Can not prepare patches selection clause: " << sqlite3_errmsg ( db) << endl;
+       ERR << "Clause: [" << query << "]" << endl;
+       sqlite3_finalize (handle);
+       return NULL;
+    }
+
+    return handle;
+}
+
+
+static sqlite3_stmt *
+create_pattern_handle (sqlite3 *db)
+{
+    const char *query;
+    int rc;
+    sqlite3_stmt *handle = NULL;
+
+    query =
+       //      0   1     2        3        4      5
+       "SELECT id, name, version, release, epoch, arch, "
+       //      6               7
+       "       installed_size, catalog,"
+       //      8          9      10
+       "       installed, local, status "
+       "FROM patterns "
+       "WHERE catalog = ?";
+
+    rc = sqlite3_prepare ( db, query, -1, &handle, NULL);
+    if (rc != SQLITE_OK) {
+       ERR << "Can not prepare patterns selection clause: " << sqlite3_errmsg ( db) << endl;
+       ERR << "Clause: [" << query << "]" << endl;
+       sqlite3_finalize (handle);
+       return NULL;
+    }
+
+    return handle;
+}
+
+
+static sqlite3_stmt *
+create_product_handle (sqlite3 *db)
+{
+    const char *query;
+    int rc;
+    sqlite3_stmt *handle = NULL;
+
+    query =
+       //      0   1     2        3        4      5
+       "SELECT id, name, version, release, epoch, arch, "
+       //      6               7
+       "       installed_size, catalog,"
+       //      8          9      10      11
+       "       installed, local, status, category "
+       "FROM products "
+       "WHERE catalog = ?";
+
+    rc = sqlite3_prepare ( db, query, -1, &handle, NULL);
+    if (rc != SQLITE_OK) {
+       ERR << "Can not prepare products selection clause: " << sqlite3_errmsg ( db) << endl;
+       ERR << "Clause: [" << query << "]" << endl;
+       sqlite3_finalize (handle);
+       return NULL;
+    }
+
+    return handle;
+}
+
+
+//-----------------------------------------------------------------------------
+
+void
+SqliteSourceImpl::createResolvables(Source_Ref source_r)
+{
+    MIL << "SqliteSourceImpl::createResolvables(" << source_r.id() << ")" << endl;
+    _source = source_r;
+    if ( _db == NULL) {
+       ERR << "Must call attachDatabase() first" << endl;
+       return;
+    }
+
+    _dependency_handle = create_dependency_handle ( _db);
+    if ( _dependency_handle == NULL) return;
+
+    createPackages();
+    createAtoms();
+    createMessages();
+    createScripts();
+    createLanguages();
+    createPatches();
+    createPatterns();
+    createProducts();
+
+    return;
+}
+
+
+void
+SqliteSourceImpl::createAtoms(void)
+{
+    sqlite3_stmt *handle = create_resolvables_handle( _db );
+    if (handle == NULL) return;
+
+    sqlite3_bind_text (handle, 1, _source.id().c_str(), -1, SQLITE_STATIC);
+    sqlite3_bind_int (handle, 2, RC_DEP_TARGET_ATOM);
+
+    int rc;
+    while ((rc = sqlite3_step (handle)) == SQLITE_ROW) {
+
+       string name;
+
+       try
+       {
+           sqlite_int64 id = sqlite3_column_int64( handle, 0 );
+           name = (const char *) sqlite3_column_text( handle, 1 );
+           string version ((const char *) sqlite3_column_text( handle, 2 ));
+           string release ((const char *) sqlite3_column_text( handle, 3 ));
+           unsigned epoch = sqlite3_column_int( handle, 4 );
+           Arch arch( SqliteAccess::Rc2Arch( (RCArch)(sqlite3_column_int( handle, 5 )) ) );
+
+           detail::ResImplTraits<SqliteAtomImpl>::Ptr impl( new SqliteAtomImpl( _source, id ) );
+
+           // Collect basic Resolvable data
+           NVRAD dataCollect( name,
+                       Edition( version, release, epoch ),
+                       arch,
+                       createDependencies (id ) );
+
+           Atom::Ptr atom = detail::makeResolvableFromImpl( dataCollect, impl );
+           _store.insert( atom );
+           XXX << "Atom[" << id << "] " << *atom << endl;
+           if ( _idmap != 0)
+               (*_idmap)[id] = atom;
+       }
+       catch (const Exception & excpt_r)
+       {
+           ERR << "Cannot create atom object '" << name << "' from catalog '" << _source.id() << "'" << endl;
+           sqlite3_reset (handle);
+           ZYPP_RETHROW (excpt_r);
+       }
+    }
+
+    sqlite3_reset (handle);
+    return;
+}
+
+
+void
+SqliteSourceImpl::createMessages(void)
+{
+    sqlite3_stmt *handle = create_message_handle( _db );
+    if (handle == NULL) return;
+
+    sqlite3_bind_text( handle, 1, _source.id().c_str(), -1, SQLITE_STATIC );
+
+    int rc;
+    while ((rc = sqlite3_step (handle)) == SQLITE_ROW) {
+
+       string name;
+
+       try
+       {
+           sqlite_int64 id = sqlite3_column_int64( handle, 0 );
+           name = (const char *) sqlite3_column_text( handle, 1 );
+           string version( (const char *)sqlite3_column_text( handle, 2 ) );
+           string release( (const char *)sqlite3_column_text( handle, 3 ) );
+           unsigned epoch = sqlite3_column_int( handle, 4 );
+           Arch arch( SqliteAccess::Rc2Arch( (RCArch)(sqlite3_column_int( handle, 5 )) ) );
+
+           string content( (const char *)sqlite3_column_text( handle, 10 ) );
+
+           detail::ResImplTraits<SqliteMessageImpl>::Ptr impl( new SqliteMessageImpl( _source, TranslatedText( content ), id ) );
+
+           // Collect basic Resolvable data
+           NVRAD dataCollect( name,
+                       Edition( version, release, epoch ),
+                       arch,
+                       createDependencies (id ) );
+
+           Message::Ptr message = detail::makeResolvableFromImpl( dataCollect, impl );
+           _store.insert( message );
+           XXX << "Message[" << id << "] " << *message << endl;
+           if (_idmap != 0)
+               (*_idmap)[id] = message;
+       }
+       catch (const Exception & excpt_r)
+       {
+           ERR << "Cannot create message object '" << name << "' from catalog '" << _source.id() << "'" << endl;
+           sqlite3_reset (handle);
+           ZYPP_RETHROW (excpt_r);
+       }
+    }
+
+    sqlite3_reset (handle);
+    return;
+}
+
+
+void
+SqliteSourceImpl::createScripts(void)
+{
+    sqlite3_stmt *handle = create_script_handle( _db );
+    if (handle == NULL) return;
+
+    sqlite3_bind_text( handle, 1, _source.id().c_str(), -1, SQLITE_STATIC );
+
+    int rc;
+    while ((rc = sqlite3_step (handle)) == SQLITE_ROW) {
+
+       string name;
+
+       try
+       {
+           sqlite_int64 id = sqlite3_column_int64( handle, 0 );
+           name = (const char *) sqlite3_column_text( handle, 1 );
+           string version ((const char *) sqlite3_column_text( handle, 2 ));
+           string release ((const char *) sqlite3_column_text( handle, 3 ));
+           unsigned epoch = sqlite3_column_int( handle, 4 );
+           Arch arch( SqliteAccess::Rc2Arch( (RCArch)(sqlite3_column_int( handle, 5 )) ) );
+
+           string do_script( (const char *)sqlite3_column_text( handle, 10 ) );
+           string undo_script( (const char *)sqlite3_column_text( handle, 11 ) );
+
+           detail::ResImplTraits<SqliteScriptImpl>::Ptr impl( new SqliteScriptImpl( _source, do_script, undo_script, id ) );
+
+           // Collect basic Resolvable data
+           NVRAD dataCollect( name,
+                       Edition( version, release, epoch ),
+                       arch,
+                       createDependencies (id ) );
+
+           Script::Ptr script = detail::makeResolvableFromImpl( dataCollect, impl );
+           _store.insert( script );
+           XXX << "Script[" << id << "] " << *script << endl;
+           if ( _idmap != 0)
+               (*_idmap)[id] = script;
+       }
+       catch (const Exception & excpt_r)
+       {
+           ERR << "Cannot create script object '" << name << "' from catalog '" << _source.id() << "'" << endl;
+           sqlite3_reset (handle);
+           ZYPP_RETHROW (excpt_r);
+       }
+    }
+
+    sqlite3_reset (handle);
+    return;
+}
+
+
+void
+SqliteSourceImpl::createLanguages(void)
+{
+    sqlite3_stmt *handle = create_resolvables_handle( _db );
+    if (handle == NULL) return;
+
+    sqlite3_bind_text (handle, 1, _source.id().c_str(), -1, SQLITE_STATIC);
+    sqlite3_bind_int (handle, 2, RC_DEP_TARGET_LANGUAGE);
+
+    int rc;
+    while ((rc = sqlite3_step (handle)) == SQLITE_ROW) {
+
+       string name;
+
+       try
+       {
+           sqlite_int64 id = sqlite3_column_int64( handle, 0 );
+           name = (const char *) sqlite3_column_text( handle, 1 );
+           string version ((const char *) sqlite3_column_text( handle, 2 ));
+           string release ((const char *) sqlite3_column_text( handle, 3 ));
+           unsigned epoch = sqlite3_column_int( handle, 4 );
+           Arch arch( SqliteAccess::Rc2Arch( (RCArch)(sqlite3_column_int( handle, 5 )) ) );
+
+           detail::ResImplTraits<SqliteLanguageImpl>::Ptr impl( new SqliteLanguageImpl( _source, id ) );
+
+           // Collect basic Resolvable data
+           NVRAD dataCollect( name,
+                       Edition( version, release, epoch ),
+                       arch,
+                       createDependencies (id ) );
+
+           Language::Ptr language = detail::makeResolvableFromImpl( dataCollect, impl );
+           _store.insert( language );
+           XXX << "Language[" << id << "] " << *language << endl;
+           if ( _idmap != 0)
+               (*_idmap)[id] = language;
+       }
+       catch (const Exception & excpt_r)
+       {
+           ERR << "Cannot create language object '" << name << "' from catalog '" << _source.id() << "'" << endl;
+           sqlite3_reset (handle);
+           ZYPP_RETHROW (excpt_r);
+       }
+    }
+
+    sqlite3_reset (handle);
+    return;
+}
+
+
+void
+SqliteSourceImpl::createPackages(void)
+{
+    sqlite3_stmt *handle = create_package_handle ( _db);
+    if (handle == NULL) return;
+
+    sqlite3_bind_text (handle, 1, _source.id().c_str(), -1, SQLITE_STATIC);
+
+    int rc;
+    while ((rc = sqlite3_step (handle)) == SQLITE_ROW) {
+
+       string name;
+
+       try
+       {
+           detail::ResImplTraits<SqlitePackageImpl>::Ptr impl( new SqlitePackageImpl( _zyppsource ? _zyppsource :_source ) );
+
+           sqlite_int64 id = sqlite3_column_int64( handle, 0 );
+           name = (const char *) sqlite3_column_text( handle, 1 );
+           string version ((const char *) sqlite3_column_text( handle, 2 ));
+           string release ((const char *) sqlite3_column_text( handle, 3 ));
+           unsigned epoch = sqlite3_column_int( handle, 4 );
+           Arch arch( SqliteAccess::Rc2Arch( (RCArch)(sqlite3_column_int( handle, 5 )) ) );
+
+           impl->readHandle( id, handle );
+
+           // Collect basic Resolvable data
+           NVRAD dataCollect( name,
+                       Edition( version, release, epoch ),
+                       arch,
+                       createDependencies (id ) );
+
+           Package::Ptr package = detail::makeResolvableFromImpl( dataCollect, impl );
+           _store.insert( package );
+           if ( _idmap != 0)
+               (*_idmap)[id] = package;
+       }
+       catch (const Exception & excpt_r)
+       {
+           ERR << "Cannot create package object '" << name << "' from catalog '" << _source.id() << "'" << endl;
+           sqlite3_reset (handle);
+           ZYPP_RETHROW (excpt_r);
+       }
+    }
+
+    sqlite3_reset (handle);
+    return;
+}
+
+
+void
+SqliteSourceImpl::createPatches(void)
+{
+    sqlite3_stmt *handle = create_patch_handle( _db );
+    if (handle == NULL) return;
+
+    sqlite3_bind_text( handle, 1, _source.id().c_str(), -1, SQLITE_STATIC );
+
+    int rc;
+    while ((rc = sqlite3_step (handle)) == SQLITE_ROW) {
+
+       string name;
+
+       try
+       {
+           detail::ResImplTraits<SqlitePatchImpl>::Ptr impl( new SqlitePatchImpl( _source ) );
+
+           sqlite_int64 id = sqlite3_column_int64( handle, 0 );
+           name = (const char *) sqlite3_column_text( handle, 1 );
+           string version ((const char *) sqlite3_column_text( handle, 2 ));
+           string release ((const char *) sqlite3_column_text( handle, 3 ));
+           unsigned epoch = sqlite3_column_int( handle, 4 );
+           Arch arch( SqliteAccess::Rc2Arch( (RCArch)(sqlite3_column_int( handle, 5 )) ) );
+
+           impl->readHandle( id, handle );
+
+           // Collect basic Resolvable data
+           NVRAD dataCollect( name,
+                       Edition( version, release, epoch ),
+                       arch,
+                       createDependencies (id ) );
+
+           Patch::Ptr patch = detail::makeResolvableFromImpl( dataCollect, impl );
+           _store.insert( patch );
+           XXX << "Patch[" << id << "] " << *patch << endl;
+           if ( _idmap != 0)
+               (*_idmap)[id] = patch;
+       }
+       catch (const Exception & excpt_r)
+       {
+           ERR << "Cannot create patch object '" << name << "' from catalog '" << _source.id() << "'" << endl;
+           sqlite3_reset (handle);
+           ZYPP_RETHROW (excpt_r);
+       }
+    }
+
+    sqlite3_reset (handle);
+    return;
+}
+
+
+void
+SqliteSourceImpl::createPatterns(void)
+{
+    sqlite3_stmt *handle = create_pattern_handle( _db );
+    if (handle == NULL) return;
+
+    sqlite3_bind_text( handle, 1, _source.id().c_str(), -1, SQLITE_STATIC );
+
+    int rc;
+    while ((rc = sqlite3_step (handle)) == SQLITE_ROW) {
+
+       string name;
+
+       try
+       {
+           detail::ResImplTraits<SqlitePatternImpl>::Ptr impl( new SqlitePatternImpl( _source ) );
+
+           sqlite_int64 id = sqlite3_column_int64( handle, 0 );
+           name = (const char *) sqlite3_column_text( handle, 1 );
+           string version ((const char *) sqlite3_column_text( handle, 2 ));
+           string release ((const char *) sqlite3_column_text( handle, 3 ));
+           unsigned epoch = sqlite3_column_int( handle, 4 );
+           Arch arch( SqliteAccess::Rc2Arch( (RCArch)(sqlite3_column_int( handle, 5 )) ) );
+
+           impl->readHandle( id, handle );
+
+           // Collect basic Resolvable data
+           NVRAD dataCollect( name,
+                       Edition( version, release, epoch ),
+                       arch,
+                       createDependencies (id ) );
+
+           Pattern::Ptr pattern = detail::makeResolvableFromImpl( dataCollect, impl );
+           _store.insert( pattern );
+           XXX << "Pattern[" << id << "] " << *pattern << endl;
+           if ( _idmap != 0)
+               (*_idmap)[id] = pattern;
+       }
+       catch (const Exception & excpt_r)
+       {
+           ERR << "Cannot create pattern object '" << name << "' from catalog '" << _source.id() << "'" << endl;
+           sqlite3_reset (handle);
+           ZYPP_RETHROW (excpt_r);
+       }
+    }
+
+    sqlite3_reset (handle);
+    return;
+}
+
+
+void
+SqliteSourceImpl::createProducts(void)
+{
+    sqlite3_stmt *handle = create_product_handle( _db );
+    if (handle == NULL) return;
+
+    sqlite3_bind_text( handle, 1, _source.id().c_str(), -1, SQLITE_STATIC );
+
+    int rc;
+    while ((rc = sqlite3_step (handle)) == SQLITE_ROW) {
+
+       string name;
+
+       try
+       {
+           detail::ResImplTraits<SqliteProductImpl>::Ptr impl( new SqliteProductImpl( _source ) );
+
+           sqlite_int64 id = sqlite3_column_int64( handle, 0 );
+           name = (const char *) sqlite3_column_text( handle, 1 );
+           string version ((const char *) sqlite3_column_text( handle, 2 ));
+           string release ((const char *) sqlite3_column_text( handle, 3 ));
+           unsigned epoch = sqlite3_column_int( handle, 4 );
+           Arch arch( SqliteAccess::Rc2Arch( (RCArch)(sqlite3_column_int( handle, 5 )) ) );
+
+           impl->readHandle( id, handle );
+
+           // Collect basic Resolvable data
+           NVRAD dataCollect( name,
+                       Edition( version, release, epoch ),
+                       arch,
+                       createDependencies (id ) );
+
+           Product::Ptr product = detail::makeResolvableFromImpl( dataCollect, impl );
+           _store.insert( product );
+           XXX << "Product[" << id << "] " << *product << endl;
+           if ( _idmap != 0)
+               (*_idmap)[id] = product;
+       }
+       catch (const Exception & excpt_r)
+       {
+           ERR << "Cannot create product object '" << name << "' from catalog '" << _source.id() << "'" << endl;
+           sqlite3_reset (handle);
+           ZYPP_RETHROW (excpt_r);
+       }
+    }
+
+    sqlite3_reset (handle);
+    return;
+}
+
+
+//-----------------------------------------------------------------------------
+
+// convert ZMD RCDependencyTarget to ZYPP Resolvable kind
+static Resolvable::Kind 
+target2kind( RCDependencyTarget dep_target )
+{
+    Resolvable::Kind kind;
+
+    switch ( dep_target)
+    {
+       case RC_DEP_TARGET_PACKAGE:     kind = ResTraits<Package>::kind;
+       break;
+       case RC_DEP_TARGET_SCRIPT:      kind = ResTraits<Package>::kind;
+       break;
+       case RC_DEP_TARGET_MESSAGE:     kind = ResTraits<Message>::kind;
+       break;
+       case RC_DEP_TARGET_PATCH:       kind = ResTraits<Patch>::kind;
+       break;
+       case RC_DEP_TARGET_SELECTION:   kind = ResTraits<Selection>::kind;
+       break;
+       case RC_DEP_TARGET_PATTERN:     kind = ResTraits<Pattern>::kind;
+       break;
+       case RC_DEP_TARGET_PRODUCT:     kind = ResTraits<Product>::kind;
+       break;
+       case RC_DEP_TARGET_LANGUAGE:    kind = ResTraits<Language>::kind;
+       break;
+       case RC_DEP_TARGET_ATOM:        kind = ResTraits<Atom>::kind;
+       break;
+       case RC_DEP_TARGET_SRC:         kind = ResTraits<SrcPackage>::kind;
+       break;
+       case RC_DEP_TARGET_SYSTEM:      kind = ResTraits<SystemResObject>::kind;
+       break;
+       default:                        WAR << "Unknown dep_target " << dep_target << endl;
+                                       kind = ResTraits<Package>::kind;
+       break;
+    }
+    return kind;
+}
+
+
+Dependencies
+SqliteSourceImpl::createDependencies (sqlite_int64 resolvable_id)
+{
+    Dependencies deps;
+    CapFactory factory;
+
+    sqlite3_bind_int64 ( _dependency_handle, 1, resolvable_id);
+
+    RCDependencyType dep_type;
+    string name, version, release;
+    unsigned epoch;
+    Arch arch;
+    Rel rel;
+    Capability cap;
+    Resolvable::Kind dkind;
+    
+    const char *text;
+    int rc;
+    while ((rc = sqlite3_step( _dependency_handle)) == SQLITE_ROW) {
+       try {
+           dep_type = (RCDependencyType)sqlite3_column_int( _dependency_handle, 0);
+           name = string ( (const char *)sqlite3_column_text( _dependency_handle, 1) );
+           text = (const char *)sqlite3_column_text( _dependency_handle, 2);
+           dkind = target2kind( (RCDependencyTarget)sqlite3_column_int( _dependency_handle, 7 ) );
+
+           if (text == NULL) {
+               cap = factory.parse( dkind, name );
+           }
+           else {
+               version = text;
+               text = (const char *)sqlite3_column_text( _dependency_handle, 3);
+               if (text != NULL)
+                   release = text;
+               else
+                   release.clear();
+               epoch = sqlite3_column_int( _dependency_handle, 4 );
+               arch = SqliteAccess::Rc2Arch( (RCArch) sqlite3_column_int( _dependency_handle, 5 ) );
+               rel = SqliteAccess::Rc2Rel( (RCResolvableRelation) sqlite3_column_int( _dependency_handle, 6 ) );
+
+               cap = factory.parse( dkind, name, rel, Edition( version, release, epoch ) );
+           }
+
+           switch ( dep_type) {
+               case RC_DEP_TYPE_REQUIRE:
+                   deps[Dep::REQUIRES].insert( cap );
+               break;
+               case RC_DEP_TYPE_PROVIDE:
+                   deps[Dep::PROVIDES].insert( cap );
+               break;
+               case RC_DEP_TYPE_CONFLICT:
+                   deps[Dep::CONFLICTS].insert( cap );
+               break;
+               case RC_DEP_TYPE_OBSOLETE:
+                   deps[Dep::OBSOLETES].insert( cap );
+               break;
+               case RC_DEP_TYPE_PREREQUIRE:
+                   deps[Dep::PREREQUIRES].insert( cap );
+               break;
+               case RC_DEP_TYPE_FRESHEN:
+                   deps[Dep::FRESHENS].insert( cap );
+               break;
+               case RC_DEP_TYPE_RECOMMEND:
+                   deps[Dep::RECOMMENDS].insert( cap );
+               break;
+               case RC_DEP_TYPE_SUGGEST:
+                   deps[Dep::SUGGESTS].insert( cap );
+               break;
+               case RC_DEP_TYPE_SUPPLEMENT:
+                   deps[Dep::SUPPLEMENTS].insert( cap );
+               break;
+               case RC_DEP_TYPE_ENHANCE:
+                   deps[Dep::ENHANCES].insert( cap );
+               break;
+               default:
+                  ERR << "Unhandled dep_type " << dep_type << endl;
+               break;
+           }
+       }
+       catch ( Exception & excpt_r ) {
+           ERR << "Can't parse dependencies for resolvable_id " << resolvable_id << ", name '" << name << "', version '" << version << "', release '" << release << "'" << endl;
+           ZYPP_CAUGHT( excpt_r );
+       }
+    }
+
+    sqlite3_reset ( _dependency_handle);
+    return deps;
+}
+
+// EOF
diff --git a/zypp/source/sqlite-source/SqliteSourceImpl.h b/zypp/source/sqlite-source/SqliteSourceImpl.h
new file mode 100644 (file)
index 0000000..008961a
--- /dev/null
@@ -0,0 +1,95 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* SqliteSourceImpl.h
+ *
+ * Copyright (C) 2000-2002 Ximian, Inc.
+ * Copyright (C) 2005 SUSE Linux Products GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef ZMD_BACKEND_DBSOURCEIMPL_H
+#define ZMD_BACKEND_DBSOURCEIMPL_H
+
+#include <iosfwd>
+#include <string>
+
+#include "zypp/source/SourceImpl.h"
+#include "zypp/media/MediaManager.h"
+
+#include "SqliteAccess.h"
+
+#include "zypp/Package.h"
+#include "zypp/Atom.h"
+#include "zypp/Message.h"
+#include "zypp/Script.h"
+#include "zypp/Language.h"
+#include "zypp/Patch.h"
+#include "zypp/Product.h"
+#include "zypp/Pattern.h"
+       
+///////////////////////////////////////////////////////////////////
+//
+//     CLASS NAME : SqliteSourceImpl
+
+class SqliteSourceImpl : public zypp::source::SourceImpl {
+
+ public:
+    /** Default ctor */
+    SqliteSourceImpl();
+
+ private:
+    /** Ctor substitute.
+     * Actually get the metadata.
+     * \throw EXCEPTION on fail
+     */
+    virtual void factoryInit();
+
+    sqlite3 *_db;
+    sqlite3_stmt *_dependency_handle;
+    sqlite3_stmt *_message_handle;
+    sqlite3_stmt *_script_handle;
+    sqlite3_stmt *_patch_handle;
+    sqlite3_stmt *_pattern_handle;
+    sqlite3_stmt *_product_handle;
+
+    void createPackages(void);
+    void createAtoms(void);
+    void createMessages(void);
+    void createScripts(void);
+    void createLanguages(void);
+    void createPatches(void);
+    void createPatterns(void);
+    void createProducts(void);
+
+    zypp::Dependencies createDependencies (sqlite_int64 resolvable_id);
+
+ public:
+
+    virtual const bool valid() const
+    { return true; }
+
+    void attachDatabase( sqlite3 *db );
+    void attachIdMap (IdMap *idmap);
+    void attachZyppSource( zypp::Source_Ref source );
+
+  private:
+    zypp::Source_Ref _source;          // reference to SqliteSource for this Impl
+    zypp::Source_Ref _zyppsource;      // reference to real zypp source, if exists
+    IdMap *_idmap;                     // map sqlite resolvable.id to actual objects
+    void createResolvables( zypp::Source_Ref source_r );
+};
+
+
+#endif // ZMD_BACKEND_DBSOURCEIMPL_H
diff --git a/zypp/source/sqlite-source/SqliteSources.cc b/zypp/source/sqlite-source/SqliteSources.cc
new file mode 100644 (file)
index 0000000..9f65347
--- /dev/null
@@ -0,0 +1,243 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* SqliteSources.cc  wrapper for zmd.db 'catalogs' table
+ *
+ * Copyright (C) 2000-2002 Ximian, Inc.
+ * Copyright (C) 2005 SUSE Linux Products GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <iostream>
+
+#include "zypp/base/Logger.h"
+#include "zypp/base/Exception.h"
+
+#include "zypp/Source.h"
+#include "zypp/SourceFactory.h"
+#include "zypp/SourceManager.h"
+#include "zypp/source/SourceImpl.h"
+
+#include "zypp/media/MediaManager.h"
+
+#include "SqliteSources.h"
+#include "SqliteSourceImpl.h"
+#include <sqlite3.h>
+
+using namespace std;
+using namespace zypp;
+
+//---------------------------------------------------------------------------
+
+SqliteSources::SqliteSources (sqlite3 *db)
+    : _db (db)
+{ 
+    MIL << "SqliteSources::SqliteSources(" << db << ")" << endl;
+}
+
+SqliteSources::~SqliteSources ()
+{
+}
+
+
+ResObject::constPtr
+SqliteSources::getById (sqlite_int64 id) const
+{
+    IdMap::const_iterator it = _idmap.find(id);
+    if (it == _idmap.end())
+       return NULL;
+    return it->second;
+}
+
+
+Source_Ref
+SqliteSources::createDummy( const Url & url, const string & catalog )
+{
+    media::MediaManager mmgr;
+    media::MediaId mediaid = mmgr.open( url );
+    SourceFactory factory;
+
+    try {
+
+       SqliteSourceImpl *impl = new SqliteSourceImpl ();
+       impl->factoryCtor( mediaid, Pathname(), catalog );
+       impl->setId( catalog );
+       impl->setZmdName( catalog );
+       impl->setZmdDescription ( catalog );
+       impl->setPriority( 0 );
+       impl->setSubscribed( true );
+
+       Source_Ref src( factory.createFrom( impl ) );
+       return src;
+    }
+    catch (Exception & excpt_r) {
+       ZYPP_CAUGHT(excpt_r);
+    }
+
+    return Source_Ref();
+}
+
+
+//
+// actually create sources from catalogs table
+// if zypp_restore == true, match catalogs entries with actual zypp sources
+//   and return zypp source on match
+// else create dummy file:/ source since a real source is either not needed
+//   or files are provided by zmd
+//
+
+const SourcesList &
+SqliteSources::sources( bool zypp_restore, bool refresh )
+{
+    MIL << "SqliteSources::sources(" << (zypp_restore ? "zypp_restore " : "") << (refresh ? "refresh" : "") << ")" << endl;
+
+    if (_db == NULL)
+       return _sources;
+
+    if (!refresh
+       && !_sources.empty())
+    {
+       return _sources;
+    }
+
+    _sources.clear();
+
+    const char *query =
+       //      0   1     2      3            4         5
+       "SELECT id, name, alias, description, priority, subscribed "
+       "FROM catalogs";
+
+    sqlite3_stmt *handle = NULL;
+    int rc = sqlite3_prepare (_db, query, -1, &handle, NULL);
+    if (rc != SQLITE_OK) {
+       ERR << "Can not read 'channels': " << sqlite3_errmsg (_db) << endl;
+       return _sources;
+    }
+
+    media::MediaManager mmgr;
+    _smgr = SourceManager::sourceManager();
+
+    try {
+       _smgr->restore("/");
+    }
+    catch (Exception & excpt_r) {
+       ZYPP_CAUGHT (excpt_r);
+       ERR << "Couldn't restore sources" << endl;
+       return _sources;
+    }
+
+    media::MediaId mediaid = mmgr.open( Url( "file:/" ) );
+    SourceFactory factory;
+
+    // read catalogs table
+
+    while ((rc = sqlite3_step (handle)) == SQLITE_ROW) {
+       const char *text = (const char *) sqlite3_column_text( handle, 0 );
+       if (text == NULL) {
+           ERR << "Catalog id is NULL" << endl;
+           continue;
+       }
+       string id (text);
+       string name;
+       text = (const char *) sqlite3_column_text( handle, 1 );
+       if (text != NULL) name = text;
+       string alias;
+       text = (const char *) sqlite3_column_text( handle, 2 );
+       if (text != NULL) alias = text;
+       string desc;
+       text = (const char *) sqlite3_column_text( handle, 3 );
+       if (text != NULL) desc = text;
+       unsigned priority = sqlite3_column_int( handle, 4 );
+       int subscribed = sqlite3_column_int( handle, 5 );
+
+       MIL << "id " << id
+           << ", name " << name
+           << ", alias " << alias
+           << ", desc " << desc
+           << ", prio " << priority
+           << ", subs " << subscribed
+           << endl;
+
+       if (alias.empty()) alias = name;
+       if (desc.empty()) desc = alias;
+
+       Source_Ref zypp_source;
+
+       if (zypp_restore
+           && id[0] != '@')            // not for zmd '@system' and '@local'
+       {
+           MIL << "Try to find '" << name << "' as zypp source" << endl;
+           try {
+               zypp_source = _smgr->findSource( name );
+           }
+           catch( const Exception & excpt_r ) {
+               ZYPP_CAUGHT(excpt_r);
+
+               MIL << "Try to find '" << alias << "' as zypp source" << endl;
+               try {
+                   zypp_source = _smgr->findSource( alias );
+               }
+               catch( const Exception & excpt_r ) {
+                   ZYPP_CAUGHT(excpt_r);
+
+                   // #177543
+                   MIL << "Try to find URL '" << id << "' as zypp source" << endl;
+                   try {
+                       Url url = id;
+                       zypp_source = _smgr->findSourceByUrl( url );
+                   }
+                   catch( const Exception & excpt_r ) {
+                       ZYPP_CAUGHT(excpt_r);
+                   }
+               }
+           }
+
+           if (zypp_source) {
+               zypp_source.setId( id );                // set id, to match resolvable catalog
+               MIL << "Found " << zypp_source << endl;
+           }
+       }
+
+       try {
+
+           SqliteSourceImpl *impl = new SqliteSourceImpl ();
+           impl->factoryCtor( mediaid, Pathname(), alias );
+           impl->setId( id );
+           impl->setZmdName( name );
+           impl->setZmdDescription ( desc );
+           impl->setPriority( priority );
+           impl->setSubscribed( subscribed != 0 );
+
+           impl->attachDatabase( _db );
+           impl->attachIdMap( &_idmap );
+           impl->attachZyppSource( zypp_source );
+
+           Source_Ref src( factory.createFrom( impl ) );
+           _sources.push_back( src );
+       }
+       catch (Exception & excpt_r) {
+           ZYPP_CAUGHT(excpt_r);
+           ERR << "Couldn't create zmd source" << endl;
+       }
+
+    }
+
+    if (rc != SQLITE_DONE) {
+       ERR << "Error while reading 'channels': " << sqlite3_errmsg (_db) << endl;
+       _sources.clear();
+    }
+
+    MIL << "Read " << _sources.size() << " catalogs" << endl;
+    return _sources;
+}
diff --git a/zypp/source/sqlite-source/SqliteSources.h b/zypp/source/sqlite-source/SqliteSources.h
new file mode 100644 (file)
index 0000000..32b934d
--- /dev/null
@@ -0,0 +1,63 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* SqliteSources.h: sqlite catalogs table reader
+ *
+ * Copyright (C) 2000-2002 Ximian, Inc.
+ * Copyright (C) 2005 SUSE Linux Products GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef ZMD_BACKEND_DBSOURCES_H
+#define ZMD_BACKEND_DBSOURCES_H
+
+#include <iosfwd>
+#include <string>
+#include <list>
+#include <map>
+
+#include <sqlite3.h>
+#include <zypp/Source.h>
+#include <zypp/SourceManager.h>
+#include <zypp/Url.h>
+#include <zypp/PoolItem.h>
+
+#include "SqliteAccess.h"
+
+///////////////////////////////////////////////////////////////////
+//
+//      CLASS NAME : SqliteSources
+
+typedef std::list<zypp::Source_Ref> SourcesList;
+
+class SqliteSources
+{
+  private:
+     sqlite3 *_db; 
+     SourcesList _sources;
+     IdMap _idmap;
+     zypp::SourceManager_Ptr _smgr;
+
+  public:
+
+    SqliteSources (sqlite3 *db);
+    virtual ~SqliteSources();
+
+    const SourcesList & sources( bool zypp_restore = false, bool refresh = false );
+    zypp::ResObject::constPtr getById (sqlite_int64 id) const;
+
+    static zypp::Source_Ref createDummy( const zypp::Url & url, const std::string & catalog );
+};
+
+#endif  // ZMD_BACKEND_DBSOURCES_H