Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAleksey Lim <alsroot@sugarlabs.org>2014-01-05 07:45:41 (GMT)
committer Aleksey Lim <alsroot@sugarlabs.org>2014-01-05 07:45:41 (GMT)
commit28f17ea51f50fd75025bc598cbca1351aad4be3f (patch)
treea9664ac563352705f02b3fecd6ef094bc5c511ea
parent5955e4a46d48dd6099e56e17b7fa545be46de540 (diff)
Delete blobs while updating existing properties
-rw-r--r--sugar_network/db/directory.py8
-rw-r--r--sugar_network/db/storage.py10
-rwxr-xr-xtests/units/db/resource.py20
3 files changed, 31 insertions, 7 deletions
diff --git a/sugar_network/db/directory.py b/sugar_network/db/directory.py
index 50f209e..eb2f0e2 100644
--- a/sugar_network/db/directory.py
+++ b/sugar_network/db/directory.py
@@ -304,7 +304,8 @@ class Directory(object):
meta['seqno'] = (orig_meta or {}).get('seqno') or 0
meta.update(kwargs)
merge[prop] = meta
- patch[prop] = meta.get('value')
+ if op is not None:
+ patch[prop] = meta.get('value')
if not merge:
return seqno, False
@@ -312,7 +313,8 @@ class Directory(object):
if op is not None:
op(patch)
for prop, meta in merge.items():
- record.set(prop, **meta)
+ is_blob = isinstance(self.metadata[prop], BlobProperty)
+ record.set(prop, cleanup_blob=is_blob, **meta)
if record.consistent:
props = {}
@@ -351,7 +353,7 @@ class Directory(object):
value = changes.get(name)
if isinstance(prop, BlobProperty):
if isinstance(value, dict):
- record.set(name, seqno=seqno, **value)
+ record.set(name, seqno=seqno, cleanup_blob=True, **value)
elif isinstance(value, basestring):
record.set(name, seqno=seqno, blob=StringIO(value))
elif isinstance(prop, StoredProperty):
diff --git a/sugar_network/db/storage.py b/sugar_network/db/storage.py
index 83fb0c7..a280a13 100644
--- a/sugar_network/db/storage.py
+++ b/sugar_network/db/storage.py
@@ -135,14 +135,16 @@ class Record(object):
meta['mtime'] = int(os.stat(path).st_mtime)
return meta
- def set(self, prop, mtime=None, **meta):
+ def set(self, prop, mtime=None, cleanup_blob=False, blob=None, **meta):
if not exists(self._root):
os.makedirs(self._root)
meta_path = join(self._root, prop)
+ dst_blob_path = meta_path + _BLOB_SUFFIX
- if 'blob' in meta:
- dst_blob_path = meta_path + _BLOB_SUFFIX
- blob = meta.pop('blob')
+ if (cleanup_blob or blob is not None) and exists(dst_blob_path):
+ os.unlink(dst_blob_path)
+
+ if blob is not None:
if hasattr(blob, 'read'):
with toolkit.new_file(dst_blob_path) as f:
shutil.copyfileobj(blob, f)
diff --git a/tests/units/db/resource.py b/tests/units/db/resource.py
index 97e8b1b..ad4580f 100755
--- a/tests/units/db/resource.py
+++ b/tests/units/db/resource.py
@@ -900,6 +900,26 @@ class ResourceTest(tests.Test):
self.assertEqual([], [i.guid for i in directory.find()[0]])
assert directory.mtime == 0
+ def test_DeleteOldBlobOnUpdate(self):
+
+ class Document(db.Resource):
+
+ @db.blob_property()
+ def blob(self, value):
+ return value
+
+ directory = Directory(tests.tmpdir, Document, IndexWriter)
+
+ directory.create({'guid': 'guid', 'blob': 'foo'})
+ assert exists('gu/guid/blob.blob')
+ directory.update('guid', {'blob': {'url': 'foo'}})
+ assert not exists('gu/guid/blob.blob')
+
+ directory.update('guid', {'blob': 'foo'})
+ assert exists('gu/guid/blob.blob')
+ directory.update('guid', {'blob': {}})
+ assert not exists('gu/guid/blob.blob')
+
def diff(directory, in_seq, out_seq, exclude_seq=None, **kwargs):
for guid, patch in directory.diff(Sequence(in_seq), Sequence(exclude_seq) if exclude_seq else None, **kwargs):