Source code for tinychain.chain

"""Data structures responsible for keeping track of mutations to a :class:`Value` or :class:`Collection`"""

from .scalar import ref
from .scalar.value import Nil
from .state import State
from .uri import URI


[docs]class Chain(State): """Data structure responsible for keeping track of mutations to a :class:`Value` or :class:`Collection`.""" __uri__ = URI(State) + "/chain" def __new__(cls, form): if ref.is_ref(form): return State.__new__(cls) elif isinstance(form, State): class _Chain(cls, type(form)): def __json__(self): return cls.__json__(self) return State.__new__(_Chain) else: raise ValueError(f"Chain subject must be a State, not {form}") def __init__(self, form): # in this case, the type of form is significant # so we can't call State.__init__ because it will discard the type of the form if isinstance(form, URI): self.__uri__ = form elif ref.is_ref(form) and hasattr(form, "__uri__"): self.__uri__ = URI(form) self.__form__ = form
[docs] def set(self, value): """Update the value of this `Chain`.""" return ref.Put(URI(self), None, value)
# TODO: delete these overrides def _get(self, name, key=None, rtype=State): op_ref = ref.Get(URI(self).append(name), key) rtype = Nil if rtype is None else rtype return rtype(form=op_ref) def _put(self, name, key=None, value=None): return Nil(ref.Put(URI(self).append(name), key, value)) def _post(self, name, params, rtype=State): op_ref = ref.Post(URI(self).append(name), params) rtype = Nil if rtype is None else rtype return rtype(form=op_ref) def _delete(self, name, key=None): return Nil(ref.Delete(URI(self).append(name), key))
[docs]class Block(Chain): """A :class:`Chain` which keeps track of the entire update history of its subject.""" __uri__ = URI(Chain) + "/block"
[docs]class Sync(Chain): """ A :class:`Chain` which keeps track of only the current transaction's operations, in order to recover from a transaction failure (e.g. if the host crashes). """ __uri__ = URI(Chain) + "/sync"