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"