UNPKG

orchestrate

Version:

Orchestrate is a database service. It is a simple REST API that is optimized for queries. Orchestrate combines full-text search, graph, time-series, and key/value.

207 lines (186 loc) 7.4 kB
// Copyright 2014 Orchestrate, Inc. // Module Dependencies. var assert = require('assert'); var Builder = require('./builder'); /** * @constructor */ function PatchBuilder (collection, key) { this._collection = collection; this._key = key; this._ops = []; } require('util').inherits(PatchBuilder, Builder); /** * Add a value at the given path in the JSON document * @param {string} path - JSON document path; delimited by periods or slashes * @param {Object} value - Value to store at the given path */ PatchBuilder.prototype.add = function (path, value) { assert(path, 'Add requires a path parameter.'); this._ops.push({"op": "add", "path": path, "value": value}); return this; }; /** * Remove a value from the given path in the JSON document * @param {string} path - JSON document path; delimited by periods or slashes */ PatchBuilder.prototype.remove = function (path) { assert(path, 'Remove requires a path parameter.'); this._ops.push({"op": "remove", "path": path}); return this; }; /** * Replace a value at the given path in the JSON document * @param {string} path - JSON document path; delimited by periods or slashes * @param {Object} value - Value to replace at the given {path} */ PatchBuilder.prototype.replace = function (path, value) { assert(path, 'Replace requires a path parameter.'); this._ops.push({"op": "replace", "path": path, "value": value}); return this; }; /** * Move a value at from one path in the JSON document to another path * @param {string} from - Source from which to move the value * @param {string} path - Destination document path for the value */ PatchBuilder.prototype.move = function (from, path) { assert(from && path, 'Move requires from and path parameters.'); this._ops.push({"op": "move", "from": from, "path": path}); return this; }; /** * Copy a value at from one path in the JSON document to another path * @param {string} from - Source path from which to copy the value * @param {string} path - Destination path for the value */ PatchBuilder.prototype.copy = function (from, path) { assert(from && path, 'Copy requires from and path parameters.'); this._ops.push({"op": "copy", "from": from, "path": path}); return this; }; /** * Test equality of a value at the specified JSON document path * @param {string} path - JSON document path; delimited by periods or slashes * @param {Object} value - Value to compare against * @param {boolean} negate - true if the test should be negated */ PatchBuilder.prototype.test = function (path, value, negate) { assert(path, 'Test requires a path parameter.'); var op = {"op": "test", "path": path, "value": value}; if (negate === true) op.negate = true; this._ops.push(op); return this; }; /** * Test NON-equality of a value at the specified JSON document path * @param {string} path - JSON document path; delimited by periods or slashes * @param {Object} value - Value to compare against */ PatchBuilder.prototype.testNot = function (path, value) { return this.test(path, value, true); }; /** * Increase the value at the specified JSON document path by the given number * @param {string} path - JSON document path; delimited by periods or slashes * @param {Object} value - Number by which to increase the value */ PatchBuilder.prototype.inc = function (path, value) { assert(path, 'Inc requires a path parameter.'); var op = { op: "inc", path: path, }; if (value) op.value = value; this._ops.push(op); return this; }; /** * Init the value at the specified JSON document path to the given value * ONLY if there isn't already a value there. * @param {string} path - JSON document path; delimited by periods or slashes * @param {Object} value - Value to initialize the path to (if not present). */ PatchBuilder.prototype.init = function (path, value) { assert(path, 'Init requires a path parameter.'); assert(value !== undefined, 'Init requires a value parameter.'); this._ops.push({"op": "init", "path": path, "value": value}); return this; }; /** * Append the given value to an Array at the specified JSON document path. * If value is an Array, all items in the Array will be appended to the target * Array. Otherwise, the single value will be appended. * @param {string} path - JSON document path; delimited by periods or slashes * @param {Object|Array} value - Value(s) to append to the Array. */ PatchBuilder.prototype.append = function (path, value) { assert(path, 'Append requires a path parameter.'); assert(value !== undefined, 'Append requires a value parameter.'); this._ops.push({"op": "append", "path": path, "value": value}); return this; }; /** * Merge the given value with an Object at the specified JSON document path. * @param {string} path - JSON document path; delimited by periods or slashes * @param {Object|Array} value - Value to merge in. */ PatchBuilder.prototype.merge = function (path, value) { assert(path, 'Merge requires a path parameter.'); assert(value !== undefined, 'Merge requires a value parameter.'); this._ops.push({"op": "merge", "path": path, "value": value}); return this; }; /** * Apply the given value as a patch against an Object at the specified JSON document path. * @param {string} path - JSON document path; delimited by periods or slashes * @param {PatchBuilder|Array} value - Patch ops to apply. * @param {boolean} conditional - true if this nested patch op is conditional, * meaning the test ops in this nested patch's ops list will only be used * to determine whether the nested patch will be applied, but will not * fail the overall patch operation. */ PatchBuilder.prototype.patch = function (path, value, conditional) { assert(path, 'Patch Op requires a path parameter.'); assert(value !== undefined, 'Patch Op requires a value parameter.'); assert(Array.isArray(value) || value instanceof PatchBuilder, 'Patch Op value must be an Array of ops or a PatchBuilder.'); var ops = value._ops || value; var op = {"op": "patch", "path": path, "value": ops}; if (conditional === true) op.conditional = true; this._ops.push(op); return this; }; /** * Convenience method for creating a conditional nested patch op. Just calls * PatchBuilder.prototype.patch with 'true' for the conditional argument. * @param {string} path - JSON document path; delimited by periods or slashes * @param {PatchBuilder|Array} value - Patch ops to apply. */ PatchBuilder.prototype.patchIf = function (path, value) { return this.patch(path, value, true); } /** * Make this patch an 'upsert'. If the key does not exist in the collection, * it will be created as an empty Json Object, then the patch applied. * Call with true or with no argument to enable upsert. The default behavior * is non-upsert, where the response will be 404 if trying to patch a key * that does not exist. * * @param {boolean} upsert - true to make this patch an upsert. */ PatchBuilder.prototype.upsert = function (upsert) { this._upsert = upsert !== false; return this; } /** * return {Promise} */ PatchBuilder.prototype.apply = function (match) { assert(this.getDelegate(), 'No client delegate assigned'); return this.getDelegate().patch(this._collection, this._key, this._ops, {match:match,upsert:this._upsert === true}) }; // Module Exports. module.exports = PatchBuilder;