Skip to content

Commit 5c64820

Browse files
committed
return object with cookies from transaction open and send with
transaction requests #164
1 parent f9f01f6 commit 5c64820

File tree

7 files changed

+234
-95
lines changed

7 files changed

+234
-95
lines changed

lib/documents.js

Lines changed: 61 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,9 @@ function probeOutputTransform(/*headers, data*/) {
155155
* a uri string.
156156
* @method documents#probe
157157
* @param {string} uri - the uri for the database document
158-
* @param {string} [txid] - the transaction id for an open transaction
158+
* @param {string|transactions.Transaction} [txid] - a string
159+
* transaction id or Transaction object identifying an open
160+
* multi-statement transaction
159161
* @returns {ResultProvider} an object whose result() function takes
160162
* a {@link documents#probeResult} success callback.
161163
*/
@@ -170,7 +172,8 @@ function probeDocumentsImpl(contentOnly, args) {
170172

171173
var params = (!valcheck.isString(args[0])) ? args[0] : null;
172174

173-
var uri;
175+
var uri = null;
176+
var txid = null;
174177

175178
var path = '/v1/documents?format=json';
176179
if (params === null) {
@@ -183,16 +186,17 @@ function probeDocumentsImpl(contentOnly, args) {
183186
}
184187
path += '&uri='+encodeURIComponent(uri);
185188

186-
var txid = params.txid;
189+
txid = params.txid;
187190
if (!valcheck.isNullOrUndefined(txid)) {
188-
path += '&txid='+txid;
191+
path += '&txid='+mlutil.getTxidParam(txid);
189192
}
190193
}
191194

192195
var connectionParams = this.client.connectionParams;
193196
var requestOptions = mlutil.copyProperties(connectionParams);
194197
requestOptions.method = 'HEAD';
195198
requestOptions.path = mlutil.databaseParam(connectionParams, path, '&');
199+
mlutil.addTxidHeaders(requestOptions, txid);
196200

197201
var operation = new Operation(
198202
'probe document', this.client, requestOptions, 'empty', 'empty'
@@ -281,7 +285,9 @@ function singleReadOutputTransform(headers, data) {
281285
* for the database documents
282286
* @param {documents.categories|documents.categories[]} [categories] - the categories of information
283287
* to retrieve for the documents
284-
* @param {string} [txid] - the transaction id for an open transaction
288+
* @param {string|transactions.Transaction} [txid] - a string
289+
* transaction id or Transaction object identifying an open
290+
* multi-statement transaction
285291
* @param {string} [transform] - the name of a transform extension to apply
286292
* to each document; the transform must have been installed using
287293
* the {@link transforms#write} function.
@@ -334,7 +340,7 @@ function readDocumentsImpl(contentOnly, args) {
334340
uris.map(encodeURIComponent).join('&uri=');
335341
path += '&category=' + categories.join('&category=');
336342
if (!valcheck.isNullOrUndefined(txid)) {
337-
path += '&txid='+txid;
343+
path += '&txid='+mlutil.getTxidParam(txid);
338344
}
339345
if (!valcheck.isNullOrUndefined(transform)) {
340346
path += '&'+mlutil.endpointTransform(transform);
@@ -412,6 +418,7 @@ function readDocumentsImpl(contentOnly, args) {
412418
};
413419
}
414420
}
421+
mlutil.addTxidHeaders(requestOptions, txid);
415422

416423
var operation = new Operation(
417424
'read documents', this.client, requestOptions, 'empty',
@@ -444,7 +451,9 @@ function readDocumentsImpl(contentOnly, args) {
444451
* @param {number} [quality] - a weight to increase or decrease the rank of the document
445452
* @param {number} [versionId] - an identifier for the currently stored version of the
446453
* document (when enforcing optimistic locking)
447-
* @param {string} [txid] - the transaction id for an open transaction
454+
* @param {string|transactions.Transaction} [txid] - a string
455+
* transaction id or Transaction object identifying an open
456+
* multi-statement transaction
448457
* @param {string} [transform] - the name of a transform extension to apply
449458
* to the document; the transform must have been installed using
450459
* the {@link transforms#write} function.
@@ -480,7 +489,9 @@ function writeStreamImpl(document, categories) {
480489

481490
var sep = '?';
482491

483-
var writeParams = addWriteParams(document, categories);
492+
var txid = getTxid(document);
493+
494+
var writeParams = addWriteParams(document, categories, txid);
484495
if (writeParams.length > 0) {
485496
endpoint += writeParams;
486497
sep = '&';
@@ -496,6 +507,7 @@ function writeStreamImpl(document, categories) {
496507
'Accept': 'application/json'
497508
};
498509
requestOptions.path = mlutil.databaseParam(connectionParams, endpoint, sep);
510+
mlutil.addTxidHeaders(requestOptions, txid);
499511

500512
// TODO: treat as chunked single document if no properties
501513
var requestPartList = [];
@@ -587,7 +599,9 @@ function writeListOutputTransform(headers, data) {
587599
* or an array of document descriptors to write
588600
* @param {documents.categories|documents.categories[]} [categories] - the categories of information
589601
* to write for the documents
590-
* @param {string} [txid] - the transaction id for an open transaction
602+
* @param {string|transactions.Transaction} [txid] - a string
603+
* transaction id or Transaction object identifying an open
604+
* multi-statement transaction
591605
* @param {string} [transform] - the name of a transform extension to apply
592606
* to each document; the transform must have been installed using
593607
* the {@link transforms#write} function.
@@ -685,7 +699,7 @@ function writeMetadata(document, categories) {
685699

686700
var txid = document.txid;
687701
if (!valcheck.isNullOrUndefined(txid)) {
688-
endpoint += '&txid='+txid;
702+
endpoint += '&txid='+mlutil.getTxidParam(txid);
689703
}
690704

691705
var requestHeaders = {
@@ -698,6 +712,7 @@ function writeMetadata(document, categories) {
698712
requestOptions.method = 'PUT';
699713
requestOptions.headers = requestHeaders;
700714
requestOptions.path = mlutil.databaseParam(connectionParams, endpoint, '&');
715+
mlutil.addTxidHeaders(requestOptions, txid);
701716

702717
var operation = new Operation(
703718
'write single metadata', this.client, requestOptions, 'single', 'empty'
@@ -721,7 +736,9 @@ function writeContent(contentOnly, document, requestParams, categories, requestT
721736

722737
var sep = '?';
723738

724-
var writeParams = addWriteParams(requestParams, categories);
739+
var txid = getTxid(requestParams);
740+
741+
var writeParams = addWriteParams(requestParams, categories, txid);
725742
if (writeParams.length > 0) {
726743
endpoint += writeParams;
727744
sep = '&';
@@ -807,6 +824,7 @@ function writeContent(contentOnly, document, requestParams, categories, requestT
807824
requestOptions.method = hasUri ? 'PUT' : 'POST';
808825
requestOptions.headers = requestHeaders;
809826
requestOptions.path = mlutil.databaseParam(connectionParams, endpoint, sep);
827+
mlutil.addTxidHeaders(requestOptions, txid);
810828

811829
var operation = new Operation(
812830
'write single document', this.client, requestOptions, requestType, 'empty'
@@ -835,7 +853,9 @@ function writeDocumentList(contentOnly, documents, requestParams, categories) {
835853

836854
var endpoint = '/v1/documents';
837855

838-
var writeParams = addWriteParams(requestParams, categories);
856+
var txid = getTxid(requestParams);
857+
858+
var writeParams = addWriteParams(requestParams, categories, txid);
839859
var sep = '?';
840860
if (writeParams.length > 0) {
841861
endpoint += writeParams;
@@ -854,6 +874,7 @@ function writeDocumentList(contentOnly, documents, requestParams, categories) {
854874
requestOptions.method = 'POST';
855875
requestOptions.headers = requestHeaders;
856876
requestOptions.path = mlutil.databaseParam(connectionParams, endpoint, sep);
877+
mlutil.addTxidHeaders(requestOptions, txid);
857878

858879
var operation = new Operation(
859880
'write document list', this.client, requestOptions, 'multipart', 'single'
@@ -874,8 +895,11 @@ function writeDocumentList(contentOnly, documents, requestParams, categories) {
874895

875896
return requester.startRequest(operation);
876897
}
898+
function getTxid(requestParams) {
899+
return valcheck.isNullOrUndefined(requestParams) ? null : requestParams.txid;
900+
}
877901
/** @ignore */
878-
function addWriteParams(requestParams, categories) {
902+
function addWriteParams(requestParams, categories, txid) {
879903
var writeParams = '';
880904

881905
var sep = '?';
@@ -884,9 +908,8 @@ function addWriteParams(requestParams, categories) {
884908
writeParams += sep+'category='+categories.join('&category=');
885909
if (sep !== '&') { sep = '&'; }
886910
}
887-
var txid = requestParams.txid;
888911
if (!valcheck.isNullOrUndefined(txid)) {
889-
writeParams += sep+'txid='+txid;
912+
writeParams += sep+'txid='+mlutil.getTxidParam(txid);
890913
if (sep !== '&') { sep = '&'; }
891914
}
892915
var transform = mlutil.endpointTransform(requestParams.transform);
@@ -1118,7 +1141,9 @@ function removeOutputTransform(headers/*, data*/) {
11181141
* @method documents#remove
11191142
* @param {string|string[]} uris - the uri string or an array of uri strings
11201143
* identifying the database documents
1121-
* @param {string} [txid] - the transaction id for an open transaction
1144+
* @param {string|transactions.Transaction} [txid] - a string
1145+
* transaction id or Transaction object identifying an open
1146+
* multi-statement transaction
11221147
* @param {string} [temporalCollection] - the name of the temporal collection;
11231148
* use only when deleting a document created as a temporal document; sets the
11241149
* system end time to record when the document was no longer active
@@ -1173,7 +1198,7 @@ function removeDocumentImpl(contentOnly, isLegacy, args) {
11731198
var path = '/v1/documents?uri='+
11741199
uris.map(encodeURIComponent).join('&uri=');
11751200
if (!valcheck.isNullOrUndefined(txid)) {
1176-
path += '&txid='+txid;
1201+
path += '&txid='+mlutil.getTxidParam(txid);
11771202
}
11781203
if (!valcheck.isNullOrUndefined(temporalCollection)) {
11791204
path += '&temporal-collection='+temporalCollection;
@@ -1193,6 +1218,7 @@ function removeDocumentImpl(contentOnly, isLegacy, args) {
11931218
}
11941219
requestOptions.method = 'DELETE';
11951220
requestOptions.path = mlutil.databaseParam(connectionParams, path, '&');
1221+
mlutil.addTxidHeaders(requestOptions, txid);
11961222

11971223
var operation = new Operation(
11981224
'remove document', this.client, requestOptions, 'empty', 'empty'
@@ -1293,7 +1319,7 @@ function removeAllDocumentsImpl(contentOnly, params) {
12931319
}
12941320

12951321
if (!valcheck.isNullOrUndefined(txid)) {
1296-
endpoint += sep+'txid='+txid;
1322+
endpoint += sep+'txid='+mlutil.getTxidParam(txid);
12971323
if (sep === '?') {
12981324
sep = '&';
12991325
}
@@ -1303,6 +1329,7 @@ function removeAllDocumentsImpl(contentOnly, params) {
13031329
var requestOptions = mlutil.copyProperties(connectionParams);
13041330
requestOptions.method = 'DELETE';
13051331
requestOptions.path = mlutil.databaseParam(connectionParams, endpoint, sep);
1332+
mlutil.addTxidHeaders(requestOptions, txid);
13061333

13071334
var operation = new Operation(
13081335
'remove all documents', this.client, requestOptions, 'empty', 'empty'
@@ -1341,8 +1368,10 @@ function listOutputTransform(headers, data) {
13411368
* page of result documents (also known as the result slice)
13421369
* @property {number} [pageLength] - the number of documents in the returned page
13431370
* of result documents
1344-
* @property {string} [txid] - the transaction id for an open transaction to include
1345-
* modified documents in the results if the documents match the criteria
1371+
* @param {string|transactions.Transaction} [txid] - a string
1372+
* transaction id or Transaction object identifying an open
1373+
* multi-statement transaction to include modified documents
1374+
* in the results if the documents match the criteria
13461375
* @property {string} [view] - a value from the enumeration
13471376
* all|facets|metadata|none|results|uris controlling whether to generate some or all
13481377
* of a search response summarizing the search response in addition to the result
@@ -1408,7 +1437,7 @@ function queryDocumentsImpl(collectionParam, contentOnly, builtQuery) {
14081437
endpoint += '&pageLength='+pageLength;
14091438
}
14101439
if (!valcheck.isNullOrUndefined(txid)) {
1411-
endpoint += '&txid='+txid;
1440+
endpoint += '&txid='+mlutil.getTxidParam(txid);
14121441
}
14131442
if (!valcheck.isNullOrUndefined(transform)) {
14141443
endpoint += '&'+mlutil.endpointTransform(transform);
@@ -1431,6 +1460,7 @@ function queryDocumentsImpl(collectionParam, contentOnly, builtQuery) {
14311460
'application/json')
14321461
};
14331462
requestOptions.path = mlutil.databaseParam(connectionParams, endpoint, '&');
1463+
mlutil.addTxidHeaders(requestOptions, txid);
14341464

14351465
var operation = new Operation(
14361466
'query documents', this.client, requestOptions, 'single',
@@ -1729,8 +1759,10 @@ function patchOutputTransform(/*headers, data*/) {
17291759
* to the document.
17301760
* @param {documents.categories|documents.categories[]} [categories] - the
17311761
* categories of information modified by the patch (typically 'content')
1732-
* @param {string} [txid] - the transaction id to patch the document
1733-
* as part of a larger multi-statement transaction
1762+
* @param {string|transactions.Transaction} [txid] - a string
1763+
* transaction id or Transaction object identifying an open
1764+
* multi-statement transaction to patch the document as part
1765+
* of a larger multi-statement transaction
17341766
* @param {number} [versionId] - an identifier for the currently stored version
17351767
* of the document (when enforcing optimistic locking)
17361768
* @returns {ResultProvider} an object whose result() function takes
@@ -1821,7 +1853,7 @@ Documents.prototype.patch = function patchDocuments() {
18211853
}
18221854
}
18231855
if (!valcheck.isNullOrUndefined(txid)) {
1824-
endpoint += '&txid=' + txid;
1856+
endpoint += '&txid=' + mlutil.getTxidParam(txid);
18251857
}
18261858

18271859
var patchBody = isRawPatch ? documentOperations : {patch: documentOperations};
@@ -1842,6 +1874,7 @@ Documents.prototype.patch = function patchDocuments() {
18421874
requestOptions.headers['If-Match'] = versionId;
18431875
}
18441876
requestOptions.path = mlutil.databaseParam(connectionParams, endpoint, '&');
1877+
mlutil.addTxidHeaders(requestOptions, txid);
18451878

18461879
var operation = new Operation(
18471880
'patch document', this.client, requestOptions, 'single', 'single'
@@ -1912,7 +1945,9 @@ Documents.prototype.suggest = function suggestDocuments() {
19121945
throw new Error('no query with bindings for document suggestion');
19131946
}
19141947

1915-
var searchBody = makeSearchBody(query).searchBody;
1948+
var wrapper = makeSearchBody(query);
1949+
1950+
var searchBody = wrapper.searchBody;
19161951
var search = searchBody.search;
19171952
if (valcheck.isNullOrUndefined(search)) {
19181953
throw new Error('cannot get document suggestions for empty search');
@@ -1962,6 +1997,7 @@ Documents.prototype.suggest = function suggestDocuments() {
19621997
'Accept': 'application/json',
19631998
};
19641999
requestOptions.path = mlutil.databaseParam(connectionParams, endpoint, '&');
2000+
mlutil.addTxidHeaders(requestOptions, wrapper.txid);
19652001

19662002
var operation = new Operation(
19672003
'search suggest', this.client, requestOptions, 'single', 'single'

lib/mlutil.js

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,62 @@ function unmarshal(format, data) {
246246
}
247247
}
248248

249+
function Transaction(id, cookies) {
250+
if (!(this instanceof Transaction)) {
251+
return new Transaction(id, cookies);
252+
}
253+
254+
this.txid = id;
255+
if (valcheck.isArray(cookies) && cookies.length > 0) {
256+
for (var i=0; i < cookies.length; i++) {
257+
cookies[i] = cookies[i].replace(/;\s*expires\s*=[^;]+(;|$)/i, '$1');
258+
}
259+
this.cookies = cookies;
260+
}
261+
}
262+
Transaction.prototype.toString = function transactionToString() {
263+
return this.txid;
264+
};
265+
266+
function getTxidParam(txid, action) {
267+
if (valcheck.isNullOrUndefined(txid)) {
268+
if (!valcheck.isNullOrUndefined(action)) {
269+
throw new Error(
270+
'cannot '+action+' transaction without string or Transaction object identifier'
271+
);
272+
}
273+
return;
274+
}
275+
276+
if (valcheck.isString(txid)) {
277+
return txid;
278+
} else if (txid instanceof Transaction) {
279+
return txid.txid;
280+
}
281+
282+
throw new Error(
283+
'can only '+action+' transaction with string or Transaction object identifier: '+
284+
(typeof txid)
285+
);
286+
}
287+
function addTxidHeaders(requestOptions, txid) {
288+
if (txid instanceof Transaction) {
289+
var cookies = txid.cookies;
290+
if (!valcheck.isNullOrUndefined(cookies)) {
291+
var headers = requestOptions.headers;
292+
if (!valcheck.isNullOrUndefined(headers)) {
293+
headers.cookie = cookies;
294+
} else {
295+
requestOptions.headers = {
296+
cookie: cookies
297+
};
298+
}
299+
}
300+
}
301+
}
302+
249303
module.exports = {
304+
addTxidHeaders: addTxidHeaders,
250305
appendItem: appendItem,
251306
asArray: asArray,
252307
callbackOn: callbackOn,
@@ -257,9 +312,11 @@ module.exports = {
257312
Error: MarkLogicError,
258313
extension: extension,
259314
first: first,
315+
getTxidParam: getTxidParam,
260316
marshal: marshal,
261317
multipartBoundary: multipartBoundary,
262318
parseJSON: parseJSON,
263319
rootname: rootname,
320+
Transaction: Transaction,
264321
unmarshal: unmarshal
265322
};

lib/query-builder.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4766,7 +4766,9 @@ function snippet() {
47664766
* @param {...string} [forestNames] - the names of forests providing documents
47674767
* for the result set
47684768
* @param {...string} [search] - options modifying the default behaviour of the query
4769-
* @param {string} [txid] - the transaction id for an open transaction
4769+
* @param {string|transactions.Transaction} [txid] - a string
4770+
* transaction id or Transaction object identifying an open
4771+
* multi-statement transaction
47704772
* @param {number} [weight] - a weighting factor between -16 and 64
47714773
* @param {boolean} [debug] - whether to return query debugging
47724774
* @param {boolean} [metrics] - whether to return metrics for the query performance

0 commit comments

Comments
 (0)