Commit 1fc48848 authored by Shane Hathaway's avatar Shane Hathaway

Changed object import so it happens in a subtransaction. This cleans up

the undo log.
parent 4c6db658
......@@ -84,8 +84,8 @@
##############################################################################
"""Database connection support
$Id: Connection.py,v 1.49 2001/04/02 14:54:54 chrism Exp $"""
__version__='$Revision: 1.49 $'[11:-2]
$Id: Connection.py,v 1.50 2001/04/14 23:16:44 shane Exp $"""
__version__='$Revision: 1.50 $'[11:-2]
from cPickleCache import PickleCache
from POSException import ConflictError, ExportError
......@@ -260,9 +260,20 @@ class Connection(ExportImport.ExportImport):
# Return the connection to the pool.
db._closeConnection(self)
__onCommitActions=()
def onCommitAction(self, method_name, *args, **kw):
self.__onCommitActions = self.__onCommitActions + (
(method_name, args, kw),)
get_transaction().register(self)
def commit(self, object, transaction, _type=type, _st=type('')):
if object is self:
return # we registered ourself
# We registered ourself. Execute a commit action, if any.
if self.__onCommitActions:
method_name, args, kw = self.__onCommitActions[0]
self.__onCommitActions = self.__onCommitActions[1:]
apply(getattr(self, method_name), (transaction,) + args, kw)
return
oid=object._p_oid
invalid=self._invalid
if oid is None or object._p_jar is not self:
......@@ -413,6 +424,7 @@ class Connection(ExportImport.ExportImport):
def commit_sub(self, t,
_type=type, _st=type(''), _None=None):
"""Commit all work done in subtransactions"""
tmp=self._tmp
if tmp is _None: return
src=self._storage
......@@ -597,6 +609,7 @@ class Connection(ExportImport.ExportImport):
raise
def tpc_abort(self, transaction):
self.__onCommitActions = ()
self._storage.tpc_abort(transaction)
cache=self._cache
cache.invalidate(self._invalidated)
......@@ -622,6 +635,7 @@ class Connection(ExportImport.ExportImport):
def tpc_vote(self, transaction,
_type=type, _st=type('')):
self.__onCommitActions = ()
try: vote=self._storage.tpc_vote
except: return
s=vote(transaction)
......
......@@ -142,22 +142,35 @@ class ExportImport:
return customImporters[magic](self, file, clue)
raise POSException.ExportError, 'Invalid export header'
t=get_transaction().sub()
t.note('import into %s from %s' % (self.db().getName(), file_name))
t = get_transaction()
if clue: t.note(clue)
storage=self._storage
new_oid=storage.new_oid
oids={}
wrote_oid=oids.has_key
new_oid=storage.new_oid
store=storage.store
return_oid_list = []
self.onCommitAction('_importDuringCommit', file, return_oid_list)
t.commit(1)
# Return the root imported object.
if return_oid_list:
return self[return_oid_list[0]]
else:
return None
def _importDuringCommit(self, transaction, file, return_oid_list):
'''
Invoked by the transaction manager mid commit.
Appends one item, the OID of the first object created,
to return_oid_list.
'''
oids = {}
storage = self._storage
new_oid = storage.new_oid
store = storage.store
read = file.read
def persistent_load(ooid,
Ghost=Ghost, StringType=StringType,
atoi=string.atoi, TupleType=type(()),
oids=oids, wrote_oid=wrote_oid, new_oid=new_oid):
oids=oids, wrote_oid=oids.has_key,
new_oid=storage.new_oid):
"Remap a persistent id to a new ID and create a ghost for it."
......@@ -174,50 +187,41 @@ class ExportImport:
Ghost.oid=oid
return Ghost
version=self._version
return_oid=None
storage.tpc_begin(t)
try:
while 1:
h=read(16)
if h==export_end_marker: break
if len(h) != 16:
raise POSException.ExportError, 'Truncated export file'
l=u64(h[8:16])
p=read(l)
if len(p) != l:
raise POSException.ExportError, 'Truncated export file'
ooid=h[:8]
if oids:
oid=oids[ooid]
if type(oid) is TupleType: oid=oid[0]
else:
oids[ooid]=return_oid=oid=new_oid()
pfile=StringIO(p)
unpickler=Unpickler(pfile)
unpickler.persistent_load=persistent_load
newp=StringIO()
pickler=Pickler(newp,1)
pickler.persistent_id=persistent_id
pickler.dump(unpickler.load())
pickler.dump(unpickler.load())
p=newp.getvalue()
plen=len(p)
store(oid, None, p, version, t)
except:
storage.tpc_abort(t)
raise
else:
storage.tpc_vote(t)
storage.tpc_finish(t)
if return_oid is not None: return self[return_oid]
version = self._version
while 1:
h=read(16)
if h==export_end_marker: break
if len(h) != 16:
raise POSException.ExportError, 'Truncated export file'
l=u64(h[8:16])
p=read(l)
if len(p) != l:
raise POSException.ExportError, 'Truncated export file'
ooid=h[:8]
if oids:
oid=oids[ooid]
if type(oid) is TupleType: oid=oid[0]
else:
oids[ooid] = oid = storage.new_oid()
return_oid_list.append(oid)
pfile=StringIO(p)
unpickler=Unpickler(pfile)
unpickler.persistent_load=persistent_load
newp=StringIO()
pickler=Pickler(newp,1)
pickler.persistent_id=persistent_id
pickler.dump(unpickler.load())
pickler.dump(unpickler.load())
p=newp.getvalue()
plen=len(p)
store(oid, None, p, version, transaction)
StringType=type('')
......@@ -233,6 +237,6 @@ export_end_marker='\377'*16
class Ghost: pass
def persistent_id(object, Ghost=Ghost):
if hasattr(object, '__class__') and object.__class__ is Ghost:
if getattr(object, '__class__', None) is Ghost:
return object.oid
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment