Exemplo n.º 1
0
class SchevoStoreBackend(object):

    DEFAULT_CACHE_SIZE = 100000

    description = 'Built-in backend, based on Durus 3.4'
    backend_args_help = """
    Use "schevostore:///:memory:" for an in-memory database.

    cache_size=%(DEFAULT_CACHE_SIZE)i (int)
        Set the size of the in-memory object cache to SIZE, which is an
        integer specifying the maximum number of objects to keep in the
        cache.

    fp=None (file-like object)
        Optional file object to use instead of an actual file in the
        filesystem.
    """ % locals()

    __test__ = False

    BTree = BTree
    PDict = PersistentDict
    PList = PersistentList

    TestMethods_CreatesDatabase = TestMethods_CreatesDatabase
    TestMethods_CreatesSchema = TestMethods_CreatesSchema
    TestMethods_EvolvesSchemata = TestMethods_EvolvesSchemata

    def __init__(self,
                 database,
                 fp=None,
                 cache_size=DEFAULT_CACHE_SIZE,
                 ):
        self.database = database
        if database == ':memory:' and fp is None:
            fp = StringIO()
        self.fp = fp
        self.cache_size = cache_size
        self.is_open = False
        self.open()

    @classmethod
    def usable_by_backend(cls, filename):
        """Return (`True`, *additional backend args*) if the named
        file is usable by this backend, or `False` if not."""
        # Get first 128 bytes of file.
        f = open(filename, 'rb')
        try:
            try:
                header = f.read(128)
            except IOError:
                if sys.platform == 'win32':
                    raise DatabaseFileLocked()
                else:
                    raise
        finally:
            f.close()
        # Look for Durus file storage signature and schevo.store
        # module signature.
        if header[:5] == 'DFS20':
            if 'schevo.store.persistent_dict' in header:
                return (True, {})
        return False

    @property
    def has_db(self):
        """Return `True` if the backend contains a Schevo database."""
        return self.get_root().has_key('SCHEVO')

    def close(self):
        """Close the underlying storage (and the connection if
        needed)."""
        self.storage.close()
        self.is_open = False

    def get_root(self):
        """Return the backend's `root` object."""
        return self.conn.get_root()

    def commit(self):
        """Commit the current transaction."""
        self.conn.commit()

    def open(self):
        """Open the underlying storage based on initial arguments."""
        if not self.is_open:
            try:
                self.storage = FileStorage(self.database, fp=self.fp)
            except RuntimeError:
                raise DatabaseFileLocked()
            self.conn = Connection(self.storage, cache_size=self.cache_size)
            self.is_open = True

    def pack(self):
        """Pack the underlying storage."""
        self.conn.pack()

    def rollback(self):
        """Abort the current transaction."""
        self.conn.abort()
Exemplo n.º 2
0
class SchevoStoreBackend(object):

    description = 'Built-in backend, based on Durus 3.4'
    backend_args_help = """
    cache_size=SIZE
        Set the size of the in-memory object cache to SIZE, which is an
        integer specifying the maximum number of objects to keep in the
        cache.
    """

    __test__ = False

    BTree = BTree
    PDict = PersistentDict
    PList = PersistentList

    TestMethods_CreatesDatabase = TestMethods_CreatesDatabase
    TestMethods_CreatesSchema = TestMethods_CreatesSchema
    TestMethods_EvolvesSchemata = TestMethods_EvolvesSchemata

    def __init__(self, filename, fp=None, cache_size=100000):
        """Create a new `SchevoStoreBackend` instance.

        - `filename`: Name of file to open with this backend. If
          `None`, the backend will expect that you passed in a value
          for `fp` instead.
        - `fp`: (optional) File-like object to use instead of an
          actual file in the filesystem.
        - `cache_size`: Maximum number of objects to keep in the
          in-memory object cache.
        """
        self._filename = filename
        self._fp = fp
        self._cache_size = cache_size
        self._is_open = False
        self.open()

    @classmethod
    def args_from_string(cls, s):
        """Return a dictionary of keyword arguments based on a string given
        to a command-line tool."""
        kw = {}
        if s is not None:
            for arg in (p.strip() for p in s.split(',')):
                name, value = (p2.strip() for p2 in arg.split('='))
                if name == 'cache_size':
                    kw[name] = int(value)
                else:
                    raise KeyError(
                        '%s is not a valid name for backend args' % name)
        return kw

    @classmethod
    def usable_by_backend(cls, filename):
        """Return (`True`, *additional backend args*) if the named
        file is usable by this backend, or `False` if not."""
        # Get first 128 bytes of file.
        f = open(filename, 'rb')
        try:
            try:
                header = f.read(128)
            except IOError:
                if sys.platform == 'win32':
                    raise DatabaseFileLocked()
                else:
                    raise
        finally:
            f.close()
        # Look for Durus file storage signature and schevo.store
        # module signature.
        if header[:5] == 'DFS20':
            if 'schevo.store.persistent_dict' in header:
                return (True, {})
        return False

    @property
    def has_db(self):
        """Return `True` if the backend contains a Schevo database."""
        return self.get_root().has_key('SCHEVO')

    def close(self):
        """Close the underlying storage (and the connection if
        needed)."""
        self.storage.close()
        self._is_open = False

    def get_root(self):
        """Return the backend's `root` object."""
        return self.conn.get_root()

    def commit(self):
        """Commit the current transaction."""
        self.conn.commit()

    def open(self):
        """Open the underlying storage based on initial arguments."""
        if not self._is_open:
            try:
                self.storage = FileStorage(self._filename, fp=self._fp)
            except RuntimeError:
                raise DatabaseFileLocked()
            self.conn = Connection(self.storage, cache_size=self._cache_size)
            self._is_open = True

    def pack(self):
        """Pack the underlying storage."""
        self.conn.pack()

    def rollback(self):
        """Abort the current transaction."""
        self.conn.abort()