- commit current state of binding and examples
authorMichael Schroeder <mls@suse.de>
Mon, 2 May 2011 13:09:00 +0000 (15:09 +0200)
committerMichael Schroeder <mls@suse.de>
Mon, 2 May 2011 13:09:00 +0000 (15:09 +0200)
examples/p5solv
examples/pysolv
examples/rbsolv
examples/solv.c
examples/solv.i

index 2519d2d..c2efc39 100755 (executable)
@@ -95,16 +95,16 @@ sub download {
   if ($chksum) {
     my $fchksum = solv::Chksum->new($chksum->{'type'});
     $fchksum->add_fd(fileno($f));
-    if (!$fchksum->matches($chksum)) {
+    if ($fchksum != $chksum) {
       print "$file: checksum error\n";
       $self->{'incomplete'} = 1 if $markincomplete;
       return undef;
     }
   }
   if ($uncompress) {
-    return solv::xfopen_fd($file, POSIX::dup(fileno($f)));
+    return solv::xfopen_dup($file, fileno($f));
   } else {
-    return solv::xfopen_fd('', POSIX::dup(fileno($f)));
+    return solv::xfopen_dup(undef, fileno($f));
   }
 }
 
@@ -124,7 +124,7 @@ sub usecachedrepo {
       return undef if sysread($f, $fextcookie, 32) != 32;
     }
     sysseek($f, 0, Fcntl::SEEK_SET);
-    $f = solv::xfopen_fd('', POSIX::dup(fileno($f)));
+    $f = solv::xfopen_dup(undef, fileno($f));
     my $flags = $ext ? $solv::Repo::REPO_USE_LOADING|$solv::Repo::REPO_EXTEND_SOLVABLES : 0;
     $flags |= $solv::Repo::REPO_LOCALPOOL if $ext && $ext ne 'DL';
     if (!$self->{'handle'}->add_solv($f, $flags)) {
@@ -162,7 +162,7 @@ sub writecachedrepo {
   };
   return unless $f;
   chmod 0444, $f;
-  my $ff = solv::xfopen_fd('', POSIX::dup(fileno($f)));
+  my $ff = solv::xfopen_dup(undef, fileno($f));
   if (!$info) {
     $self->{'handle'}->write($ff);
   } elsif ($ext) {
@@ -373,7 +373,7 @@ sub add_exts {
   my $di = $self->{'handle'}->Dataiterator($solv::SOLVID_META, $solv::SUSETAGS_FILE_NAME, undef, 0);
   $di->prepend_keyname($solv::SUSETAGS_FILE);
   for my $d (@$di) {
-    my $filename = $d->match_str();
+    my $filename = $d->str();
     next unless $filename && $filename =~ /^packages\.(..)(?:\..*)$/;
     next if $1 eq 'en' || $1 eq 'gz';
     $self->add_ext($repodata, $filename, $1);
@@ -479,6 +479,7 @@ sub load {
   print "reading\n";
   $self->{'handle'}->add_products("/etc/products.d", $solv::Repo::REPO_NO_INTERNALIZE);
   $self->{'handle'}->add_rpmdb(undef, $solv::Repo::REPO_REUSE_REPODATA);
+  $self->writecachedrepo();
   return 1;
 }
 
@@ -496,7 +497,7 @@ sub depglob {
   my $id = $pool->str2id($name, 0);
   if ($id) {
     my $match;
-    for my $s ($pool->providers($id)) {
+    for my $s ($pool->whatprovides($id)) {
       return $pool->Job($solv::Job::SOLVER_SOLVABLE_NAME, $id) if $globname && $s->{'nameid'} == $id;
       $match = 1;
     }
@@ -800,6 +801,7 @@ if ($cmd eq 'install' || $cmd eq 'erase' || $cmd eq 'up' || $cmd eq 'dup' || $cm
            print "  - allow something else\n";
          }
         }
+        print "\n";
       }
       my $sol;
       while (1) {
@@ -817,7 +819,7 @@ if ($cmd eq 'install' || $cmd eq 'erase' || $cmd eq 'up' || $cmd eq 'dup' || $cm
          $jobs[$element->{'jobidx'}] = $pool->Job($solv::Job::SOLVER_NOOP, 0);
         } else {
          my $newjob = $element->Job();
-         push @jobs, $newjob if $newjob && !grep {$_->{'how'} == $newjob->{'how'} && $_->{'what'} == $newjob->{'what'}} @jobs;
+         push @jobs, $newjob if $newjob && !grep {$_ == $newjob} @jobs;
        }
       }
     }
index 84fb9f7..f6ea3bd 100755 (executable)
@@ -177,14 +177,14 @@ class repo_generic(dict):
                    self['incomplete'] = True
                return None
            fchksum.add_fd(f.fileno())
-           if not fchksum.matches(chksum):
+           if fchksum != chksum:
                print "%s: checksum mismatch" % file
                if markincomplete:
                    self['incomplete'] = True
                return None
        if uncompress:
            return solv.xfopen_fd(file, os.dup(f.fileno()))
-       return solv.xfopen_fd("", os.dup(f.fileno()))
+       return solv.xfopen_fd(None, os.dup(f.fileno()))
 
     def usecachedrepo(self, ext, mark=False):
        if not ext:
@@ -495,7 +495,7 @@ class repo_susetags(repo_generic):
        di = self.handle.Dataiterator(solv.SOLVID_META, solv.SUSETAGS_FILE_NAME, None, 0)
        di.prepend_keyname(solv.SUSETAGS_FILE)
        for d in di:
-           filename = d.match_str()
+           filename = d.str
            if not filename:
                continue
            if filename[0:9] != "packages.":
@@ -668,7 +668,7 @@ def depglob(pool, name, globname, globdep):
     id = pool.str2id(name, False)
     if id:
        match = False
-       for s in pool.providers(id):
+       for s in pool.whatprovides(id):
            if globname and s.nameid == id:
                return [ pool.Job(Job.SOLVER_SOLVABLE_NAME, id) ]
            match = True
@@ -805,8 +805,8 @@ if cmd == 'list' or cmd == 'info':
     for job in jobs:
        for s in job.solvables():
            if cmd == 'info':
-               print "Name:        %s" % s.str()
-               print "Repo:        %s" % s.repo.name
+               print "Name:        %s" % s
+               print "Repo:        %s" % s.repo
                print "Summary:     %s" % s.lookup_str(solv.SOLVABLE_SUMMARY)
                str = s.lookup_str(solv.SOLVABLE_URL)
                if str:
@@ -817,7 +817,7 @@ if cmd == 'list' or cmd == 'info':
                print "Description:\n%s" % s.lookup_str(solv.SOLVABLE_DESCRIPTION)
                print
            else:
-               print "  - %s [%s]" % (s.str(), s.repo.name)
+               print "  - %s [%s]" % (s, s.repo)
                print "    %s" % s.lookup_str(solv.SOLVABLE_SUMMARY)
     sys.exit(0)
 
@@ -877,32 +877,33 @@ if cmd == 'install' or cmd == 'erase' or cmd == 'up' or cmd == 'dup' or cmd == '
                 for element in elements:
                    etype = element.type
                    if etype == Solver.SOLVER_SOLUTION_JOB:
-                       print "  - do not ask to", jobs[element.jobidx].str()
+                       print "  - do not ask to", jobs[element.jobidx]
                    elif etype == Solver.SOLVER_SOLUTION_INFARCH:
                        if element.solvable.isinstalled():
-                           print "  - keep %s despite the inferior architecture" % element.solvable.str()
+                           print "  - keep %s despite the inferior architecture" % element.solvable
                        else:
-                           print "  - install %s despite the inferior architecture" % element.solvable.str()
+                           print "  - install %s despite the inferior architecture" % element.solvable
                    elif etype == Solver.SOLVER_SOLUTION_DISTUPGRADE:
                        if element.solvable.isinstalled():
-                           print "  - keep obsolete %s" % element.solvable.str()
+                           print "  - keep obsolete %s" % element.solvable
                        else:
-                           print "  - install %s from excluded repository" % element.solvable.str()
+                           print "  - install %s from excluded repository" % element.solvable
                    elif etype == Solver.SOLVER_SOLUTION_REPLACE:
                        illegal = element.illegalreplace()
                        if illegal & solver.POLICY_ILLEGAL_DOWNGRADE:
-                           print "  - allow downgrade of %s to %s" % (element.solvable.str(), element.replacement.str())
+                           print "  - allow downgrade of %s to %s" % (element.solvable, element.replacement)
                        if illegal & solver.POLICY_ILLEGAL_ARCHCHANGE:
-                           print "  - allow architecture change of %s to %s" % (element.solvable.str(), element.replacement.str())
+                           print "  - allow architecture change of %s to %s" % (element.solvable, element.replacement)
                        if illegal & solver.POLICY_ILLEGAL_VENDORCHANGE:
                            if element.replacement.vendorid:
-                               print "  - allow vendor change from '%s' (%s) to '%s' (%s)" % (element.solvable.vendor, element.solvable.str(), element.replacement.vendor, element.replacement.str())
+                               print "  - allow vendor change from '%s' (%s) to '%s' (%s)" % (element.solvable.vendor, element.solvable, element.replacement.vendor, element.replacement)
                            else:
-                               print "  - allow vendor change from '%s' (%s) to no vendor (%s)" % (element.solvable.vendor, element.solvable.str(), element.replacement.str())
+                               print "  - allow vendor change from '%s' (%s) to no vendor (%s)" % (element.solvable.vendor, element.solvable, element.replacement)
                        if illegal == 0:
-                           print "  - allow replacement of %s with %s" % (element.solvable.str(), element.replacement.str())
+                           print "  - allow replacement of %s with %s" % (element.solvable, element.replacement)
                    elif etype == Solver.SOLVER_SOLUTION_ERASE:
-                       print "  - allow deinstallation of %s" % element.solvable.str()
+                       print "  - allow deinstallation of %s" % element.solvable
+               print
            sol = ''
            while not (sol == 's' or sol == 'q' or (sol.isdigit() and int(sol) >= 1 and int(sol) <= len(solutions))):
                sys.stdout.write("Please choose a solution: ")
@@ -919,13 +920,9 @@ if cmd == 'install' or cmd == 'erase' or cmd == 'up' or cmd == 'dup' or cmd == '
                    jobs[element.jobidx] = pool.Job(Job.SOLVER_NOOP, 0)
                else:
                    newjob = element.Job()
-                   if newjob:
-                       for job in jobs:
-                           if job.how == newjob.how and job.what == newjob.what:
-                               newjob = None
-                               break
-                       if newjob:
-                           jobs.append(newjob)
+                   if newjob and newjob not in jobs:
+                       jobs.append(newjob)
+                       
     # no problems, show transaction
     trans = solver.transaction()
     del solver
@@ -957,9 +954,9 @@ if cmd == 'install' or cmd == 'erase' or cmd == 'up' or cmd == 'dup' or cmd == '
        for p in cl.solvables():
            if cl.type == Transaction.SOLVER_TRANSACTION_UPGRADED or cl.type == Transaction.SOLVER_TRANSACTION_DOWNGRADED:
                op = trans.othersolvable(p)
-               print "  - %s -> %s" % (p.str(), op.str())
+               print "  - %s -> %s" % (p, op)
            else:
-               print "  - %s" % p.str()
+               print "  - %s" % p
         print
     print "install size change: %d K" % trans.calc_installsizechange()
     print
@@ -999,7 +996,7 @@ if cmd == 'install' or cmd == 'erase' or cmd == 'up' or cmd == 'dup' or cmd == '
                        continue
                    baseevrid = pool.lookup_id(solv.SOLVID_POS, solv.DELTA_BASE_EVR)
                    candidate = None
-                   for installedp in pool.providers(p.nameid):
+                   for installedp in pool.whatprovides(p.nameid):
                        if installedp.isinstalled() and installedp.nameid == p.nameid and installedp.archid == p.archid and installedp.evrid == baseevrid:
                            candidate = installedp
                    if not candidate:
@@ -1051,7 +1048,7 @@ if cmd == 'install' or cmd == 'erase' or cmd == 'up' or cmd == 'dup' or cmd == '
            rpmdbid = p.lookup_num(solv.RPM_RPMDBID)
            erasenamehelper[p.name] = p
            if not rpmdbid:
-               sys.exit("\ninternal error: installed package %s has no rpmdbid\n" % p.str())
+               sys.exit("\ninternal error: installed package %s has no rpmdbid\n" % p)
            ts.addErase(rpmdbid)
        elif type == Transaction.SOLVER_TRANSACTION_INSTALL:
            f = newpkgsfp[p.id]
@@ -1072,12 +1069,12 @@ if cmd == 'install' or cmd == 'erase' or cmd == 'up' or cmd == 'dup' or cmd == '
        if reason == rpm.RPMCALLBACK_INST_OPEN_FILE:
            return solv.xfileno(newpkgsfp[p.id])
        if reason == rpm.RPMCALLBACK_INST_START:
-           print "install", p.str()
+           print "install", p
        if reason == rpm.RPMCALLBACK_UNINST_START:
            # argh, p is just the name of the package
            if p in erasenamehelper:
                p = erasenamehelper[p]
-               print "erase", p.str()
+               print "erase", p
     runproblems = ts.run(runCallback, '')
     if runproblems:
        print runproblems
index d7b3d92..5cc2a5a 100755 (executable)
@@ -427,7 +427,7 @@ class Repo_susetags < Repo_generic
     di = @handle.Dataiterator(Solv::SOLVID_META, Solv::SUSETAGS_FILE_NAME, nil, 0)
     di.prepend_keyname(Solv::SUSETAGS_FILE)
     for d in di
-      filename = d.match_str
+      filename = d.str
       next unless filename && filename =~ /^packages\.(..)(?:\..*)$/
       next if $1 == 'en' || $1 == 'gz'
       add_ext(repodata, filename, $1)
@@ -502,7 +502,7 @@ def depglob(pool, name, globname, globdep)
   id = pool.str2id(name, false)
   if id != 0
     match = false
-    providers = pool.providers(id)
+    providers = pool.whatprovides(id)
     if globname && providers.find {|s| s.nameid == id }
       return [ pool.Job(Solv::Job::SOLVER_SOLVABLE_NAME, id) ]
     end
index f9a0f7a..7046181 100644 (file)
@@ -84,7 +84,7 @@
 
 #define SOLVCACHE_PATH "/var/cache/solv"
 
-#define METADATA_EXPIRE (60 * 90)
+#define METADATA_EXPIRE (60 * 15)
 
 struct repoinfo {
   Repo *repo;
@@ -1467,18 +1467,6 @@ load_stub(Pool *pool, Repodata *data, void *dp)
 static unsigned char installedcookie[32];
 
 #ifdef DEBIAN
-void
-repo_add_debdb(Repo *repo, int flags)
-{
-  FILE *fp;
-  if ((fp = fopen("/var/lib/dpkg/status", "r")) == 0)
-    {
-      perror("/var/lib/dpkg/status");
-      exit(1);
-    }
-  repo_add_debpackages(repo, fp, flags);
-  fclose(fp);
-}
 
 const char *
 debian_find_component(struct repoinfo *cinfo, FILE *fp, char *comp, const unsigned char **chksump, Id *chksumtypep)
@@ -1660,7 +1648,7 @@ read_repos(Pool *pool, struct repoinfo *repoinfos, int nrepoinfos)
       if (!done)
         repo_add_rpmdb(repo, 0, 0, REPO_REUSE_REPODATA);
 #else
-        repo_add_debdb(repo, REPO_REUSE_REPODATA);
+        repo_add_debdb(repo, 0, REPO_REUSE_REPODATA);
 #endif
       writecachedrepo(repo, 0, 0, installedcookie);
     }
index 15a737b..7d237c3 100644 (file)
@@ -338,7 +338,10 @@ typedef VALUE AppObjectPtr;
 #include "repo_solv.h"
 #include "chksum.h"
 
+#ifndef DEBIAN
 #include "repo_rpmdb.h"
+#endif
+#include "repo_deb.h"
 #include "repo_rpmmd.h"
 #include "repo_write.h"
 #include "repo_products.h"
@@ -365,7 +368,7 @@ typedef void *AppObjectPtr;
 typedef struct {
   Pool *pool;
   Id id;
-} XId;
+} Dep;
 
 typedef struct {
   Pool *pool;
@@ -399,7 +402,7 @@ typedef struct {
 
 typedef struct {
   Pool *pool;
-  Id how;
+  int how;
   Id what;
 } Job;
 
@@ -470,7 +473,7 @@ typedef int Id;
 typedef struct {
   Pool* const pool;
   Id const id;
-} XId;
+} Dep;
 
 typedef struct {
   Pool* const pool;
@@ -505,12 +508,17 @@ typedef struct {} Repo_solvable_iterator;
 typedef struct {
   Pool * const pool;
   Repo * const repo;
-  const Id solvid;
+  Id const solvid;
 } Datamatch;
 
+%nodefaultctor Datapos;
+typedef struct {
+  Repo * const repo;
+} Datapos;
+
 typedef struct {
   Pool * const pool;
-  Id how;
+  int how;
   Id what;
 } Job;
 
@@ -644,7 +652,7 @@ typedef struct {
   static const Id SOLVER_NOAUTOSET = SOLVER_NOAUTOSET;
   static const Id SOLVER_SETMASK = SOLVER_SETMASK;
 
-  Job(Pool *pool, Id how, Id what) {
+  Job(Pool *pool, int how, Id what) {
     Job *job = sat_calloc(1, sizeof(*job));
     job->pool = pool;
     job->how = how;
@@ -652,11 +660,9 @@ typedef struct {
     return job;
   }
 
-  const char *str() {
-    return pool_job2str($self->pool, $self->how, $self->what, 0);
-  }
-
-  Queue solvableids() {
+  %typemap(out) Queue solvables Queue2Array(XSolvable *, 1, new_XSolvable(arg1->pool, id));
+  %newobject solvables;
+  Queue solvables() {
     Pool *pool = $self->pool;
     Id p, pp, how;
     Queue q;
@@ -666,10 +672,23 @@ typedef struct {
       queue_push(&q, p);
     return q;
   }
-  %typemap(out) Queue solvables Queue2Array(XSolvable *, 1, new_XSolvable(arg1->pool, id));
-  %newobject solvables;
-  Queue solvables() {
-    return Job_solvableids($self);
+
+  const char *str() {
+    return pool_job2str($self->pool, $self->how, $self->what, 0);
+  }
+
+  bool __eq__(Job *j) {
+    return $self->pool == j->pool && $self->how == j->how && $self->what == j->what;
+  }
+  bool __ne__(Job *j) {
+    return !Job___eq__($self, j);
+  }
+  const char *__str__() {
+    return pool_job2str($self->pool, $self->how, $self->what, 0);
+  }
+  const char *__repr__() {
+    const char *str = pool_job2str($self->pool, $self->how, $self->what, ~0);
+    return pool_tmpjoin($self->pool, "<Job ", str, ">");
   }
 }
 
@@ -721,17 +740,6 @@ typedef struct {
     sat_chksum_add($self, &stb.st_size, sizeof(stb.st_size));
     sat_chksum_add($self, &stb.st_mtime, sizeof(stb.st_mtime));
   }
-  bool matches(Chksum *othersum) {
-    int l;
-    const unsigned char *b, *bo;
-    if (!othersum)
-      return 0;
-    if (sat_chksum_get_type($self) != sat_chksum_get_type(othersum))
-      return 0;
-    b = sat_chksum_get($self, &l);
-    bo = sat_chksum_get(othersum, 0);
-    return memcmp(b, bo, l) == 0;
-  }
   SWIGCDATA raw() {
     int l;
     const unsigned char *b;
@@ -749,6 +757,42 @@ typedef struct {
     sat_bin2hex(b, l, ret);
     return ret;
   }
+
+  bool __eq__(Chksum *chk) {
+    int l;
+    const unsigned char *b, *bo;
+    if (!chk)
+      return 0;
+    if (sat_chksum_get_type($self) != sat_chksum_get_type(chk))
+      return 0;
+    b = sat_chksum_get($self, &l);
+    bo = sat_chksum_get(chk, 0);
+    return memcmp(b, bo, l) == 0;
+  }
+  bool __ne__(Chksum *chk) {
+    return !Chksum___eq__($self, chk);
+  }
+#if defined(SWIGRUBY)
+  %rename("to_s") __str__;
+  %rename("inspect") __repr__;
+#endif
+  %newobject __str__;
+  const char *__str__() {
+    const char *str;
+    const char *h = 0;
+    if (sat_chksum_isfinished($self))
+      h = Chksum_hex($self);
+    str = sat_dupjoin(sat_chksum_type2str(sat_chksum_get_type($self)), ":", h ? h : "unfinished");
+    sat_free((void *)h);
+    return str;
+  }
+  %newobject __repr__;
+  const char *__repr__() {
+    const char *h = Chksum___str__($self);
+    const char *str = sat_dupjoin("<Chksum ", h, ">");
+    sat_free((void *)h);
+    return str;
+  }
 }
 
 %extend Pool {
@@ -786,30 +830,28 @@ typedef struct {
   }
 #endif
 #if defined(SWIGPERL)
-  %{
-
-SWIGINTERN int loadcallback(Pool *pool, Repodata *data, void *d) {
-  int count;
-  int ret = 0;
-  dSP;
-  XRepodata *xd = new_XRepodata(data->repo, data - data->repo->repodata);
-
-  ENTER;
-  SAVETMPS;
-  PUSHMARK(SP);
-  XPUSHs(SWIG_NewPointerObj(SWIG_as_voidptr(xd), SWIGTYPE_p_XRepodata, SWIG_OWNER | SWIG_SHADOW));
-  PUTBACK;
-  count = perl_call_sv((SV *)d, G_EVAL|G_SCALAR);
-  SPAGAIN;
-  if (count)
-    ret = POPi;
-  PUTBACK;
-  FREETMPS;
-  LEAVE;
-  return ret;
-}
+%{
+  SWIGINTERN int loadcallback(Pool *pool, Repodata *data, void *d) {
+    int count;
+    int ret = 0;
+    dSP;
+    XRepodata *xd = new_XRepodata(data->repo, data - data->repo->repodata);
 
-  %}
+    ENTER;
+    SAVETMPS;
+    PUSHMARK(SP);
+    XPUSHs(SWIG_NewPointerObj(SWIG_as_voidptr(xd), SWIGTYPE_p_XRepodata, SWIG_OWNER | SWIG_SHADOW));
+    PUTBACK;
+    count = perl_call_sv((SV *)d, G_EVAL|G_SCALAR);
+    SPAGAIN;
+    if (count)
+      ret = POPi;
+    PUTBACK;
+    FREETMPS;
+    LEAVE;
+    return ret;
+  }
+%}
   void set_loadcallback(SV *callable) {
     if ($self->loadcallback == loadcallback)
       SvREFCNT_dec($self->loadcallbackdata);
@@ -849,16 +891,16 @@ SWIGINTERN int loadcallback(Pool *pool, Repodata *data, void *d) {
     pool_free($self);
   }
   Id str2id(const char *str, bool create=1) {
-    return str2id($self, str, create);
+    return pool_str2id($self, str, create);
   }
   const char *id2str(Id id) {
-    return id2str($self, id);
+    return pool_id2str($self, id);
   }
   const char *dep2str(Id id) {
-    return dep2str($self, id);
+    return pool_dep2str($self, id);
   }
   Id rel2id(Id name, Id evr, int flags, bool create=1) {
-    return rel2id($self, name, evr, flags, create);
+    return pool_rel2id($self, name, evr, flags, create);
   }
   Id id2langid(Id id, const char *lang, bool create=1) {
     return pool_id2langid($self, id, lang, create);
@@ -893,7 +935,7 @@ SWIGINTERN int loadcallback(Pool *pool, Repodata *data, void *d) {
     return new_Dataiterator($self, 0, p, key, match, flags);
   }
   const char *solvid2str(Id solvid) {
-    return solvid2str($self, solvid);
+    return pool_solvid2str($self, solvid);
   }
   void addfileprovides() {
     pool_addfileprovides($self);
@@ -913,6 +955,9 @@ SWIGINTERN int loadcallback(Pool *pool, Repodata *data, void *d) {
     pool_createwhatprovides($self);
   }
 
+  XSolvable *id2solvable(Id id) {
+    return new_XSolvable($self, id);
+  }
   %newobject solvables;
   Pool_solvable_iterator * const solvables;
   %{
@@ -925,6 +970,11 @@ SWIGINTERN int loadcallback(Pool *pool, Repodata *data, void *d) {
     return new_Pool_solvable_iterator($self);
   }
 
+  Repo *id2repo(Id id) {
+    if (id < 1 || id > $self->nrepos)
+      return 0;
+    return pool_id2repo($self, id);
+  }
   %newobject repos;
   Pool_repo_iterator * const repos;
   %{
@@ -947,15 +997,6 @@ SWIGINTERN int loadcallback(Pool *pool, Repodata *data, void *d) {
   }
   %}
 
-  Queue providerids(Id dep) {
-    Pool *pool = $self;
-    Queue q;
-    Id p, pp;
-    queue_init(&q);
-    FOR_PROVIDES(p, pp, dep)
-      queue_push(&q, p);
-    return q;
-  }
   Queue matchprovidingids(const char *match, int flags) {
     Pool *pool = $self;
     Queue q;
@@ -977,13 +1018,13 @@ SWIGINTERN int loadcallback(Pool *pool, Repodata *data, void *d) {
     return q;
   }
 
-  Job *Job(Id how, Id what) {
+  Job *Job(int how, Id what) {
     return new_Job($self, how, what);
   }
 
-  %typemap(out) Queue providers Queue2Array(XSolvable *, 1, new_XSolvable(arg1, id));
-  %newobject providers;
-  Queue providers(Id dep) {
+  %typemap(out) Queue whatprovides Queue2Array(XSolvable *, 1, new_XSolvable(arg1, id));
+  %newobject whatprovides;
+  Queue whatprovides(Id dep) {
     Pool *pool = $self;
     Queue q;
     Id p, pp;
@@ -996,6 +1037,7 @@ SWIGINTERN int loadcallback(Pool *pool, Repodata *data, void *d) {
   Id towhatprovides(Queue q) {
     return pool_queuetowhatprovides($self, &q);
   }
+
 #ifdef SWIGRUBY
   %rename("isknownarch?") isknownarch;
 #endif
@@ -1058,6 +1100,7 @@ SWIGINTERN int loadcallback(Pool *pool, Repodata *data, void *d) {
     repo_add_rpmmd($self, fp, language, flags);
     return 1;
   }
+#ifndef DEBIAN
   bool add_rpmdb(Repo *ref, int flags = 0) {
     repo_add_rpmdb($self, ref, 0, flags);
     return 1;
@@ -1065,6 +1108,14 @@ SWIGINTERN int loadcallback(Pool *pool, Repodata *data, void *d) {
   Id add_rpm(const char *name, int flags = 0) {
     return repo_add_rpm($self, name, flags);
   }
+#endif
+  bool add_debdb(int flags = 0) {
+    repo_add_debdb($self, 0, flags);
+    return 1;
+  }
+  Id add_deb(const char *name, int flags = 0) {
+    return repo_add_deb($self, name, flags);
+  }
   bool add_susetags(FILE *fp, Id defvendor, const char *language, int flags = 0) {
     repo_add_susetags($self, fp, defvendor, language, flags);
     return 1;
@@ -1101,7 +1152,7 @@ SWIGINTERN int loadcallback(Pool *pool, Repodata *data, void *d) {
     repo_write($self, fp, repo_write_stdkeyfilter, 0, 0);
   }
   # HACK, remove if no longer needed!
-  bool write_first_repodata(FILE *fp, int flags = 0) {
+  bool write_first_repodata(FILE *fp) {
     int oldnrepodata = $self->nrepodata;
     $self->nrepodata = 1;
     repo_write($self, fp, repo_write_stdkeyfilter, 0, 0);
@@ -1166,6 +1217,32 @@ SWIGINTERN int loadcallback(Pool *pool, Repodata *data, void *d) {
          return 0;       /* oops, not an extension */
      return new_XRepodata($self, 0);
    }
+
+  bool __eq__(Repo *repo) {
+    return $self == repo;
+  }
+  bool __ne__(Repo *repo) {
+    return $self != repo;
+  }
+  %newobject __str__;
+  const char *__str__() {
+    char buf[20];
+    if ($self->name)
+      return strdup($self->name);
+    sprintf(buf, "Repo#%d", $self->repoid);
+    return strdup(buf);
+  }
+  %newobject __repr__;
+  const char *__repr__() {
+    char buf[20];
+    if ($self->name)
+      {
+        sprintf(buf, "<Repo #%d ", $self->repoid);
+        return sat_dupjoin(buf, $self->name, ">");
+      }
+    sprintf(buf, "<Repo #%d>", $self->repoid);
+    return strdup(buf);
+  }
 }
 
 %extend Dataiterator {
@@ -1252,27 +1329,30 @@ SWIGINTERN int loadcallback(Pool *pool, Repodata *data, void *d) {
   const char *key_idstr() {
     return id2str($self->pool, $self->key->name);
   }
-  Id keytype_id() {
+  Id type_id() {
     return $self->key->type;
   }
-  const char *keytype_idstr() {
+  const char *type_idstr() {
     return id2str($self->pool, $self->key->type);
   }
-  Id match_id() {
+  Id id() {
      return $self->kv.id;
   }
-  const char *match_idstr() {
+  const char *idstr() {
      return id2str($self->pool, $self->kv.id);
   }
-  const char *match_str() {
+  const char *str() {
      return $self->kv.str;
   }
-  int match_num() {
+  int num() {
      return $self->kv.num;
   }
-  int match_num2() {
+  int num2() {
      return $self->kv.num2;
   }
+  void setpos() {
+    dataiterator_setpos($self);
+  }
   void setpos_parent() {
     dataiterator_setpos_parent($self);
   }
@@ -1451,9 +1531,9 @@ SWIGINTERN int loadcallback(Pool *pool, Repodata *data, void *d) {
   }
 }
 
-%extend XId {
-  XId(Pool *pool, Id id) {
-    XId *s;
+%extend Dep {
+  Dep(Pool *pool, Id id) {
+    Dep *s;
     if (!id)
       return 0;
     s = sat_calloc(1, sizeof(*s));
@@ -1464,12 +1544,27 @@ SWIGINTERN int loadcallback(Pool *pool, Repodata *data, void *d) {
   const char *str() {
     return dep2str($self->pool, $self->id);
   }
+  bool __eq__(Dep *s) {
+    return $self->pool == s->pool && $self->id == s->id;
+  }
+  bool __ne__(Dep *s) {
+    return !Dep___eq__($self, s);
+  }
+  const char *__str__() {
+    return dep2str($self->pool, $self->id);
+  }
+  %newobject __repr__;
+  const char *__repr__() {
+    char buf[20];
+    sprintf(buf, "<Id #%d ", $self->id);
+    return sat_dupjoin(buf, dep2str($self->pool, $self->id), ">");
+  }
 }
 
 %extend XSolvable {
   XSolvable(Pool *pool, Id id) {
     XSolvable *s;
-    if (!id)
+    if (!id || id >= pool->nsolvables)
       return 0;
     s = sat_calloc(1, sizeof(*s));
     s->pool = pool;
@@ -1477,7 +1572,7 @@ SWIGINTERN int loadcallback(Pool *pool, Repodata *data, void *d) {
     return s;
   }
   const char *str() {
-    return solvid2str($self->pool, $self->id);
+    return pool_solvid2str($self->pool, $self->id);
   }
   const char *lookup_str(Id keyname) {
     return pool_lookup_str($self->pool, $self->id, keyname);
@@ -1572,6 +1667,22 @@ SWIGINTERN int loadcallback(Pool *pool, Repodata *data, void *d) {
       return xs->pool->solvables[xs->id].repo;
     }
   %}
+
+  bool __eq__(XSolvable *s) {
+    return $self->pool == s->pool && $self->id == s->id;
+  }
+  bool __ne__(XSolvable *s) {
+    return !XSolvable___eq__($self, s);
+  }
+  const char *__str__() {
+    return pool_solvid2str($self->pool, $self->id);
+  }
+  %newobject __repr__;
+  const char *__repr__() {
+    char buf[20];
+    sprintf(buf, "<Solvable #%d ", $self->id);
+    return sat_dupjoin(buf, pool_solvid2str($self->pool, $self->id), ">");
+  }
 }
 
 %extend Problem {
@@ -2006,6 +2117,19 @@ rb_eval_string(
     solver_allruleinfos($self->solv, $self->id, &q);
     return q;
   }
+
+  bool __eq__(XRule *xr) {
+    return $self->solv == xr->solv && $self->id == xr->id;
+  }
+  bool __ne__(XRule *xr) {
+    return !XRule___eq__($self, xr);
+  }
+  %newobject __repr__;
+  const char *__repr__() {
+    char buf[20];
+    sprintf(buf, "<Rule #%d>", $self->id);
+    return strdup(buf);
+  }
 }
 
 %extend Ruleinfo {
@@ -2093,7 +2217,7 @@ rb_eval_string(
     int r, oldstate = data->state;
     data->state = REPODATA_LOADING;
     r = repo_add_solv_flags(data->repo, fp, flags | REPO_USE_LOADING);
-    if (r)
+    if (r || data->state == REPODATA_LOADING)
       data->state = oldstate;
     return r;
   }
@@ -2101,5 +2225,17 @@ rb_eval_string(
     Repodata *data = $self->repo->repodata + $self->id;
     repodata_extend_block(data, data->repo->start, data->repo->end - data->repo->start);
   }
+  bool __eq__(XRepodata *xr) {
+    return $self->repo == xr->repo && $self->id == xr->id;
+  }
+  bool __ne__(XRepodata *xr) {
+    return !XRepodata___eq__($self, xr);
+  }
+  %newobject __repr__;
+  const char *__repr__() {
+    char buf[20];
+    sprintf(buf, "<Repodata #%d>", $self->id);
+    return strdup(buf);
+  }
 }