* more elaborate txn protection for packagedb, componentdb and installdb

This commit is contained in:
Eray Özkural
2005-12-08 17:05:46 +00:00
parent d9fea24685
commit 7ba956ac41
6 changed files with 98 additions and 71 deletions
+7 -3
View File
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Project SYSTEM "Project-3.8.dtd"> <!DOCTYPE Project SYSTEM "Project-3.8.dtd">
<!-- Project file for project pisi --> <!-- Project file for project pisi -->
<!-- Saved: 2005-12-06, 19:01:57 --> <!-- Saved: 2005-12-08, 18:50:27 -->
<!-- Copyright (C) 2005 PiSi Development Team, --> <!-- Copyright (C) 2005 PiSi Development Team, -->
<Project version="3.8"> <Project version="3.8">
<ProgLanguage mixed="0">Python</ProgLanguage> <ProgLanguage mixed="0">Python</ProgLanguage>
@@ -462,6 +462,10 @@
<Dir>tests</Dir> <Dir>tests</Dir>
<Name>searchtests.py</Name> <Name>searchtests.py</Name>
</Source> </Source>
<Source>
<Dir>pisi</Dir>
<Name>dbshelve.py</Name>
</Source>
</Sources> </Sources>
<Forms> <Forms>
</Forms> </Forms>
@@ -503,10 +507,10 @@
<VcsOtherData>{'standardLayout': 1}</VcsOtherData> <VcsOtherData>{'standardLayout': 1}</VcsOtherData>
</Vcs> </Vcs>
<FiletypeAssociations> <FiletypeAssociations>
<FiletypeAssociation pattern="*.py" type="SOURCES" />
<FiletypeAssociation pattern="*.ui.h" type="FORMS" /> <FiletypeAssociation pattern="*.ui.h" type="FORMS" />
<FiletypeAssociation pattern="*.ptl" type="SOURCES" />
<FiletypeAssociation pattern="*.idl" type="INTERFACES" /> <FiletypeAssociation pattern="*.idl" type="INTERFACES" />
<FiletypeAssociation pattern="*.ui" type="FORMS" /> <FiletypeAssociation pattern="*.ui" type="FORMS" />
<FiletypeAssociation pattern="*.py" type="SOURCES" /> <FiletypeAssociation pattern="*.ptl" type="SOURCES" />
</FiletypeAssociations> </FiletypeAssociations>
</Project> </Project>
-1
View File
@@ -179,7 +179,6 @@ class Install(AtomicOperation):
if not ctx.ui.confirm(x): if not ctx.ui.confirm(x):
raise Error(_('Package downgrade declined')) raise Error(_('Package downgrade declined'))
# schedule for reinstall # schedule for reinstall
self.old_files = ctx.installdb.files(pkg.name) self.old_files = ctx.installdb.files(pkg.name)
self.old_path = ctx.installdb.pkg_dir(pkg.name, iversion, irelease) self.old_path = ctx.installdb.pkg_dir(pkg.name, iversion, irelease)
+33 -25
View File
@@ -87,13 +87,15 @@ class ComponentDB(object):
def close(self): def close(self):
self.d.close() self.d.close()
def has_component(self, name): def has_component(self, name, txn = None):
return self.d.has_key(str(name)) return self.d.has_key(str(name), txn)
def get_component(self, name): def get_component(self, name, txn = None):
if not self.has_component(name): def proc(txn):
self.d[name] = Component(name = name) if not self.has_component(name):
return self.d[name] self.d[name] = Component(name = name)
return self.d[name]
return self.d.txn_proc(proc, txn)
def list_components(self): def list_components(self):
list = [] list = []
@@ -101,27 +103,33 @@ class ComponentDB(object):
list.append(pkg) list.append(pkg)
return list return list
def update_component(self, component): def update_component(self, component, txn = None):
if self.d.has_key(component.name): def proc(txn):
# preserve the list of packages if self.d.has_key(component.name):
component.packages = self.d[component.name].packages # preserve the list of packages
self.d[component.name] = component component.packages = self.d[component.name].packages
self.d[component.name] = component
self.d.txn_proc(proc, txn)
def add_package(self, component_name, package): def add_package(self, component_name, package, txn = None):
component = self.get_component(component_name) def proc(txn):
component.packages.append(package) component = self.get_component(component_name, txn)
self.d[component_name] = component # update component.packages.append(package)
self.d.put(component_name, component, txn) # update
self.d.txn_proc(proc, txn)
def remove_package(self, component_name, package): def remove_package(self, component_name, package, txn = None):
if not self.has_component(component_name): def proc(txn):
raise Error(_('Information for component %s not available') % component_name) if not self.has_component(component_name, txn):
component = self.get_component(component_name) raise Error(_('Information for component %s not available') % component_name)
component.packages.remove(package) component = self.get_component(component_name, txn)
self.d[component_name] = component # update component.packages.remove(package)
self.d.put(component_name, component, txn) # update
self.d.txn_proc(proc, txn)
def clear(self): def clear(self, txn = None):
self.d.clear() self.d.clear(txn)
def remove_component(self, name): def remove_component(self, name, txn = None):
name = str(name) name = str(name)
del self.d[name] self.d.delete(name, txn)
+2
View File
@@ -34,9 +34,11 @@ from pisi.uri import URI
import pisi.component as component import pisi.component as component
import pisi.specfile as specfile import pisi.specfile as specfile
class Error(pisi.Error): class Error(pisi.Error):
pass pass
class Index(XmlFile): class Index(XmlFile):
__metaclass__ = autoxml.autoxml __metaclass__ = autoxml.autoxml
+33 -25
View File
@@ -96,26 +96,33 @@ class InstallDB:
def pkg_dir(self, pkg, version, release): def pkg_dir(self, pkg, version, release):
return join(ctx.config.lib_dir(), pkg + '-' + version + '-' + release) return join(ctx.config.lib_dir(), pkg + '-' + version + '-' + release)
def is_recorded(self, pkg): def is_recorded(self, pkg, txn = None):
pkg = str(pkg) pkg = str(pkg)
return self.d.has_key(pkg) def proc(txn):
return self.d.has_key(pkg)
return self.d.txn_proc(proc, txn)
def is_installed(self, pkg): def is_installed(self, pkg, txn = None):
pkg = str(pkg) pkg = str(pkg)
if self.is_recorded(pkg): def proc(txn):
info = self.d[pkg] if self.is_recorded(pkg, txn):
return info.state=='i' or info.state=='ip' info = self.d.get(pkg, txn)
else: return info.state=='i' or info.state=='ip'
return False else:
return False
return self.d.txn_proc(proc, txn)
def list_installed(self): def list_installed(self, txn = None):
list = [] def proc(txn):
for (pkg, info) in self.d.items(): list = []
if info.state=='i' or info.state=='ip': for (pkg, info) in self.d.items(txn):
list.append(pkg) if info.state=='i' or info.state=='ip':
return list list.append(pkg)
return list
return self.d.txn_proc(proc, txn)
def list_pending(self): def list_pending(self):
# warning: reads the entire db
dict = {} dict = {}
for (pkg, x) in self.dp.items(): for (pkg, x) in self.dp.items():
pkginfo = self.d[pkg] pkginfo = self.d[pkg]
@@ -139,18 +146,20 @@ class InstallDB:
else: else:
return False return False
def install(self, pkg, version, release, build, distro = ""): def install(self, pkg, version, release, build, distro = "", txn = None):
"""install package with specific version, release, build""" """install package with specific version, release, build"""
pkg = str(pkg) pkg = str(pkg)
if self.is_installed(pkg): def proc(txn):
raise InstallDBError(_("Already installed")) if self.is_installed(pkg, txn):
if ctx.config.get_option('ignore_comar'): raise InstallDBError(_("Already installed"))
state = 'ip' if ctx.config.get_option('ignore_comar'):
self.dp[pkg] = True state = 'ip'
else: self.dp.put(pkg, True, txn)
state = 'i' else:
state = 'i'
self.d[pkg] = InstallInfo(state, version, release, build, distro) self.d.put(pkg, InstallInfo(state, version, release, build, distro), txn)
self.d.txn_proc(proc,txn)
def clear_pending(self, pkg): def clear_pending(self, pkg):
pkg = str(pkg) pkg = str(pkg)
@@ -188,4 +197,3 @@ def finalize():
if db: if db:
db.close() db.close()
db = None db = None
+23 -17
View File
@@ -67,24 +67,30 @@ class PackageDB(object):
#TODO: list_upgrades? #TODO: list_upgrades?
def add_package(self, package_info): def add_package(self, package_info, txn = None):
name = str(package_info.name) name = str(package_info.name)
self.d[name] = package_info
for dep in package_info.runtimeDependencies(): def proc(txn):
dep_name = str(dep.package) self.d.put(name, package_info, txn)
if self.dr.has_key(dep_name): for dep in package_info.runtimeDependencies():
self.dr[dep_name].append( (name, dep) ) dep_name = str(dep.package)
else: if self.dr.has_key(dep_name, txn):
self.dr[dep_name] = [ (name, dep) ] revdep = self.dr.get(dep_name, txn)
# add component revdep.append( (name, dep) )
ctx.componentdb.add_package(package_info.partOf, package_info.name) self.dr.put(dep_name, revdep, txn)
# index summary and description else:
for (lang, doc) in package_info.summary.iteritems(): self.dr.put(dep_name, [ (name, dep) ], txn)
if lang in ['en', 'tr']: # add component
pisi.search.add_doc('summary', lang, package_info.name, doc) ctx.componentdb.add_package(package_info.partOf, package_info.name, txn)
for (lang, doc) in package_info.description.iteritems(): # index summary and description
if lang in ['en', 'tr']: for (lang, doc) in package_info.summary.iteritems():
pisi.search.add_doc('description', lang, package_info.name, doc) if lang in ['en', 'tr']:
pisi.search.add_doc('summary', lang, package_info.name, doc)
for (lang, doc) in package_info.description.iteritems():
if lang in ['en', 'tr']:
pisi.search.add_doc('description', lang, package_info.name, doc)
self.d.txn_proc(proc, txn)
def clear(self): def clear(self):
self.d.clear() self.d.clear()