add repo_add_rpmdb_reffp to easily add rpmdb content when there is an old solv file
[platform/upstream/libsolv.git] / src / repo.c
index 9f6d426..9ea328f 100644 (file)
@@ -218,6 +218,54 @@ repo_free_solvable_block(Repo *repo, Id start, int count, int reuseids)
     }
 }
 
+/* specialized version of repo_add_solvable_block that inserts the new solvable
+ * block before the indicated repo, which gets relocated.
+ * used in repo_add_rpmdb
+ */
+Id
+repo_add_solvable_block_before(Repo *repo, int count, Repo *beforerepo)
+{
+  Pool *pool = repo->pool;
+  Id p;
+  Solvable *s;
+  Repodata *data;
+  int i;
+
+  if (!count || !beforerepo || beforerepo->end != pool->nsolvables || beforerepo->start == beforerepo->end)
+    return repo_add_solvable_block(repo, count);
+  p = beforerepo->start;
+  /* make sure all solvables belong to beforerepo */
+  for (i = p, s = pool->solvables + i; i < beforerepo->end; i++, s++)
+    if (s->repo && s->repo != beforerepo)
+      return repo_add_solvable_block(repo, count);
+  /* now move beforerepo to back */
+  pool_add_solvable_block(pool, count);        /* must return beforerepo->end! */
+  memmove(pool->solvables + p + count, pool->solvables + p, (beforerepo->end - p) * sizeof(Solvable));
+  memset(pool->solvables + p, 0, sizeof(Solvable) * count);
+  /* adapt repodata */
+  FOR_REPODATAS(beforerepo, i, data)
+    {
+      if (data->start < p)
+       continue;
+      data->start += count;
+      data->end += count;
+    }
+  beforerepo->start += count;
+  beforerepo->end += count;
+  /* we now have count free solvables at id p */
+  /* warning: sidedata must be extended before adapting start/end */
+  if (repo->rpmdbid)
+    repo->rpmdbid = (Id *)repo_sidedata_extend(repo, repo->rpmdbid, sizeof(Id), p, count);
+  if (p < repo->start)
+    repo->start = p;
+  if (p + count > repo->end)
+    repo->end = p + count;
+  repo->nsolvables += count;
+  for (s = pool->solvables + p; count--; s++)
+    s->repo = repo;
+  return p;
+}
+
 
 /* repository sidedata is solvable data allocated on demand.
  * It is used for data that is normally not present
@@ -844,6 +892,9 @@ repo_matchvalue(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyValu
 
   if (md->matcher.match)
     {
+      if (key->name == SOLVABLE_FILELIST && key->type == REPOKEY_TYPE_DIRSTRARRAY && (md->matcher.flags & SEARCH_FILES) != 0)
+       if (!datamatcher_checkbasename(&md->matcher, kv->str))
+         return 0;
       if (!repodata_stringify(md->pool, data, key, kv, md->flags))
        return 0;
       if (!datamatcher_match(&md->matcher, kv->str))
@@ -1236,7 +1287,7 @@ int
 repo_lookup_deparray(Repo *repo, Id entry, Id keyname, Queue *q, Id marker)
 {
   int r = repo_lookup_idarray(repo, entry, keyname, q);
-  if (r && marker)
+  if (r && marker && q->count)
     {
       int i;
       if (marker < 0)
@@ -1429,7 +1480,7 @@ repo_set_num(Repo *repo, Id p, Id keyname, unsigned long long num)
        {
          if (!repo->rpmdbid)
            repo->rpmdbid = repo_sidedata_create(repo, sizeof(Id));
-         repo->rpmdbid[p] = num;
+         repo->rpmdbid[p - repo->start] = num;
          return;
        }
     }
@@ -1563,9 +1614,7 @@ repo_set_deparray(Repo *repo, Id p, Id keyname, Queue *q, Id marker)
        {
          if (q2.count)
            queue_insert(&q2, 0, -marker);
-         queue_insertn(&q2, 0, q->count);
-         for (i = 0; i < q->count; i++)
-          q2.elements[i] = q->elements[i];
+         queue_insertn(&q2, 0, q->count, q->elements);
        }
       repo_set_deparray(repo, p, keyname, &q2, 0);
       queue_free(&q2);
@@ -1613,6 +1662,62 @@ repo_set_idarray(Repo *repo, Id p, Id keyname, Queue *q)
 }
 
 void
+repo_unset(Repo *repo, Id p, Id keyname)
+{
+  Repodata *data;
+  if (p >= 0)
+    {
+      Solvable *s = repo->pool->solvables + p;
+      switch (keyname)
+       {
+       case SOLVABLE_NAME:
+         s->name = 0;
+         return;
+       case SOLVABLE_ARCH:
+         s->arch = 0;
+         return;
+       case SOLVABLE_EVR:
+         s->evr = 0;
+         return;
+       case SOLVABLE_VENDOR:
+         s->vendor = 0;
+         return;
+        case RPM_RPMDBID:
+         if (repo->rpmdbid)
+           repo->rpmdbid[p - repo->start] = 0;
+         return;
+       case SOLVABLE_PROVIDES:
+         s->provides = 0;
+         return;
+       case SOLVABLE_OBSOLETES:
+         s->obsoletes = 0;
+         return;
+       case SOLVABLE_CONFLICTS:
+         s->conflicts = 0;
+         return;
+       case SOLVABLE_REQUIRES:
+         s->requires = 0;
+         return;
+       case SOLVABLE_RECOMMENDS:
+         s->recommends = 0;
+         return;
+       case SOLVABLE_SUGGESTS:
+         s->suggests = 0;
+         return;
+       case SOLVABLE_SUPPLEMENTS:
+         s->supplements = 0;
+       case SOLVABLE_ENHANCES:
+         s->enhances = 0;
+         return;
+       default:
+         break;
+       }
+    }
+  data = repo_last_repodata(repo);
+  repodata_unset(data, p, keyname);
+}
+
+void
 repo_internalize(Repo *repo)
 {
   int i;