Last active
February 25, 2017 17:58
-
-
Save jmakeig/1faceb1ce8d7d1522c383729cdf2d8d7 to your computer and use it in GitHub Desktop.
Decorator function for updates in MarkLogic that wraps a document update with a lock on the URI.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
declareUpdate(); | |
/** | |
* An example function that take a Document node and some paramaters and returns | |
* an updated copy, in Object form. Specifically, it adds a property with both the | |
* name and value of the `letter` parameter. By design, this function doesn’t actually | |
* change the input Document node. The point here is to decouple the mutation | |
* of the document from the update in the database. | |
* | |
* @param {Node} doc - The document to update | |
* @param {string} letter - The key and value of the JSON property to add | |
* @return {Object} - The updated document as a JavaScript Object | |
*/ | |
function addStuff(doc, letter) { | |
var obj = doc.toObject(); | |
obj[letter] = letter; | |
return obj; | |
} | |
// Decorate `addStuff` to handle the lock and node update. | |
var addLetter = lockForUpdate(addStuff); | |
for(var uri of cts.uris()) { | |
addLetter(uri, 'r'); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
declareUpdate(); | |
/** | |
* Creates a write lock on a URI and updates the document at the URI | |
* with the result of calling the `transformer` function with the `Document` | |
* at the URI. | |
* | |
* @example | |
* const updateWithTransform = (uri, letter) => lockAndUpdate(uri, (doc) => doTransform(doc, letter)); | |
* | |
* @param {string} uri - the URI of the document to update | |
* @param {function} transformer - a pure function that transforms a document | |
* @return {object|Node} - the unmodified return value of calling `transformer(doc)` | |
* for downstream processing | |
* @throws {ReferenceError} - missing uri or the document at the URI doesn’t exist | |
* @throws {TypeError} - non-function or missing transformer | |
*/ | |
function lockAndUpdate(uri, transformer) { | |
if(null === uri || undefined === uri) { throw new ReferenceError(`uri must be string`); } | |
uri = String(uri); | |
if('function' !== typeof transformer) { throw new TypeError(`transformer must be a function`); } | |
xdmp.lockForUpdate(uri); | |
const doc = cts.doc(uri); | |
if(doc) { | |
const result = transformer(doc); | |
xdmp.nodeReplace(doc, result); | |
return result; | |
} else { | |
throw new ReferenceError(`No document exists at ${uri}`); | |
} | |
} | |
// Pure function that takes a Document node and some parameters. | |
// Returns the new state of the doc. | |
function doTransform(doc, letter) { | |
return Object.assign(doc.toObject(), { [letter]: letter }); | |
} | |
const updateWithTransform = (uri, letter) => lockAndUpdate(uri, (doc) => doTransform(doc, letter)); | |
for(const uri of cts.uris()) { | |
updateWithTransform(uri, 'h'); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Decorates a function that updates documents in order to 1) lock the URI of the document | |
* and 2) acutally perform the database update. The `updater` implementation is passed a | |
* Document node and any other runtime arguments. It need only conern itself with | |
* returning a new version of that document. It need not (read: should not) worry | |
* about the mechanics up locking or updating. | |
* | |
* @param {function} updater - The function that actually does the updates. | |
* The first param is assumed to be the URI of the | |
* document to be updated. When called, `updater` is | |
* passed the the actual Document node and any other | |
* parameters originall passed in through the decorator. | |
* @return {function} - A decorator function with the signature `(document, ...other)` | |
*/ | |
function lockAndUpdate(updater) { | |
if('function' !== typeof updater) { throw new TypeError(`${String(f)} is not a function`); } | |
return function _wrappedLockForUpdate() { | |
if(arguments.length < 1) { throw new ReferenceError(`The first parameter must be a URI as a string`); } | |
var args = Array.prototype.slice.call(arguments); | |
var uri = args.shift(); | |
//var doc = args.shift(); | |
if(uri) { | |
xdmp.lockForUpdate(uri); | |
var doc = cts.doc(uri); | |
//if(!(doc instanceof Document)) { throw new TypeError(`Must be a Document node`); } | |
//xdmp.lockForUpdate(xdmp.nodeUri(doc)); | |
if(doc) { | |
var result = updater.apply(null, [doc].concat(args)); | |
xdmp.nodeReplace(doc, result); | |
return result; | |
} | |
} | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment