예제 #1
0
    async def clear_manifest(self, entry_id: EntryID) -> None:
        """
        Raises:
            FSLocalMissError
        """

        async with self._open_cursor() as cursor:

            # Safely remove from cache
            in_cache = bool(self._cache.pop(entry_id, None))

            # Remove from local database
            cursor.execute("DELETE FROM vlobs WHERE vlob_id = ?",
                           (entry_id.bytes, ))
            cursor.execute("SELECT changes()")
            deleted, = cursor.fetchone()

            # Clean all the pending chunks
            # TODO: should also add the content of the popped manifest
            pending_chunk_ids = self._cache_ahead_of_localdb.pop(entry_id, ())
            for chunk_id in pending_chunk_ids:
                cursor.execute("DELETE FROM chunks WHERE chunk_id = ?",
                               (chunk_id.bytes, ))

        # Raise a miss if the entry wasn't found
        if not deleted and not in_cache:
            raise FSLocalMissError(entry_id)
예제 #2
0
 async def get_manifest(self, entry_id: EntryID) -> BaseLocalManifest:
     """Raises: FSLocalMissError"""
     assert isinstance(entry_id, EntryID)
     try:
         return self._cache[entry_id]
     except KeyError:
         raise FSLocalMissError(entry_id)
예제 #3
0
    async def get_manifest(self, entry_id: EntryID) -> BaseLocalManifest:
        """
        Raises:
            FSLocalMissError
        """
        # Look in cache first
        try:
            return self._cache[entry_id]
        except KeyError:
            pass

        # Look into the database
        async with self._open_cursor() as cursor:
            cursor.execute("SELECT blob FROM vlobs WHERE vlob_id = ?",
                           (entry_id.bytes, ))
            manifest_row = cursor.fetchone()

        # Not found
        if not manifest_row:
            raise FSLocalMissError(entry_id)

        # Safely fill the cache
        if entry_id not in self._cache:
            self._cache[entry_id] = BaseLocalManifest.decrypt_and_load(
                manifest_row[0], key=self.device.local_symkey)

        # Always return the cached value
        return self._cache[entry_id]
예제 #4
0
    async def clear_chunk(self, chunk_id: ChunkID) -> None:
        async with self._open_cursor() as cursor:
            cursor.execute("DELETE FROM chunks WHERE chunk_id = ?", (chunk_id.bytes,))
            cursor.execute("SELECT changes()")
            changes, = cursor.fetchone()

        if not changes:
            raise FSLocalMissError(chunk_id)
예제 #5
0
    async def clear_chunk(self, chunk_id: ChunkID) -> None:
        async with self._open_cursor() as cursor:
            # Use a thread as executing a statement that modifies the content of the database might,
            # in some case, block for several hundreds of milliseconds
            await self.localdb.run_in_thread(
                cursor.execute, "DELETE FROM chunks WHERE chunk_id = ?",
                (chunk_id.bytes, ))
            cursor.execute("SELECT changes()")
            changes, = cursor.fetchone()

        if not changes:
            raise FSLocalMissError(chunk_id)
예제 #6
0
    async def get_chunk(self, chunk_id: ChunkID) -> bytes:
        async with self._open_cursor() as cursor:
            cursor.execute(
                """
                UPDATE chunks SET accessed_on = ? WHERE chunk_id = ?;
                """,
                (time.time(), chunk_id.bytes),
            )
            cursor.execute("SELECT changes()")
            changes, = cursor.fetchone()
            if not changes:
                raise FSLocalMissError(chunk_id)

            cursor.execute("""SELECT data FROM chunks WHERE chunk_id = ?""", (chunk_id.bytes,))
            ciphered, = cursor.fetchone()

        return self.local_symkey.decrypt(ciphered)
예제 #7
0
    async def get_chunk(self, chunk_id: ChunkID) -> bytes:
        async with self._open_cursor() as cursor:
            # Use a thread as executing a statement that modifies the content of the database might,
            # in some case, block for several hundreds of milliseconds
            await self.localdb.run_in_thread(
                cursor.execute,
                """
                UPDATE chunks SET accessed_on = ? WHERE chunk_id = ?;
                """,
                (time.time(), chunk_id.bytes),
            )
            cursor.execute("SELECT changes()")
            changes, = cursor.fetchone()
            if not changes:
                raise FSLocalMissError(chunk_id)
            cursor.execute("""SELECT data FROM chunks WHERE chunk_id = ?""",
                           (chunk_id.bytes, ))
            ciphered, = cursor.fetchone()

        return self.local_symkey.decrypt(ciphered)