1 # Copyright 1999-2009 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
5 from portage.dbapi import dbapi
7 class PackageVirtualDbapi(dbapi):
9 A dbapi-like interface class that represents the state of the installed
10 package database as new packages are installed, replacing any packages
11 that previously existed in the same slot. The main difference between
12 this class and fakedbapi is that this one uses Package instances
13 internally (passed in via cpv_inject() and cpv_remove() calls).
15 def __init__(self, settings):
17 self.settings = settings
18 self._match_cache = {}
32 obj = PackageVirtualDbapi(self.settings)
33 obj._match_cache = self._match_cache.copy()
34 obj._cp_map = self._cp_map.copy()
35 for k, v in obj._cp_map.items():
37 obj._cpv_map = self._cpv_map.copy()
41 return bool(self._cpv_map)
43 if sys.hexversion < 0x3000000:
44 __nonzero__ = __bool__
47 return iter(self._cpv_map.values())
49 def __contains__(self, item):
50 existing = self._cpv_map.get(item.cpv)
51 if existing is not None and \
56 def get(self, item, default=None):
57 cpv = getattr(item, "cpv", None)
61 type_name, root, cpv, operation = item
63 existing = self._cpv_map.get(cpv)
64 if existing is not None and \
69 def match_pkgs(self, atom):
70 return [self._cpv_map[cpv] for cpv in self.match(atom)]
72 def _clear_cache(self):
73 if self._categories is not None:
74 self._categories = None
76 self._match_cache = {}
78 def match(self, origdep, use_cache=1):
79 result = self._match_cache.get(origdep)
80 if result is not None:
82 result = dbapi.match(self, origdep, use_cache=use_cache)
83 self._match_cache[origdep] = result
86 def cpv_exists(self, cpv, myrepo=None):
87 return cpv in self._cpv_map
89 def cp_list(self, mycp, use_cache=1):
90 cachelist = self._match_cache.get(mycp)
91 # cp_list() doesn't expand old-style virtuals
92 if cachelist and cachelist[0].startswith(mycp):
94 cpv_list = self._cp_map.get(mycp)
98 cpv_list = [pkg.cpv for pkg in cpv_list]
99 self._cpv_sort_ascending(cpv_list)
100 if not (not cpv_list and mycp.startswith("virtual/")):
101 self._match_cache[mycp] = cpv_list
105 return list(self._cp_map)
108 return list(self._cpv_map)
110 def cpv_inject(self, pkg):
111 cp_list = self._cp_map.get(pkg.cp)
114 self._cp_map[pkg.cp] = cp_list
115 e_pkg = self._cpv_map.get(pkg.cpv)
116 if e_pkg is not None:
119 self.cpv_remove(e_pkg)
120 for e_pkg in cp_list:
121 if e_pkg.slot_atom == pkg.slot_atom:
124 self.cpv_remove(e_pkg)
127 self._cpv_map[pkg.cpv] = pkg
130 def cpv_remove(self, pkg):
131 old_pkg = self._cpv_map.get(pkg.cpv)
134 self._cp_map[pkg.cp].remove(pkg)
135 del self._cpv_map[pkg.cpv]
138 def aux_get(self, cpv, wants, myrepo=None):
139 metadata = self._cpv_map[cpv].metadata
140 return [metadata.get(x, "") for x in wants]
142 def aux_update(self, cpv, values):
143 self._cpv_map[cpv].metadata.update(values)