* more elaborate txn protection for packagedb, componentdb and installdb
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
+23
-15
@@ -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):
|
||||||
|
def proc(txn):
|
||||||
if not self.has_component(name):
|
if not self.has_component(name):
|
||||||
self.d[name] = Component(name = name)
|
self.d[name] = Component(name = name)
|
||||||
return self.d[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):
|
||||||
|
def proc(txn):
|
||||||
if self.d.has_key(component.name):
|
if self.d.has_key(component.name):
|
||||||
# preserve the list of packages
|
# preserve the list of packages
|
||||||
component.packages = self.d[component.name].packages
|
component.packages = self.d[component.name].packages
|
||||||
self.d[component.name] = component
|
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 = self.get_component(component_name, txn)
|
||||||
component.packages.append(package)
|
component.packages.append(package)
|
||||||
self.d[component_name] = component # update
|
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):
|
||||||
|
if not self.has_component(component_name, txn):
|
||||||
raise Error(_('Information for component %s not available') % component_name)
|
raise Error(_('Information for component %s not available') % component_name)
|
||||||
component = self.get_component(component_name)
|
component = self.get_component(component_name, txn)
|
||||||
component.packages.remove(package)
|
component.packages.remove(package)
|
||||||
self.d[component_name] = component # update
|
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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
+19
-11
@@ -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)
|
||||||
|
def proc(txn):
|
||||||
return self.d.has_key(pkg)
|
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):
|
||||||
|
info = self.d.get(pkg, txn)
|
||||||
return info.state=='i' or info.state=='ip'
|
return info.state=='i' or info.state=='ip'
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
return self.d.txn_proc(proc, txn)
|
||||||
|
|
||||||
def list_installed(self):
|
def list_installed(self, txn = None):
|
||||||
|
def proc(txn):
|
||||||
list = []
|
list = []
|
||||||
for (pkg, info) in self.d.items():
|
for (pkg, info) in self.d.items(txn):
|
||||||
if info.state=='i' or info.state=='ip':
|
if info.state=='i' or info.state=='ip':
|
||||||
list.append(pkg)
|
list.append(pkg)
|
||||||
return list
|
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):
|
||||||
|
if self.is_installed(pkg, txn):
|
||||||
raise InstallDBError(_("Already installed"))
|
raise InstallDBError(_("Already installed"))
|
||||||
if ctx.config.get_option('ignore_comar'):
|
if ctx.config.get_option('ignore_comar'):
|
||||||
state = 'ip'
|
state = 'ip'
|
||||||
self.dp[pkg] = True
|
self.dp.put(pkg, True, txn)
|
||||||
else:
|
else:
|
||||||
state = 'i'
|
state = 'i'
|
||||||
|
self.d.put(pkg, InstallInfo(state, version, release, build, distro), txn)
|
||||||
|
|
||||||
self.d[pkg] = InstallInfo(state, version, release, build, distro)
|
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
|
||||||
|
|
||||||
|
|||||||
+12
-6
@@ -67,17 +67,21 @@ 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
|
|
||||||
|
def proc(txn):
|
||||||
|
self.d.put(name, package_info, txn)
|
||||||
for dep in package_info.runtimeDependencies():
|
for dep in package_info.runtimeDependencies():
|
||||||
dep_name = str(dep.package)
|
dep_name = str(dep.package)
|
||||||
if self.dr.has_key(dep_name):
|
if self.dr.has_key(dep_name, txn):
|
||||||
self.dr[dep_name].append( (name, dep) )
|
revdep = self.dr.get(dep_name, txn)
|
||||||
|
revdep.append( (name, dep) )
|
||||||
|
self.dr.put(dep_name, revdep, txn)
|
||||||
else:
|
else:
|
||||||
self.dr[dep_name] = [ (name, dep) ]
|
self.dr.put(dep_name, [ (name, dep) ], txn)
|
||||||
# add component
|
# add component
|
||||||
ctx.componentdb.add_package(package_info.partOf, package_info.name)
|
ctx.componentdb.add_package(package_info.partOf, package_info.name, txn)
|
||||||
# index summary and description
|
# index summary and description
|
||||||
for (lang, doc) in package_info.summary.iteritems():
|
for (lang, doc) in package_info.summary.iteritems():
|
||||||
if lang in ['en', 'tr']:
|
if lang in ['en', 'tr']:
|
||||||
@@ -86,6 +90,8 @@ class PackageDB(object):
|
|||||||
if lang in ['en', 'tr']:
|
if lang in ['en', 'tr']:
|
||||||
pisi.search.add_doc('description', lang, package_info.name, doc)
|
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()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user