[Checkins] SVN: zc.beforestorage/trunk/ 1. Added a new option "before_from_file" that can be used to preserve the beforestorage state between restarts.
Satchidanand Haridas
satchit at zope.com
Thu Dec 9 17:19:16 EST 2010
Log message for revision 118782:
1. Added a new option "before_from_file" that can be used to preserve the beforestorage state between restarts.
2. Updated test part in buildout.cfg to add zope.testing so tests could be run.
Changed:
U zc.beforestorage/trunk/buildout.cfg
U zc.beforestorage/trunk/src/zc/beforestorage/README.txt
U zc.beforestorage/trunk/src/zc/beforestorage/__init__.py
U zc.beforestorage/trunk/src/zc/beforestorage/component.xml
-=-
Modified: zc.beforestorage/trunk/buildout.cfg
===================================================================
--- zc.beforestorage/trunk/buildout.cfg 2010-12-09 22:02:53 UTC (rev 118781)
+++ zc.beforestorage/trunk/buildout.cfg 2010-12-09 22:19:16 UTC (rev 118782)
@@ -14,3 +14,4 @@
[test]
recipe = zc.recipe.testrunner
eggs = zc.beforestorage
+ zope.testing
Modified: zc.beforestorage/trunk/src/zc/beforestorage/README.txt
===================================================================
--- zc.beforestorage/trunk/src/zc/beforestorage/README.txt 2010-12-09 22:02:53 UTC (rev 118781)
+++ zc.beforestorage/trunk/src/zc/beforestorage/README.txt 2010-12-09 22:19:16 UTC (rev 118782)
@@ -82,6 +82,9 @@
Using ZConfig to configure Before storages
==========================================
+"before" option
+---------------
+
To use before storages from ZConfig configuration files, you need to
import zc.beforestorage and then use a before storage section.
@@ -164,6 +167,190 @@
2008-01-21 18:22:43.000000
>>> storage.close()
+
+"before-from-file" option
+-------------------------
+
+The "before-from-file" option can be used to preserve the changes file between
+restarts. It's value is the absolute path to a file. If the file exists, the
+"before" time will be read from that file. If the file does not exist,
+it will be created and the current UTC time will be written to it
+
+When used with a Changes file that does NOT have the "create=true"
+option set, the database will be preserved between restarts.
+
+ >>> import os.path
+ >>> import tempfile
+
+ >>> tempdir = tempfile.mkdtemp()
+ >>> before_file = os.path.join(tempdir, 'before-file')
+
+Currently the file does not exist. So it'll be created and written with the
+current time. In order to make this repeatable, we "monkeypatch" the "get_now"
+function in the module to return a fixed value:
+
+ >>> import datetime
+ >>> import zc.beforestorage
+
+ >>> def fake_get_utcnow():
+ ... return datetime.datetime(2008, 1, 1, 15, 0)
+ >>> orig_get_utcnow = zc.beforestorage.get_utcnow
+ >>> zc.beforestorage.get_utcnow = fake_get_utcnow
+
+ >>> os.path.exists(before_file)
+ False
+
+ >>> storage = ZODB.config.storageFromString("""
+ ...
+ ... %%import zc.beforestorage
+ ...
+ ... <before>
+ ... before-from-file %s
+ ... <filestorage>
+ ... path my.fs
+ ... </filestorage>
+ ... </before>
+ ... """ % before_file)
+
+ >>> storage
+ <Before: my.fs before 2008-01-01 15:00:00.000000>
+
+ >>> storage.close()
+
+The file will now have been created:
+
+ >>> os.path.exists(before_file)
+ True
+
+ >>> f = open(before_file)
+ >>> f.read() == fake_get_utcnow().replace(microsecond=0).isoformat()
+ True
+
+If we now write a new value to the file, the storage will be started with that
+time.
+
+ >>> f = open(before_file, 'w')
+ >>> f.write('1990-01-01T11:11')
+ >>> f.close()
+
+ >>> storage = ZODB.config.storageFromString("""
+ ...
+ ... %%import zc.beforestorage
+ ...
+ ... <before>
+ ... before-from-file %s
+ ... <filestorage>
+ ... path my.fs
+ ... </filestorage>
+ ... </before>
+ ... """ % before_file)
+
+ >>> storage
+ <Before: my.fs before 1990-01-01 11:11:00.000000>
+
+ >>> storage.close()
+
+If we restart the storage, the value from the file will be used.
+
+ >>> storage = ZODB.config.storageFromString("""
+ ...
+ ... %%import zc.beforestorage
+ ...
+ ... <before>
+ ... before-from-file %s
+ ... <filestorage>
+ ... path my.fs
+ ... </filestorage>
+ ... </before>
+ ... """ % before_file)
+
+ >>> storage
+ <Before: my.fs before 1990-01-01 11:11:00.000000>
+
+ >>> storage.close()
+
+This will continue to happen until we remove the file. The "before_from_file"
+path is stored on the storage itself, so applications that use it have access
+to it.
+
+ >>> os.remove(storage.before_from_file)
+
+ >>> os.path.exists(before_file)
+ False
+
+If we restart the storage again, a new file will be created.
+
+ >>> storage = ZODB.config.storageFromString("""
+ ...
+ ... %%import zc.beforestorage
+ ...
+ ... <before>
+ ... before-from-file %s
+ ... <filestorage>
+ ... path my.fs
+ ... </filestorage>
+ ... </before>
+ ... """ % before_file)
+
+ >>> storage
+ <Before: my.fs before 2008-01-01 15:00:00.000000>
+
+ >>> storage.close()
+
+Note that unlike the "before" option, the "before-from-file" file cannot
+contain special values such as "now" or "startup".
+
+ >>> f = open(before_file, 'w')
+ >>> f.write('now')
+ >>> f.close()
+
+ >>> storage = ZODB.config.storageFromString("""
+ ...
+ ... %%import zc.beforestorage
+ ...
+ ... <before>
+ ... before-from-file %s
+ ... <filestorage>
+ ... path my.fs
+ ... </filestorage>
+ ... </before>
+ ... """ % before_file)
+
+ >>> storage
+ Traceback (most recent call last):
+ ...
+ ValueError: 8-character string expected
+
+ >>> storage.close()
+
+Note that only one of "before" or "before-from-file" options can be specified,
+not both:
+
+ >>> storage = ZODB.config.storageFromString("""
+ ...
+ ... %%import zc.beforestorage
+ ...
+ ... <before>
+ ... before 2008-01-01
+ ... before-from-file %s
+ ... <filestorage>
+ ... path my.fs
+ ... </filestorage>
+ ... </before>
+ ... """ % before_file)
+ Traceback (most recent call last):
+ ...
+ ValueError: Only one of "before" or "before-from-file" options can be specified, not both
+
+
+Cleanup...
+
+ >>> import shutil
+ >>> shutil.rmtree(tempdir)
+
+ >>> zc.beforestorage.get_utcnow = orig_get_utcnow
+
+
Demonstration (doctest)
=======================
Modified: zc.beforestorage/trunk/src/zc/beforestorage/__init__.py
===================================================================
--- zc.beforestorage/trunk/src/zc/beforestorage/__init__.py 2010-12-09 22:02:53 UTC (rev 118781)
+++ zc.beforestorage/trunk/src/zc/beforestorage/__init__.py 2010-12-09 22:19:16 UTC (rev 118782)
@@ -12,6 +12,8 @@
#
##############################################################################
+import datetime
+import os.path
import time
import ZODB.POSException
@@ -26,6 +28,9 @@
before = repr(ZODB.TimeStamp.TimeStamp(*(g[:5] + (g[5]+(t%1), ))))
return before
+def get_utcnow():
+ return datetime.datetime.utcnow()
+
startup_time_stamp = time_stamp()
class Before:
@@ -169,10 +174,28 @@
def open(self):
base = self.config.base.open()
before = self.config.before
- if isinstance(before, basestring):
+ before_from_file = self.config.before_from_file
+ if (before and before_from_file):
+ raise ValueError(
+ 'Only one of "before" or "before-from-file" options '
+ 'can be specified, not both')
+ if before and isinstance(before, basestring):
if before.lower() == 'now':
self.config.before = None
elif before.lower() == 'startup':
self.config.before = startup_time_stamp
- return Before(base, self.config.before)
+ elif before_from_file:
+ if os.path.exists(before_from_file):
+ f = open(before_from_file)
+ self.config.before = f.read()
+ else:
+ f = open(before_from_file, 'w')
+ self.config.before = get_utcnow().replace(microsecond=0).isoformat()
+ f.write(self.config.before)
+ f.close()
+ before_storage = Before(base, self.config.before)
+ before_storage.before_from_file = self.config.before_from_file
+ return before_storage
+
+
Modified: zc.beforestorage/trunk/src/zc/beforestorage/component.xml
===================================================================
--- zc.beforestorage/trunk/src/zc/beforestorage/component.xml 2010-12-09 22:02:53 UTC (rev 118781)
+++ zc.beforestorage/trunk/src/zc/beforestorage/component.xml 2010-12-09 22:19:16 UTC (rev 118782)
@@ -21,6 +21,15 @@
opening of the beforestorage.
</description>
</key>
+ <key name="before-from-file" datatype="string" required="no">
+ <description>
+ An absolute path to a file used to track the 'before' time. If the file
+ exists it should contain the before time to use. Note that unlike the
+ 'before' option, 'now' and 'startup' cannot be used here.
+ If the file does not exist, it'll be created and written with the
+ current time.
+ </description>
+ </key>
</sectiontype>
</component>
More information about the checkins
mailing list