Skip to content

Commit e1f3dee

Browse files
Add data version tracking (#116)
1 parent 85a9c72 commit e1f3dee

File tree

3 files changed

+89
-26
lines changed

3 files changed

+89
-26
lines changed

docs/api/woqlClient.js.md

+19-6
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ client.updateTriples("schema", "alt", turtle_string, "dumping triples to graph a
138138
```
139139

140140
### Query
141-
#### woqlClient.query(woql, [commitMsg], [allWitnesses]) ⇒ <code>Promise</code>
141+
#### woqlClient.query(woql, [commitMsg], [allWitnesses], [lastDataVersion], [getDataVersion]) ⇒ <code>Promise</code>
142142
Executes a WOQL query on the specified database and returns the results
143143

144144
**Returns**: <code>Promise</code> - A promise that returns the call response object, or an Error if rejected.
@@ -148,6 +148,8 @@ Executes a WOQL query on the specified database and returns the results
148148
| woql | <code>WOQLQuery</code> | an instance of the WOQLQuery class |
149149
| [commitMsg] | <code>string</code> | a message describing the reason for the change that will be written into the commit log (only relevant if the query contains an update) |
150150
| [allWitnesses] | <code>boolean</code> | |
151+
| [lastDataVersion] | <code>string</code> | If passed it will be used for data version tracking |
152+
| [getDataVersion] | <code>string</code> | If true it the function will return object having result and dataVersion |
151153

152154
**Example**
153155
```js
@@ -625,6 +627,7 @@ Common request dispatch function
625627
| action | <code>string</code> | the action name |
626628
| apiUrl | <code>string</code> | the server call endpoint |
627629
| [payload] | <code>object</code> | the post body |
630+
| [getDataVersion] | <code>boolean</code> | If true return response with data version |
628631
629632
630633
### generateCommitInfo
@@ -670,7 +673,7 @@ update the database details
670673
671674
672675
### addDocument
673-
#### woqlClient.addDocument(json, [params], [dbId], [string]) ⇒ <code>Promise</code>
676+
#### woqlClient.addDocument(json, [params], [dbId], [string], [lastDataVersion], [getDataVersion]) ⇒ <code>Promise</code>
674677
to add a new document or a list of new documents into the instance or the schema graph.
675678
676679
**Returns**: <code>Promise</code> - A promise that returns the call response object, or an Error if rejected.
@@ -681,6 +684,8 @@ to add a new document or a list of new documents into the instance or the schema
681684
| [params] | <code>typedef.DocParamsPost</code> | the post parameters |
682685
| [dbId] | <code>string</code> | the dbid |
683686
| [string] | <code>message</code> | the insert commit message |
687+
| [lastDataVersion] | <code>string</code> | If passed it will be used for data version tracking. |
688+
| [getDataVersion] | <code>string</code> | If true it the function will return object having result and dataVersion. |
684689
685690
**Example**
686691
```js
@@ -701,7 +706,7 @@ client.addDocument(json,{"graph_type":"schema"},"mydb","add new schema")
701706
```
702707
703708
### queryDocument
704-
#### woqlClient.queryDocument(query, [params], [dbId], [branch]) ⇒ <code>Promise</code>
709+
#### woqlClient.queryDocument(query, [params], [dbId], [branch], [lastDataVersion], [getDataVersion]) ⇒ <code>Promise</code>
705710
Retrieves all documents that match a given document template
706711
707712
**Returns**: <code>Promise</code> - A promise that returns the call response object, or an Error if rejected.
@@ -712,6 +717,8 @@ Retrieves all documents that match a given document template
712717
| [params] | <code>typedef.DocParamsGet</code> | the get parameters |
713718
| [dbId] | <code>string</code> | the database id |
714719
| [branch] | <code>string</code> | the database branch |
720+
| [lastDataVersion] | <code>string</code> | If passed it will be used for data version tracking. |
721+
| [getDataVersion] | <code>string</code> | If true it the function will return object having result and dataVersion. |
715722
716723
**Example**
717724
```js
@@ -723,14 +730,16 @@ client.queryDocument(query,{"as_list":true})
723730
```
724731
725732
### getDocument
726-
#### woqlClient.getDocument([params], [dbId], [branch]) ⇒ <code>Promise</code>
733+
#### woqlClient.getDocument([params], [dbId], [branch], [lastDataVersion], [getDataVersion]) ⇒ <code>Promise</code>
727734
**Returns**: <code>Promise</code> - A promise that returns the call response object, or an Error if rejected.
728735
729736
| Param | Type | Description |
730737
| --- | --- | --- |
731738
| [params] | <code>typedef.DocParamsGet</code> | the get parameters |
732739
| [dbId] | <code>string</code> | the database id |
733740
| [branch] | <code>string</code> | the database branch |
741+
| [lastDataVersion] | <code>string</code> | If passed it will be used for data version tracking. |
742+
| [getDataVersion] | <code>string</code> | If true it the function will return object having result and dataVersion. |
734743
735744
**Example**
736745
```js
@@ -742,7 +751,7 @@ client.getDocument({"graph_type":"schema","as_list":true,"id":"Country"})
742751
```
743752
744753
### updateDocument
745-
#### woqlClient.updateDocument(json, [params], [dbId], [message]) ⇒ <code>Promise</code>
754+
#### woqlClient.updateDocument(json, [params], [dbId], [message], [lastDataVersion], [getDataVersion]) ⇒ <code>Promise</code>
746755
**Returns**: <code>Promise</code> - A promise that returns the call response object, or an Error if rejected.
747756
748757
| Param | Type | Description |
@@ -751,10 +760,12 @@ client.getDocument({"graph_type":"schema","as_list":true,"id":"Country"})
751760
| [params] | <code>typedef.DocParamsPut</code> | the Put parameters |
752761
| [dbId] | <code>\*</code> | the database id |
753762
| [message] | <code>\*</code> | the update commit message |
763+
| [lastDataVersion] | <code>string</code> | If passed it will be used for data version tracking. |
764+
| [getDataVersion] | <code>string</code> | If true it the function will return object having result and dataVersion. |
754765
755766
756767
### deleteDocument
757-
#### woqlClient.deleteDocument([params], [dbId], [message]) ⇒ <code>Promise</code>
768+
#### woqlClient.deleteDocument([params], [dbId], [message], [lastDataVersion], [getDataVersion]) ⇒ <code>Promise</code>
758769
to delete the document
759770
760771
**Returns**: <code>Promise</code> - A promise that returns the call response object, or an Error if rejected.
@@ -764,6 +775,8 @@ to delete the document
764775
| [params] | <code>typedef.DocParamsDelete</code> | |
765776
| [dbId] | <code>string</code> | the database id |
766777
| [message] | <code>string</code> | the delete message |
778+
| [lastDataVersion] | <code>string</code> | If passed it will be used for data version tracking |
779+
| [getDataVersion] | <code>string</code> | If true it the function will return object having result and dataVersion |
767780
768781
**Example**
769782
```js

lib/dispatchRequest.js

+20-7
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,19 @@ function btoaImplementation(str) {
1515
}
1616
}
1717

18+
/**
19+
* @param {object} response
20+
* @returns {object} Object having two properties result and dataVersion
21+
*/
22+
function getResultWithDataVersion(response) {
23+
return {
24+
result: response.data,
25+
dataVersion: response.headers["terminusdb-data-version"]
26+
? response.headers["terminusdb-data-version"]
27+
: ""
28+
};
29+
}
30+
1831
/**
1932
* @file Dispatch Request
2033
* @license Apache Version 2
@@ -25,7 +38,7 @@ function btoaImplementation(str) {
2538
* @param {string} key optional basic auth string to be passed
2639
* @param {object} customHeaders the unique reqID
2740
*/
28-
function DispatchRequest(url, action, payload, local_auth, remote_auth = null, customHeaders = null) {
41+
function DispatchRequest(url, action, payload, local_auth, remote_auth = null, customHeaders = null, getDataVersion = false) {
2942
/*
3043
*CORS is only required when trying to fetch data from a browser,
3144
*as browsers by default will block requests to different origins
@@ -91,7 +104,7 @@ function DispatchRequest(url, action, payload, local_auth, remote_auth = null, c
91104
}
92105
return axiosInstance
93106
.delete(url, options)
94-
.then(response => response.data)
107+
.then(response => getDataVersion ? getResultWithDataVersion(response) : response.data)
95108
.catch(err => {
96109
const e = new Error(ErrorMessage.getAPIErrorMessage(url, options, err))
97110
if (err.response && err.response.data) e.data = err.response.data
@@ -100,7 +113,7 @@ function DispatchRequest(url, action, payload, local_auth, remote_auth = null, c
100113
case CONST.HEAD:
101114
return axiosInstance
102115
.head(url, options)
103-
.then(response => response.data)
116+
.then(response => getDataVersion ? getResultWithDataVersion(response) : response.data)
104117
.catch(err => {
105118
let e = new Error(ErrorMessage.getAPIErrorMessage(url, options, err))
106119
if (err.response && err.response.data) {
@@ -115,7 +128,7 @@ function DispatchRequest(url, action, payload, local_auth, remote_auth = null, c
115128
}
116129
return axiosInstance
117130
.get(url, options)
118-
.then(response => response.data)
131+
.then(response => getDataVersion ? getResultWithDataVersion(response) : response.data)
119132
.catch(err => {
120133
let e = new Error(ErrorMessage.getAPIErrorMessage(url, options, err))
121134
if (err.response && err.response.data) {
@@ -129,7 +142,7 @@ function DispatchRequest(url, action, payload, local_auth, remote_auth = null, c
129142
options.headers['Content-Type'] = 'application/form-data; charset=utf-8'
130143
return axiosInstance
131144
.put(url, payload, options)
132-
.then(response => response.data)
145+
.then(response => getDataVersion ? getResultWithDataVersion(response) : response.data)
133146
.catch(err => {
134147
const e = new Error(ErrorMessage.getAPIErrorMessage(url, options, err))
135148
if (err.response && err.response.data) e.data = err.response.data
@@ -140,7 +153,7 @@ function DispatchRequest(url, action, payload, local_auth, remote_auth = null, c
140153
options.headers['Content-Type'] = 'application/json; charset=utf-8'
141154
return axiosInstance
142155
.put(url, payload, options)
143-
.then(response => response.data)
156+
.then(response => getDataVersion ? getResultWithDataVersion(response) : response.data)
144157
.catch(err => {
145158
const e = new Error(ErrorMessage.getAPIErrorMessage(url, options, err))
146159
if (err.response && err.response.data) e.data = err.response.data
@@ -154,7 +167,7 @@ function DispatchRequest(url, action, payload, local_auth, remote_auth = null, c
154167
options.headers['Content-Type'] = 'application/json; charset=utf-8'
155168
return axiosInstance
156169
.post(url, payload, options)
157-
.then(response => response.data)
170+
.then(response => getDataVersion ? getResultWithDataVersion(response) : response.data)
158171
.catch(err => {
159172
const e = new Error(ErrorMessage.getAPIErrorMessage(url, options, err))
160173
if (err.response && err.response.data) e.data = err.response.data

lib/woqlClient.js

+50-13
Original file line numberDiff line numberDiff line change
@@ -543,18 +543,25 @@ WOQLClient.prototype.info = function() {
543543
* @param {WOQLQuery} woql - an instance of the WOQLQuery class
544544
* @param {string} [commitMsg] - a message describing the reason for the change that will be written into the commit log (only relevant if the query contains an update)
545545
* @param {boolean} [allWitnesses]
546+
* @param {string} [lastDataVersion] - If passed it will be used for data version tracking
547+
* @param {string} [getDataVersion] - If true it the function will return object having result and dataVersion
546548
* @returns {Promise} A promise that returns the call response object, or an Error if rejected.
547549
* @example
548550
* const result = await client.query(WOQL.star())
549551
*/
550-
WOQLClient.prototype.query = function(woql, commitMsg, allWitnesses) {
552+
WOQLClient.prototype.query = function(woql, commitMsg, allWitnesses, lastDataVersion='', getDataVersion=false) {
551553
allWitnesses = allWitnesses || false
552554
commitMsg = commitMsg || 'Commit generated with javascript client without message'
553555
if (woql && woql.json && (!woql.containsUpdate() || commitMsg)) {
554556
let doql = woql.containsUpdate() ? this.generateCommitInfo(commitMsg) : {}
555557
doql.query = woql.json()
556558
if (allWitnesses) doql.all_witnesses = true
557-
return this.dispatch(CONST.WOQL_QUERY, this.connectionConfig.queryURL(), doql)
559+
560+
if(typeof lastDataVersion === 'string' && lastDataVersion !== '') {
561+
this.customHeaders({'TerminusDB-Data-Version': lastDataVersion})
562+
}
563+
564+
return this.dispatch(CONST.WOQL_QUERY, this.connectionConfig.queryURL(), doql, getDataVersion)
558565
}
559566
let errmsg = `WOQL query parameter error`
560567
if (woql && woql.json && woql.containsUpdate() && !commitMsg) {
@@ -761,9 +768,10 @@ WOQLClient.prototype.clonedb = function(cloneSource, newDbId, orgId) {
761768
* @property {string} action - the action name
762769
* @property {string} apiUrl - the server call endpoint
763770
* @property {object} [payload] - the post body
771+
* @property {boolean} [getDataVersion] - If true return response with data version
764772
* @returns {Promise} A promise that returns the call response object, or an Error if rejected.
765773
*/
766-
WOQLClient.prototype.dispatch = function(action, apiUrl, payload) {
774+
WOQLClient.prototype.dispatch = function(action, apiUrl, payload, getDataVersion) {
767775
if (!apiUrl) {
768776
return Promise.reject(
769777
new Error(
@@ -799,6 +807,7 @@ WOQLClient.prototype.dispatch = function(action, apiUrl, payload) {
799807
this.localAuth(),
800808
this.remoteAuth(),
801809
this.customHeaders(),
810+
getDataVersion,
802811
)
803812
//}
804813

@@ -858,6 +867,8 @@ WOQLClient.prototype.updateDatabase = function(dbDoc) {
858867
* @param {typedef.DocParamsPost} [params] - the post parameters
859868
* @param {string} [dbId] - the dbid
860869
* @param {message} [string] - the insert commit message
870+
* @param {string} [lastDataVersion] If passed it will be used for data version tracking.
871+
* @param {string} [getDataVersion] If true it the function will return object having result and dataVersion.
861872
* @returns {Promise} A promise that returns the call response object, or an Error if rejected.
862873
* @example
863874
* const json = [{ "@type" : "Class",
@@ -876,14 +887,19 @@ WOQLClient.prototype.updateDatabase = function(dbDoc) {
876887
* client.addDocument(json,{"graph_type":"schema"},"mydb","add new schema")
877888
*/
878889

879-
WOQLClient.prototype.addDocument = function(json, params, dbId, message="add a new document"){
890+
WOQLClient.prototype.addDocument = function(json, params, dbId, message="add a new document", lastDataVersion='', getDataVersion=false){
880891
if (dbId) {
881892
this.db(dbId)
882893
}
894+
895+
if(typeof lastDataVersion === 'string' && lastDataVersion !== '') {
896+
this.customHeaders({'TerminusDB-Data-Version': lastDataVersion})
897+
}
898+
883899
const docParams = params || {}
884900
docParams['author'] = this.author()
885901
docParams['message'] = message
886-
return this.dispatch(CONST.POST, this.connectionConfig.documentURL(docParams), json)
902+
return this.dispatch(CONST.POST, this.connectionConfig.documentURL(docParams), json, getDataVersion)
887903
}
888904

889905
/**
@@ -892,6 +908,8 @@ WOQLClient.prototype.addDocument = function(json, params, dbId, message="add a n
892908
* @param {typedef.DocParamsGet} [params] - the get parameters
893909
* @param {string} [dbId] - the database id
894910
* @param {string} [branch] - the database branch
911+
* @param {string} [lastDataVersion] If passed it will be used for data version tracking.
912+
* @param {string} [getDataVersion] If true it the function will return object having result and dataVersion.
895913
* @returns {Promise} A promise that returns the call response object, or an Error if rejected.
896914
* @example
897915
* const query = {
@@ -901,21 +919,27 @@ WOQLClient.prototype.addDocument = function(json, params, dbId, message="add a n
901919
* client.queryDocument(query,{"as_list":true})
902920
*/
903921

904-
WOQLClient.prototype.queryDocument = function(query, params, dbId, branch){
922+
WOQLClient.prototype.queryDocument = function(query, params, dbId, branch, lastDataVersion='', getDataVersion = false){
905923
if (dbId) {
906924
this.db(dbId)
907925
}
908926
if(branch){
909927
this.checkout(branch)
910928
}
911-
return this.dispatch(CONST.QUERY_DOCUMENT, this.connectionConfig.documentURL(params),query)
929+
if(typeof lastDataVersion === 'string' && lastDataVersion !== '') {
930+
this.customHeaders({'TerminusDB-Data-Version': lastDataVersion})
931+
}
932+
933+
return this.dispatch(CONST.QUERY_DOCUMENT, this.connectionConfig.documentURL(params), query, getDataVersion)
912934
}
913935

914936
/**
915937
*
916938
* @param {typedef.DocParamsGet} [params] - the get parameters
917939
* @param {string} [dbId] - the database id
918940
* @param {string} [branch] - the database branch
941+
* @param {string} [lastDataVersion] If passed it will be used for data version tracking.
942+
* @param {string} [getDataVersion] If true it the function will return object having result and dataVersion.
919943
* @returns {Promise} A promise that returns the call response object, or an Error if rejected.
920944
* @example
921945
* //return the schema graph as a json array
@@ -927,14 +951,17 @@ WOQLClient.prototype.queryDocument = function(query, params, dbId, branch){
927951
*
928952
*/
929953
//document interface
930-
WOQLClient.prototype.getDocument = function(params,dbId,branch){
954+
WOQLClient.prototype.getDocument = function(params,dbId,branch,lastDataVersion='', getDataVersion=false){
931955
if (dbId) {
932956
this.db(dbId)
933957
}
934958
if(branch){
935959
this.checkout(branch)
936960
}
937-
return this.dispatch(CONST.GET, this.connectionConfig.documentURL(params))
961+
if(typeof lastDataVersion === 'string' && lastDataVersion !== '') {
962+
this.customHeaders({'TerminusDB-Data-Version': lastDataVersion})
963+
}
964+
return this.dispatch(CONST.GET, this.connectionConfig.documentURL(params),{}, getDataVersion)
938965
}
939966

940967
/**
@@ -943,30 +970,37 @@ WOQLClient.prototype.getDocument = function(params,dbId,branch){
943970
* @param {typedef.DocParamsPut} [params] - the Put parameters
944971
* @param {*} [dbId] - the database id
945972
* @param {*} [message] - the update commit message
973+
* @param {string} [lastDataVersion] If passed it will be used for data version tracking.
974+
* @param {string} [getDataVersion] If true it the function will return object having result and dataVersion.
946975
* @returns {Promise} A promise that returns the call response object, or an Error if rejected.
947976
*/
948977

949-
WOQLClient.prototype.updateDocument = function(json,params,dbId, message="update document"){
978+
WOQLClient.prototype.updateDocument = function(json,params,dbId, message="update document", lastDataVersion='', getDataVersion=false){
950979
const docParams = params || {}
951980
docParams['author']=this.author()
952981
docParams['message'] = message
953982
if (dbId) {
954983
this.db(dbId)
955984
}
956-
return this.dispatch(CONST.PUT, this.connectionConfig.documentURL(docParams),json)
985+
if(typeof lastDataVersion === 'string' && lastDataVersion !== '') {
986+
this.customHeaders({'TerminusDB-Data-Version': lastDataVersion})
987+
}
988+
return this.dispatch(CONST.PUT, this.connectionConfig.documentURL(docParams),json, getDataVersion)
957989
}
958990

959991
/**
960992
* to delete the document
961993
* @param {typedef.DocParamsDelete} [params]
962994
* @param {string} [dbId] - the database id
963995
* @param {string} [message] - the delete message
996+
* @param {string} [lastDataVersion] If passed it will be used for data version tracking
997+
* @param {string} [getDataVersion] If true it the function will return object having result and dataVersion
964998
* @returns {Promise} A promise that returns the call response object, or an Error if rejected.
965999
* @example
9661000
* client.deleteDocument({"graph_type":"schema",id:['Country','Coordinate'])
9671001
*/
9681002

969-
WOQLClient.prototype.deleteDocument = function(params,dbId,message="delete document"){
1003+
WOQLClient.prototype.deleteDocument = function(params,dbId,message="delete document", lastDataVersion='', getDataVersion=false){
9701004
const docParams = params || {}
9711005
let payload = null
9721006
if(Array.isArray(params.id)){
@@ -978,7 +1012,10 @@ WOQLClient.prototype.deleteDocument = function(params,dbId,message="delete docum
9781012
if (dbId) {
9791013
this.db(dbId)
9801014
}
981-
return this.dispatch(CONST.DELETE, this.connectionConfig.documentURL(docParams),payload)
1015+
if(typeof lastDataVersion === 'string' && lastDataVersion !== '') {
1016+
this.customHeaders({'TerminusDB-Data-Version': lastDataVersion})
1017+
}
1018+
return this.dispatch(CONST.DELETE, this.connectionConfig.documentURL(docParams),payload, getDataVersion)
9821019
}
9831020
/**
9841021
* The purpose of this method is to quickly discover the supported fields of a particular type.

0 commit comments

Comments
 (0)