gludb.versioning module
versioning.py
GLUDB versioning implementation
"""versioning.py
GLUDB versioning implementation
"""
import json
import datetime
import json_delta  # External dependency
from .utils import now_field
# Yes, this could be an enum, but we're supporting Python 2.7
class VersioningTypes(object):
    NONE = "ver:none"
    DELTA_HISTORY = "ver:delta"
# Python 2&3 compatible string testing
def _isstr(s):
    try:
        _basestring = basestring
    except NameError:
        _basestring = str
    return isinstance(s, _basestring)
# If any parameter is a string, parse it as JSON
def _norm_json_params(*args):
    return tuple([
        json.loads(param) if _isstr(param) else param
        for param in args
    ])
def record_diff(old, new):
    """Return a JSON-compatible structure capable turn the `new` record back
    into the `old` record. The parameters must be structures compatible with
    json.dumps *or* strings compatible with json.loads. Note that by design,
    `old == record_patch(new, record_diff(old, new))`"""
    old, new = _norm_json_params(old, new)
    return json_delta.diff(new, old, verbose=False)
def record_patch(rec, diff):
    """Return the JSON-compatible structure that results from applying the
    changes in `diff` to the record `rec`. The parameters must be structures
    compatible with json.dumps *or* strings compatible with json.loads. Note
    that by design, `old == record_patch(new, record_diff(old, new))`"""
    rec, diff = _norm_json_params(rec, diff)
    return json_delta.patch(rec, diff, in_place=False)
def append_diff_hist(diff, diff_hist=list()):
    """Given a diff as generated by record_diff, append a diff record to the
    list of diff_hist records."""
    diff, diff_hist = _norm_json_params(diff, diff_hist)
    if not diff_hist:
        diff_hist = list()
    diff_hist.append({'diff': diff, 'diff_date': now_field()})
    return diff_hist
def parse_diff_hist(curr_obj, diff_hist):
    """Given a diff_hist as created, appended by append_diff_hist, yield the
    versions of the object start with curr_obj and working backwards in time.
    Each instance yielded is of the form (obj, date-string) where obj is the
    JSON version of the object created by applying a diff in the
    diff history and date-string is a string representing the date/time that
    the diff was taken"""
    curr_obj, diff_hist = _norm_json_params(curr_obj, diff_hist)
    yield (json.dumps(curr_obj), None)
    last_obj = curr_obj
    for one in reversed(diff_hist):
        last_obj = record_patch(last_obj, one['diff'])
        yield json.dumps(last_obj), one['diff_date']
Functions
def append_diff_hist(
diff, diff_hist=[])
Given a diff as generated by record_diff, append a diff record to the list of diff_hist records.
def append_diff_hist(diff, diff_hist=list()):
    """Given a diff as generated by record_diff, append a diff record to the
    list of diff_hist records."""
    diff, diff_hist = _norm_json_params(diff, diff_hist)
    if not diff_hist:
        diff_hist = list()
    diff_hist.append({'diff': diff, 'diff_date': now_field()})
    return diff_hist
def parse_diff_hist(
curr_obj, diff_hist)
Given a diff_hist as created, appended by append_diff_hist, yield the versions of the object start with curr_obj and working backwards in time. Each instance yielded is of the form (obj, date-string) where obj is the JSON version of the object created by applying a diff in the diff history and date-string is a string representing the date/time that the diff was taken
def parse_diff_hist(curr_obj, diff_hist):
    """Given a diff_hist as created, appended by append_diff_hist, yield the
    versions of the object start with curr_obj and working backwards in time.
    Each instance yielded is of the form (obj, date-string) where obj is the
    JSON version of the object created by applying a diff in the
    diff history and date-string is a string representing the date/time that
    the diff was taken"""
    curr_obj, diff_hist = _norm_json_params(curr_obj, diff_hist)
    yield (json.dumps(curr_obj), None)
    last_obj = curr_obj
    for one in reversed(diff_hist):
        last_obj = record_patch(last_obj, one['diff'])
        yield json.dumps(last_obj), one['diff_date']
def record_diff(
old, new)
Return a JSON-compatible structure capable turn the new record back
into the old record. The parameters must be structures compatible with
json.dumps or strings compatible with json.loads. Note that by design,
old == record_patch(new, record_diff(old, new))
def record_diff(old, new):
    """Return a JSON-compatible structure capable turn the `new` record back
    into the `old` record. The parameters must be structures compatible with
    json.dumps *or* strings compatible with json.loads. Note that by design,
    `old == record_patch(new, record_diff(old, new))`"""
    old, new = _norm_json_params(old, new)
    return json_delta.diff(new, old, verbose=False)
def record_patch(
rec, diff)
Return the JSON-compatible structure that results from applying the
changes in diff to the record rec. The parameters must be structures
compatible with json.dumps or strings compatible with json.loads. Note
that by design, old == record_patch(new, record_diff(old, new))
def record_patch(rec, diff):
    """Return the JSON-compatible structure that results from applying the
    changes in `diff` to the record `rec`. The parameters must be structures
    compatible with json.dumps *or* strings compatible with json.loads. Note
    that by design, `old == record_patch(new, record_diff(old, new))`"""
    rec, diff = _norm_json_params(rec, diff)
    return json_delta.patch(rec, diff, in_place=False)
Classes
class VersioningTypes
class VersioningTypes(object):
    NONE = "ver:none"
    DELTA_HISTORY = "ver:delta"