Back to index

plone3  3.1.7
IStorage.py
Go to the documentation of this file.
00001 #########################################################################
00002 # Copyright (c) 2004, 2005 Alberto Berti, Gregoire Weber.
00003 # All Rights Reserved.
00004 #
00005 # This file is part of CMFEditions.
00006 #
00007 # CMFEditions is free software; you can redistribute it and/or modify
00008 # it under the terms of the GNU General Public License as published by
00009 # the Free Software Foundation; either version 2 of the License, or
00010 # (at your option) any later version.
00011 #
00012 # CMFEditions is distributed in the hope that it will be useful,
00013 # but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 # GNU General Public License for more details.
00016 #
00017 # You should have received a copy of the GNU General Public License
00018 # along with CMFEditions; if not, write to the Free Software
00019 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00020 #########################################################################
00021 """Manages Storing and Retrieving Version to and from the Storage
00022 
00023 ``IStorage`` defines the fundamental storage operations wheras
00024 ``IPurgePolicy`` defines support for purging versions from the
00025 storage. The other interface definitions are defintions for types
00026 returned by storage methods.
00027 
00028 $Id$
00029 """
00030 
00031 from Interface import Interface, Attribute
00032 
00033 class IStorage(Interface):
00034     """Manages Storing and Retrieving Version to and from the Storage
00035 
00036     Every resource has it's own history.
00037     """
00038 
00039     def isRegistered(history_id):
00040         """Returns True if the object is already registered.
00041 
00042         A registered object has a history.
00043         """
00044 
00045     def register(history_id, object, referenced_data={}, metadata={}):
00046         """Sets up a new history for the object and does the first save.
00047 
00048         The 'object' and the 'referenced_data' together contain the whole
00049         data to be added to the history.
00050 
00051         'object' is already a clone and needn't be cloned anymore before
00052         beeing added to the history. Data in 'referenced_data' are direct
00053         references to the original object and must be cloned before being
00054         added to the history.
00055 
00056         'referenced_data' is a list or tuple of python references or
00057         'IStreamableReference' objects.
00058 
00059         'metadata' must be a (nested) dictionary. If a 'comment' key exists
00060         the implementation may assume it is a human readable string.
00061 
00062         May veto the registering proces by raising a 'StorageError'
00063         exception. No action is performed on repeated registering.
00064 
00065         Returns the value of the newest version(selector).
00066         """
00067 
00068     def save(history_id, object, referenced_data={}, metadata={}):
00069         """Appends an object current state to a history.
00070 
00071         The 'object' and the 'referenced_data' together contain the whole
00072         data to be added to the history.
00073 
00074         'object' is already a clone and needn't be cloned anymore before
00075         beeing added to the history. Data in 'referenced_data' are direct
00076         references to the original object and must be cloned before being
00077         added to the history.
00078 
00079         'referenced_data' is a list or tuple of python references or
00080         'IStreamableReference' objects.
00081 
00082         'metadata' must be a (nested) dictionary. If a 'comment' key exists
00083         the implementation may assume it is a human readable string.
00084 
00085         Returns the value of the newest version(selector).
00086         """
00087 
00088     def retrieve(history_id, selector):
00089         """Returns a selected version of an object, which has the given
00090            history id.
00091 
00092         Returns a 'IVersionData' object.
00093         """
00094 
00095     def getHistory(history_id):
00096         """Return the history of an object by the given history id.
00097 
00098         Returns a 'IHistory' object.
00099         """
00100 
00101     def getModificationDate(history_id, selector=None):
00102         """ Returns the modification date of the selected version of object
00103             which has the given history id.
00104 
00105         If selected is None, the most recent version (HEAD) is taken.
00106         """
00107 
00108 
00109 class IPurgeSupport(Interface):
00110     """Storage Purge Support
00111 
00112     Purging a version from the storage removes that version irrevocably.
00113 
00114     Adds ``purge`` and extends the signature of ``retrieve``, ``getHistory``
00115     and ``getModificationDate``. The defaults of the extended methods
00116     mimique the standard behaviour of the original methods.
00117 
00118     With the introduction of purging two selection scheme exist for
00119     retrieving versions. Either purged versions are taken into account
00120     or not:
00121 
00122     - By passing ``countPurged=True`` purged versions are taken into
00123       account when accessing a version. When a purged version is accessed
00124       the storage tool decides what to do.
00125     - By passing ``countPurged=False`` purged versions are **not taken into
00126       account** when accessing a version.
00127 
00128     Example:
00129 
00130     An object got saved ten times. Two versions got purged in earlier
00131     calls. The history looks like this (``s`` means: depends on storage,
00132     ``e`` means: exception raised)::
00133 
00134       countPurged==True:
00135 
00136         selector:          0, 1, 2, 3, 4, 5, 6, 7, 8, 9
00137         version retrieved: 0, 1, 2, s, s, 5, 6, 7, 8, 9
00138 
00139       countPurged==False:
00140 
00141         selector:          0, 1, 2, 3, 4, 5, 6, 7, 8, 9
00142         version retrieved: 0, 1, 2, 5, 6, 7, 8, 9, e, e
00143     """
00144 
00145     def purge(history_id, selector, metadata={}, countPurged=True):
00146         """Purge a Version from a Resources History
00147 
00148         If ``countPurged`` is ``True`` version numbering counts purged
00149         versions also. If ``False`` purged versiona are not taken into
00150         account.
00151 
00152         Purge the given version from the given history. The metadata
00153         passed may be used to store informations about the reasons of
00154         the purging.
00155         """
00156 
00157     def retrieve(history_id, selector, countPurged=True, substitute=True):
00158         """Return the Version of the Resource with the given History Id
00159 
00160         If ``countPurged`` is ``True`` purged versions are taken into
00161         account also. If ``False`` purged versions are ignored and not
00162         taken into account in counting.
00163 
00164         If ``substitute`` is ``True`` a substitute is returned in case
00165         the requested version was purged before.
00166 
00167         Return a ``IVersionData`` object.
00168         """
00169 
00170     def getHistory(history_id, countPurged=True, substitute=True):
00171         """Return the history of an object by the given history id.
00172 
00173         If ``countPurged`` is ``True`` purged versions are returned also.
00174         If ``False`` purged versions aren't returned.
00175 
00176         If ``substitute`` is ``True`` a substitute is returned in case
00177         the requested version was purged before.
00178 
00179         Return a ``IHistory`` object.
00180         """
00181 
00182     def getModificationDate(history_id, selector=None, countPurged=True,
00183                             substitute=True):
00184         """ Returns the modification date of the selected version of object
00185             which has the given history id.
00186 
00187         If ``countPurged`` is ``True`` purged versions are returned also.
00188         If ``False`` purged versions aren't returned.
00189 
00190         If ``substitute`` is ``True`` a substitute is returned in case
00191         the requested version was purged before.
00192 
00193         If selected is None, the most recent version (HEAD) is taken.
00194         """
00195 
00196 
00197 class IHistory(Interface):
00198     """Iterable version history.
00199     """
00200 
00201     def __len__():
00202         """Return the length of the history.
00203         """
00204 
00205     def __getattr__(version_id):
00206         """Return the version of an object corresponding to the version id.
00207 
00208         The item returned is of ``IVersionData``.
00209         """
00210 
00211     def __iter__():
00212         """Iterator returning the versions.
00213 
00214         The iterators ``next`` method returns ``IVersionData`` objects.
00215         """
00216 
00217 
00218 class IVersionData(Interface):
00219     """
00220     """
00221     object = Attribute(
00222         """The objects state at save time.
00223 
00224         To avoid temporal problems (by changing the history) this
00225         object has to be cloned before any change.
00226         """)
00227 
00228     referenced_data = Attribute(
00229         """Data beeing passed by reference at save time.
00230 
00231         Needs not be cloned before allowing write access. Cloning was
00232         already done by the storage layer.
00233         """)
00234 
00235     metadata = Attribute(
00236         """Metadata stored alongside when the objects state was saved.
00237 
00238         Metadata has to be cloned before any write change to avoid
00239         temporal problems (by changing the history).
00240         """)
00241 
00242 
00243 class IStreamableReference(Interface):
00244     """Marks an object passed to the storage by reference as streamable.
00245 
00246     This allows the history storage to optimize saving and retrieving by
00247     e.g. avoiding pickling/unpickling. This is mostly interesting for
00248     long streams.
00249     """
00250 
00251     def __init__(self, obj):
00252         """Wrap the object to be passed to the storage
00253         """
00254 
00255     def getObject(self):
00256         """Return the object
00257         """
00258 
00259     def getSize(self):
00260         """Return the size of the streamable object or None
00261         """
00262 
00263 class StorageError(Exception):
00264     """History storage exception.
00265     """
00266 
00267 class StorageRetrieveError(StorageError):
00268     """Raised if tried to retrieve a non existent version of a resource.
00269     """
00270 
00271 class StorageRegisterError(StorageError):
00272     """Raised if registering the resource failed.
00273     """
00274 
00275 class StorageSaveError(StorageError):
00276     """Raised if saving a new version of a resource failed.
00277     """
00278 
00279 class StorageUnregisteredError(StorageError):
00280     """Raised if trying to save an unregistered resource.
00281     """
00282 
00283 class StoragePurgeError(StorageError):
00284     """Raised if tried to purge a non existent version of a resource.
00285     """