[storage] consider fs_importing on update operations too stable
authorAdrien Di Mascio <Adrien.DiMascio@logilab.fr>
Thu, 08 Apr 2010 09:59:59 +0200
branchstable
changeset 5183 8d66003351f8
parent 5182 3bc8250731fe
child 5185 92376b009b98
[storage] consider fs_importing on update operations too
server/sources/storages.py
server/test/unittest_storage.py
--- a/server/sources/storages.py	Thu Apr 08 10:00:22 2010 +0200
+++ b/server/sources/storages.py	Thu Apr 08 09:59:59 2010 +0200
@@ -85,9 +85,16 @@
 
     def entity_updated(self, entity, attr):
         """an entity using this storage for attr has been updatded"""
-        binary = entity.pop(attr)
-        fpath = self.current_fs_path(entity, attr)
-        UpdateFileOp(entity._cw, filepath=fpath, filedata=binary.getvalue())
+        if entity._cw.transaction_data.get('fs_importing'):
+            oldpath = self.current_fs_path(entity, attr)
+            fpath = entity[attr].getvalue()
+            if oldpath != fpath:
+                DeleteFileOp(entity._cw, filepath=oldpath)
+            binary = Binary(file(fpath).read())
+        else:
+            binary = entity.pop(attr)
+            fpath = self.current_fs_path(entity, attr)
+            UpdateFileOp(entity._cw, filepath=fpath, filedata=binary.getvalue())
         return binary
 
     def entity_deleted(self, entity, attr):
--- a/server/test/unittest_storage.py	Thu Apr 08 10:00:22 2010 +0200
+++ b/server/test/unittest_storage.py	Thu Apr 08 09:59:59 2010 +0200
@@ -57,6 +57,11 @@
         return req.create_entity('File', data=Binary(content),
                                  data_format=u'text/plain', data_name=u'foo')
 
+    def fspath(self, entity):
+        fspath = self.execute('Any fspath(D) WHERE F eid %(f)s, F data D',
+                              {'f': entity.eid})[0][0]
+        return fspath.getvalue()
+
     def test_bfss_storage(self):
         f1 = self.create_file()
         expected_filepath = osp.join(self.tempdir, '%s_data' % f1.eid)
@@ -81,18 +86,14 @@
     def test_bfss_sqlite_fspath(self):
         f1 = self.create_file()
         expected_filepath = osp.join(self.tempdir, '%s_data' % f1.eid)
-        fspath = self.execute('Any fspath(D) WHERE F eid %(f)s, F data D',
-                              {'f': f1.eid})[0][0]
-        self.assertEquals(fspath.getvalue(), expected_filepath)
+        self.assertEquals(self.fspath(f1), expected_filepath)
 
     def test_bfss_fs_importing_doesnt_touch_path(self):
         self.session.transaction_data['fs_importing'] = True
         filepath = osp.abspath(__file__)
         f1 = self.session.create_entity('File', data=Binary(filepath),
                                         data_format=u'text/plain', data_name=u'foo')
-        fspath = self.execute('Any fspath(D) WHERE F eid %(f)s, F data D',
-                              {'f': f1.eid})[0][0]
-        self.assertEquals(fspath.getvalue(), filepath)
+        self.assertEquals(self.fspath(f1), filepath)
 
     def test_source_storage_transparency(self):
         with self.temporary_appobjects(DummyBeforeHook, DummyAfterHook):
@@ -180,5 +181,21 @@
         self.assertEquals(f2.data.getvalue(), 'some other data')
 
 
+    def test_bfss_update_with_fs_importing(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')
+        old_fspath = self.fspath(f1)
+        self.session.transaction_data['fs_importing'] = True
+        new_fspath = osp.join(self.tempdir, 'newfile.txt')
+        file(new_fspath, 'w').write('the new data')
+        self.execute('SET F data %(d)s WHERE F eid %(f)s',
+                     {'d': Binary(new_fspath), 'f': f1.eid})
+        self.commit()
+        self.assertEquals(f1.data.getvalue(), 'the new data')
+        self.assertEquals(self.fspath(f1), new_fspath)
+        self.failIf(osp.isfile(old_fspath))
+
+
 if __name__ == '__main__':
     unittest_main()