# HG changeset patch # User Pierre-Yves David # Date 1275026717 -7200 # Node ID be94157bd75418b6579b6e3ac83b524ebc676d45 # Parent 0a68e7f5829c406a31c4d84c08a5755ed1f9187e [bfss] Rename filenames according to their metadata on entity update. diff -r 0a68e7f5829c -r be94157bd754 server/sources/storages.py --- a/server/sources/storages.py Wed May 26 18:32:27 2010 +0200 +++ b/server/sources/storages.py Fri May 28 08:05:17 2010 +0200 @@ -125,17 +125,18 @@ def entity_updated(self, entity, attr): """an entity using this storage for attr has been updatded""" + oldpath = self.current_fs_path(entity, attr) if entity._cw.transaction_data.get('fs_importing'): - oldpath = self.current_fs_path(entity, attr) fpath = entity[attr].getvalue() - if oldpath != fpath: - hook.set_operation(entity._cw, 'bfss_deleted', oldpath, - DeleteFileOp) binary = Binary(file(fpath).read()) else: binary = entity.pop(attr) - fpath = self.current_fs_path(entity, attr) + fpath = self.new_fs_path(entity, attr) UpdateFileOp(entity._cw, filepath=fpath, filedata=binary.getvalue()) + if oldpath != fpath: + entity[attr] = Binary(fpath) + hook.set_operation(entity._cw, 'bfss_deleted', oldpath, + DeleteFileOp) return binary def entity_deleted(self, entity, attr): diff -r 0a68e7f5829c -r be94157bd754 server/test/unittest_storage.py --- a/server/test/unittest_storage.py Wed May 26 18:32:27 2010 +0200 +++ b/server/test/unittest_storage.py Fri May 28 08:05:17 2010 +0200 @@ -21,7 +21,7 @@ from __future__ import with_statement -from logilab.common.testlib import unittest_main +from logilab.common.testlib import unittest_main, tag from cubicweb.devtools.testlib import CubicWebTC import os.path as osp @@ -180,7 +180,7 @@ self.assertEquals(f1.data.getvalue(), file(filepath).read(), 'files content differ') - + @tag('Storage', 'BFSS', 'update') def test_bfss_update_with_existing_data(self): # use self.session to use server-side cache f1 = self.session.create_entity('File', data=Binary('some data'), @@ -194,6 +194,52 @@ f2 = self.execute('Any F WHERE F eid %(f)s, F is File', {'f': f1.eid}).get_entity(0, 0) self.assertEquals(f2.data.getvalue(), 'some other data') + @tag('Storage', 'BFSS', 'update', 'extension', 'commit') + def test_bfss_update_with_different_extension_commited(self): + # use self.session to use server-side cache + f1 = self.session.create_entity('File', data=Binary('some data'), + data_format=u'text/plain', data_name=u'foo.txt') + # NOTE: do not use set_attributes() which would automatically + # update f1's local dict. We want the pure rql version to work + self.commit() + old_path = self.fspath(f1) + self.failUnless(osp.isfile(old_path)) + self.assertEquals(osp.splitext(old_path)[1], '.txt') + self.execute('SET F data %(d)s, F data_name %(dn)s, F data_format %(df)s WHERE F eid %(f)s', + {'d': Binary('some other data'), 'f': f1.eid, 'dn': u'bar.jpg', 'df': u'image/jpeg'}) + self.commit() + # the new file exists with correct extension + # the old file is dead + f2 = self.execute('Any F WHERE F eid %(f)s, F is File', {'f': f1.eid}).get_entity(0, 0) + new_path = self.fspath(f2) + self.failIf(osp.isfile(old_path)) + self.failUnless(osp.isfile(new_path)) + self.assertEquals(osp.splitext(new_path)[1], '.jpg') + + @tag('Storage', 'BFSS', 'update', 'extension', 'rollback') + def test_bfss_update_with_different_extension_rollbacked(self): + # use self.session to use server-side cache + f1 = self.session.create_entity('File', data=Binary('some data'), + data_format=u'text/plain', data_name=u'foo.txt') + # NOTE: do not use set_attributes() which would automatically + # update f1's local dict. We want the pure rql version to work + self.commit() + old_path = self.fspath(f1) + old_data = f1.data.getvalue() + self.failUnless(osp.isfile(old_path)) + self.assertEquals(osp.splitext(old_path)[1], '.txt') + self.execute('SET F data %(d)s, F data_name %(dn)s, F data_format %(df)s WHERE F eid %(f)s', + {'d': Binary('some other data'), 'f': f1.eid, 'dn': u'bar.jpg', 'df': u'image/jpeg'}) + self.rollback() + # the new file exists with correct extension + # the old file is dead + f2 = self.execute('Any F WHERE F eid %(f)s, F is File', {'f': f1.eid}).get_entity(0, 0) + new_path = self.fspath(f2) + new_data = f2.data.getvalue() + self.failUnless(osp.isfile(new_path)) + self.assertEquals(osp.splitext(new_path)[1], '.txt') + self.assertEquals(old_path, new_path) + self.assertEquals(old_data, new_data) def test_bfss_update_with_fs_importing(self): # use self.session to use server-side cache