initial commit

This commit is contained in:
Cadey Ratio 2019-09-18 19:30:14 +00:00
commit d0f1b8287d
3 changed files with 82 additions and 0 deletions

12
LICENSE Normal file
View File

@ -0,0 +1,12 @@
Copyright (c) 2019 Christine Dodrill <me@christine.website>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.

14
objpatch.nimble Normal file
View File

@ -0,0 +1,14 @@
# Package
version = "0.1.0"
author = "Christine Dodrill"
description = "Store JSON objects and patches to them, then query the aggregate object"
license = "0BSD"
srcDir = "src"
bin = @["objpatch"]
# Dependencies
requires "nim >= 0.20.2"

56
src/objpatch.nim Normal file
View File

@ -0,0 +1,56 @@
import hashes, json, strformat, tables
proc diff(old, new: JsonNode): JsonNode =
## return the json fields that are different between the two objects
result = newJObject()
var
oldFields = old.getFields
newFields = new.getFields
oldHashes = newOrderedTable[string, Hash]()
newHashes = newOrderedTable[string, Hash]()
for k, v in old.getFields.pairs:
oldHashes[k] = v.hash
for k, v in new.getFields.pairs:
newHashes[k] = v.hash
if not old.contains(k):
result.add k, v
for k, v in oldHashes.pairs:
if newHashes.contains(k) and newHashes[k] != v:
if oldFields[k].kind == JObject:
result.add k, diff(oldFields[k], newFields[k])
else:
result.add k, newFields[k]
proc combine(old, patch: JsonNode): JsonNode =
## Applies the patch on top of the old data to get the resulting aggregate
## object.
result = newJObject()
var
oldFields = old.getFields
newFields = patch.getFields
for k, v in oldFields.pairs:
result.add k, v
for k, v in newFields.pairs:
if v.kind == JObject:
result.add k, combine(oldFields[k], newFields[k])
else:
result.add k, v
when isMainModule:
let
old = """{"foo": "bar", "shouldnt": "change", "obj": {"is": "fine", "too": false}}""".parseJson
new = """{"foo": "baz", "bar": "boz", "new": "data", "with_an_array": ["foo", "bar", "baz"], "obj": {"hi": "mom"}}""".parseJson
patch = old.diff new
res = old.combine patch
echo fmt"old: {old.pretty}"
echo fmt"new: {new.pretty}"
echo fmt"patch: {patch.pretty}"
echo fmt"result: {res.pretty}"