summaryrefslogtreecommitdiff
path: root/lib/thandy/packagesys/PackageDB.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/thandy/packagesys/PackageDB.py')
-rw-r--r--lib/thandy/packagesys/PackageDB.py153
1 files changed, 104 insertions, 49 deletions
diff --git a/lib/thandy/packagesys/PackageDB.py b/lib/thandy/packagesys/PackageDB.py
index a81507d..94a5ad9 100644
--- a/lib/thandy/packagesys/PackageDB.py
+++ b/lib/thandy/packagesys/PackageDB.py
@@ -2,13 +2,18 @@
import atexit
import shelve
+import logging
import thandy.util
import thandy.formats
-import thandy.packagesys.PackageSystem
+import thandy.packagesys.PackageSystem as PS
class SimplePackageDB:
+ """Trivial wrapper around Python's shelve module to provide storage for
+ installation information for package items that don't automatically
+ record their presence.
+ """
def __init__(self, filename):
thandy.util.ensureParentDir(filename)
self._db = shelve.open(filename, 'c')
@@ -23,71 +28,121 @@ class SimplePackageDB:
def setInstallParameters(self, package, params):
self._db['ip_%s'%str(package)] = params
+ def setManifest(self, package, fnameToDigest):
+ self._db['mf_%s'%str(package)] = fnameToDigest
+
def getCurVersion(self, package):
v = self._db.get('pv_%s'%str(package))
if v != None:
return v[0]
+ else:
+ return None
def getInstallParameters(self, package):
return self._db.get('pi_%s'%str(package))
-class DBBackedPackageSystem(thandy.packagesys.PackageSystem.PackageSystem):
- def __init__(self):
- self._packageDB = None
+ def getManifest(self, package):
+ return self._db.get('mf_%'%str(package), {})
- def getDB(self):
- if self._packageDB is None:
- fname = thandy.util.userFilename("db/packages")
- self._packageDB = SimplePackageDB(fname)
- return self._packageDB
-
-class DBBackedPackageHandle(thandy.packagesys.PackageSystem.PackageHandle):
- def __init__(self, packageDB, name, version, filelist):
- thandy.packagesys.PackageSystem.PackageHandle.__init__(self)
- self._packageDB = packageDB
- self._name = name
- self._version = version
- self._filelist = filelist
+ def removeAll(self, package):
+ for template in ["pv_%s", "ip_%s", "mf_%s"]:
+ try:
+ del self._db[template % str(package)]
+ except KeyError:
+ pass
+
+_DB_INSTANCE = None
- self._metaData = None
+def getPackageDBInstance():
+ global _DB_INSTANCE
+ if _DB_INSTANCE == None:
+ fname = thandy.util.userFilename("db/packages")
+ logging.info("Opening package database in %s", fname)
+ _DB_INSTANCE = SimplePackageDB(fname)
+ return _DB_INSTANCEx
- def _getInstallBase(self):
- raise NotImplemented()
+class _DBMixin:
+ def setDB(self, db):
+ self._db = db
- def anyVersionInstalled(self, transaction=None):
- return self.getInstalledVersion(transaction) != None
+ def getDB(self):
+ if self._db is None:
+ self._db = getPackageDBInstance()
+ return self._db
+
+class DBChecker(PS.Checker, _DBMixin):
+ def __init__(self, name, version):
+ PS.Checker.__init__(self)
+ self._name = name
+ self._version = version
+ self._db = None
+
+ def __repr__(self):
+ return "DBChecker(%r, %r)"%(self._name, self._version)
+
+# def checkInstall(self):
+# if not self.isInstalled():
+# return False
+# else:
+# return self._checkManifest()
+#
+# def _getInstallRoot(self):
+# return "/"
+#
+# def _checkManifest(self):
+# manifest = self.getDB().getManifest(self._name)
+# root = self._getInstallRoot()
+# all_ok = True
+# for fname, digest_want in manifest:
+# real_fname = os.path.join(self._getInstallRoot(), fname)
+# logging.info("Checking digest on %s", fname)
+# try:
+# digest = thandy.formats.getFileDigest(real_fname):
+# if digest != digest_want:
+# logging.warn("Digest on %s not as expected", real_fname)
+# all_ok = False
+# except OSError:
+# logging.warn("File %s not found.", real_fname)
+# all_ok = False
+# return all_ok
+#
+ def getInstalledVersions(self):
+ return [ self.getDB().getCurVersion(self._name) ]
+
+ def isInstalled(self):
+ return self._version in self.getInstalledVersions(transaction)
+
+class DBInstaller(PS.Installer, _DBMixin):
+ def __init__(self, name, version, relPath, installer):
+ PS.Installer.__init__(self, relPath)
+ self._name = name
+ self._version = version
+ self._installer = installer
- def getInstalledVersion(self, transaction=None):
- return self._packageDB.getCurVersion(self._name)
+ def __repr__(self):
+ return "DBInstaller(%r, %r, %r, %r)"%(self._name,
+ self._version,
+ self._relPath,
+ self._installer)
- def install(self, transaction=None):
- params = self._doInstall()
- self._packageDB.setVersion(
- self._name, self._version, self._filelist)
- self._packageDB.setInstallParameters(self._name, params)
+ def setTransaction(self, transaction):
+ self._installer.setTransaction(transaction)
- def _doInstall(self):
- raise NotImplemented()
+ def setCacheRoot(self, cacheRoot):
+ self._installer.setCacheRoot(cacheRoot)
- def isInstalled(self, transaction=None):
- return self.getInstalledVersion(transaction) == self._version
+ def install(self):
+ self._installer.install()
- def checkInstall(self, transaction=None):
- base = self._getInstallBase()
+ params, manifest = self._installer.getInstallResult()
+ self.getDB().setCurVersion(self._name, self._version)
+ if params != None:
+ self.getDB().getInstallParameters(self._name, params)
+ if manifest != None:
+ self.getDB().setManifest(self._name, manifest)
- all_ok = True
- for fn, hash in self._filelist:
- fn = os.path.join(base, fn)
- if not os.path.exists(fn):
- all_ok = False
- else:
- try:
- d = thandy.formats.getFileDigest(fn)
- if d != hash:
- all_ok = False
- except OSError:
- all_ok = False
- break
+ def remove(self):
+ self._installer.remove()
+ self.getDB().removeAll(self._name)
- return all_ok