Commit e6481ad9 authored by Jim Fulton's avatar Jim Fulton

*** empty log message ***

parent 2109ffe6
......@@ -4,7 +4,7 @@
__doc__='''Python implementation of persistent base types
$Id: Persistence.py,v 1.10 1997/10/30 18:49:22 jim Exp $'''
$Id: Persistence.py,v 1.11 1997/12/15 23:01:17 jim Exp $'''
# Copyright
#
# Copyright 1996 Digital Creations, L.C., 910 Princess Anne
......@@ -59,7 +59,143 @@ $Id: Persistence.py,v 1.10 1997/10/30 18:49:22 jim Exp $'''
#
# (540) 371-6909
#
__version__='$Revision: 1.11 $'[11:-2]
try:
from cPersistence import Persistent
except:
class Persistent:
"""\
Persistent object support mix-in class
When a persistent object is loaded from a database, the object's
data is not immediately loaded. Loading of the objects data is
defered until an attempt is made to access an attribute of the
object.
The object also tries to keep track of whether it has changed. It
is easy for this to be done incorrectly. For this reason, methods
of subclasses that change state other than by setting attributes
should: 'self.__changed__(1)' to flag instances as changed.
You must not override the object's '__getattr__' and '__setattr__'
methods. If you override the objects '__getstate__' method, then
you must be careful not to include any attributes with names
starting with '_p_' in the state.
"""
_p_oid=None # A Persistent object-id, unique within a jar
_p_changed=0 # The object state: None=ghost, 0=normal, 1=changed
_p_jar=None # The last jar that this object was stored in.
def _p___init__(self,oid,jar):
"""Post creation initialization
This is *only* used if we have __getinitargs__!
"""
d=self.__dict__
if d:
newstate={}
for key in d.keys():
if key[:3] != '_p_':
newstate[key]=d[key]
del d[key]
if newstate: d['_p_newstate']=newstate
d['_p_oid']=oid
d['_p_jar']=jar
d['_p_changed']=None
def _p_deactivate(self,copy=None):
if copy is None: newstate=None
else: newstate=copy.__dict__
d=self.__dict__
oid=self._p_oid
jar=self._p_jar
d.clear()
if newstate: d['_p_newstate']=newstate
d['_p_oid']=oid
d['_p_jar']=jar
d['_p_changed']=None
_p___reinit=_p_deactivate # Back. Comp.
def __getattr__(self,key):
'Get an item'
if self._p_changed is None and key[:3] != '_p_':
self._p_jar.setstate(self)
if self.__dict__.has_key(key): return self.__dict__[key]
raise AttributeError, key
def __setattr__(self,key,value):
' '
if key[:3]=='_p_':
self.__dict__[key]=value
return
jar=self._p_jar
if self._p_changed is None: jar.setstate(self)
self.__dict__[key]=value
if jar is not None:
try:
get_transaction().register(self)
self._p_changed=1
except: pass
def __changed__(self,v=-1):
old=self._p_changed
if v != -1:
if v and not old and self._p_jar is not None:
try:
get_transaction().register(self)
self._p_changed=1
except: pass
return old
def __getstate__(self):
# First, update my state, if necessary:
if self._p_changed is None: self._p_jar.setstate(self)
state={}
d=self.__dict__
for k,v in d.items():
if k[:3] != '_p_' and k[:3] != '_v_': state[k]=v
return state
def __setstate__(self,state):
d=self.__dict__
for k,v in state.items(): d[k]=v
return state
def __save__(self):
'''\
Update the object in a persistent database.
'''
jar=self._p_jar
if jar and self._p_changed: jar.store(self)
def __repr__(self):
' '
return '<%s instance at %s>' % (self.__class__.__name__,
hex(id(self)))
def __inform_commit__(self,T,start_time):
jar=self._p_jar
if jar and self._p_changed: jar.store(self,T)
def __inform_abort__(self,T,start_time):
try: self._p_jar.abort(self,start_time)
except: pass
############################################################################
# $Log: Persistence.py,v $
# Revision 1.11 1997/12/15 23:01:17 jim
# *** empty log message ***
#
# Revision 1.10 1997/10/30 18:49:22 jim
# Changed abort to use jar's abort method.
#
......@@ -95,218 +231,3 @@ $Id: Persistence.py,v 1.10 1997/10/30 18:49:22 jim Exp $'''
#
#
#
__version__='$Revision: 1.10 $'[11:-2]
class Persistent:
"""\
Persistent object support mix-in class
When a persistent object is loaded from a database, the object's
data is not immediately loaded. Loading of the objects data is
defered until an attempt is made to access an attribute of the
object.
The object also tries to keep track of whether it has changed. It
is easy for this to be done incorrectly. For this reason, methods
of subclasses that change state other than by setting attributes
should: 'self.__changed__(1)' to flag instances as changed.
Data are not saved automatically. To save an object's state, call
the object's '__save__' method.
You must not override the object's '__getattr__' and '__setattr__'
methods. If you override the objects '__getstate__' method, then
you must be careful not to include any attributes with names
starting with '_p_' in the state.
"""
_p_oid=None # A Persistent object-id, unique within a jar
_p_changed=None # A flag indicating whether the object has changed
_p_read_time=0 # The time when the object was read.
_p_jar=None # The last jar that this object was stored in.
def __getattr__(self,key):
' '
try: setstate=self.__dict__['_p_setstate']
except: raise AttributeError, key
setstate(self)
try: return self.__dict__[key]
except: raise AttributeError, key
def _p___init__(self,oid,jar):
d=self.__dict__
if self._p_oid is None:
d['_p_oid']=oid
if self._p_oid==oid:
newstate={}
for key in d.keys():
if key[:3] != '_p_':
newstate[key]=d[key]
del d[key]
d['_p_newstate']=newstate
d['_p_jar']=jar
d['_p_setstate']=jar.setstate
d['_p_changed']=0
def _p___reinit__(self,copy=None):
if copy is None: return
d=self.__dict__
cd=copy.__dict__
oid=self._p_oid
jar=self._p_jar
newstate={}
for key in cd.keys():
if key[:3] != '_p_': newstate[key]=cd[key]
for key in d.keys():
if key[:3] != '_p_': del d[key]
d['_p_newstate']=newstate
d['_p_jar']=jar
d['_p_setstate']=jar.setstate
d['_p_changed']=0
def __setattr__(self,key,value):
' '
if key[:3]=='_p_':
self.__dict__[key]=value
return
try:
setstate=self.__dict__['_p_setstate']
try: setstate(self)
except: raise TypeError, (sys.exc_type, sys.exc_value,
sys.exc_traceback)
except KeyError: pass
except TypeError, v: raise v[0], v[1], v[2]
self.__dict__[key]=value
self.__changed__(1)
def __repr__(self):
' '
return '<%s instance at %s>' % (self.__class__.__name__,hex(id(self)))
def __getstate__(self):
# First, update my state, if necessary:
try:
setstate=self.__dict__['_p_setstate']
try: setstate(self)
except: raise TypeError, (sys.exc_type, sys.exc_value,
sys.exc_traceback)
except KeyError: pass
except TypeError, v: raise v[0], v[1], v[2]
state={}
d=self.__dict__
for k in d.keys():
if k[:3] != '_p_':
state[k]=d[k]
return state
def __setstate__(self,state):
d=self.__dict__
for k in state.keys():
d[k]=state[k]
return state
def __save__(self):
'''\
Update the object in a persistent database.
'''
jar=self._p_jar
if jar and self._p_changed: jar.store(self)
def __changed__(self,value=None):
'''\
Flag or determine whether an object has changed
If a value is specified, then it should indicate whether an
object has or has not been changed. If no value is specified,
then the return value will indicate whether the object has
changed.
'''
if value is not None:
self.__dict__['_p_changed']=value
else:
return self._p_changed
# The following was copied from the SingleThreadedTransaction module:
#
# Base class for all transactional objects
# Transactional objects, like persistent objects track
# changes in state. Unlike persistent objects, transactional
# objects work in conjunction with a transaction manager to manage
# saving state and recovering from errors.
#
def __changed__(self,v=None):
if v and not self._p_changed and self._p_jar is not None:
try: get_transaction().register(self)
except: pass
return Persistence.Persistent.__changed__(self,v)
def __inform_commit__(self,T,start_time):
jar=self._p_jar
if jar and self._p_changed: jar.store(self,T)
def __inform_abort__(self,T,start_time):
try: self._p_jar.abort(self,start_time)
except: pass
try:
import cPersistence
from cPersistence import Persistent
except: pass
class PersistentMapping(Persistent):
"""\
A persistent wrapper for mapping objects.
This class allows wrapping of mapping objects so that
object changes are registered. As a side effect,
mapping objects may be subclassed.
"""
def __init__(self,container=None):
if container is None: container={}
self._container=container
def __getitem__(self, key):
return self._container[key]
def __setitem__(self, key, v):
self._container[key]=v
try: del self._v_keys
except: pass
self.__changed__(1)
def __delitem__(self, key):
del self._container[key]
try: del self._v_keys
except: pass
self.__changed__(1)
def __len__(self): return len(self._container)
def keys(self):
try: return self._v_keys
except: pass
keys=self._v_keys=filter(
lambda k: k[:1]!='_',
self._container.keys())
keys.sort()
return keys
def clear(self):
self._container={}
if hasattr(self,'_v_keys'): del self._v_keys
def values(self):
return map(lambda k, d=self: d[k], self.keys())
def items(self):
return map(lambda k, d=self: (k,d[k]), self.keys())
def has_key(self,key): return self._container.has_key(key)
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