UNPKG

marklogic

Version:

The official MarkLogic Node.js client API.

196 lines (169 loc) 6.42 kB
/* * Copyright (c) 2015-2025 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved. */ 'use strict'; 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;