Skip to content

Instantly share code, notes, and snippets.

View jmakeig's full-sized avatar

Justin Makeig jmakeig

View GitHub Profile
@jmakeig
jmakeig / about.md
Last active April 14, 2017 00:40
Separating concerns with chained lambdas in MarkLogic Server-Side JavaScript.

It’s a best practice in MarkLogic to lock a document, using xdmp.lockForUpdate(), before you update it to avoid deadlocks. This got me thinking about how to better decouple concerns like locking, transactions, and other context from the actual implementation of transformation logic.

For example, let’s say I’ve implemented my update business logic in a pure function, (i.e. no side-effects) like,

function addOrUpdateKey(doc, key) {
 return Object.assign(doc.toObject(), { [key]: key });
}
@jmakeig
jmakeig / example.sjs
Last active February 25, 2017 17:58
Decorator function for updates in MarkLogic that wraps a document update with a lock on the URI.
'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.
*
@jmakeig
jmakeig / row-sequence.sjs
Last active February 17, 2017 23:20
Experiments with typing tabular output from the MarkLogic Optic API
'use strict';
function RowSequence(rows) {
//if(!(this instanceof RowSequence)) { return new RowSequence(rows); }
this._rows = rows;
}
RowSequence.prototype = new Sequence;
RowSequence.prototype[Symbol.iterator] = function*() { yield* this._rows; } // This won’t stream
const op = require('/MarkLogic/optic');
@jmakeig
jmakeig / version-test.sjs
Created December 10, 2016 19:28
MarkLogic version test
/**
* @throws {Error} - Throws an error of the MarkLogic major version is less than 9
*/
(function(ver){if(parseInt(xdmp.version().match(/(\d+)\.(\d+)-(\d+)(?:\.(\d+))?/)[1], 10) < ver) { throw new Error('This module will only run on MarkLogic ' + String(ver) + ' and up'); }})(9)
'use strict';
/** {@link https://gist.github.com/jmakeig/0a331823ad9a458167f6#file-apply-as-9-sjs} */
function applyAs(fct,options,thisArg){return function(){const f=()=>{return[fct.call(thisArg,...arguments)]};options=options||{};if('string'===typeof options.database){options.database=xdmp.database(options.database)}if(options.user){options.userId=xdmp.user(options.user);delete options.user}if(fct.transactionMode&&!(options.transactionMode)){options.transactionMode=fct.transactionMode}return fn.head(xdmp.invokeFunction(f,options)).pop();}};
/** {@link https://gist.github.com/jmakeig/0a331823ad9a458167f6#file-hof-mapper-sjs} */
function map(fct,mapper){const ident=item=>item;mapper=mapper||ident;return function*_map(){const itr=fct.apply(null,arguments);if('string'===typeof itr||!(itr[Symbol.iterator])){yield itr}else{for(const item of itr){yield mapper(item)}}}};
const sec = require('/MarkLogic/security');
/**
@jmakeig
jmakeig / require-override.sjs
Last active December 3, 2016 19:13
Proof-Of-Concept that overrides the global require() function in MarkLogic to (eventually) operate like Node
// IIFE to avoid polluting global scope.
(function() {
/** {@link https://nodejs.org/api/modules.html#modules_all_together}
/*
require(X) from module at path Y
1. If X is a core module,
a. return the core module
b. STOP
2. If X begins with './' or '/' or '../'
a. LOAD_AS_FILE(Y + X)
@jmakeig
jmakeig / json-stringify.xqy
Created December 1, 2016 19:21
Pretty print JSON nodes from XQuery in MarkLogic (>=8)
(: NOTE: In a production system you should amp json:stringify to avoid arbitrary JavaScript execution. :)
declare function json:stringify($json as node(), $spaces as xs:int) as xs:string? {
xdmp:javascript-eval("JSON.stringify($json.toObject(), null, $spaces)", ('$json', $json, '$spaces', $spaces))
};
declare function json:stringify($json as node()) as xs:string? {
json:stringify($json, 2)
};
let $node := xdmp:unquote('["B", "B"]')
@jmakeig
jmakeig / callback.js
Last active November 19, 2022 23:59
JSDoc/Documentation.js examples
/**
* A success callback for {@link ResultProvider} that receives the result from
* the {@link documents#probe}.
* @callback documents#probeResult
* @since 1.0
* @param {documents.DocumentDescriptor} document - a sparse document descriptor with an exists
* property that identifies whether the document exists
*/
/**
* Probes whether a document exists; takes a configuration
@jmakeig
jmakeig / recursive-lock.sh
Created October 6, 2016 23:05
Recursively lock PowerPoint files in OS X
#! /usr/bin/evn bash
# <http://hints.macworld.com/article.php?story=20031017061722471>
find . -name '*.pptx' -exec chflags uchg {} \; # nouchg is the antidote
@jmakeig
jmakeig / runner.js
Last active October 3, 2016 16:53
Minimal Tape implementation for MarkLogic 8
var harness = {
items: [],
register: function(test) {
this.items.push(test);
return this;
},
run: function() {
return new TestOutcomes(
this.items.map(function(test) {
//return test.call(null, 'Hi!');