From 46052f494e3d2cc7db86c3af96072f23503c659a Mon Sep 17 00:00:00 2001 From: Benjamin Saller Date: Mon, 23 Jul 2007 21:13:59 +0000 Subject: create new files on inplace stores properly --- diff --git a/src/olpc/datastore/backingstore.py b/src/olpc/datastore/backingstore.py index 5aede54..8903df7 100644 --- a/src/olpc/datastore/backingstore.py +++ b/src/olpc/datastore/backingstore.py @@ -240,6 +240,10 @@ class FileBackingStore(BackingStore): def _targetFile(self, uid, target=None, ext=None, env=None): # paths out of the datastore, working copy targets + path = self._translatePath(uid) + if not os.path.exists(path): + return None + if target: targetpath = target else: targetpath = uid.replace('/', '_').replace('.', '__') @@ -267,8 +271,7 @@ class FileBackingStore(BackingStore): break targetpath = "%s(%s)%s" % (targetpath, attempt, ext) - - path = self._translatePath(uid) + if subprocess.call(['cp', path, targetpath]): raise OSError("unable to create working copy") return open(targetpath, 'rw') @@ -331,7 +334,6 @@ class FileBackingStore(BackingStore): # File Management API def create(self, props, filelike): uid = self.indexmanager.index(props, filelike) - filename = filelike if filelike: if isinstance(filelike, basestring): # lets treat it as a filename @@ -484,17 +486,36 @@ class InplaceFileBackingStore(FileBackingStore): except KeyError: return None return os.path.join(self.uri, content.get_property('filename')) - def _targetFile(self, uid, target=None, ext=None, env=None): - # in this case the file should really be there unless it was - # deleted in place or something which we typically isn't allowed - targetpath = self._translatePath(uid) - return open(targetpath, 'rw') +## def _targetFile(self, uid, target=None, ext=None, env=None): +## # in this case the file should really be there unless it was +## # deleted in place or something which we typically isn't +## # allowed +## # XXX: catch this case and remove the index +## targetpath = self._translatePath(uid) +## return open(targetpath, 'rw') # File Management API def create(self, props, filelike): # the file would have already been changed inplace # don't touch it - return self.indexmanager.index(props, filelike) + uid = self.indexmanager.index(props, filelike) + if filelike: + if isinstance(filelike, basestring): + # lets treat it as a filename + filelike = open(filelike, "r") + filelike.seek(0) + # usually with USB drives and the like the file we are + # indexing is already on it, however in the case of moving + # files to these devices we need to detect this case and + # place the file + proposed_name = props.get('filename', None) + if not proposed_name: + proposed_name = os.path.split(filelike.name)[1] + proposed_name = os.path.join(self.uri, proposed_name) + if not os.path.exists(proposed_name): + self._writeContent(uid, filelike, replace=False) + + return uid def get(self, uid, env=None, allowMissing=False): content = self.indexmanager.get(uid) diff --git a/src/olpc/datastore/model.py b/src/olpc/datastore/model.py index 4c592be..a867c2f 100644 --- a/src/olpc/datastore/model.py +++ b/src/olpc/datastore/model.py @@ -259,7 +259,7 @@ class Content(object): file = property(get_file, set_file) @property - def filename(self): return self.file.name + def filename(self): return os.path.abspath(self.file.name) @property def contents(self): return self.file.read() @@ -274,13 +274,6 @@ class Content(object): def data(self): return self._doc.data -## class Buddy(object): -## """A co-author on content. Information is collected and managed -## here""" -## pass - - - def noop(value): return value import re diff --git a/src/olpc/datastore/xapianindex.py b/src/olpc/datastore/xapianindex.py index e650241..ce09c62 100644 --- a/src/olpc/datastore/xapianindex.py +++ b/src/olpc/datastore/xapianindex.py @@ -158,6 +158,10 @@ class IndexManager(object): # for example if a USB stick is added and quickly removed # the mount should however get a stop() call which would # request that the indexing finish + # XXX: we can in many cases index, not from the tempfile but + # from the item in the repo as that will become our immutable + # copy. Detect those cases and use the internal filename + # property or backingstore._translatePath to get at it while self.indexer_running: # include timeout here to ease shutdown of the thread # if this is a non-issue we can simply allow it to block diff --git a/tests/mountpoints.txt b/tests/mountpoints.txt index c1f4619..304d4eb 100644 --- a/tests/mountpoints.txt +++ b/tests/mountpoints.txt @@ -151,9 +151,22 @@ primary store. >>> ds.complete_indexing() + >>> result, count = ds.find(dict(fulltext="four")) >>> assert count == 2 +We also need to test that we can copy from a normal store to an +inplace one. Lets move the object with u1 to mp3 + +>>> props = ds.get_properties(u1) +>>> props['mountpoint'] = mp3 +>>> pen_copy = ds.create(props, ds.get_filename(u1)) + +>>> ds.complete_indexing() + +>>> result, count = ds.find(dict(mountpoints=[mp3], filename="one.txt")) +>>> assert count == 1 +>>> assert result[0]['uid'] == pen_copy >>> ds.stop(); del ds diff --git a/tests/runalltests.py b/tests/runalltests.py index 52ec486..564cee2 100644 --- a/tests/runalltests.py +++ b/tests/runalltests.py @@ -8,7 +8,6 @@ # Alternatively use the testrunner: # python /path/to/Zope/utilities/testrunner.py -qa # - import os, sys import unittest import doctest -- cgit v0.9.1