marklogic
Version:
The official MarkLogic Node.js client API.
196 lines (169 loc) • 6.42 kB
JavaScript
/*
* Copyright (c) 2015-2025 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
*/
;
const requester = require('./requester.js');
const mlutil = require('./mlutil.js');
const Operation = require('./operation.js');
/**
* Provides functions to open, commit, or rollback multi-statement
* transactions. The client must have been created for a user with
* the rest-writer role.
* @namespace transactions
*/
/** @ignore */
function openOutputTransform(headers/*, data*/) {
/*jshint validthis:true */
const operation = this;
const txid = headers.location.substring('/v1/transactions/'.length);
if (operation.withState === true) {
return new mlutil.Transaction(txid, operation.rawHeaders['set-cookie']);
}
return {txid: txid};
}
/** @ignore */
function Transactions(client) {
this.client = client;
}
/**
* An object representing a multi-statement transaction on the server.
* @typedef {object} transactions.Transaction
* @since 1.0
*/
/**
* Creates a multi-statement transaction, providing a transactionId or
* Transaction object to pass to write, read, and remove functions
* before calling the {@link transactions#commit} or {@link transactions#rollback}
* function to finish the transaction.
* @method transactions#open
* @since 1.0
* @param {string} [transactionName] - a label to assign to the transaction
* for easier recognition in reports
* @param {number} [timeLimit] - the maximum number of seconds that
* the transaction should run before rolling back automatically
* @param {boolean} [withState] - whether to return a Transaction
* object that can track the properties of the transaction
* @returns {transactions.Transaction|string} either a Transaction object
* (the default) or string transactionId identifying the multi-statement
* transaction; returning a string transactionId is deprecated and
* will be removed in the next major release.
*/
Transactions.prototype.open = function openTransaction() {
const args = mlutil.asArray.apply(null, arguments);
const argLen = args.length;
let transactionName = null;
let timeLimit = null;
let withState = null;
let arg = (argLen > 0) ? args[0] : null;
if (argLen > 1 || (typeof arg === 'string' || arg instanceof String) || (typeof arg === 'number' || arg instanceof Number) ||
(typeof arg === 'boolean')) {
let i=0;
for (; i < argLen; i++) {
arg = args[i];
if (transactionName === null && (typeof arg === 'string' || arg instanceof String)) {
transactionName = arg;
continue;
} else if (timeLimit === null && (typeof arg === 'number' || arg instanceof Number)) {
timeLimit = arg;
continue;
} else if (withState === null && (typeof arg === 'boolean')) {
withState = arg;
continue;
}
throw new Error('unknown parameter for transaction open: '+arg);
}
} else if (argLen === 1 && arg) {
transactionName = arg.transactionName;
timeLimit = arg.timeLimit;
withState = arg.withState;
}
let path = '/v1/transactions';
let sep = '?';
if (transactionName != null) {
path += sep+'name='+encodeURIComponent(transactionName);
sep = '&';
}
if (timeLimit != null) {
path += sep+'timeLimit='+timeLimit;
}
const requestOptions = mlutil.newRequestOptions(this.client.getConnectionParams(), path, 'POST');
const operation = new Operation(
'open transaction', this.client, requestOptions, 'empty', 'empty'
);
operation.validStatusCodes = [303];
operation.outputTransform = openOutputTransform;
operation.withState = withState || true;
return requester.startRequest(operation);
};
/**
* Reads the current state of a multi-statement transaction
* created with the {@link transactions#open} function.
* @method transactions#read
* @since 1.0
* @param {string|transactions.Transaction} txid - a string
* transaction id or Transaction object identifying an open
* multi-statement transaction
* @returns {object} information about the transaction
*/
Transactions.prototype.read = function readTransaction(txidRaw) {
const txid = mlutil.convertTransaction(txidRaw);
const path =
'/v1/transactions/'+mlutil.getTxidParam(txid, 'read')+'?format=json';
const requestOptions = mlutil.newRequestOptions(this.client.getConnectionParams(), path, 'GET');
requestOptions.headers = {
'Accept': 'application/json'
};
mlutil.addTxidHeaders(requestOptions, txid);
const operation = new Operation(
'read transaction', this.client, requestOptions, 'empty', 'single'
);
operation.txid = txid;
return requester.startRequest(operation);
};
/**
* Finishes a multi-statement transaction by applying the changes.
* @method transactions#commit
* @since 1.0
* @param {string|transactions.Transaction} txid - a string
* transaction id or Transaction object identifying an open
* multi-statement transaction
*/
Transactions.prototype.commit = function commitTransaction(txid) {
return finishTransaction(this.client, 'commit', txid);
};
/**
* Finishes a multi-statement transaction by reverting the changes.
* @method transactions#rollback
* @since 1.0
* @param {string|transactions.Transaction} txid - a string
* transaction id or Transaction object identifying an open
* multi-statement transaction
*/
Transactions.prototype.rollback = function rollbackTransaction(txid) {
return finishTransaction(this.client, 'rollback', txid);
};
/** @ignore */
function finishOutputTransform(/*headers, data*/) {
/*jshint validthis:true */
const operation = this;
return {
txid: operation.txid,
finished: operation.finish
};
}
/** @ignore */
function finishTransaction(client, result, txidRaw) {
const txid = mlutil.convertTransaction(txidRaw);
const path =
'/v1/transactions/'+mlutil.getTxidParam(txid, result)+'?result='+result;
const requestOptions = mlutil.newRequestOptions(client.getConnectionParams(), path, 'POST');
mlutil.addTxidHeaders(requestOptions, txid);
const operation = new Operation(
result+' transaction', client, requestOptions, 'empty', 'empty'
);
operation.txid = txid;
operation.finish = result;
operation.outputTransform = finishOutputTransform;
return requester.startRequest(operation);
}
module.exports = Transactions;