as we redesign the sources.
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 \
## 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\"
SourceImpl.h \
Builtin.h \
PackageDelta.h \
- MediaSet.h
+ MediaSet.h \
+ SourceCreateContext.h
noinst_LTLIBRARIES = lib@PACKAGE@_source.la
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
## ##################################################
--- /dev/null
+#
+# 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
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ 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;
+}
+
+
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ 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
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ 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
+///////////////////////////////////////////////////////////////////
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ 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
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ 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
+///////////////////////////////////////////////////////////////////
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ 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
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ 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
+///////////////////////////////////////////////////////////////////
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ 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
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ 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
+///////////////////////////////////////////////////////////////////
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ 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
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ 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
+///////////////////////////////////////////////////////////////////
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ 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
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ 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
+///////////////////////////////////////////////////////////////////
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ 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
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ 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
+///////////////////////////////////////////////////////////////////
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ 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
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ 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
+///////////////////////////////////////////////////////////////////
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ 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
--- /dev/null
+/* -*- 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
--- /dev/null
+/* -*- 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
--- /dev/null
+/* -*- 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;
+}
--- /dev/null
+/* -*- 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