- fix compilation with older python versions
[platform/upstream/libsolv.git] / bindings / solv.i
index bf59ccb..a5b9552 100644 (file)
   int size, i;
   VALUE *o;
   queue_init(&$1);
-  size = RARRAY($input)->len;
+  size = RARRAY_LEN($input);
   i = 0;
-  o = RARRAY($input)->ptr;
+  o = RARRAY_PTR($input);
   for (i = 0; i < size; i++, o++) {
     int v;
     int e = SWIG_AsVal_int(*o, &v);
@@ -299,7 +299,7 @@ SWIG_Perl_NewArrayObj(SWIG_MAYBE_PERL_OBJECT void *ptr, swig_type_info *t, int f
 #if defined(SWIGPYTHON)
 typedef PyObject *AppObjectPtr;
 %typemap(out) AppObjectPtr {
-  $result = $1;
+  $result = $1 ? $1 : Py_None;
   Py_INCREF($result);
 }
 #endif
@@ -344,20 +344,40 @@ typedef VALUE AppObjectPtr;
 #include "repo_solv.h"
 #include "chksum.h"
 
-#ifndef DEBIAN
+#include "repo_write.h"
+#ifdef ENABLE_RPMDB
 #include "repo_rpmdb.h"
 #endif
+#ifdef ENABLE_DEBIAN
 #include "repo_deb.h"
+#endif
+#ifdef ENABLE_RPMMD
 #include "repo_rpmmd.h"
-#include "repo_write.h"
-#include "repo_products.h"
-#include "repo_susetags.h"
 #include "repo_updateinfoxml.h"
 #include "repo_deltainfoxml.h"
 #include "repo_repomdxml.h"
+#endif
+#ifdef ENABLE_SUSEREPO
+#include "repo_products.h"
+#include "repo_susetags.h"
 #include "repo_content.h"
+#endif
+#ifdef ENABLE_MDKREPO
+#include "repo_mdk.h"
+#endif
+#ifdef ENABLE_ARCHREPO
+#include "repo_arch.h"
+#endif
 #include "solv_xfopen.h"
 
+/* for old ruby versions */
+#ifndef RARRAY_PTR
+#define RARRAY_PTR(ary) (RARRAY(ary)->ptr)
+#endif
+#ifndef RARRAY_LEN
+#define RARRAY_LEN(ary) (RARRAY(ary)->len)
+#endif
+
 #define true 1
 #define false 1
 
@@ -536,7 +556,7 @@ typedef struct {
 
 %nodefaultctor Repo;
 %nodefaultdtor Repo;
-typedef struct _Repo {
+typedef struct {
   Pool * const pool;
   const char * const name;
   int priority;
@@ -549,23 +569,9 @@ typedef struct _Repo {
 %nodefaultdtor Solver;
 typedef struct {
   Pool * const pool;
-  bool fixsystem;
-  bool allowdowngrade;
-  bool allowarchchange;
-  bool allowvendorchange;
-  bool allowuninstall;
-  bool updatesystem;
-  bool noupdateprovide;
-  bool dosplitprovides;
-  bool dontinstallrecommended;
-  bool ignorealreadyrecommended;
-  bool dontshowinstalledrecommended;
-  bool distupgrade;
-  bool distupgrade_removeunsupported;
-  bool noinfarchcheck;
 } Solver;
 
-typedef struct chksum {
+typedef struct {
 } Chksum;
 
 %rename(xfopen) solv_xfopen;
@@ -813,10 +819,16 @@ typedef struct {
   void set_debuglevel(int level) {
     pool_setdebuglevel($self, level);
   }
+  int set_flag(int flag, int value) {
+    return pool_set_flag($self, flag, value);
+  }
+  int get_flag(int flag) {
+    return pool_get_flag($self, flag);
+  }
 #if defined(SWIGPYTHON)
   %{
   SWIGINTERN int loadcallback(Pool *pool, Repodata *data, void *d) {
-    XRepodata *xd = new_XRepodata(data->repo, data - data->repo->repodata);
+    XRepodata *xd = new_XRepodata(data->repo, data->repodataid);
     PyObject *args = Py_BuildValue("(O)", SWIG_NewPointerObj(SWIG_as_voidptr(xd), SWIGTYPE_p_XRepodata, SWIG_POINTER_OWN | 0));
     PyObject *result = PyEval_CallObject((PyObject *)d, args);
     int ecode = 0;
@@ -831,7 +843,8 @@ typedef struct {
   %}
   void set_loadcallback(PyObject *callable) {
     if ($self->loadcallback == loadcallback) {
-      Py_DECREF($self->loadcallbackdata);
+      PyObject *obj = $self->loadcallbackdata;
+      Py_DECREF(obj);
     }
     if (callable) {
       Py_INCREF(callable);
@@ -845,7 +858,7 @@ typedef struct {
     int count;
     int ret = 0;
     dSP;
-    XRepodata *xd = new_XRepodata(data->repo, data - data->repo->repodata);
+    XRepodata *xd = new_XRepodata(data->repo, data->repodataid);
 
     ENTER;
     SAVETMPS;
@@ -874,7 +887,7 @@ typedef struct {
 #if defined(SWIGRUBY)
 %{
   SWIGINTERN int loadcallback(Pool *pool, Repodata *data, void *d) {
-    XRepodata *xd = new_XRepodata(data->repo, data - data->repo->repodata);
+    XRepodata *xd = new_XRepodata(data->repo, data->repodataid);
     VALUE callable = (VALUE)d;
     VALUE rd = SWIG_NewPointerObj(SWIG_as_voidptr(xd), SWIGTYPE_p_XRepodata, SWIG_POINTER_OWN | 0);
     VALUE res = rb_funcall(callable, rb_intern("call"), 1, rd);
@@ -903,6 +916,10 @@ typedef struct {
   Id str2id(const char *str, bool create=1) {
     return pool_str2id($self, str, create);
   }
+  Dep *Dep(const char *str, bool create=1) {
+    Id id = pool_str2id($self, str, create);
+    return new_Dep($self, id);
+  }
   const char *id2str(Id id) {
     return pool_id2str($self, id);
   }
@@ -950,15 +967,10 @@ typedef struct {
   void addfileprovides() {
     pool_addfileprovides($self);
   }
-  Queue addfileprovides_ids() {
+  Queue addfileprovides_queue() {
     Queue r;
-    Id *addedfileprovides = 0;
     queue_init(&r);
-    pool_addfileprovides_ids($self, $self->installed, &addedfileprovides);
-    if (addedfileprovides) {
-      for (; *addedfileprovides; addedfileprovides++)
-        queue_push(&r, *addedfileprovides);
-    }
+    pool_addfileprovides_queue($self, &r, 0);
     return r;
   }
   void createwhatprovides() {
@@ -981,7 +993,7 @@ typedef struct {
   }
 
   Repo *id2repo(Id id) {
-    if (id < 1 || id > $self->nrepos)
+    if (id < 1 || id >= $self->nrepos)
       return 0;
     return pool_id2repo($self, id);
   }
@@ -1075,8 +1087,9 @@ typedef struct {
   static const int REPO_USE_LOADING = REPO_USE_LOADING;
   static const int REPO_EXTEND_SOLVABLES = REPO_EXTEND_SOLVABLES;
   static const int SOLV_ADD_NO_STUBS = SOLV_ADD_NO_STUBS;       /* repo_solv */
-  static const int SUSETAGS_RECORD_SHARES = SUSETAGS_RECORD_SHARES; /* repo_susetags */
-  static const int SOLV_ADD_NO_STUBS = SOLV_ADD_NO_STUBS ; /* repo_solv */
+#ifdef ENABLE_SUSEREPO
+  static const int SUSETAGS_RECORD_SHARES = SUSETAGS_RECORD_SHARES;     /* repo_susetags */
+#endif
 
   void free(bool reuseids = 0) {
     repo_free($self, reuseids);
@@ -1095,30 +1108,47 @@ typedef struct {
     int r;
     if (!fp)
       return 0;
-    r = repo_add_solv_flags($self, fp, flags);
+    r = repo_add_solv($self, fp, flags);
     fclose(fp);
     return r == 0;
   }
   bool add_solv(FILE *fp, int flags = 0) {
-    return repo_add_solv_flags($self, fp, flags) == 0;
+    return repo_add_solv($self, fp, flags) == 0;
   }
-  bool add_products(const char *proddir, int flags = 0) {
-    repo_add_products($self, proddir, 0, flags);
+
+  XSolvable *add_solvable() {
+    Id solvid = repo_add_solvable($self);
+    return new_XSolvable($self->pool, solvid);
+  }
+
+#ifdef ENABLE_RPMDB
+  bool add_rpmdb(Repo *ref, int flags = 0) {
+    repo_add_rpmdb($self, ref, 0, flags);
     return 1;
   }
+  Id add_rpm(const char *name, int flags = 0) {
+    return repo_add_rpm($self, name, flags);
+  }
+#endif
+#ifdef ENABLE_RPMMD
   bool add_rpmmd(FILE *fp, const char *language, int flags = 0) {
     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);
+  bool add_repomdxml(FILE *fp, int flags = 0) {
+    repo_add_repomdxml($self, fp, flags);
     return 1;
   }
-  Id add_rpm(const char *name, int flags = 0) {
-    return repo_add_rpm($self, name, flags);
+  bool add_updateinfoxml(FILE *fp, int flags = 0) {
+    repo_add_updateinfoxml($self, fp, flags);
+    return 1;
+  }
+  bool add_deltainfoxml(FILE *fp, int flags = 0) {
+    repo_add_deltainfoxml($self, fp, flags);
+    return 1;
   }
 #endif
+#ifdef ENABLE_DEBIAN
   bool add_debdb(int flags = 0) {
     repo_add_debdb($self, 0, flags);
     return 1;
@@ -1126,26 +1156,40 @@ typedef struct {
   Id add_deb(const char *name, int flags = 0) {
     return repo_add_deb($self, name, flags);
   }
+#endif
+#ifdef ENABLE_SUSEREPO
   bool add_susetags(FILE *fp, Id defvendor, const char *language, int flags = 0) {
     repo_add_susetags($self, fp, defvendor, language, flags);
     return 1;
   }
-  bool add_repomdxml(FILE *fp, int flags = 0) {
-    repo_add_repomdxml($self, fp, flags);
-    return 1;
-  }
   bool add_content(FILE *fp, int flags = 0) {
     repo_add_content($self, fp, flags);
     return 1;
   }
-  bool add_updateinfoxml(FILE *fp, int flags = 0) {
-    repo_add_updateinfoxml($self, fp, flags);
+  bool add_products(const char *proddir, int flags = 0) {
+    repo_add_products($self, proddir, 0, flags);
     return 1;
   }
-  bool add_deltainfoxml(FILE *fp, int flags = 0) {
-    repo_add_deltainfoxml($self, fp, flags);
+#endif
+#ifdef ENABLE_MDKREPO
+  bool add_mdk(FILE *fp, int flags = 0) {
+    repo_add_mdk($self, fp, flags);
+    return 1;
+  }
+  bool add_mdk_info(FILE *fp, int flags = 0) {
+    repo_add_mdk($self, fp, flags);
     return 1;
   }
+#endif
+#ifdef ENABLE_ARCHREPO
+  bool add_arch_repo(FILE *fp, int flags = 0) {
+    repo_add_arch_repo($self, fp, flags);
+    return 1;
+  }
+  Id add_arch_pkg(const char *name, int flags = 0) {
+    return repo_add_arch_pkg($self, name, flags);
+  }
+#endif
   void internalize() {
     repo_internalize($self);
   }
@@ -1155,17 +1199,17 @@ typedef struct {
   Id lookup_id(Id entry, Id keyname) {
     return repo_lookup_id($self, entry, keyname);
   }
-  unsigned int lookup_num(Id entry, Id keyname, unsigned int notfound = 0) {
+  unsigned long long lookup_num(Id entry, Id keyname, unsigned long long notfound = 0) {
     return repo_lookup_num($self, entry, keyname, notfound);
   }
   void write(FILE *fp) {
-    repo_write($self, fp, repo_write_stdkeyfilter, 0, 0);
+    repo_write($self, fp);
   }
   # HACK, remove if no longer needed!
   bool write_first_repodata(FILE *fp) {
     int oldnrepodata = $self->nrepodata;
-    $self->nrepodata = 1;
-    repo_write($self, fp, repo_write_stdkeyfilter, 0, 0);
+    $self->nrepodata = oldnrepodata > 2 ? 2 : oldnrepodata;
+    repo_write($self, fp);
     $self->nrepodata = oldnrepodata;
     return 1;
   }
@@ -1194,14 +1238,14 @@ typedef struct {
 
   XRepodata *add_repodata(int flags = 0) {
     Repodata *rd = repo_add_repodata($self, flags);
-    return new_XRepodata($self, rd - $self->repodata);
+    return new_XRepodata($self, rd->repodataid);
   }
 
   void create_stubs() {
     Repodata *data;
     if (!$self->nrepodata)
       return;
-    data = $self->repodata  + ($self->nrepodata - 1);
+    data = repo_id2repodata($self, $self->nrepodata - 1);
     if (data->state != REPODATA_STUB)
       repodata_create_stubs(data);
   }
@@ -1216,17 +1260,22 @@ typedef struct {
     return 1;
   }
   XRepodata *first_repodata() {
-     int i;
-     if (!$self->nrepodata)
+    Repodata *data;
+    int i;
+    if ($self->nrepodata < 2)
+      return 0;
+    /* make sure all repodatas but the first are extensions */
+    data = repo_id2repodata($self, 1);
+    if (data->loadcallback)
        return 0;
-     /* make sure all repodatas but the first are extensions */
-     if ($self->repodata[0].loadcallback)
-        return 0;
-     for (i = 1; i < $self->nrepodata; i++)
-       if (!$self->repodata[i].loadcallback)
-         return 0;       /* oops, not an extension */
-     return new_XRepodata($self, 0);
-   }
+    for (i = 2; i < $self->nrepodata; i++)
+      {
+        data = repo_id2repodata($self, i);
+        if (!data->loadcallback)
+          return 0;       /* oops, not an extension */
+      }
+    return new_XRepodata($self, 1);
+  }
 
   bool __eq__(Repo *repo) {
     return $self == repo;
@@ -1241,9 +1290,9 @@ typedef struct {
   const char *__str__() {
     char buf[20];
     if ($self->name)
-      return strdup($self->name);
+      return solv_strdup($self->name);
     sprintf(buf, "Repo#%d", $self->repoid);
-    return strdup(buf);
+    return solv_strdup(buf);
   }
   %newobject __repr__;
   const char *__repr__() {
@@ -1254,7 +1303,7 @@ typedef struct {
         return solv_dupjoin(buf, $self->name, ">");
       }
     sprintf(buf, "<Repo #%d>", $self->repoid);
-    return strdup(buf);
+    return solv_strdup(buf);
   }
 }
 
@@ -1324,6 +1373,38 @@ typedef struct {
   }
 }
 
+%extend Datapos {
+  Id lookup_id(Id keyname) {
+    Pool *pool = $self->repo->pool;
+    Datapos oldpos = pool->pos;
+    Id r;
+    pool->pos = *$self;
+    r = pool_lookup_id(pool, SOLVID_POS, keyname);
+    pool->pos = oldpos;
+    return r;
+  }
+  const char *lookup_str(Id keyname) {
+    Pool *pool = $self->repo->pool;
+    Datapos oldpos = pool->pos;
+    const char *r;
+    pool->pos = *$self;
+    r = pool_lookup_str(pool, SOLVID_POS, keyname);
+    pool->pos = oldpos;
+    return r;
+  }
+  %newobject lookup_checksum;
+  Chksum *lookup_checksum(Id keyname) {
+    Pool *pool = $self->repo->pool;
+    Datapos oldpos = pool->pos;
+    Id type = 0;
+    const unsigned char *b;
+    pool->pos = *$self;
+    b = pool_lookup_bin_checksum(pool, SOLVID_POS, keyname, &type);
+    pool->pos = oldpos;
+    return solv_chksum_create_from_bin(type, b);
+  }
+}
+
 %extend Datamatch {
   ~Datamatch() {
     dataiterator_free($self);
@@ -1363,6 +1444,26 @@ typedef struct {
   int num2() {
      return $self->kv.num2;
   }
+  %newobject pos;
+  Datapos *pos() {
+    Pool *pool = $self->pool;
+    Datapos *pos, oldpos = pool->pos;
+    dataiterator_setpos($self);
+    pos = solv_calloc(1, sizeof(*pos));
+    *pos = pool->pos;
+    pool->pos = oldpos;
+    return pos;
+  }
+  %newobject parentpos;
+  Datapos *parentpos() {
+    Pool *pool = $self->pool;
+    Datapos *pos, oldpos = pool->pos;
+    dataiterator_setpos_parent($self);
+    pos = solv_calloc(1, sizeof(*pos));
+    *pos = pool->pos;
+    pool->pos = oldpos;
+    return pos;
+  }
   void setpos() {
     dataiterator_setpos($self);
   }
@@ -1456,9 +1557,9 @@ typedef struct {
   %newobject __next__;
   Repo *__next__() {
     Pool *pool = $self->pool;
-    if ($self->id >= pool->nrepos + 1)
+    if ($self->id >= pool->nrepos)
       return 0;
-    while (++$self->id < pool->nrepos + 1) {
+    while (++$self->id < pool->nrepos) {
       Repo *r = pool_id2repo(pool, $self->id);
       if (r)
         return r;
@@ -1469,18 +1570,18 @@ typedef struct {
   void each() {
     Repo *n;
     while ((n = Pool_repo_iterator___next__($self)) != 0) {
-      rb_yield(SWIG_NewPointerObj(SWIG_as_voidptr(n), SWIGTYPE_p__Repo, SWIG_POINTER_OWN | 0));
+      rb_yield(SWIG_NewPointerObj(SWIG_as_voidptr(n), SWIGTYPE_p_Repo, SWIG_POINTER_OWN | 0));
     }
   }
 #endif
   Repo *__getitem__(Id key) {
     Pool *pool = $self->pool;
-    if (key > 0 && key < pool->nrepos + 1)
+    if (key > 0 && key < pool->nrepos)
       return pool_id2repo(pool, key);
     return 0;
   }
   int __len__() {
-    return $self->pool->nrepos + 1;
+    return $self->pool->nrepos;
   }
 }
 
@@ -1594,7 +1695,7 @@ typedef struct {
   Id lookup_id(Id keyname) {
     return pool_lookup_id($self->pool, $self->id, keyname);
   }
-  unsigned int lookup_num(Id keyname, unsigned int notfound = 0) {
+  unsigned long long lookup_num(Id keyname, unsigned long long notfound = 0) {
     return pool_lookup_num($self->pool, $self->id, keyname, notfound);
   }
   bool lookup_void(Id keyname) {
@@ -1606,6 +1707,38 @@ typedef struct {
     const unsigned char *b = pool_lookup_bin_checksum($self->pool, $self->id, keyname, &type);
     return solv_chksum_create_from_bin(type, b);
   }
+  Queue lookup_idarray(Id keyname, Id marker = 1) {
+    Solvable *s = $self->pool->solvables + $self->id;
+    Queue r;
+    queue_init(&r);
+    if (marker == 1) {
+      if (keyname == SOLVABLE_PROVIDES)
+        marker = -SOLVABLE_FILEMARKER;
+      else if (keyname == SOLVABLE_REQUIRES)
+        marker = -SOLVABLE_PREREQMARKER;
+      else
+        marker = 0;
+    }
+    solvable_lookup_deparray(s, keyname, &r, marker);
+    return r;
+  }
+  %typemap(out) Queue lookup_deparray Queue2Array(Dep *, 1, new_Dep(arg1->pool, id));
+  %newobject lookup_deparray;
+  Queue lookup_deparray(Id keyname, Id marker = 1) {
+    Solvable *s = $self->pool->solvables + $self->id;
+    Queue r;
+    queue_init(&r);
+    if (marker == 1) {
+      if (keyname == SOLVABLE_PROVIDES)
+        marker = -SOLVABLE_FILEMARKER;
+      else if (keyname == SOLVABLE_REQUIRES)
+        marker = -SOLVABLE_PREREQMARKER;
+      else
+        marker = 0;
+    }
+    solvable_lookup_deparray(s, keyname, &r, marker);
+    return r;
+  }
   const char *lookup_location(unsigned int *OUTPUT) {
     return solvable_get_location($self->pool->solvables + $self->id, OUTPUT);
   }
@@ -1623,54 +1756,82 @@ typedef struct {
     return pool->installed && pool_id2solvable(pool, $self->id)->repo == pool->installed;
   }
 
-  const char * const name;
+  const char *name;
   %{
+    SWIGINTERN void XSolvable_name_set(XSolvable *xs, const char *name) {
+      Pool *pool = xs->pool;
+      pool->solvables[xs->id].name = pool_str2id(pool, name, 1);
+    }
     SWIGINTERN const char *XSolvable_name_get(XSolvable *xs) {
       Pool *pool = xs->pool;
       return pool_id2str(pool, pool->solvables[xs->id].name);
     }
   %}
-  Id const nameid;
+  Id nameid;
   %{
+    SWIGINTERN void XSolvable_nameid_set(XSolvable *xs, Id nameid) {
+      xs->pool->solvables[xs->id].name = nameid;
+    }
     SWIGINTERN Id XSolvable_nameid_get(XSolvable *xs) {
       return xs->pool->solvables[xs->id].name;
     }
   %}
-  const char * const evr;
+  const char *evr;
   %{
+    SWIGINTERN void XSolvable_evr_set(XSolvable *xs, const char *evr) {
+      Pool *pool = xs->pool;
+      pool->solvables[xs->id].evr = pool_str2id(pool, evr, 1);
+    }
     SWIGINTERN const char *XSolvable_evr_get(XSolvable *xs) {
       Pool *pool = xs->pool;
       return pool_id2str(pool, pool->solvables[xs->id].evr);
     }
   %}
-  Id const evrid;
+  Id evrid;
   %{
+    SWIGINTERN void XSolvable_evrid_set(XSolvable *xs, Id evrid) {
+      xs->pool->solvables[xs->id].evr = evrid;
+    }
     SWIGINTERN Id XSolvable_evrid_get(XSolvable *xs) {
       return xs->pool->solvables[xs->id].evr;
     }
   %}
-  const char * const arch;
+  const char *arch;
   %{
+    SWIGINTERN void XSolvable_arch_set(XSolvable *xs, const char *arch) {
+      Pool *pool = xs->pool;
+      pool->solvables[xs->id].arch = pool_str2id(pool, arch, 1);
+    }
     SWIGINTERN const char *XSolvable_arch_get(XSolvable *xs) {
       Pool *pool = xs->pool;
       return pool_id2str(pool, pool->solvables[xs->id].arch);
     }
   %}
-  Id const archid;
+  Id archid;
   %{
+    SWIGINTERN void XSolvable_archid_set(XSolvable *xs, Id archid) {
+      xs->pool->solvables[xs->id].arch = archid;
+    }
     SWIGINTERN Id XSolvable_archid_get(XSolvable *xs) {
       return xs->pool->solvables[xs->id].arch;
     }
   %}
-  const char * const vendor;
+  const char *vendor;
   %{
+    SWIGINTERN void XSolvable_vendor_set(XSolvable *xs, const char *vendor) {
+      Pool *pool = xs->pool;
+      pool->solvables[xs->id].vendor = pool_str2id(pool, vendor, 1);
+    }
     SWIGINTERN const char *XSolvable_vendor_get(XSolvable *xs) {
       Pool *pool = xs->pool;
       return pool_id2str(pool, pool->solvables[xs->id].vendor);
     }
   %}
-  Id const vendorid;
+  Id vendorid;
   %{
+    SWIGINTERN void XSolvable_vendorid_set(XSolvable *xs, Id vendorid) {
+      xs->pool->solvables[xs->id].vendor = vendorid;
+    }
     SWIGINTERN Id XSolvable_vendorid_get(XSolvable *xs) {
       return xs->pool->solvables[xs->id].vendor;
     }
@@ -1682,6 +1843,71 @@ typedef struct {
     }
   %}
 
+  void add_provides(Dep *dep, Id marker = -SOLVABLE_FILEMARKER) {
+    Solvable *s = $self->pool->solvables + $self->id;
+    s->provides = repo_addid_dep(s->repo, s->provides, dep->id, marker);
+  }
+  void add_providesid(Id id, Id marker = -SOLVABLE_FILEMARKER) {
+    Solvable *s = $self->pool->solvables + $self->id;
+    s->provides = repo_addid_dep(s->repo, s->provides, id, marker);
+  }
+  void add_obsoletes(Dep *dep) {
+    Solvable *s = $self->pool->solvables + $self->id;
+    s->obsoletes = repo_addid_dep(s->repo, s->obsoletes, dep->id, 0);
+  }
+  void add_obsoletesid(Id id) {
+    Solvable *s = $self->pool->solvables + $self->id;
+    s->obsoletes = repo_addid_dep(s->repo, s->obsoletes, id, 0);
+  }
+  void add_conflicts(Dep *dep) {
+    Solvable *s = $self->pool->solvables + $self->id;
+    s->conflicts = repo_addid_dep(s->repo, s->conflicts, dep->id, 0);
+  }
+  void add_conflictsid(Id id) {
+    Solvable *s = $self->pool->solvables + $self->id;
+    s->conflicts = repo_addid_dep(s->repo, s->conflicts, id, 0);
+  }
+  void add_requires(Dep *dep, Id marker = -SOLVABLE_PREREQMARKER) {
+    Solvable *s = $self->pool->solvables + $self->id;
+    s->requires = repo_addid_dep(s->repo, s->requires, dep->id, marker);
+  }
+  void add_requiresid(Id id, Id marker = -SOLVABLE_PREREQMARKER) {
+    Solvable *s = $self->pool->solvables + $self->id;
+    s->requires = repo_addid_dep(s->repo, s->requires, id, marker);
+  }
+  void add_recommends(Dep *dep) {
+    Solvable *s = $self->pool->solvables + $self->id;
+    s->recommends = repo_addid_dep(s->repo, s->recommends, dep->id, 0);
+  }
+  void add_recommendsid(Id id) {
+    Solvable *s = $self->pool->solvables + $self->id;
+    s->recommends = repo_addid_dep(s->repo, s->recommends, id, 0);
+  }
+  void add_suggests(Dep *dep) {
+    Solvable *s = $self->pool->solvables + $self->id;
+    s->suggests = repo_addid_dep(s->repo, s->suggests, dep->id, 0);
+  }
+  void add_suggestsid(Id id) {
+    Solvable *s = $self->pool->solvables + $self->id;
+    s->suggests = repo_addid_dep(s->repo, s->suggests, id, 0);
+  }
+  void add_supplements(Dep *dep) {
+    Solvable *s = $self->pool->solvables + $self->id;
+    s->supplements = repo_addid_dep(s->repo, s->supplements, dep->id, 0);
+  }
+  void add_supplementsid(Id id) {
+    Solvable *s = $self->pool->solvables + $self->id;
+    s->supplements = repo_addid_dep(s->repo, s->supplements, id, 0);
+  }
+  void add_enhances(Dep *dep) {
+    Solvable *s = $self->pool->solvables + $self->id;
+    s->enhances = repo_addid_dep(s->repo, s->enhances, dep->id, 0);
+  }
+  void add_enhancesid(Id id) {
+    Solvable *s = $self->pool->solvables + $self->id;
+    s->enhances = repo_addid_dep(s->repo, s->enhances, id, 0);
+  }
+
   bool __eq__(XSolvable *s) {
     return $self->pool == s->pool && $self->id == s->id;
   }
@@ -1728,8 +1954,10 @@ typedef struct {
       {
         for (i = j = 0; i < q.count; i++)
           {
+            SolverRuleinfo rclass;
             probr = q.elements[i];
-            if ((probr >= solv->updaterules && probr < solv->updaterules_end) || (probr >= solv->jobrules && probr < solv->jobrules_end))
+            rclass = solver_ruleclass(solv, probr);
+            if (rclass == SOLVER_RULE_UPDATE || rclass == SOLVER_RULE_JOB)
               continue;
             q.elements[j++] = probr;
           }
@@ -1883,17 +2111,22 @@ typedef struct {
       return new_XSolvable(e->solv->pool, e->rp);
     }
     SWIGINTERN int Solutionelement_jobidx_get(Solutionelement *e) {
+      if (e->type != SOLVER_SOLUTION_JOB)
+        return -1;
       return (e->p - 1) / 2;
     }
   %}
   %newobject Job;
   Job *Job() {
+    Id extraflags = solver_solutionelement_extrajobflags($self->solv, $self->problemid, $self->solutionid);
+    if ($self->type == SOLVER_SOLUTION_JOB)
+      return new_Job($self->solv->pool, SOLVER_NOOP, 0);
     if ($self->type == SOLVER_SOLUTION_INFARCH || $self->type == SOLVER_SOLUTION_DISTUPGRADE)
-      return new_Job($self->solv->pool, SOLVER_INSTALL|SOLVER_SOLVABLE, $self->p);
+      return new_Job($self->solv->pool, SOLVER_INSTALL|SOLVER_SOLVABLE|extraflags, $self->p);
     if ($self->type == SOLVER_SOLUTION_REPLACE || $self->type == SOLVER_SOLUTION_REPLACE_DOWNGRADE || $self->type == SOLVER_SOLUTION_REPLACE_ARCHCHANGE || $self->type == SOLVER_SOLUTION_REPLACE_VENDORCHANGE)
-      return new_Job($self->solv->pool, SOLVER_INSTALL|SOLVER_SOLVABLE, $self->rp);
+      return new_Job($self->solv->pool, SOLVER_INSTALL|SOLVER_SOLVABLE|extraflags, $self->rp);
     if ($self->type == SOLVER_SOLUTION_ERASE)
-      return new_Job($self->solv->pool, SOLVER_ERASE|SOLVER_SOLVABLE, $self->p);
+      return new_Job($self->solv->pool, SOLVER_ERASE|SOLVER_SOLVABLE|extraflags, $self->p);
     return 0;
   }
 }
@@ -1932,9 +2165,26 @@ typedef struct {
   static const int POLICY_ILLEGAL_ARCHCHANGE = POLICY_ILLEGAL_ARCHCHANGE;
   static const int POLICY_ILLEGAL_VENDORCHANGE = POLICY_ILLEGAL_VENDORCHANGE;
 
+  static const int SOLVER_FLAG_ALLOW_DOWNGRADE = SOLVER_FLAG_ALLOW_DOWNGRADE;
+  static const int SOLVER_FLAG_ALLOW_ARCHCHANGE = SOLVER_FLAG_ALLOW_ARCHCHANGE;
+  static const int SOLVER_FLAG_ALLOW_VENDORCHANGE = SOLVER_FLAG_ALLOW_VENDORCHANGE;
+  static const int SOLVER_FLAG_ALLOW_UNINSTALL = SOLVER_FLAG_ALLOW_UNINSTALL;
+  static const int SOLVER_FLAG_NO_UPDATEPROVIDE = SOLVER_FLAG_NO_UPDATEPROVIDE;
+  static const int SOLVER_FLAG_SPLITPROVIDES = SOLVER_FLAG_SPLITPROVIDES;
+  static const int SOLVER_FLAG_IGNORE_RECOMMENDED = SOLVER_FLAG_IGNORE_RECOMMENDED;
+  static const int SOLVER_FLAG_ADD_ALREADY_RECOMMENDED = SOLVER_FLAG_ADD_ALREADY_RECOMMENDED;
+  static const int SOLVER_FLAG_NO_INFARCHCHECK = SOLVER_FLAG_NO_INFARCHCHECK;
+
   ~Solver() {
     solver_free($self);
   }
+
+  int set_flag(int flag, int value) {
+    return solver_set_flag($self, flag, value);
+  }
+  int get_flag(int flag) {
+    return solver_get_flag($self, flag);
+  }
 #if defined(SWIGPYTHON)
   %pythoncode {
     def solve(self, jobs):
@@ -2141,7 +2391,7 @@ rb_eval_string(
   const char *__repr__() {
     char buf[20];
     sprintf(buf, "<Rule #%d>", $self->id);
-    return strdup(buf);
+    return solv_strdup(buf);
   }
 }
 
@@ -2179,63 +2429,63 @@ rb_eval_string(
     return xr;
   }
   Id new_handle() {
-    return repodata_new_handle($self->repo->repodata + $self->id);
+    return repodata_new_handle(repo_id2repodata($self->repo, $self->id));
   }
   void set_id(Id solvid, Id keyname, Id id) {
-    repodata_set_id($self->repo->repodata + $self->id, solvid, keyname, id);
+    repodata_set_id(repo_id2repodata($self->repo, $self->id), solvid, keyname, id);
   }
   void set_str(Id solvid, Id keyname, const char *str) {
-    repodata_set_str($self->repo->repodata + $self->id, solvid, keyname, str);
+    repodata_set_str(repo_id2repodata($self->repo, $self->id), solvid, keyname, str);
   }
   void set_poolstr(Id solvid, Id keyname, const char *str) {
-    repodata_set_poolstr($self->repo->repodata + $self->id, solvid, keyname, str);
+    repodata_set_poolstr(repo_id2repodata($self->repo, $self->id), solvid, keyname, str);
   }
   void add_idarray(Id solvid, Id keyname, Id id) {
-    repodata_add_idarray($self->repo->repodata + $self->id, solvid, keyname, id);
+    repodata_add_idarray(repo_id2repodata($self->repo, $self->id), solvid, keyname, id);
   }
   void add_flexarray(Id solvid, Id keyname, Id handle) {
-    repodata_add_flexarray($self->repo->repodata + $self->id, solvid, keyname, handle);
+    repodata_add_flexarray(repo_id2repodata($self->repo, $self->id), solvid, keyname, handle);
   }
   void set_checksum(Id solvid, Id keyname, Chksum *chksum) {
     const unsigned char *buf = solv_chksum_get(chksum, 0);
     if (buf)
-      repodata_set_bin_checksum($self->repo->repodata + $self->id, solvid, keyname, solv_chksum_get_type(chksum), buf);
+      repodata_set_bin_checksum(repo_id2repodata($self->repo, $self->id), solvid, keyname, solv_chksum_get_type(chksum), buf);
   }
   const char *lookup_str(Id solvid, Id keyname) {
-    return repodata_lookup_str($self->repo->repodata + $self->id, solvid, keyname);
+    return repodata_lookup_str(repo_id2repodata($self->repo, $self->id), solvid, keyname);
   }
   Queue lookup_idarray(Id solvid, Id keyname) {
     Queue r;
     queue_init(&r);
-    repodata_lookup_idarray($self->repo->repodata + $self->id, solvid, keyname, &r);
+    repodata_lookup_idarray(repo_id2repodata($self->repo, $self->id), solvid, keyname, &r);
     return r;
   }
   %newobject lookup_checksum;
   Chksum *lookup_checksum(Id solvid, Id keyname) {
     Id type = 0;
-    const unsigned char *b = repodata_lookup_bin_checksum($self->repo->repodata + $self->id, solvid, keyname, &type);
+    const unsigned char *b = repodata_lookup_bin_checksum(repo_id2repodata($self->repo, $self->id), solvid, keyname, &type);
     return solv_chksum_create_from_bin(type, b);
   }
   void internalize() {
-    repodata_internalize($self->repo->repodata + $self->id);
+    repodata_internalize(repo_id2repodata($self->repo, $self->id));
   }
   void create_stubs() {
-    repodata_create_stubs($self->repo->repodata + $self->id);
+    repodata_create_stubs(repo_id2repodata($self->repo, $self->id));
   }
   void write(FILE *fp) {
-    repodata_write($self->repo->repodata + $self->id, fp, repo_write_stdkeyfilter, 0);
+    repodata_write(repo_id2repodata($self->repo, $self->id), fp);
   }
   bool add_solv(FILE *fp, int flags = 0) {
-    Repodata *data = $self->repo->repodata + $self->id;
+    Repodata *data = repo_id2repodata($self->repo, $self->id);
     int r, oldstate = data->state;
     data->state = REPODATA_LOADING;
-    r = repo_add_solv_flags(data->repo, fp, flags | REPO_USE_LOADING);
+    r = repo_add_solv(data->repo, fp, flags | REPO_USE_LOADING);
     if (r || data->state == REPODATA_LOADING)
       data->state = oldstate;
     return r;
   }
   void extend_to_repo() {
-    Repodata *data = $self->repo->repodata + $self->id;
+    Repodata *data = repo_id2repodata($self->repo, $self->id);
     repodata_extend_block(data, data->repo->start, data->repo->end - data->repo->start);
   }
   bool __eq__(XRepodata *xr) {
@@ -2248,7 +2498,7 @@ rb_eval_string(
   const char *__repr__() {
     char buf[20];
     sprintf(buf, "<Repodata #%d>", $self->id);
-    return strdup(buf);
+    return solv_strdup(buf);
   }
 }