コード例 #1
0
def join_diffs(db, series_of_diffs, expected):
    diffs = []
    for changes in series_of_diffs:
        tracker = DBDiffTracker()
        for key, val in changes.items():
            if val is None:
                del tracker[key]
            else:
                tracker[key] = val
        diffs.append(tracker.diff())

    DBDiff.join(diffs).apply_to(db)
    assert db == expected
コード例 #2
0
def db():
    return DBDiffTracker()
コード例 #3
0
ファイル: batch.py プロジェクト: zixuanzh/py-evm
 def __init__(self, wrapped_db: BaseDB) -> None:
     self.wrapped_db = wrapped_db
     self._track_diff = DBDiffTracker()
コード例 #4
0
ファイル: batch.py プロジェクト: zixuanzh/py-evm
 def clear(self):
     self._track_diff = DBDiffTracker()
コード例 #5
0
ファイル: batch.py プロジェクト: zixuanzh/py-evm
class BatchDB(BaseDB):
    """
    A wrapper of basic DB objects with uncommitted DB changes stored in local cache,
    which represents as a dictionary of database keys and values.
    This class should be usable as a context manager, the changes either all fail or all succeed.
    Upon exiting the context, it writes all of the key value pairs from the cache into
    the underlying database. If anyerror occurred before committing phase,
    we would not apply commits at all.
    """
    logger = logging.getLogger("evm.db.BatchDB")

    wrapped_db = None  # type: BaseDB
    _track_diff = None  # type: DBDiffTracker

    def __init__(self, wrapped_db: BaseDB) -> None:
        self.wrapped_db = wrapped_db
        self._track_diff = DBDiffTracker()

    def __enter__(self) -> 'BatchDB':
        return self

    def __exit__(self, exc_type: None, exc_value: None,
                 traceback: None) -> None:
        # commit all the changes from local cache to underlying db
        if exc_type is None:
            self.commit()
        else:
            self.clear()
            self.logger.exception(
                "Unexpected error occurred during batch update")

    def clear(self):
        self._track_diff = DBDiffTracker()

    def commit(self, apply_deletes: bool = True) -> None:
        self.diff().apply_to(self.wrapped_db, apply_deletes)
        self.clear()

    def _exists(self, key: bytes) -> bool:
        try:
            self[key]
        except KeyError:
            return False
        else:
            return True

    def __getitem__(self, key: bytes) -> bytes:
        try:
            value = self._track_diff[key]
        except DiffMissingError as missing:
            if missing.is_deleted:
                raise KeyError(key)
            else:
                return self.wrapped_db[key]
        else:
            return value

    def __setitem__(self, key: bytes, value: bytes) -> None:
        self._track_diff[key] = value

    def __delitem__(self, key: bytes) -> None:
        if key not in self:
            raise KeyError(key)
        del self._track_diff[key]

    def diff(self) -> DBDiff:
        return self._track_diff.diff()