terminusdb 12.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/Contributing.md +36 -0
  2. package/LICENSE +201 -0
  3. package/README.md +175 -0
  4. package/RELEASE_NOTES.md +462 -0
  5. package/dist/index.html +22 -0
  6. package/dist/terminusdb-client.min.js +3 -0
  7. package/dist/terminusdb-client.min.js.LICENSE.txt +188 -0
  8. package/dist/terminusdb-client.min.js.map +1 -0
  9. package/dist/typescript/index.d.ts +14 -0
  10. package/dist/typescript/lib/accessControl.d.ts +554 -0
  11. package/dist/typescript/lib/axiosInstance.d.ts +2 -0
  12. package/dist/typescript/lib/connectionConfig.d.ts +381 -0
  13. package/dist/typescript/lib/const.d.ts +54 -0
  14. package/dist/typescript/lib/dispatchRequest.d.ts +17 -0
  15. package/dist/typescript/lib/errorMessage.d.ts +25 -0
  16. package/dist/typescript/lib/query/woqlBuilder.d.ts +75 -0
  17. package/dist/typescript/lib/query/woqlCore.d.ts +341 -0
  18. package/dist/typescript/lib/query/woqlDoc.d.ts +63 -0
  19. package/dist/typescript/lib/query/woqlLibrary.d.ts +718 -0
  20. package/dist/typescript/lib/query/woqlPrinter.d.ts +71 -0
  21. package/dist/typescript/lib/query/woqlQuery.d.ts +833 -0
  22. package/dist/typescript/lib/typedef.d.ts +624 -0
  23. package/dist/typescript/lib/utils.d.ts +199 -0
  24. package/dist/typescript/lib/valueHash.d.ts +146 -0
  25. package/dist/typescript/lib/viewer/chartConfig.d.ts +62 -0
  26. package/dist/typescript/lib/viewer/chooserConfig.d.ts +38 -0
  27. package/dist/typescript/lib/viewer/documentFrame.d.ts +44 -0
  28. package/dist/typescript/lib/viewer/frameConfig.d.ts +74 -0
  29. package/dist/typescript/lib/viewer/frameRule.d.ts +145 -0
  30. package/dist/typescript/lib/viewer/graphConfig.d.ts +73 -0
  31. package/dist/typescript/lib/viewer/objectFrame.d.ts +212 -0
  32. package/dist/typescript/lib/viewer/streamConfig.d.ts +23 -0
  33. package/dist/typescript/lib/viewer/tableConfig.d.ts +66 -0
  34. package/dist/typescript/lib/viewer/terminusRule.d.ts +75 -0
  35. package/dist/typescript/lib/viewer/viewConfig.d.ts +47 -0
  36. package/dist/typescript/lib/viewer/woqlChart.d.ts +1 -0
  37. package/dist/typescript/lib/viewer/woqlChooser.d.ts +56 -0
  38. package/dist/typescript/lib/viewer/woqlGraph.d.ts +26 -0
  39. package/dist/typescript/lib/viewer/woqlPaging.d.ts +1 -0
  40. package/dist/typescript/lib/viewer/woqlResult.d.ts +128 -0
  41. package/dist/typescript/lib/viewer/woqlRule.d.ts +96 -0
  42. package/dist/typescript/lib/viewer/woqlStream.d.ts +31 -0
  43. package/dist/typescript/lib/viewer/woqlTable.d.ts +102 -0
  44. package/dist/typescript/lib/viewer/woqlView.d.ts +49 -0
  45. package/dist/typescript/lib/woql.d.ts +1267 -0
  46. package/dist/typescript/lib/woqlClient.d.ts +1216 -0
  47. package/index.js +28 -0
  48. package/lib/.eslintrc +1 -0
  49. package/lib/accessControl.js +988 -0
  50. package/lib/axiosInstance.js +5 -0
  51. package/lib/connectionConfig.js +765 -0
  52. package/lib/const.js +59 -0
  53. package/lib/dispatchRequest.js +236 -0
  54. package/lib/errorMessage.js +110 -0
  55. package/lib/query/woqlBuilder.js +234 -0
  56. package/lib/query/woqlCore.js +934 -0
  57. package/lib/query/woqlDoc.js +177 -0
  58. package/lib/query/woqlLibrary.js +1015 -0
  59. package/lib/query/woqlPrinter.js +476 -0
  60. package/lib/query/woqlQuery.js +1865 -0
  61. package/lib/typedef.js +248 -0
  62. package/lib/utils.js +817 -0
  63. package/lib/valueHash.js_old +581 -0
  64. package/lib/viewer/chartConfig.js +411 -0
  65. package/lib/viewer/chooserConfig.js +234 -0
  66. package/lib/viewer/documentFrame.js +206 -0
  67. package/lib/viewer/frameConfig.js +469 -0
  68. package/lib/viewer/frameRule.js +519 -0
  69. package/lib/viewer/graphConfig.js +345 -0
  70. package/lib/viewer/objectFrame.js +1550 -0
  71. package/lib/viewer/streamConfig.js +82 -0
  72. package/lib/viewer/tableConfig.js +310 -0
  73. package/lib/viewer/terminusRule.js +196 -0
  74. package/lib/viewer/viewConfig.js +219 -0
  75. package/lib/viewer/woqlChart.js +17 -0
  76. package/lib/viewer/woqlChooser.js +171 -0
  77. package/lib/viewer/woqlGraph.js +295 -0
  78. package/lib/viewer/woqlPaging.js +148 -0
  79. package/lib/viewer/woqlResult.js +258 -0
  80. package/lib/viewer/woqlRule.js +312 -0
  81. package/lib/viewer/woqlStream.js +27 -0
  82. package/lib/viewer/woqlTable.js +332 -0
  83. package/lib/viewer/woqlView.js +107 -0
  84. package/lib/woql.js +1693 -0
  85. package/lib/woqlClient.js +2091 -0
  86. package/package.json +110 -0
@@ -0,0 +1,1865 @@
1
+ /* eslint-disable class-methods-use-this */
2
+ /* eslint-disable no-redeclare */
3
+ /* eslint-disable block-scoped-var */
4
+ /* eslint-disable no-var */
5
+ /* eslint-disable vars-on-top */
6
+ /* eslint-disable no-param-reassign */
7
+ /* eslint-disable no-unused-vars */
8
+ /* eslint-disable camelcase */
9
+ /* eslint-disable no-plusplus */
10
+ /* eslint-disable prefer-destructuring */
11
+ /* eslint-disable guard-for-in */
12
+ /* eslint-disable no-restricted-syntax */
13
+
14
+ /// /@ts-check
15
+ // WOQLQuery
16
+ /**
17
+ * defines the internal functions of the woql query object - the
18
+ * language API is defined in WOQLQuery
19
+ * @module WOQLQuery
20
+ * @constructor
21
+ * @param {object} [query] json-ld query for initialisation
22
+ * @returns {WOQLQuery}
23
+ */
24
+
25
+ const WOQLCore = require('./woqlCore');
26
+ const {
27
+ Var, Vars, Doc, VarsUnique,
28
+ } = require('./woqlDoc');
29
+ // eslint-disable-next-line no-unused-vars
30
+ const typedef = require('../typedef');
31
+
32
+ // I HAVE TO REVIEW THE Inheritance and the prototype chain
33
+ class WOQLQuery extends WOQLCore {
34
+ /**
35
+ * defines the internal functions of the woql query object - the
36
+ * language API is defined in WOQLQuery
37
+ * @module WOQLQuery
38
+ * @constructor
39
+ * @param {object} [query] json-ld query for initialisation
40
+ * @returns {WOQLQuery}
41
+ */
42
+
43
+ /**
44
+ * Update a pattern matching rule for the triple (Subject, Predicate, oldObjValue) with the
45
+ * new one (Subject, Predicate, newObjValue)
46
+ * @param {string|Var} subject - The IRI of a triple’s subject or a variable
47
+ * @param {string|Var} predicate - The IRI of a property or a variable
48
+ * @param {string|Var} newObjValue - The value to update or a literal
49
+ * @param {string|Var} oldObjValue - The old value of the object
50
+ * @returns {WOQLQuery} A WOQLQuery which contains the a Update Triple Statement
51
+ */
52
+ update_triple(subject, predicate, newObjValue, oldObjValue) { return this; }
53
+
54
+ /**
55
+ * Generates a query that by default matches all triples in a graph identified by "graph"
56
+ * or in all the current terminusDB's graph
57
+ * @param {string | boolean} [graph] - false or the resource identifier of a graph possible
58
+ * value are schema/{main - myschema - *} | instance/{main - myschema - *} |
59
+ * inference/{main - myschema - *}
60
+ * @param {string|Var} [subject] - The IRI of a triple’s subject or a variable,
61
+ * default value "v:Subject"
62
+ * @param {string|Var} [predicate] - The IRI of a property or a variable,
63
+ * default value "v:Predicate"
64
+ * @param {string|Var} [object] - The IRI of a node or a variable, or a literal,
65
+ * default value "v:Object"
66
+ * @returns {WOQLQuery} A WOQLQuery which contains the pattern matching expression
67
+ */
68
+ star(graph, subject, predicate, object) { return this; }
69
+
70
+ /**
71
+ * Update a pattern matching rule for the quad [S, P, O, G] (Subject, Predicate, Object, Graph)
72
+ * @param {string|Var} subject - The IRI of a triple’s subject or a variable
73
+ * @param {string|Var} predicate - The IRI of a property or a variable
74
+ * @param {string|Var} newObject - The value to update or a literal
75
+ * @param {typedef.GraphRef} graphRef - A valid graph resource identifier string
76
+ * @returns {WOQLQuery} A WOQLQuery which contains the a Update Quad Statement
77
+ */
78
+ update_quad(subject, predicate, newObject, graphRef) { return this; }
79
+
80
+ /**
81
+ * @param {string|Var} id - IRI string or variable containing
82
+ * @param {string|Var} type - IRI string or variable containing the IRI of the
83
+ * @param {typedef.GraphRef} [refGraph] - Optional Graph resource identifier
84
+ * @returns {WOQLQuery} A WOQLQuery which contains the insert expression
85
+ */
86
+ insert(id, type, refGraph) { return this; }
87
+
88
+ /**
89
+ * Sets the graph resource ID that will be used for subsequent chained function calls
90
+ * @param {typedef.GraphRef} [graphRef] Resource String identifying the graph which will
91
+ * be used for subsequent chained schema calls
92
+ * @returns {WOQLQuery} A WOQLQuery which contains the partial Graph pattern matching expression
93
+ */
94
+ graph(graphRef) { return this; }
95
+
96
+ /**
97
+ * Specifies the identity of a node that can then be used in subsequent builder functions.
98
+ * Note that node() requires subsequent chained functions to complete the triples / quads
99
+ * that it produces - by itself it only generates the subject.
100
+ * @param {string|Var} nodeid - The IRI of a node or a variable containing an IRI which will
101
+ * be the subject of the builder functions
102
+ * @param {typedef.FuntionType} [chainType] - Optional type of builder function to build
103
+ * (default is triple)
104
+ * @returns {WOQLQuery} - A WOQLQuery which contains the partial Node pattern matching expression
105
+ */
106
+ node(nodeid, chainType) { return this; }
107
+
108
+ /**
109
+ * Deletes all triples in the passed graph (defaults to instance/main)
110
+ * @param {typedef.GraphRef} [graphRef] - Resource String identifying the graph from
111
+ * which all triples will be removed
112
+ * @returns {WOQLQuery} - A WOQLQuery which contains the deletion expression
113
+ * @example
114
+ * nuke("schema/main")
115
+ * //will delete everything from the schema/main graph
116
+ */
117
+ nuke(graphRef) { return this; }
118
+
119
+ /**
120
+ * @param {string|Var} [Subj] - The IRI of a triple’s subject or a variable
121
+ * @param {string|Var} [Pred] - The IRI of a property or a variable
122
+ * @param {string|Var} [Obj] - The IRI of a node or a variable, or a literal
123
+ * @param {typedef.GraphRef} [Graph] - the resource identifier of a graph possible
124
+ * @returns {WOQLQuery} - A WOQLQuery which contains the pattern matching expression
125
+ */
126
+ all(Subj, Pred, Obj, Graph) { return this; }
127
+
128
+ /**
129
+ * @param {boolean} tf
130
+ * @returns {object}
131
+ */
132
+ boolean(tf) { return {}; }
133
+
134
+ /**
135
+ * @param {string} s
136
+ * @returns {object}
137
+ */
138
+ string(s) { return {}; }
139
+
140
+ /**
141
+ * @param {any} s
142
+ * @param {string} t
143
+ * @returns {object}
144
+
145
+ */
146
+ literal(s, t) { return {}; }
147
+
148
+ /**
149
+ * @param {string} s
150
+ * @returns {object}
151
+ */
152
+ iri(s) { return {}; }
153
+
154
+ // eslint-disable-next-line no-underscore-dangle
155
+ _set_context(ctxt) { return this; }
156
+
157
+ /**
158
+ * @param {WOQLQuery} Subq
159
+ * @returns {WOQLQuery}
160
+ */
161
+ addSubQuery(Subq) {
162
+ super.addSubQuery(Subq);
163
+ return this;
164
+ }
165
+
166
+ /**
167
+ * @param {string} msg
168
+ * @returns {WOQLQuery}
169
+ */
170
+ parameterError(msg) {
171
+ super.parameterError(msg);
172
+ return this;
173
+ }
174
+
175
+ /**
176
+ * @returns {WOQLQuery}
177
+ */
178
+ updated() {
179
+ super.updated();
180
+ return this;
181
+ }
182
+
183
+ // eslint-disable-next-line no-useless-constructor
184
+ constructor(query) {
185
+ super(query);
186
+ }
187
+ }
188
+
189
+ /**
190
+ * Read a node identified by an IRI as a JSON-LD document
191
+ * @param {string} IRI - The document id or a variable to read
192
+ * @param {string} output - Variable which will be bound to the document.
193
+ * @return {WOQLQuery} WOQLQuery
194
+ */
195
+ WOQLQuery.prototype.read_document = function (IRI, output) {
196
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
197
+ this.cursor['@type'] = 'ReadDocument';
198
+ this.cursor.identifier = this.cleanNodeValue(IRI);
199
+ this.cursor.document = this.expandValueVariable(output);
200
+ return this;
201
+ };
202
+
203
+ /**
204
+ * Insert a document in the graph.
205
+ * @param {object} docjson - The document to insert. Must either have an '@id' or
206
+ * have a class specified key.
207
+ * @param {string} [IRI] - An optional identifier specifying the document location.
208
+ * @return {WOQLQuery} WOQLQuery
209
+ */
210
+
211
+ WOQLQuery.prototype.insert_document = function (docjson, IRI) {
212
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
213
+ this.cursor['@type'] = 'InsertDocument';
214
+ if (typeof IRI !== 'undefined') this.cursor.identifier = this.cleanNodeValue(IRI);
215
+
216
+ this.cursor.document = this.cleanObject(docjson);
217
+
218
+ return this.updated();
219
+ };
220
+
221
+ /**
222
+ * Update a document identified by an IRI
223
+ * @param {object} docjson - The document to update. Must either have an '@id' or
224
+ * have a class specified key.
225
+ * @param {string} [IRI] - An optional identifier specifying the document location.
226
+ * @return {WOQLQuery} WOQLQuery
227
+ */
228
+
229
+ WOQLQuery.prototype.update_document = function (docjson, IRI) {
230
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
231
+ this.cursor['@type'] = 'UpdateDocument';
232
+ if (typeof IRI !== 'undefined') this.cursor.identifier = this.cleanNodeValue(IRI);
233
+
234
+ this.cursor.document = this.cleanObject(docjson);
235
+
236
+ return this.updated();
237
+ };
238
+
239
+ /**
240
+ * Delete a document from the graph.
241
+ * @param {string} IRI - The document id or a variable
242
+ * @return {WOQLQuery} WOQLQuery
243
+ */
244
+
245
+ WOQLQuery.prototype.delete_document = function (IRI) {
246
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
247
+ this.cursor['@type'] = 'DeleteDocument';
248
+ this.cursor.identifier = this.cleanNodeValue(IRI);
249
+ return this.updated();
250
+ };
251
+
252
+ /**
253
+ * Contains definitions of the WOQL functions which map directly to JSON-LD types
254
+ * All other calls and queries can be composed from these
255
+ */
256
+
257
+ // moved from woqlCore
258
+ WOQLQuery.prototype.wrapCursorWithAnd = function () {
259
+ if (this.cursor && this.cursor['@type'] === 'And') {
260
+ const newby = this.cursor.and.length;
261
+ this.and({});
262
+ this.cursor = this.cursor.and[newby];
263
+ } else {
264
+ const nj = new WOQLQuery().json(this.cursor);
265
+ for (const k in this.cursor) delete this.cursor[k];
266
+ // create an empty json for the new query
267
+ this.and(nj, {});
268
+ this.cursor = this.cursor.and[1];
269
+ }
270
+ };
271
+
272
+ /**
273
+ * Query running against any specific commit Id
274
+ * @param {string} refPath - path to specific reference Id or commit Id
275
+ * @param {WOQLQuery} [subquery] - subquery for the specific commit point
276
+ * @returns {WOQLQuery}
277
+ */
278
+
279
+ WOQLQuery.prototype.using = function (refPath, subquery) {
280
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
281
+ this.cursor['@type'] = 'Using';
282
+ if (!refPath || typeof refPath !== 'string') {
283
+ return this.parameterError('The first parameter to using must be a Collection ID (string)');
284
+ }
285
+ this.cursor.collection = refPath;
286
+ return this.addSubQuery(subquery);
287
+ };
288
+
289
+ /**
290
+ * Adds a text comment to a query - can also be used to wrap any part of a query to turn it off
291
+ * @param {string} comment - text comment
292
+ * @param {WOQLQuery} [subquery] - query that is "commented out"
293
+ * @returns {WOQLQuery}
294
+ */
295
+
296
+ WOQLQuery.prototype.comment = function (comment, subquery) {
297
+ // if (comment && comment === 'args')
298
+ // return ['comment', 'query']
299
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
300
+ this.cursor['@type'] = 'Comment';
301
+ this.cursor.comment = this.jlt(comment);
302
+ return this.addSubQuery(subquery);
303
+ };
304
+
305
+ /**
306
+ * Filters the query so that only the variables included in [V1...Vn] are returned in the bindings
307
+ * @param {...string|...Var} varNames - only these variables are returned
308
+ * @returns {WOQLQuery}
309
+ */
310
+
311
+ WOQLQuery.prototype.select = function (...varNames) {
312
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
313
+ this.cursor['@type'] = 'Select';
314
+ if (!varNames || varNames.length <= 0) {
315
+ return this.parameterError('Select must be given a list of variable names');
316
+ }
317
+ const last = varNames[varNames.length - 1];
318
+ /**
319
+ *@type {any}
320
+ */
321
+ let embedquery = false;
322
+ if (typeof last === 'object' && !(last instanceof Var) && last.json) {
323
+ embedquery = varNames.pop();
324
+ } // else var embedquery = false
325
+ this.cursor.variables = this.rawVarList(varNames);
326
+ return this.addSubQuery(embedquery);
327
+ };
328
+
329
+ /**
330
+ * Build a localized scope for variables to prevent leaking local variables to outer scope.
331
+ * Returns a tuple [localized, v] where:
332
+ * - localized: function that wraps queries with select("") and eq() bindings
333
+ * - v: object with unique variable names for use in the inner query
334
+ *
335
+ * Parameters with non-null values are bound from outer scope via eq().
336
+ * Parameters with null values are local-only variables.
337
+ *
338
+ * @param {object} paramSpec - Object mapping parameter names to values (or null for local vars)
339
+ * @returns {LocalizeResult} Tuple of [localized function, variables object]
340
+ * @example
341
+ * const [localized, v] = WOQL.localize({ consSubject, valueVar, last_cell: null });
342
+ * return localized(
343
+ * WOQL.and(
344
+ * WOQL.triple(v.consSubject, 'rdf:type', 'rdf:List'),
345
+ * WOQL.triple(v.last_cell, 'rdf:rest', 'rdf:nil')
346
+ * )
347
+ * );
348
+ */
349
+ WOQLQuery.prototype.localize = function (paramSpec) {
350
+ // Generate unique variable names for all parameters
351
+ const paramNames = Object.keys(paramSpec);
352
+ const v = VarsUnique(...paramNames);
353
+
354
+ const localized = (queryOrUndefined) => {
355
+ // CRITICAL: Create eq bindings for outer parameters OUTSIDE select("")
356
+ // This ensures outer parameters are visible in query results
357
+ const outerEqBindings = [];
358
+ for (const paramName of paramNames) {
359
+ const outerValue = paramSpec[paramName];
360
+ if (outerValue !== null) {
361
+ // If the outer value is a variable, add eq(var, var) to register it in outer scope
362
+ if (typeof outerValue === 'string' && outerValue.startsWith('v:')) {
363
+ outerEqBindings.push(new WOQLQuery().eq(outerValue, outerValue));
364
+ }
365
+ // Bind the unique variable to the outer parameter OUTSIDE the select("")
366
+ outerEqBindings.push(new WOQLQuery().eq(v[paramName], outerValue));
367
+ }
368
+ }
369
+
370
+ if (queryOrUndefined) {
371
+ // Functional mode: wrap query in select(""), then add outer eq bindings
372
+ const localizedQuery = new WOQLQuery().select('').and(queryOrUndefined);
373
+
374
+ if (outerEqBindings.length > 0) {
375
+ // Wrap: eq(outer) AND select("") { query }
376
+ return new WOQLQuery().and(...outerEqBindings, localizedQuery);
377
+ }
378
+ return localizedQuery;
379
+ }
380
+
381
+ // Fluent mode: return wrapper that applies pattern on and()
382
+ const fluentWrapper = new WOQLQuery();
383
+ // eslint-disable-next-line no-underscore-dangle
384
+ fluentWrapper._localizeOuterEq = outerEqBindings;
385
+
386
+ // Override and() to apply the localize pattern
387
+ fluentWrapper.and = function (...args) {
388
+ const innerQuery = new WOQLQuery().and(...args);
389
+ const localizedQuery = new WOQLQuery().select('').and(innerQuery);
390
+
391
+ // eslint-disable-next-line no-underscore-dangle
392
+ if (fluentWrapper._localizeOuterEq.length > 0) {
393
+ // eslint-disable-next-line no-underscore-dangle
394
+ return new WOQLQuery().and(...fluentWrapper._localizeOuterEq, localizedQuery);
395
+ }
396
+ return localizedQuery;
397
+ };
398
+
399
+ return fluentWrapper;
400
+ };
401
+
402
+ return [localized, v];
403
+ };
404
+
405
+ /**
406
+ * Filter the query to return only results that are distinct in the given variables
407
+ * @param {...string|...Var} varNames - these variables are guaranteed to be unique as a tuple
408
+ * @returns {WOQLQuery}
409
+ */
410
+
411
+ WOQLQuery.prototype.distinct = function (...varNames) {
412
+ // if (list && list[0] === 'args')
413
+ // return ['variable_list', 'query']
414
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
415
+ this.cursor['@type'] = 'Distinct';
416
+ if (!varNames || varNames.length <= 0) {
417
+ return this.parameterError('Distinct must be given a list of variable names');
418
+ }
419
+ const last = varNames[varNames.length - 1];
420
+ /**
421
+ * @type {any}
422
+ */
423
+ let embedquery = false;
424
+ if (typeof last === 'object' && !(last instanceof Var) && last.json) {
425
+ embedquery = varNames.pop();
426
+ } // else var embedquery = false
427
+ this.cursor.variables = this.rawVarList(varNames);
428
+ return this.addSubQuery(embedquery);
429
+ };
430
+
431
+ /**
432
+ * Logical conjunction of the contained queries - all queries must match or the entire clause fails
433
+ * @param {...WOQLQuery} subqueries - A list of one or more woql queries to execute as a conjunction
434
+ * @returns {WOQLQuery} - A WOQLQuery object containing the conjunction of queries
435
+ */
436
+
437
+ WOQLQuery.prototype.and = function (...subqueries) {
438
+ if (this.cursor['@type'] && this.cursor['@type'] !== 'And') {
439
+ const nj = new WOQLQuery().json(this.cursor);
440
+ for (const k in this.cursor) delete this.cursor[k];
441
+ subqueries.unshift(nj);
442
+ }
443
+ this.cursor['@type'] = 'And';
444
+ if (typeof this.cursor.and === 'undefined') this.cursor.and = [];
445
+ for (let i = 0; i < subqueries.length; i++) {
446
+ const onevar = this.jobj(subqueries[i]);
447
+ if (
448
+ onevar['@type'] === 'And'
449
+ && onevar.and
450
+ ) {
451
+ for (let j = 0; j < onevar.and.length; j++) {
452
+ const qjson = onevar.and[j];
453
+ if (qjson) {
454
+ const subvar = this.jobj(qjson);
455
+ this.cursor.and.push(subvar);
456
+ }
457
+ }
458
+ } else {
459
+ this.cursor.and.push(onevar);
460
+ }
461
+ }
462
+ return this;
463
+ };
464
+
465
+ /**
466
+ * Creates a logical OR of the arguments
467
+ * @param {...WOQLQuery} subqueries - A list of one or more woql queries
468
+ * to execute as alternatives
469
+ * @returns {WOQLQuery} - A WOQLQuery object containing the logical Or of the subqueries
470
+ */
471
+
472
+ WOQLQuery.prototype.or = function (...subqueries) {
473
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
474
+ this.cursor['@type'] = 'Or';
475
+ if (typeof this.cursor.or === 'undefined') this.cursor.or = [];
476
+ for (let i = 0; i < subqueries.length; i++) {
477
+ const onevar = this.jobj(subqueries[i]);
478
+ this.cursor.or.push(onevar);
479
+ }
480
+ return this;
481
+ };
482
+ /**
483
+ * Specifies the database URL that will be the default database for the enclosed query
484
+ * @param {typedef.GraphRef} graphRef- A valid graph resource identifier string
485
+ * @param {WOQLQuery} [query] - The query
486
+ * @returns {WOQLQuery} A WOQLQuery object containing the from expression
487
+ */
488
+
489
+ /**
490
+ * Specifies the database URL that will be the default database for the enclosed query
491
+ * @param {typedef.GraphRef} graphRef- A valid graph resource identifier string
492
+ * @param {WOQLQuery} [query] - The query
493
+ * @returns {WOQLQuery} A WOQLQuery object containing the from expression
494
+ */
495
+
496
+ WOQLQuery.prototype.from = function (graphRef, query) {
497
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
498
+ this.cursor['@type'] = 'From';
499
+ if (!graphRef || typeof graphRef !== 'string') {
500
+ return this.parameterError(
501
+ 'The first parameter to from must be a Graph Filter Expression (string)',
502
+ );
503
+ }
504
+ this.cursor.graph = this.jlt(graphRef);
505
+ return this.addSubQuery(query);
506
+ };
507
+
508
+ /**
509
+ * Specifies the graph resource to write the contained query into
510
+ * @param {typedef.GraphRef} graphRef- A valid graph resource identifier string
511
+ * @param {WOQLQuery} [subquery] - The query which will be written into the graph
512
+ * @returns {WOQLQuery} A WOQLQuery which will be written into the graph in question
513
+ */
514
+
515
+ WOQLQuery.prototype.into = function (graphRef, subquery) {
516
+ // if (graph_descriptor && graph_descriptor === 'args')
517
+ // return ['graph', 'query']
518
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
519
+ this.cursor['@type'] = 'Into';
520
+ if (!graphRef || typeof graphRef !== 'string') {
521
+ return this.parameterError(
522
+ 'The first parameter to from must be a Graph Filter Expression (string)',
523
+ );
524
+ }
525
+ this.cursor.graph = this.jlt(graphRef);
526
+ return this.addSubQuery(subquery);
527
+ };
528
+
529
+ /**
530
+ * Creates a triple pattern matching rule for the triple [S, P, O] (Subject, Predicate, Object)
531
+ * @param {string|Var} subject - The IRI of a triple’s subject or a variable
532
+ * @param {string|Var} predicate - The IRI of a property or a variable
533
+ * @param {string|Var} object - The IRI of a node or a variable, or a literal
534
+ * @returns {WOQLQuery}
535
+ */
536
+
537
+ WOQLQuery.prototype.triple = function (subject, predicate, object) {
538
+ // if (a && a === 'args')
539
+ // return ['subject', 'predicate', 'object']
540
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
541
+ this.cursor['@type'] = 'Triple';
542
+ this.cursor.subject = this.cleanSubject(subject);
543
+ this.cursor.predicate = this.cleanPredicate(predicate);
544
+ this.cursor.object = this.cleanObject(object);
545
+ return this;
546
+ };
547
+
548
+ /**
549
+ * Creates a triple pattern matching rule for the triple [S, P, O] (Subject, Predicate,
550
+ * Object) added in the current layer
551
+ * @param {string|Var} subject - The IRI of a triple’s subject or a variable
552
+ * @param {string|Var} predicate - The IRI of a property or a variable
553
+ * @param {string|Var} object - The IRI of a node or a variable, or a literal
554
+ * @returns {WOQLQuery}
555
+ */
556
+
557
+ WOQLQuery.prototype.added_triple = function (subject, predicate, object) {
558
+ // if (a && a === 'args')
559
+ // return ['subject', 'predicate', 'object']
560
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
561
+ this.cursor['@type'] = 'AddedTriple';
562
+ this.cursor.subject = this.cleanSubject(subject);
563
+ this.cursor.predicate = this.cleanPredicate(predicate);
564
+ this.cursor.object = this.cleanObject(object);
565
+ return this;
566
+ };
567
+
568
+ /**
569
+ * Creates a triple pattern matching rule for the triple [S, P, O] (Subject, Predicate,
570
+ * Object) added in the current commit
571
+ * @param {string|Var} subject - The IRI of a triple’s subject or a variable
572
+ * @param {string|Var} predicate - The IRI of a property or a variable
573
+ * @param {string|Var} object - The IRI of a node or a variable, or a literal
574
+ * @returns {WOQLQuery}
575
+ */
576
+
577
+ WOQLQuery.prototype.removed_triple = function (subject, predicate, object) {
578
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
579
+ this.cursor['@type'] = 'DeletedTriple';
580
+ this.cursor.subject = this.cleanSubject(subject);
581
+ this.cursor.predicate = this.cleanPredicate(predicate);
582
+ this.cursor.object = this.cleanObject(object);
583
+ return this;
584
+ };
585
+
586
+ /**
587
+ * Creates a pattern matching rule for triple [Subject, Predicate, Object]
588
+ * @param {string|Var} subject - The IRI of a triple’s subject or a variable
589
+ * @param {string|Var} predicate - The IRI of a property or a variable
590
+ * @param {string|Var} object - The IRI of a node or a variable, or a literal
591
+ * @returns {WOQLQuery} A WOQLQuery which contains the a quad or a triple Statement
592
+ */
593
+
594
+ WOQLQuery.prototype.link = function (subject, predicate, object) {
595
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
596
+ this.cursor['@type'] = 'Triple';
597
+ this.cursor.subject = this.cleanSubject(subject);
598
+ this.cursor.predicate = this.cleanPredicate(predicate);
599
+ this.cursor.object = this.cleanSubject(object);
600
+ return this;
601
+ };
602
+
603
+ /**
604
+ * Creates a pattern matching rule for triple [Subject, Predicate, Object]
605
+ * add extra information about the type of the value object
606
+ * @param {string|Var} subject - The IRI of a triple’s subject or a variable
607
+ * @param {string|Var} predicate - The IRI of a property or a variable
608
+ * @param {string | number | boolean | Var} objValue - an specific value
609
+ * @returns {WOQLQuery} A WOQLQuery which contains the a quad or a triple Statement
610
+ */
611
+
612
+ WOQLQuery.prototype.value = function (subject, predicate, objValue) {
613
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
614
+ this.cursor['@type'] = 'Triple';
615
+ this.cursor.subject = this.cleanSubject(subject);
616
+ this.cursor.predicate = this.cleanPredicate(predicate);
617
+ this.cursor.object = this.cleanDataValue(objValue, 'xsd:string');
618
+ return this;
619
+ };
620
+
621
+ /**
622
+ * Creates a pattern matching rule for the quad [S, P, O, G] (Subject, Predicate, Object, Graph)
623
+ * @param {string|Var} subject - The IRI of a triple’s subject or a variable
624
+ * @param {string|Var} predicate - The IRI of a property or a variable
625
+ * @param {string|Var} object - The IRI of a node or a variable, or a literal
626
+ * @param {typedef.GraphRef} graphRef - A valid graph resource identifier string
627
+ * @returns {WOQLQuery}
628
+ */
629
+
630
+ WOQLQuery.prototype.quad = function (subject, predicate, object, graphRef) {
631
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
632
+ const args = this.triple(subject, predicate, object);
633
+ // if (a && a === 'args')
634
+ // return args.concat(['graph'])
635
+ if (!graphRef) return this.parameterError('Quad takes four parameters, the last should be a graph filter');
636
+ this.cursor['@type'] = 'Triple';
637
+ this.cursor.graph = this.cleanGraph(graphRef);
638
+ return this;
639
+ };
640
+
641
+ /**
642
+ * Creates a pattern matching rule for the quad [S, P, O, G] (Subject, Predicate,
643
+ * Object, Graph) removed from the current commit
644
+ * @param {string|Var} subject - The IRI of a triple’s subject or a variable
645
+ * @param {string|Var} predicate - The IRI of a property or a variable
646
+ * @param {string|Var} object - The IRI of a node or a variable, or a literal
647
+ * @param {typedef.GraphRef} graphRef- A valid graph resource identifier string
648
+ * @returns {WOQLQuery}
649
+ */
650
+
651
+ WOQLQuery.prototype.added_quad = function (subject, predicate, object, graphRef) {
652
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
653
+ const args = this.triple(subject, predicate, object);
654
+ // if (a && a === 'args')
655
+ // return args.concat(['graph'])
656
+ if (!graphRef) return this.parameterError('Quad takes four parameters, the last should be a graph filter');
657
+ this.cursor['@type'] = 'AddedQuad';
658
+ this.cursor.graph = this.cleanGraph(graphRef);
659
+ return this;
660
+ };
661
+
662
+ /**
663
+ * Creates a pattern matching rule for the quad [S, P, O, G] (Subject, Predicate,
664
+ * Object, Graph) removed from the current commit
665
+ * @param {string|Var} subject - The IRI of a triple’s subject or a variable
666
+ * @param {string|Var} predicate - The IRI of a property or a variable
667
+ * @param {string|Var} object - The IRI of a node or a variable, or a literal
668
+ * @param {typedef.GraphRef} graphRef- A valid graph resource identifier string
669
+ * @returns {WOQLQuery}
670
+ */
671
+
672
+ WOQLQuery.prototype.removed_quad = function (subject, predicate, object, graphRef) {
673
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
674
+ const args = this.triple(subject, predicate, object);
675
+ // if (a && a === 'args')
676
+ // return args.concat(['graph'])
677
+ if (!graphRef) return this.parameterError('Quad takes four parameters, the last should be a graph filter');
678
+ this.cursor['@type'] = 'DeletedQuad';
679
+ this.cursor.graph = this.cleanGraph(graphRef);
680
+ return this;
681
+ };
682
+
683
+ /**
684
+ * Returns true if ClassA subsumes ClassB, according to the current DB schema
685
+ * @param {string} classA - ClassA
686
+ * @param {string} classB - ClassB
687
+ * @returns {boolean} WOQLQuery
688
+ */
689
+ WOQLQuery.prototype.sub = function (classA, classB) {
690
+ if (!classA || !classB) return this.parameterError('Subsumption takes two parameters, both URIs');
691
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
692
+ this.cursor['@type'] = 'Subsumption';
693
+ this.cursor.parent = this.cleanNodeValue(classA);
694
+ this.cursor.child = this.cleanNodeValue(classB);
695
+ return this;
696
+ };
697
+
698
+ WOQLQuery.prototype.subsumption = WOQLQuery.prototype.sub;
699
+
700
+ /**
701
+ * Matches if a is equal to b
702
+ * @param {string|number|boolean|array|Var} varName - literal, variable, array, or id
703
+ * @param {string|number|boolean|array|Var} varValue - literal, variable, array, or id
704
+ * @returns {WOQLQuery}
705
+ */
706
+ WOQLQuery.prototype.eq = function (varName, varValue) {
707
+ // if (a && a === 'args') return ['left', 'right']
708
+ if (typeof varName === 'undefined' || typeof varValue === 'undefined') return this.parameterError('Equals takes two parameters');
709
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
710
+ this.cursor['@type'] = 'Equals';
711
+ this.cursor.left = this.cleanObject(varName);
712
+ this.cursor.right = this.cleanObject(varValue);
713
+ return this;
714
+ };
715
+
716
+ WOQLQuery.prototype.equals = WOQLQuery.prototype.eq;
717
+
718
+ /**
719
+ * Substring
720
+ * @param {string|Var} string - String or variable
721
+ * @param {number|Var} before - integer or variable (characters from start to begin)
722
+ * @param {number|Var} [length] - integer or variable (length of substring)
723
+ * @param {number|Var} [after] - integer or variable (number of characters after substring)
724
+ * @param {string|Var} [subString] - String or variable
725
+ * @returns {WOQLQuery}
726
+ */
727
+ WOQLQuery.prototype.substr = function (string, before, length, after, subString) {
728
+ // if (String && String === 'args')
729
+ // return ['string', 'before', 'length', 'after', 'substring']
730
+ if (!subString) {
731
+ subString = after;
732
+ after = 0;
733
+ }
734
+ if (!subString) {
735
+ subString = length;
736
+ length = subString.length + before;
737
+ }
738
+ if (!string || !subString || typeof subString !== 'string') {
739
+ return this.parameterError(
740
+ 'Substr - the first and last parameters must be strings representing the full and substring variables / literals',
741
+ );
742
+ }
743
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
744
+ this.cursor['@type'] = 'Substring';
745
+ this.cursor.string = this.cleanDataValue(string, 'xsd:string');
746
+ this.cursor.before = this.cleanDataValue(before, 'xsd:nonNegativeInteger');
747
+ this.cursor.length = this.cleanDataValue(length, 'xsd:nonNegativeInteger');
748
+ this.cursor.after = this.cleanDataValue(after, 'xsd:nonNegativeInteger');
749
+ this.cursor.substring = this.cleanDataValue(subString, 'xsd:string');
750
+ return this;
751
+ };
752
+
753
+ WOQLQuery.prototype.substring = WOQLQuery.prototype.substr;
754
+
755
+ /**
756
+ * Use the document inteface to import documents
757
+ * @deprecated
758
+ * Retrieves the exernal resource defined by QueryResource and copies values
759
+ * from it into variables defined in AsVars
760
+ * @param {Vars | array<Var>} asvars - an array of AsVar variable mappings (see as for format below)
761
+ * @param {WOQLQuery} queryResource - an external resource (remote, file, post) to query
762
+ * @returns {WOQLQuery} A WOQLQuery which contains the get expression
763
+ */
764
+ WOQLQuery.prototype.get = function (asvars, queryResource) {
765
+ this.cursor['@type'] = 'Get';
766
+ this.cursor.columns = asvars.json ? asvars.json() : new WOQLQuery().as(...asvars).json();
767
+ if (queryResource) {
768
+ this.cursor.resource = this.jobj(queryResource);
769
+ } else {
770
+ this.cursor.resource = {};
771
+ }
772
+ this.cursor = this.cursor.resource;
773
+ return this;
774
+ };
775
+
776
+ /**
777
+ * Use the document inteface to import documents
778
+ * @deprecated
779
+ * @put Outputs the results of a query to a file
780
+ * @param {Vars | array<Var>} varsToExp - an array of AsVar variable
781
+ * mappings (see as for format below)
782
+ * @param {WOQLQuery} query - The query which will be executed to produce the results
783
+ * @param {string} fileResource - an file resource local to the server
784
+ * @returns {WOQLQuery} A WOQLQuery which contains the put expression
785
+ */
786
+ WOQLQuery.prototype.put = function (varsToExp, query, fileResource) {
787
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
788
+ this.cursor['@type'] = 'Put';
789
+ if (Array.isArray(varsToExp) && typeof varsToExp[0] !== 'object') {
790
+ const nasvars = [];
791
+ for (let i = 0; i < varsToExp.length; i++) {
792
+ const iasv = this.asv(i, varsToExp[i]);
793
+ nasvars.push(iasv);
794
+ this.cursor.columns = nasvars;
795
+ }
796
+ } else {
797
+ this.cursor.columns = varsToExp.json
798
+ ? varsToExp.json()
799
+ : new WOQLQuery().as(...varsToExp).json();
800
+ }
801
+ this.cursor.query = this.jobj(query);
802
+ if (fileResource) {
803
+ this.cursor.resource = this.jobj(fileResource);
804
+ } else {
805
+ this.cursor.resource = {};
806
+ }
807
+ this.cursor = this.cursor.resource;
808
+ return this;
809
+ };
810
+
811
+ /**
812
+ * @param {...(array|string|Var)} varList variable number of arguments
813
+ * @returns WOQLQuery
814
+ */
815
+ WOQLQuery.prototype.as = function (...varList) {
816
+ // if (varList && varList[0] == 'args')
817
+ // return [['indexed_as_var', 'named_as_var']]
818
+ if (!Array.isArray(this.query)) this.query = [];
819
+ if (Array.isArray(varList[0])) {
820
+ if (!varList[1]) {
821
+ // indexed as vars
822
+ for (var i = 0; i < varList[0].length; i++) {
823
+ const iasv = this.asv(i, varList[0][i]);
824
+ this.query.push(iasv);
825
+ }
826
+ } else {
827
+ for (var i = 0; i < varList.length; i++) {
828
+ const onemap = varList[i];
829
+ if (Array.isArray(onemap) && onemap.length >= 2) {
830
+ const type = onemap && onemap.length > 2 ? onemap[2] : false;
831
+ const oasv = this.asv(onemap[0], onemap[1], type);
832
+ this.query.push(oasv);
833
+ }
834
+ }
835
+ }
836
+ } else if (typeof varList[0] === 'number' || typeof varList[0] === 'string') {
837
+ if (varList[2] && typeof varList[2] === 'string') {
838
+ var oasv = this.asv(varList[0], varList[1], varList[2]);
839
+ } else if (varList[1] && varList[1] instanceof Var) {
840
+ var oasv = this.asv(varList[0], varList[1]);
841
+ } else if (varList[1] && typeof varList[1] === 'string') {
842
+ if (varList[1].substring(0, 4) === 'xsd:' || varList[1].substring(0, 4) === 'xdd:') {
843
+ var oasv = this.asv(this.query.length, varList[0], varList[1]);
844
+ } else {
845
+ var oasv = this.asv(varList[0], varList[1]);
846
+ }
847
+ } else {
848
+ var oasv = this.asv(this.query.length, varList[0]);
849
+ }
850
+ this.query.push(oasv);
851
+ } else if (typeof varList[0] === 'object') {
852
+ // check if it is an class object with an json method
853
+ this.query.push(varList[0].json ? varList[0].json() : varList[0]);
854
+ }
855
+ return this;
856
+ };
857
+
858
+ /**
859
+ * Identifies a remote resource by URL and specifies the format of the resource through the options
860
+ * @param {object} remoteObj - The URL at which the remote resource can be accessed
861
+ * @param {typedef.DataFormatObj} [formatObj] - The format of the resource data {}
862
+ * @returns {WOQLQuery} A WOQLQuery which contains the remote resource identifier
863
+ */
864
+
865
+ WOQLQuery.prototype.remote = function (remoteObj, formatObj) {
866
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
867
+ this.cursor['@type'] = 'QueryResource';
868
+ this.cursor.source = { '@type': 'Source', url: remoteObj };
869
+ this.cursor.format = 'csv'; // hard coded for now
870
+ if (typeof opts !== 'undefined') this.cursor.options = formatObj;
871
+ return this;
872
+ };
873
+
874
+ /**
875
+ * Identifies a resource as a local path on the client, to be sent to the server through a
876
+ * HTTP POST request, with the format defined through the options
877
+ * @param {string} url - The Path on the server at which the file resource can be accessed
878
+ * @param {typedef.DataFormatObj} [formatObj] - imput options, optional
879
+ * @param {string} [source] - It defines the source of the file, it can be 'url','post'
880
+ * @returns {WOQLQuery} A WOQLQuery which contains the Post resource identifier
881
+ */
882
+
883
+ WOQLQuery.prototype.post = function (url, formatObj, source = 'post') {
884
+ // if (fpath && fpath == 'args') return ['file', 'format']
885
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
886
+ this.cursor['@type'] = 'QueryResource';
887
+ this.cursor.source = { '@type': 'Source', [source]: url };
888
+ this.cursor.format = 'csv'; // hard coded for now
889
+ this.cursor.options = formatObj;
890
+ if (typeof formatObj !== 'undefined') this.cursor.options = formatObj;
891
+ return this;
892
+ };
893
+
894
+ /**
895
+ * Deletes a single triple from the default graph of the database
896
+ * @param {string|Var} subject - The IRI of a triple’s subject or a variable
897
+ * @param {string|Var} predicate - The IRI of a property or a variable
898
+ * @param {string|Var} object - The IRI of a node or a variable, or a literal
899
+ * @returns {WOQLQuery} - A WOQLQuery which contains the Triple Deletion statement
900
+ */
901
+
902
+ WOQLQuery.prototype.delete_triple = function (subject, predicate, object) {
903
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
904
+ const args = this.triple(subject, predicate, object);
905
+ this.cursor['@type'] = 'DeleteTriple';
906
+ return this.updated();
907
+ };
908
+
909
+ /**
910
+ * Adds triples according to the the pattern [subject,predicate,object]
911
+ * @param {string|Var} subject - The IRI of a triple’s subject or a variable
912
+ * @param {string|Var} predicate - The IRI of a property or a variable
913
+ * @param {string|Var} object - The IRI of a node or a variable, or a literal
914
+ * @returns {WOQLQuery}
915
+ */
916
+
917
+ WOQLQuery.prototype.add_triple = function (subject, predicate, object) {
918
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
919
+ const args = this.triple(subject, predicate, object);
920
+ this.cursor['@type'] = 'AddTriple';
921
+ return this.updated();
922
+ };
923
+
924
+ /**
925
+ * Deletes a single triple from the graph [Subject, Predicate, Object, Graph]
926
+ * @param {string|Var} subject - The IRI of a triple’s subject or a variable
927
+ * @param {string|Var} predicate - The IRI of a property or a variable
928
+ * @param {string|Var} object - The IRI of a node or a variable, or a literal
929
+ * @param {typedef.GraphRef} graphRef - A valid graph resource identifier string
930
+ * @returns {WOQLQuery} - A WOQLQuery which contains the Delete Quad Statement
931
+ */
932
+ WOQLQuery.prototype.delete_quad = function (subject, predicate, object, graphRef) {
933
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
934
+ const args = this.triple(subject, predicate, object);
935
+ // if (a && a == 'args') return args.concat(['graph'])
936
+ if (!graphRef) {
937
+ return this.parameterError(
938
+ 'Delete Quad takes four parameters, the last should be a graph id',
939
+ );
940
+ }
941
+ this.cursor['@type'] = 'DeleteTriple';
942
+ this.cursor.graph = this.cleanGraph(graphRef);
943
+ return this.updated();
944
+ };
945
+
946
+ /**
947
+ * Adds quads according to the pattern [S,P,O,G]
948
+ * @param {string|Var} subject - The IRI of a triple’s subject or a variable
949
+ * @param {string|Var} predicate - The IRI of a property or a variable
950
+ * @param {string|Var} object - The IRI of a node or a variable, or a literal
951
+ * @param {typedef.GraphRef} graphRef - A valid graph resource identifier string
952
+ * @returns {WOQLQuery}
953
+ */
954
+
955
+ WOQLQuery.prototype.add_quad = function (subject, predicate, object, graphRef) {
956
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
957
+ const args = this.triple(subject, predicate, object);
958
+ if (!graphRef) return this.parameterError('Add Quad takes four parameters, the last should be a graph id');
959
+ this.cursor['@type'] = 'AddTriple';
960
+ this.cursor.graph = this.cleanGraph(graphRef);
961
+ return this.updated();
962
+ };
963
+
964
+ /**
965
+ * Remove whitespace from both sides of a string:
966
+ * @param {string|Var} inputStr - A string or variable containing
967
+ * the untrimmed version of the string
968
+ * @param {string|Var} resultVarName - A string or variable
969
+ * containing the trimmed version of the string
970
+ * @returns {WOQLQuery} A WOQLQuery which contains the Trim pattern matching expression
971
+ */
972
+
973
+ WOQLQuery.prototype.trim = function (inputStr, resultVarName) {
974
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
975
+ this.cursor['@type'] = 'Trim';
976
+ this.cursor.untrimmed = this.cleanDataValue(inputStr);
977
+ this.cursor.trimmed = this.cleanDataValue(resultVarName);
978
+ return this;
979
+ };
980
+
981
+ /**
982
+ * Evaluates the passed arithmetic expression and generates or matches the result value
983
+ * @param {object| WOQLQuery | string} arithExp - query or JSON-LD representing the query
984
+ * @param {string|Var} resultVarName - output variable
985
+ * @returns {WOQLQuery}
986
+ */
987
+
988
+ WOQLQuery.prototype.eval = function (arithExp, resultVarName) {
989
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
990
+ this.cursor['@type'] = 'Eval';
991
+ this.cursor.expression = arithExp.json ? arithExp.json() : arithExp;
992
+ this.cursor.result = this.cleanArithmeticValue(resultVarName);
993
+ return this;
994
+ };
995
+
996
+ /**
997
+ * Evaluates the passed arithmetic expression and generates or matches the result value.
998
+ * Alias for eval() to support both naming conventions in fluent/chained style.
999
+ * @param {object|WOQLQuery|string} arithExp - A WOQL query containing a valid arithmetic expression
1000
+ * @param {string|number|Var} resultVarName - Either a variable to store the result, or a numeric
1001
+ * literal to test against the evaluated expression
1002
+ * @returns {WOQLQuery}
1003
+ */
1004
+
1005
+ WOQLQuery.prototype.evaluate = function (arithExp, resultVarName) {
1006
+ return this.eval(arithExp, resultVarName);
1007
+ };
1008
+
1009
+ /**
1010
+ * Adds the numbers together
1011
+ * @param {...(string|number|Var)} args - a variable or numeric containing the values to add
1012
+ * @returns {WOQLQuery} A WOQLQuery which contains the addition expression
1013
+ */
1014
+
1015
+ WOQLQuery.prototype.plus = function (...args) {
1016
+ // if (args && args[0] == 'args') return ['first', 'second']
1017
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
1018
+ this.cursor['@type'] = 'Plus';
1019
+ this.cursor.left = this.arop(args.shift());
1020
+ if (args.length > 1) {
1021
+ this.cursor.right = this.jobj(new WOQLQuery().plus(...args.map(this.arop)));
1022
+ } else {
1023
+ this.cursor.right = this.arop(args[0]);
1024
+ }
1025
+ return this;
1026
+ };
1027
+
1028
+ /**
1029
+ *
1030
+ * Subtracts Numbers N1..Nn
1031
+ * @param {...(string|number|Var)} args - variable or numeric containing the value that will be
1032
+ * subtracted from
1033
+ * @returns {WOQLQuery} A WOQLQuery which contains the subtraction expression
1034
+ */
1035
+ WOQLQuery.prototype.minus = function (...args) {
1036
+ // if (args && args[0] === 'args') return ['first', 'right']
1037
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
1038
+ this.cursor['@type'] = 'Minus';
1039
+ this.cursor.left = this.arop(args.shift());
1040
+ if (args.length > 1) {
1041
+ this.cursor.right = this.jobj(new WOQLQuery().minus(...args.map(this.arop)));
1042
+ } else {
1043
+ this.cursor.right = this.arop(args[0]);
1044
+ }
1045
+ return this;
1046
+ };
1047
+
1048
+ /**
1049
+ *
1050
+ * Multiplies numbers N1...Nn together
1051
+ * @param {...(string|number|Var)} args - a variable or numeric containing the value
1052
+ * @returns {WOQLQuery} A WOQLQuery which contains the multiplication expression
1053
+ */
1054
+ WOQLQuery.prototype.times = function (...args) {
1055
+ // if (args && args[0] === 'args') return ['first', 'right']
1056
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
1057
+ this.cursor['@type'] = 'Times';
1058
+ this.cursor.left = this.arop(args.shift());
1059
+ if (args.length > 1) {
1060
+ this.cursor.right = this.jobj(new WOQLQuery().times(...args.map(this.arop)));
1061
+ } else {
1062
+ this.cursor.right = this.arop(args[0]);
1063
+ }
1064
+ return this;
1065
+ };
1066
+
1067
+ /**
1068
+ * Divides numbers N1...Nn by each other left, to right precedence
1069
+ * @param {...(string|number|Var )} args - numbers to tbe divided
1070
+ * @returns {WOQLQuery} A WOQLQuery which contains the division expression
1071
+ */
1072
+ WOQLQuery.prototype.divide = function (...args) {
1073
+ // if (args && args[0] === 'args') return ['left', 'right']
1074
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
1075
+ this.cursor['@type'] = 'Divide';
1076
+ this.cursor.left = this.arop(args.shift());
1077
+ if (args.length > 1) {
1078
+ this.cursor.right = this.jobj(new WOQLQuery().divide(...args.map(this.arop)));
1079
+ } else {
1080
+ this.cursor.right = this.arop(args[0]);
1081
+ }
1082
+ return this;
1083
+ };
1084
+
1085
+ /**
1086
+ * Division - integer division - args are divided left to right
1087
+ * @param {...(string|number|Var)} args - numbers for division
1088
+ * @returns {WOQLQuery} A WOQLQuery which contains the division expression
1089
+ */
1090
+
1091
+ WOQLQuery.prototype.div = function (...args) {
1092
+ // if (args && args[0] === 'args') return ['left', 'right']
1093
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
1094
+ this.cursor['@type'] = 'Div';
1095
+ this.cursor.left = this.arop(args.shift());
1096
+ if (args.length > 1) {
1097
+ this.cursor.right = this.jobj(new WOQLQuery().div(...args.map(this.arop)));
1098
+ } else {
1099
+ this.cursor.right = this.arop(args[0]);
1100
+ }
1101
+ return this;
1102
+ };
1103
+
1104
+ /**
1105
+ * Exponent - raises varNum01 to the power of varNum02
1106
+ * @param {string|number|Var} varNum - a variable or numeric containing the number to be
1107
+ * raised to the power of the second number
1108
+ * @param {number} expNum - a variable or numeric containing the exponent
1109
+ * @returns {WOQLQuery} A WOQLQuery which contains the exponent expression
1110
+ */
1111
+ WOQLQuery.prototype.exp = function (varNum, expNum) {
1112
+ // if (a && a === 'args') return ['left', 'right']
1113
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
1114
+ this.cursor['@type'] = 'Exp';
1115
+ this.cursor.left = this.arop(varNum);
1116
+ this.cursor.right = this.arop(expNum);
1117
+ return this;
1118
+ };
1119
+
1120
+ /**
1121
+ * Generates the nearest lower integer to the passed number
1122
+ * @param {string|number|Var} varNum - Variable or numeric containing the number to be floored
1123
+ * @returns {WOQLQuery} A WOQLQuery which contains the floor expression
1124
+ */
1125
+ WOQLQuery.prototype.floor = function (varNum) {
1126
+ // if (a && a === 'args') return ['argument']
1127
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
1128
+ this.cursor['@type'] = 'Floor';
1129
+ this.cursor.argument = this.arop(varNum);
1130
+ return this;
1131
+ };
1132
+
1133
+ /**
1134
+ * Tests whether a given instance IRI has type Class, according to the current state of the DB
1135
+ * @param {string|Var} instanceIRI - A string IRI or a variable that identify the class instance
1136
+ * @param {string|Var} classId - A Class IRI or a variable
1137
+ * @returns {WOQLQuery} A WOQLQuery object containing the type test
1138
+ */
1139
+ WOQLQuery.prototype.isa = function (instanceIRI, classId) {
1140
+ // if (a && a === 'args') return ['element', 'of_type']
1141
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
1142
+ this.cursor['@type'] = 'IsA';
1143
+ this.cursor.element = this.cleanNodeValue(instanceIRI);
1144
+ this.cursor.type = this.cleanNodeValue(classId);
1145
+ return this;
1146
+ };
1147
+
1148
+ /**
1149
+ * Generates a string Leverstein distance measure between stringA and stringB
1150
+ * @param {string|Var} stringA - string literal or variable representing a string to be compared
1151
+ * @param {string|Var } stringB - string literal or variable
1152
+ * representing the other string to be compared
1153
+ * @param {number|string|Var} distance - variable representing the distance between the variables
1154
+ * @returns {WOQLQuery} A WOQLQuery which contains the Like pattern matching expression
1155
+ */
1156
+ WOQLQuery.prototype.like = function (stringA, stringB, distance) {
1157
+ // if (a && a === 'args')
1158
+ // return ['left', 'right', 'like_similarity']
1159
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
1160
+ this.cursor['@type'] = 'Like';
1161
+ this.cursor.left = this.cleanDataValue(stringA, 'xsd:string');
1162
+ this.cursor.right = this.cleanDataValue(stringB, 'xsd:string');
1163
+ if (distance) {
1164
+ this.cursor.similarity = this.cleanDataValue(distance, 'xsd:decimal');
1165
+ }
1166
+ return this;
1167
+ };
1168
+
1169
+ /**
1170
+ * Compares the value of v1 against v2 and returns true if v1 is less than v2
1171
+ * @param {string|number|Var} varNum01 - a variable or numeric containing
1172
+ * the number to be compared
1173
+ * @param {string|number|Var} varNum02 - a variable or numeric containing the second comporator
1174
+ * @returns {WOQLQuery} A WOQLQuery which contains the comparison expression
1175
+ */
1176
+ WOQLQuery.prototype.less = function (varNum01, varNum02) {
1177
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
1178
+ this.cursor['@type'] = 'Less';
1179
+ this.cursor.left = this.cleanDataValue(varNum01);
1180
+ this.cursor.right = this.cleanDataValue(varNum02);
1181
+ return this;
1182
+ };
1183
+
1184
+ /**
1185
+ * Compares the value of v1 against v2 and returns true if v1 is greater than v2
1186
+ * @param {string|number|Var} varNum01 - a variable or numeric containing the number to be compared
1187
+ * @param {string|number|Var} varNum02 - a variable or numeric containing the second comporator
1188
+ * @returns {WOQLQuery} A WOQLQuery which contains the comparison expression
1189
+ */
1190
+ WOQLQuery.prototype.greater = function (varNum01, varNum02) {
1191
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
1192
+ this.cursor['@type'] = 'Greater';
1193
+ this.cursor.left = this.cleanDataValue(varNum01);
1194
+ this.cursor.right = this.cleanDataValue(varNum02);
1195
+ return this;
1196
+ };
1197
+
1198
+ /**
1199
+ * Specifies that the Subquery is optional - if it does not match the query will not fail
1200
+ * @param {WOQLQuery} [subquery] - A subquery which will be optionally matched
1201
+ * @returns {WOQLQuery} A WOQLQuery object containing the optional sub Query
1202
+ */
1203
+ WOQLQuery.prototype.opt = function (subquery) {
1204
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
1205
+ this.cursor['@type'] = 'Optional';
1206
+ this.addSubQuery(subquery);
1207
+ return this;
1208
+ };
1209
+
1210
+ WOQLQuery.prototype.optional = WOQLQuery.prototype.opt;
1211
+
1212
+ /**
1213
+ * Generate a new IRI from the prefix and a hash of the variables which will be unique for any
1214
+ * given combination of variables
1215
+ * @param {string} prefix - A prefix for the IRI - typically formed of the doc prefix and the
1216
+ * classtype of the entity (“doc:Person”)
1217
+ * @param {array|string|Var} inputVarList - An array of variables and / or strings from which the
1218
+ * unique hash will be generated
1219
+ * @param {string|Var} resultVarName - Variable in which the unique ID is stored
1220
+ * @returns {WOQLQuery} A WOQLQuery object containing the unique ID generating function
1221
+ */
1222
+ WOQLQuery.prototype.unique = function (prefix, inputVarList, resultVarName) {
1223
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
1224
+ this.cursor['@type'] = 'HashKey';
1225
+ this.cursor.base = this.cleanDataValue(prefix, 'xsd:string');
1226
+ this.cursor.key_list = this.cleanDataValue(inputVarList);
1227
+ this.cursor.uri = this.cleanNodeValue(resultVarName);
1228
+ return this;
1229
+ };
1230
+
1231
+ /**
1232
+ * Generates the node's ID combined the variable list with a specific prefix (URL base).
1233
+ * If the input variables's values are the same, the output value will be the same.
1234
+ * @param {string} prefix
1235
+ * @param {string |array} inputVarList the variable input list for generate the id
1236
+ * @param {string} outputVar the output variable name
1237
+ */
1238
+
1239
+ WOQLQuery.prototype.idgen = function (prefix, inputVarList, outputVar) {
1240
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
1241
+ this.cursor['@type'] = 'LexicalKey';
1242
+ this.cursor.base = this.cleanDataValue(prefix, 'xsd:string');
1243
+ // this.cursor['base'] = this.cleanObject(this.string(prefix))
1244
+ this.cursor.key_list = this.dataValueList(inputVarList);
1245
+ this.cursor.uri = this.cleanNodeValue(outputVar);
1246
+ return this;
1247
+ };
1248
+
1249
+ WOQLQuery.prototype.idgenerator = WOQLQuery.prototype.idgen;
1250
+
1251
+ /**
1252
+ * Generates a random ID with a specified prefix
1253
+ * Uses cryptographically secure random base64 encoding to generate unique identifiers
1254
+ * @param {string} prefix - prefix for the generated ID
1255
+ * @param {string} outputVar - variable that stores the generated ID
1256
+ * @returns {WOQLQuery} A WOQLQuery which contains the random ID generation pattern
1257
+ * idgen_random("Person/", "v:person_id")
1258
+ */
1259
+ WOQLQuery.prototype.idgen_random = function (prefix, outputVar) {
1260
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
1261
+ this.cursor['@type'] = 'RandomKey';
1262
+ this.cursor.base = this.cleanDataValue(prefix, 'xsd:string');
1263
+ this.cursor.uri = this.cleanNodeValue(outputVar);
1264
+ return this;
1265
+ };
1266
+
1267
+ /**
1268
+ * Backward-compatible alias for idgen_random
1269
+ * @deprecated Use idgen_random instead
1270
+ */
1271
+ WOQLQuery.prototype.random_idgen = WOQLQuery.prototype.idgen_random;
1272
+
1273
+ /**
1274
+ * Changes a string to upper-case
1275
+ * @param {string|Var} inputVarName - string or variable representing the uncapitalized string
1276
+ * @param {string|Var} resultVarName - variable that stores the capitalized string output
1277
+ * @returns {WOQLQuery} A WOQLQuery which contains the Upper case pattern matching expression
1278
+ */
1279
+ WOQLQuery.prototype.upper = function (inputVarName, resultVarName) {
1280
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
1281
+ this.cursor['@type'] = 'Upper';
1282
+ this.cursor.mixed = this.cleanDataValue(inputVarName);
1283
+ this.cursor.upper = this.cleanDataValue(resultVarName);
1284
+ return this;
1285
+ };
1286
+
1287
+ /**
1288
+ * Changes a string to lower-case
1289
+ * @param {string|Var} inputVarName - string or variable representing the non-lowercased string
1290
+ * @param {string|Var} resultVarName - variable that stores the lowercased string output
1291
+ * @returns {WOQLQuery} A WOQLQuery which contains the Lower case pattern matching expression
1292
+ */
1293
+
1294
+ WOQLQuery.prototype.lower = function (inputVarName, resultVarName) {
1295
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
1296
+ this.cursor['@type'] = 'Lower';
1297
+ this.cursor.mixed = this.cleanDataValue(inputVarName);
1298
+ this.cursor.lower = this.cleanDataValue(resultVarName);
1299
+ return this;
1300
+ };
1301
+
1302
+ /**
1303
+ * Pads out the string input to be exactly len long by appending the pad character pad to
1304
+ * form output
1305
+ * @param {string|Var} inputVarName - The input string or variable in unpadded state
1306
+ * @param {string|Var} pad - The characters to use to pad the string or a variable representing them
1307
+ * @param {number | string | Var} len - The variable or integer value representing the length of
1308
+ * the output string
1309
+ * @param {string|Var} resultVarName - stores output
1310
+ * @returns {WOQLQuery} A WOQLQuery which contains the Pad pattern matching expression
1311
+ */
1312
+
1313
+ WOQLQuery.prototype.pad = function (inputVarName, pad, len, resultVarName) {
1314
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
1315
+ this.cursor['@type'] = 'Pad';
1316
+ this.cursor.string = this.cleanDataValue(inputVarName);
1317
+ this.cursor.char = this.cleanDataValue(pad);
1318
+ this.cursor.times = this.cleanDataValue(len, 'xsd:integer');
1319
+ this.cursor.result = this.cleanDataValue(resultVarName);
1320
+ return this;
1321
+ };
1322
+
1323
+ /**
1324
+ * Splits a string (Input) into a list strings (Output) by removing separator
1325
+ * @param {string|Var} inputVarName - A string or variable representing the unsplit string
1326
+ * @param {string|Var} separator - A string or variable containing a sequence of charatcters
1327
+ * to use as a separator
1328
+ * @param {string|Var} resultVarName - variable that stores output list
1329
+ * @returns {WOQLQuery} A WOQLQuery which contains the Split pattern matching expression
1330
+ */
1331
+
1332
+ WOQLQuery.prototype.split = function (inputVarName, separator, resultVarName) {
1333
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
1334
+ this.cursor['@type'] = 'Split';
1335
+ this.cursor.string = this.cleanDataValue(inputVarName);
1336
+ this.cursor.pattern = this.cleanDataValue(separator);
1337
+ this.cursor.list = this.cleanDataValue(resultVarName);
1338
+ return this;
1339
+ };
1340
+
1341
+ /**
1342
+ * Matches if List includes Element
1343
+ * @param {string|object|Var} element - Either a variable, IRI or any simple datatype
1344
+ * @param {string|array|Var} list - List ([string, literal] or string*) Either a variable
1345
+ * representing a list or a list of variables or literals
1346
+ * @returns {WOQLQuery} A WOQLQuery which contains the List inclusion pattern matching expression
1347
+ */
1348
+ WOQLQuery.prototype.member = function (element, list) {
1349
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
1350
+ this.cursor['@type'] = 'Member';
1351
+ this.cursor.member = this.cleanObject(element);
1352
+ this.cursor.list = this.valueList(list);
1353
+ return this;
1354
+ };
1355
+
1356
+ /**
1357
+ * Computes the set difference between two lists (elements in listA but not in listB)
1358
+ * @param {string|Var|array} listA - First list or variable
1359
+ * @param {string|Var|array} listB - Second list or variable
1360
+ * @param {string|Var} result - Variable to store the result
1361
+ * @returns {WOQLQuery} A WOQLQuery which contains the SetDifference expression
1362
+ */
1363
+ WOQLQuery.prototype.set_difference = function (listA, listB, result) {
1364
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
1365
+ this.cursor['@type'] = 'SetDifference';
1366
+ this.cursor.list_a = this.valueList(listA);
1367
+ this.cursor.list_b = this.valueList(listB);
1368
+ this.cursor.result = this.valueList(result);
1369
+ return this;
1370
+ };
1371
+
1372
+ /**
1373
+ * Computes the set intersection of two lists (elements in both listA and listB)
1374
+ * @param {string|Var|array} listA - First list or variable
1375
+ * @param {string|Var|array} listB - Second list or variable
1376
+ * @param {string|Var} result - Variable to store the result
1377
+ * @returns {WOQLQuery} A WOQLQuery which contains the SetIntersection expression
1378
+ */
1379
+ WOQLQuery.prototype.set_intersection = function (listA, listB, result) {
1380
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
1381
+ this.cursor['@type'] = 'SetIntersection';
1382
+ this.cursor.list_a = this.valueList(listA);
1383
+ this.cursor.list_b = this.valueList(listB);
1384
+ this.cursor.result = this.valueList(result);
1385
+ return this;
1386
+ };
1387
+
1388
+ /**
1389
+ * Computes the set union of two lists (all unique elements from both lists)
1390
+ * @param {string|Var|array} listA - First list or variable
1391
+ * @param {string|Var|array} listB - Second list or variable
1392
+ * @param {string|Var} result - Variable to store the result
1393
+ * @returns {WOQLQuery} A WOQLQuery which contains the SetUnion expression
1394
+ */
1395
+ WOQLQuery.prototype.set_union = function (listA, listB, result) {
1396
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
1397
+ this.cursor['@type'] = 'SetUnion';
1398
+ this.cursor.list_a = this.valueList(listA);
1399
+ this.cursor.list_b = this.valueList(listB);
1400
+ this.cursor.result = this.valueList(result);
1401
+ return this;
1402
+ };
1403
+
1404
+ /**
1405
+ * Checks if an element is a member of a set (efficient O(log n) lookup)
1406
+ * @param {string|Var|any} element - Element to check
1407
+ * @param {string|Var|array} set - Set (list) to check membership in
1408
+ * @returns {WOQLQuery} A WOQLQuery which contains the SetMember expression
1409
+ */
1410
+ WOQLQuery.prototype.set_member = function (element, set) {
1411
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
1412
+ this.cursor['@type'] = 'SetMember';
1413
+ this.cursor.element = this.cleanObject(element);
1414
+ this.cursor.set = this.valueList(set);
1415
+ return this;
1416
+ };
1417
+
1418
+ /**
1419
+ * Converts a list to a set (removes duplicates and sorts)
1420
+ * @param {string|Var|array} list - Input list or variable
1421
+ * @param {string|Var} set - Variable to store the resulting set
1422
+ * @returns {WOQLQuery} A WOQLQuery which contains the ListToSet expression
1423
+ */
1424
+ WOQLQuery.prototype.list_to_set = function (list, set) {
1425
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
1426
+ this.cursor['@type'] = 'ListToSet';
1427
+ this.cursor.list = this.valueList(list);
1428
+ this.cursor.set = this.valueList(set);
1429
+ return this;
1430
+ };
1431
+
1432
+ /**
1433
+ * takes a variable number of string arguments and concatenates them into a single string
1434
+ * @param {array|string|Var} varList - a variable representing a list or a list of variables or
1435
+ * strings - variables can be embedded in the string if they do not contain spaces
1436
+ * @param {string|Var} resultVarName - A variable or string containing the output string
1437
+ * @returns {WOQLQuery} A WOQLQuery which contains the Concatenation pattern matching expression
1438
+ */
1439
+
1440
+ WOQLQuery.prototype.concat = function (varList, resultVarName) {
1441
+ if (typeof varList === 'string') {
1442
+ const slist = varList.split(/(v:)/);
1443
+ const nlist = [];
1444
+ if (slist[0]) nlist.push(slist[0]);
1445
+ for (let i = 1; i < slist.length; i += 2) {
1446
+ if (slist[i]) {
1447
+ if (slist[i] === 'v:') {
1448
+ const slist2 = slist[i + 1].split(/([^\w_])/);
1449
+ const x = slist2.shift();
1450
+ nlist.push(`v:${x}`);
1451
+ const rest = slist2.join('');
1452
+ if (rest) nlist.push(rest);
1453
+ }
1454
+ }
1455
+ }
1456
+ varList = nlist;
1457
+ }
1458
+ if (Array.isArray(varList)) {
1459
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
1460
+ this.cursor['@type'] = 'Concatenate';
1461
+ this.cursor.list = this.cleanDataValue(varList, true);
1462
+ this.cursor.result = this.cleanDataValue(resultVarName);
1463
+ }
1464
+ return this;
1465
+ };
1466
+
1467
+ WOQLQuery.prototype.concatenate = WOQLQuery.prototype.concat;
1468
+
1469
+ /**
1470
+ * Joins a list variable together (Input) into a string variable (Output) by glueing the strings
1471
+ * together with Glue
1472
+ * @param {string|array|Var} varList - a variable representing a list or a list of strings
1473
+ * and / or variables
1474
+ * @param {string|Var} glue - A variable (v:glue) or (glue) string representing the characters
1475
+ * to put in between the joined strings in input
1476
+ * @param {string|Var} resultVarName - A variable or string containing the output string
1477
+ * @returns {WOQLQuery} A WOQLQuery which contains the Join pattern matching expression
1478
+ */
1479
+ WOQLQuery.prototype.join = function (varList, glue, resultVarName) {
1480
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
1481
+ this.cursor['@type'] = 'Join';
1482
+ this.cursor.list = this.cleanDataValue(varList);
1483
+ this.cursor.separator = this.cleanDataValue(glue);
1484
+ this.cursor.result = this.cleanDataValue(resultVarName);
1485
+ return this;
1486
+ };
1487
+
1488
+ /**
1489
+ * computes the sum of the List of values passed. In contrast to other arithmetic functions,
1490
+ * sum self-evaluates - it does not have to be passed to evaluate()
1491
+ * @param {WOQLQuery} subquery - a subquery or ([string or numeric]) - a list variable, or a
1492
+ * list of variables or numeric literals
1493
+ * @param {string|Var} total - the variable name with the sum result of the values in List
1494
+ * @returns {WOQLQuery} - A WOQLQuery which contains the Sum expression
1495
+ */
1496
+ WOQLQuery.prototype.sum = function (subquery, total) {
1497
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
1498
+ this.cursor['@type'] = 'Sum';
1499
+ this.cursor.list = this.cleanDataValue(subquery);
1500
+ this.cursor.result = this.cleanObject(total);
1501
+ return this;
1502
+ };
1503
+
1504
+ /**
1505
+ *
1506
+ * Specifies an offset position in the results to start listing results from
1507
+ * @param {number|string|Var} start - A variable that refers to an interger or an integer literal
1508
+ * @param {WOQLQuery} [subquery] - WOQL Query object, you can pass a subquery as an argument
1509
+ * or a chained query
1510
+ * @returns {WOQLQuery} A WOQLQuery whose results will be returned starting from
1511
+ * the specified offset
1512
+ */
1513
+
1514
+ WOQLQuery.prototype.start = function (start, subquery) {
1515
+ // if (start && start === 'args') return ['start', 'query']
1516
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
1517
+ this.cursor['@type'] = 'Start';
1518
+ this.cursor.start = start;
1519
+ return this.addSubQuery(subquery);
1520
+ };
1521
+
1522
+ /**
1523
+ * Specifies a maximum number of results that will be returned from the subquery
1524
+ * @param {number|string} limit - A variable that refers to an non-negative integer or a
1525
+ * non-negative integer
1526
+ * @param {WOQLQuery} [subquery] - A subquery whose results will be limited
1527
+ * @returns {WOQLQuery} A WOQLQuery whose results will be returned starting from
1528
+ * the specified offset
1529
+ */
1530
+
1531
+ WOQLQuery.prototype.limit = function (limit, subquery) {
1532
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
1533
+ this.cursor['@type'] = 'Limit';
1534
+ this.cursor.limit = limit;
1535
+ return this.addSubQuery(subquery);
1536
+ };
1537
+
1538
+ /**
1539
+ * Matches the regular expression defined in Patern against the Test string, to produce
1540
+ * the matched patterns in Matches
1541
+ * @param {string} pattern - string or variable using normal PCRE regular expression syntax with
1542
+ * the exception that special characters have to be escaped twice (to enable transport in JSONLD)
1543
+ * @param {string|Var} inputVarName - string or variable containing the string to be tested for
1544
+ * patterns with the regex
1545
+ * @param {string|array|object|Var} resultVarList - variable representing the list of matches
1546
+ * or a list of strings or variables
1547
+ * @returns {WOQLQuery} A WOQLQuery which contains the Regular Expression pattern
1548
+ * matching expression
1549
+ */
1550
+
1551
+ WOQLQuery.prototype.re = function (pattern, inputVarName, resultVarList) {
1552
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
1553
+ this.cursor['@type'] = 'Regexp';
1554
+ this.cursor.pattern = this.cleanDataValue(pattern);
1555
+ this.cursor.string = this.cleanDataValue(inputVarName);
1556
+ this.cursor.result = this.cleanDataValue(resultVarList);
1557
+ return this;
1558
+ };
1559
+
1560
+ WOQLQuery.prototype.regexp = WOQLQuery.prototype.re;
1561
+
1562
+ /**
1563
+ * Calculates the length of the list in va and stores it in vb
1564
+ * @param {string|array} inputVarList - Either a variable representing a list or a list of
1565
+ * variables or literals
1566
+ * @param {string|Var} resultVarName - A variable in which the length of the list is stored or
1567
+ * the length of the list as a non-negative integer
1568
+ * @returns {WOQLQuery} A WOQLQuery which contains the Length pattern matching expression
1569
+ */
1570
+ WOQLQuery.prototype.length = function (inputVarList, resultVarName) {
1571
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
1572
+ this.cursor['@type'] = 'Length';
1573
+ this.cursor.list = this.cleanDataValue(inputVarList);
1574
+ if (resultVarName !== undefined && resultVarName !== null) {
1575
+ if (typeof resultVarName === 'number') {
1576
+ this.cursor.length = this.cleanObject(resultVarName, 'xsd:nonNegativeInteger');
1577
+ } else {
1578
+ // Handle string, Var instances, or any other variable representation
1579
+ this.cursor.length = this.varj(resultVarName);
1580
+ }
1581
+ }
1582
+ return this;
1583
+ };
1584
+
1585
+ /**
1586
+ * Extracts a contiguous subsequence from a list, following JavaScript's slice() semantics
1587
+ * @param {string|array|Var} inputList - Either a variable representing a list or a list of
1588
+ * variables or literals
1589
+ * @param {string|Var} resultVarName - A variable in which the sliced list is stored
1590
+ * @param {number|string|Var} start - The start index (0-based, supports negative indices)
1591
+ * @param {number|string|Var} [end] - The end index (exclusive, optional - defaults to list length)
1592
+ * @returns {WOQLQuery} A WOQLQuery which contains the Slice pattern matching expression
1593
+ * let [result] = vars("result")
1594
+ * slice(["a", "b", "c", "d"], result, 1, 3) // result = ["b", "c"]
1595
+ * slice(["a", "b", "c", "d"], result, -2) // result = ["c", "d"]
1596
+ */
1597
+ WOQLQuery.prototype.slice = function (inputList, resultVarName, start, end) {
1598
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
1599
+ this.cursor['@type'] = 'Slice';
1600
+ this.cursor.list = this.cleanDataValue(inputList);
1601
+ this.cursor.result = this.cleanDataValue(resultVarName);
1602
+ if (typeof start === 'number') {
1603
+ this.cursor.start = this.cleanObject(start, 'xsd:integer');
1604
+ } else {
1605
+ this.cursor.start = this.cleanDataValue(start);
1606
+ }
1607
+ // end is optional - only set if provided
1608
+ if (end !== undefined) {
1609
+ if (typeof end === 'number') {
1610
+ this.cursor.end = this.cleanObject(end, 'xsd:integer');
1611
+ } else {
1612
+ this.cursor.end = this.cleanDataValue(end);
1613
+ }
1614
+ }
1615
+ return this;
1616
+ };
1617
+
1618
+ /**
1619
+ *
1620
+ * Logical negation of the contained subquery - if the subquery matches, the query
1621
+ * will fail to match
1622
+ * @param {string | WOQLQuery} [subquery] - A subquery which will be negated
1623
+ * @returns {WOQLQuery} A WOQLQuery object containing the negated sub Query
1624
+ */
1625
+ WOQLQuery.prototype.not = function (subquery) {
1626
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
1627
+ this.cursor['@type'] = 'Not';
1628
+ return this.addSubQuery(subquery);
1629
+ };
1630
+
1631
+ /**
1632
+ * Results in one solution of the subqueries
1633
+ * @param {string| WOQLQuery } [subquery] - WOQL Query objects
1634
+ * @returns {WOQLQuery} A WOQLQuery object containing the once sub Query
1635
+ */
1636
+ WOQLQuery.prototype.once = function (subquery) {
1637
+ // if (query && query === 'args') return ['query']
1638
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
1639
+ this.cursor['@type'] = 'Once';
1640
+ return this.addSubQuery(subquery);
1641
+ };
1642
+
1643
+ /**
1644
+ * Runs the query without backtracking on side-effects
1645
+ * @param {string| WOQLQuery } [subquery] - WOQL Query objects
1646
+ * @returns {WOQLQuery} A WOQLQuery object containing the immediately sub Query
1647
+ */
1648
+ WOQLQuery.prototype.immediately = function (query) {
1649
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
1650
+ this.cursor['@type'] = 'Immediately';
1651
+ return this.addSubQuery(query);
1652
+ };
1653
+
1654
+ /**
1655
+ * Creates a count of the results of the query
1656
+ * @param {string|number|Var} countVarName - variable or integer count
1657
+ * @param {WOQLQuery} [subquery]
1658
+ * @returns {WOQLQuery} A WOQLQuery object containing the count sub Query
1659
+ */
1660
+ WOQLQuery.prototype.count = function (countVarName, subquery) {
1661
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
1662
+ this.cursor['@type'] = 'Count';
1663
+ this.cursor.count = this.cleanObject(countVarName);
1664
+ return this.addSubQuery(subquery);
1665
+ };
1666
+
1667
+ /**
1668
+ * Casts the value of Input to a new value of type Type and stores the result in CastVar
1669
+ * @param {string|number|object|Var} varName - Either a single variable or a
1670
+ * literal of any basic type
1671
+ * @param {string|Var} varType - Either a variable or a basic datatype (xsd / xdd)
1672
+ * @param {string|Var} resultVarName - save the return variable
1673
+ * @returns {WOQLQuery} A WOQLQuery which contains the casting expression
1674
+ */
1675
+
1676
+ WOQLQuery.prototype.typecast = function (varName, varType, resultVarName) {
1677
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
1678
+ this.cursor['@type'] = 'Typecast';
1679
+ this.cursor.value = this.cleanObject(varName);
1680
+ this.cursor.type = this.cleanNodeValue(varType);
1681
+ this.cursor.result = this.cleanObject(resultVarName);
1682
+ return this;
1683
+ };
1684
+
1685
+ WOQLQuery.prototype.cast = WOQLQuery.prototype.typecast;
1686
+
1687
+ /**
1688
+ * Orders the results of the contained subquery by a precedence list of variables
1689
+ * @param {...string|...Var|...array} orderedVarlist - A sequence of variables,
1690
+ * by which to order the results,
1691
+ * each optionally followed by either “asc” or “desc” to represent order as a list, by default
1692
+ * it will sort the variable in ascending order
1693
+ * @returns {WOQLQuery} A WOQLQuery which contains the ordering expression
1694
+ */
1695
+ WOQLQuery.prototype.order_by = function (...orderedVarlist) {
1696
+ // if (orderedVarlist && orderedVarlist[0] === 'args')
1697
+ // return ['variable_ordering', 'query']
1698
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
1699
+ this.cursor['@type'] = 'OrderBy';
1700
+ this.cursor.ordering = [];
1701
+
1702
+ if (!orderedVarlist || orderedVarlist.length === 0) {
1703
+ return this.parameterError(
1704
+ 'Order by must be passed at least one variables to order the query',
1705
+ );
1706
+ }
1707
+ const embedquery = typeof orderedVarlist[orderedVarlist.length - 1] === 'object'
1708
+ && orderedVarlist[orderedVarlist.length - 1].json
1709
+ ? orderedVarlist.pop()
1710
+ : false;
1711
+
1712
+ for (let i = 0; i < orderedVarlist.length; i++) {
1713
+ let obj;
1714
+ if ((typeof orderedVarlist[i] === 'string' || orderedVarlist[i] instanceof Var) && orderedVarlist[i] !== '') {
1715
+ obj = {
1716
+ '@type': 'OrderTemplate',
1717
+ variable: this.rawVar(orderedVarlist[i]),
1718
+ order: 'asc',
1719
+ };
1720
+ } else if (orderedVarlist[i].length === 2 && orderedVarlist[i][1] === 'asc') {
1721
+ obj = {
1722
+ '@type': 'OrderTemplate',
1723
+ variable: this.rawVar(orderedVarlist[i][0]),
1724
+ order: 'asc',
1725
+ };
1726
+ } else if (orderedVarlist[i].length === 2 && orderedVarlist[i][1] === 'desc') {
1727
+ obj = {
1728
+ '@type': 'OrderTemplate',
1729
+ variable: this.rawVar(orderedVarlist[i][0]),
1730
+ order: 'desc',
1731
+ };
1732
+ }
1733
+
1734
+ if (obj) this.cursor.ordering.push(obj);
1735
+ }
1736
+ return this.addSubQuery(embedquery);
1737
+ };
1738
+
1739
+ /**
1740
+ *
1741
+ * Groups the results of the contained subquery on the basis of identical values for Groupvars,
1742
+ * extracts the patterns defined in PatternVars and stores the results in GroupedVar
1743
+ * @param {array|string|Var} gvarlist - Either a single variable or an array of variables
1744
+ * @param {array|string|Var} groupedvar - Either a single variable or an array of variables
1745
+ * @param {string|Var} output - output variable name
1746
+ * @param {WOQLQuery} [groupquery] - The query whose results will be grouped
1747
+ * @returns {WOQLQuery} A WOQLQuery which contains the grouping expression
1748
+ */
1749
+
1750
+ WOQLQuery.prototype.group_by = function (gvarlist, groupedvar, output, groupquery) {
1751
+ // if (gvarlist && gvarlist === 'args')
1752
+ // return ['group_by', 'group_template', 'grouped', 'query']
1753
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
1754
+ this.cursor['@type'] = 'GroupBy';
1755
+ this.cursor.group_by = [];
1756
+
1757
+ if (typeof gvarlist === 'string' || gvarlist instanceof Var) gvarlist = [gvarlist];
1758
+ this.cursor.group_by = this.rawVarList(gvarlist);
1759
+ if (typeof groupedvar === 'string' || groupedvar instanceof Var) groupedvar = [groupedvar];
1760
+ this.cursor.template = this.rawVarList(groupedvar);
1761
+ this.cursor.grouped = this.varj(output);
1762
+ return this.addSubQuery(groupquery);
1763
+ };
1764
+
1765
+ /**
1766
+ * A function that always matches, always returns true
1767
+ * @returns {WOQLQuery} A WOQLQuery object containing the true value that will match any pattern
1768
+ */
1769
+ WOQLQuery.prototype.true = function () {
1770
+ this.cursor['@type'] = 'True';
1771
+ return this;
1772
+ };
1773
+
1774
+ /**
1775
+ * Performs a path regular expression match on the graph
1776
+ * @param {string|Var} subject - An IRI or variable that refers to an IRI representing the subject,
1777
+ * i.e. the starting point of the path
1778
+ * @param {string} pattern -(string) - A path regular expression describing a pattern through
1779
+ * multiple edges of the graph (see: https://terminusdb.com/docs/path-query-reference-guide)
1780
+ * @param {string|Var} object - An IRI or variable that refers to an IRI representing the object,
1781
+ * i.e. ending point of the path
1782
+ * @param {string|Var} [resultVarName] - A variable in which the actual paths
1783
+ * traversed will be stored
1784
+ * @returns {WOQLQuery} - A WOQLQuery which contains the path regular expression matching expression
1785
+ */
1786
+
1787
+ WOQLQuery.prototype.path = function (subject, pattern, object, resultVarName) {
1788
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
1789
+ this.cursor['@type'] = 'Path';
1790
+ this.cursor.subject = this.cleanSubject(subject);
1791
+ if (typeof pattern === 'string') pattern = this.compilePathPattern(pattern);
1792
+ this.cursor.pattern = pattern;
1793
+ this.cursor.object = this.cleanObject(object);
1794
+ if (typeof resultVarName !== 'undefined') {
1795
+ this.cursor.path = this.varj(resultVarName);
1796
+ }
1797
+ return this;
1798
+ };
1799
+
1800
+ /**
1801
+ * Extract the value of a key in a bound document.
1802
+ * @param {string|Var} document - Document which is being accessed.
1803
+ * @param {string|Var} field - The field from which the document which is being accessed.
1804
+ * @param {string|Var} value - The value for the document and field.
1805
+ * @returns {WOQLQuery} A WOQLQuery which contains the a dot Statement
1806
+ */
1807
+
1808
+ WOQLQuery.prototype.dot = function (document, field, value) {
1809
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
1810
+ this.cursor['@type'] = 'Dot';
1811
+ this.cursor.document = this.expandValueVariable(document);
1812
+ this.cursor.field = this.cleanDataValue(field, 'xsd:string');
1813
+ this.cursor.value = this.expandValueVariable(value);
1814
+ return this;
1815
+ };
1816
+
1817
+ /**
1818
+ * Calculates the size in bytes of the contents of the resource identified in ResourceID
1819
+ * @param {string|Var} resourceId - A valid resource identifier string (can refer to any graph /
1820
+ * branch / commit / db)
1821
+ * @param {string|Var} resultVarName - The variable name
1822
+ */
1823
+
1824
+ WOQLQuery.prototype.size = function (resourceId, resultVarName) {
1825
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
1826
+ this.cursor['@type'] = 'Size';
1827
+ this.cursor.resource = this.cleanGraph(resourceId);
1828
+ this.cursor.size = this.varj(resultVarName);
1829
+ return this;
1830
+ };
1831
+
1832
+ /**
1833
+ *
1834
+ * Calculates the number of triples of the contents of the resource identified in ResourceID
1835
+ * @param {string|Var} resourceId - A valid resource identifier string (can refer to any graph /
1836
+ * branch / commit / db)
1837
+ * @param {string|number|Var} tripleCount - An integer literal with the size in bytes or a
1838
+ * variable containing that integer
1839
+ * @returns {WOQLQuery} A WOQLQuery which contains the size expression
1840
+ */
1841
+ WOQLQuery.prototype.triple_count = function (resourceId, TripleCount) {
1842
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
1843
+ this.cursor['@type'] = 'TripleCount';
1844
+ this.cursor.resource = this.cleanGraph(resourceId);
1845
+ this.cursor.count = this.varj(TripleCount);
1846
+ return this;
1847
+ };
1848
+
1849
+ /**
1850
+ * Returns true if 'elementId' is of type 'elementType', according to the current DB schema
1851
+ * @param {string|Var} elementId - the id of a schema graph element
1852
+ * @param {string|Var} elementType - the element type
1853
+ * @returns {WOQLQuery} A WOQLQuery object containing the type_of pattern matching rule
1854
+ */
1855
+
1856
+ WOQLQuery.prototype.type_of = function (elementId, elementType) {
1857
+ if (!elementId || !elementType) return this.parameterError('type_of takes two parameters, both values');
1858
+ if (this.cursor['@type']) this.wrapCursorWithAnd();
1859
+ this.cursor['@type'] = 'TypeOf';
1860
+ this.cursor.value = this.cleanObject(elementId);
1861
+ this.cursor.type = this.cleanSubject(elementType);
1862
+ return this;
1863
+ };
1864
+
1865
+ module.exports = WOQLQuery;