• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

terminusdb / terminusdb-client-js / 14723685306

29 Apr 2025 05:00AM UTC coverage: 30.205% (-0.04%) from 30.241%
14723685306

Pull #319

github

web-flow
Merge 1baa718ad into 794d70193
Pull Request #319: Issue/318 fix woql from (fixes #318)

885 of 4650 branches covered (19.03%)

Branch coverage included in aggregate %.

2 of 2 new or added lines in 1 file covered. (100.0%)

6 existing lines in 3 files now uncovered.

2485 of 6507 relevant lines covered (38.19%)

4.49 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

52.93
/lib/query/woqlQuery.js
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');
1✔
26
const { Var, Vars, Doc } = require('./woqlDoc');
1✔
27
// eslint-disable-next-line no-unused-vars
28
const typedef = require('../typedef');
1✔
29

30
// I HAVE TO REVIEW THE Inheritance and the prototype chain
31
class WOQLQuery extends WOQLCore {
2✔
32
  /**
33
   * defines the internal functions of the woql query object - the
34
   * language API is defined in WOQLQuery
35
   * @module WOQLQuery
36
   * @constructor
37
   * @param {object} [query] json-ld query for initialisation
38
   * @returns {WOQLQuery}
39
   */
40

41
  /**
42
 * Update a pattern matching rule for the triple (Subject, Predicate, oldObjValue) with the
43
 * new one (Subject, Predicate, newObjValue)
44
 * @param {string|Var} subject - The IRI of a triple’s subject or a variable
45
 * @param {string|Var} predicate - The IRI of a property or a variable
46
 * @param {string|Var} newObjValue - The value to update or a literal
47
 * @param {string|Var} oldObjValue - The old value of the object
48
 * @returns {WOQLQuery} A WOQLQuery which contains the a Update Triple Statement
49
 */
50
  update_triple(subject, predicate, newObjValue, oldObjValue) { return this; }
×
51

52
  /**
53
 * Generates a query that by default matches all triples in a graph identified by "graph"
54
 * or in all the current terminusDB's graph
55
 * @param {string | boolean} [graph] - false or the resource identifier of a graph possible
56
 * value are schema/{main - myschema - *} | instance/{main - myschema - *}  |
57
 * inference/{main - myschema - *}
58
 * @param {string|Var} [subject] - The IRI of a triple’s subject or a variable,
59
 * default value "v:Subject"
60
 * @param {string|Var} [predicate] - The IRI of a property or a variable,
61
 *  default value "v:Predicate"
62
 * @param {string|Var} [object] - The IRI of a node or a variable, or a literal,
63
 * default value "v:Object"
64
 * @returns {WOQLQuery} A WOQLQuery which contains the pattern matching expression
65
 */
66
  star(graph, subject, predicate, object) { return this; }
×
67

68
  /**
69
  * Update a pattern matching rule for the quad [S, P, O, G] (Subject, Predicate, Object, Graph)
70
  * @param {string|Var} subject - The IRI of a triple’s subject or a variable
71
  * @param {string|Var} predicate - The IRI of a property or a variable
72
  * @param {string|Var} newObject - The value to update or a literal
73
  * @param {typedef.GraphRef} graphRef - A valid graph resource identifier string
74
  * @returns {WOQLQuery} A WOQLQuery which contains the a Update Quad Statement
75
  */
76
  update_quad(subject, predicate, newObject, graphRef) { return this; }
×
77

78
  /**
79
   * @param {string|Var} id - IRI string or variable containing
80
   * @param {string|Var} type  -  IRI string or variable containing the IRI of the
81
   * @param {typedef.GraphRef} [refGraph] - Optional Graph resource identifier
82
   * @returns {WOQLQuery} A WOQLQuery which contains the insert expression
83
   */
84
  insert(id, type, refGraph) { return this; }
×
85

86
  /**
87
  * Sets the graph resource ID that will be used for subsequent chained function calls
88
  * @param {typedef.GraphRef} [graphRef] Resource String identifying the graph which will
89
  * be used for subsequent chained schema calls
90
  * @returns {WOQLQuery} A WOQLQuery which contains the partial Graph pattern matching expression
91
  * @example
92
  */
93
  graph(graphRef) { return this; }
×
94

95
  /**
96
   * Specifies the identity of a node that can then be used in subsequent builder functions.
97
   * Note that node() requires subsequent chained functions to complete the triples / quads
98
   * that it produces - by itself it only generates the subject.
99
   * @param {string|Var} nodeid -  The IRI of a node or a variable containing an IRI which will
100
   * be the subject of the builder functions
101
   * @param {typedef.FuntionType} [chainType] - Optional type of builder function to build
102
   * (default is triple)
103
   * @returns {WOQLQuery} - A WOQLQuery which contains the partial Node pattern matching expression
104
   */
105
  node(nodeid, chainType) { return this; }
×
106

107
  /**
108
   * Deletes all triples in the passed graph (defaults to instance/main)
109
   * @param {typedef.GraphRef} [graphRef] - Resource String identifying the graph from
110
   * which all triples will be removed
111
   * @returns {WOQLQuery} - A WOQLQuery which contains the deletion expression
112
   * @example
113
   * nuke("schema/main")
114
   * //will delete everything from the schema/main graph
115
   */
116
  nuke(graphRef) { return this; }
×
117

118
  /**
119
   * @param {string|Var} [Subj] - The IRI of a triple’s subject or a variable
120
   * @param {string|Var} [Pred] - The IRI of a property or a variable
121
   * @param {string|Var} [Obj] - The IRI of a node or a variable, or a literal
122
   * @param {typedef.GraphRef} [Graph] - the resource identifier of a graph possible
123
   * @returns {WOQLQuery} - A WOQLQuery which contains the pattern matching expression
124
   */
125
  all(Subj, Pred, Obj, Graph) { return this; }
×
126

127
  /**
128
   * @param {boolean} tf
129
   * @returns {object}
130
   * @example
131
   */
132
  boolean(tf) { return {}; }
×
133

134
  /**
135
   * @param {string} s
136
   * @returns {object}
137
   * @example
138
   */
139
  string(s) { return {}; }
×
140

141
  /**
142
 * @param {any} s
143
 * @param {string} t
144
 * @returns {object}
145
 * @example
146
 */
147
  literal(s, t) { return {}; }
×
148

149
  /**
150
  * @param {string} s
151
  * @returns {object}
152
  * @example
153
  */
154

155
  iri(s) { return {}; }
×
156

157
  // eslint-disable-next-line no-underscore-dangle
158
  _set_context(ctxt) { return this; }
×
159

160
  /**
161
   * @param {WOQLQuery} Subq
162
   * @returns {WOQLQuery}
163
   */
164
  addSubQuery(Subq) {
165
    super.addSubQuery(Subq);
27✔
166
    return this;
27✔
167
  }
168

169
  /**
170
   * @param {string} msg
171
   * @returns {WOQLQuery}
172
   */
173
  parameterError(msg) {
UNCOV
174
    super.parameterError(msg);
×
UNCOV
175
    return this;
×
176
  }
177

178
  /**
179
   * @returns {WOQLQuery}
180
   */
181
  updated() {
182
    super.updated();
9✔
183
    return this;
9✔
184
  }
1✔
185

186
  // eslint-disable-next-line no-useless-constructor
187
  constructor(query) {
113✔
188
    super(query);
189
  }
1✔
190
}
191

192
/**
193
 * Read a node identified by an IRI as a JSON-LD document
194
 * @param {string} IRI -  The document id  or a variable to read
195
 * @param {string} output - Variable which will be bound to the document.
196
 * @return {WOQLQuery} WOQLQuery
197
 */
198
WOQLQuery.prototype.read_document = function (IRI, output) {
1✔
199
  if (this.cursor['@type']) this.wrapCursorWithAnd();
1!
200
  this.cursor['@type'] = 'ReadDocument';
1✔
201
  this.cursor.identifier = this.cleanNodeValue(IRI);
1✔
202
  this.cursor.document = this.expandValueVariable(output);
1✔
203
  return this;
1✔
204
};
205

206
/**
207
 * Insert a document in the graph.
208
 * @param {object} docjson -  The document to insert. Must either have an '@id' or
209
 * have a class specified key.
210
 * @param {string} [IRI] - An optional identifier specifying the document location.
211
 * @return {WOQLQuery} WOQLQuery
212
 */
213

214
WOQLQuery.prototype.insert_document = function (docjson, IRI) {
1✔
215
  if (this.cursor['@type']) this.wrapCursorWithAnd();
1!
216
  this.cursor['@type'] = 'InsertDocument';
1✔
217
  if (typeof IRI !== 'undefined') this.cursor.identifier = this.cleanNodeValue(IRI);
1!
218

219
  this.cursor.document = this.cleanObject(docjson);
1✔
220

221
  return this.updated();
1✔
222
};
223

224
/**
225
 * Update a document identified by an IRI
226
 * @param {object} docjson -  The document to update. Must either have an '@id' or
227
 * have a class specified key.
228
 * @param {string} [IRI] - An optional identifier specifying the document location.
229
 * @return {WOQLQuery} WOQLQuery
230
 */
231

232
WOQLQuery.prototype.update_document = function (docjson, IRI) {
1✔
233
  if (this.cursor['@type']) this.wrapCursorWithAnd();
1!
234
  this.cursor['@type'] = 'UpdateDocument';
1✔
235
  if (typeof IRI !== 'undefined') this.cursor.identifier = this.cleanNodeValue(IRI);
1!
236

237
  this.cursor.document = this.cleanObject(docjson);
1✔
238

239
  return this.updated();
1✔
240
};
241

242
/**
243
 * Delete a document from the graph.
244
 * @param {string} IRI -  The document id  or a variable
245
 * @return {WOQLQuery} WOQLQuery
246
 */
247

248
WOQLQuery.prototype.delete_document = function (IRI) {
1✔
249
  if (this.cursor['@type']) this.wrapCursorWithAnd();
1!
250
  this.cursor['@type'] = 'DeleteDocument';
1✔
251
  this.cursor.identifier = this.cleanNodeValue(IRI);
1✔
252
  return this.updated();
1✔
253
};
254

255
/**
256
 * Contains definitions of the WOQL functions which map directly to JSON-LD types
257
 * All other calls and queries can be composed from these
258
 */
259

260
// moved from woqlCore
261
WOQLQuery.prototype.wrapCursorWithAnd = function () {
1✔
262
  if (this.cursor && this.cursor['@type'] === 'And') {
2✔
263
    const newby = this.cursor.and.length;
1✔
264
    this.and({});
1✔
265
    this.cursor = this.cursor.and[newby];
1✔
266
  } else {
267
    const nj = new WOQLQuery().json(this.cursor);
1✔
268
    for (const k in this.cursor) delete this.cursor[k];
4✔
269
    // create an empty json for the new query
270
    this.and(nj, {});
1✔
271
    this.cursor = this.cursor.and[1];
1✔
272
  }
273
};
274

275
/**
276
 * Query running against any specific commit Id
277
 * @param {string}  refPath  - path to specific reference Id or commit Id
278
 * @param {WOQLQuery} [subquery] - subquery for the specific commit point
279
 * @returns {WOQLQuery}
280
 */
281

282
WOQLQuery.prototype.using = function (refPath, subquery) {
1✔
283
  if (this.cursor['@type']) this.wrapCursorWithAnd();
4!
284
  this.cursor['@type'] = 'Using';
4✔
285
  if (!refPath || typeof refPath !== 'string') {
4!
286
    return this.parameterError('The first parameter to using must be a Collection ID (string)');
×
287
  }
288
  this.cursor.collection = refPath;
4✔
289
  return this.addSubQuery(subquery);
4✔
290
};
291

292
/**
293
 * Adds a text comment to a query - can also be used to wrap any part of a query to turn it off
294
 * @param {string} comment - text comment
295
 * @param {WOQLQuery} [subquery]  - query that is "commented out"
296
 * @returns {WOQLQuery}
297
 */
298

299
WOQLQuery.prototype.comment = function (comment, subquery) {
1✔
300
  // if (comment && comment === 'args')
301
  // return ['comment', 'query']
302
  if (this.cursor['@type']) this.wrapCursorWithAnd();
×
303
  this.cursor['@type'] = 'Comment';
×
304
  this.cursor.comment = this.jlt(comment);
×
305
  return this.addSubQuery(subquery);
×
306
};
307

308
/**
309
 * Filters the query so that only the variables included in [V1...Vn] are returned in the bindings
310
 * @param {...string|...Var} varNames - only these variables are returned
311
 * @returns {WOQLQuery}
312
 */
313

314
WOQLQuery.prototype.select = function (...varNames) {
8✔
315
  if (this.cursor['@type']) this.wrapCursorWithAnd();
4!
316
  this.cursor['@type'] = 'Select';
4✔
317
  if (!varNames || varNames.length <= 0) {
4!
318
    return this.parameterError('Select must be given a list of variable names');
×
319
  }
320
  const last = varNames[varNames.length - 1];
4✔
321
  /**
322
  *@type {any}
323
  */
324
  let embedquery = false;
4✔
325
  if (typeof last === 'object' && !(last instanceof Var) && last.json) {
4✔
326
    embedquery = varNames.pop();
2✔
327
  } // else var embedquery = false
328
  this.cursor.variables = this.rawVarList(varNames);
4✔
329
  return this.addSubQuery(embedquery);
4✔
330
};
331

332
/**
333
 * Filter the query to return only results that are distinct in the given variables
334
 * @param {...string|...Var} varNames - these variables are guaranteed to be unique as a tuple
335
 * @returns {WOQLQuery}
336
 */
337

338
WOQLQuery.prototype.distinct = function (...varNames) {
1✔
339
  // if (list && list[0] === 'args')
340
  // return ['variable_list', 'query']
341
  if (this.cursor['@type']) this.wrapCursorWithAnd();
×
342
  this.cursor['@type'] = 'Distinct';
×
343
  if (!varNames || varNames.length <= 0) {
×
344
    return this.parameterError('Distinct must be given a list of variable names');
×
345
  }
346
  const last = varNames[varNames.length - 1];
×
347
  /**
348
     * @type {any}
349
     */
350
  let embedquery = false;
×
351
  if (typeof last === 'object' && !(last instanceof Var) && last.json) {
×
352
    embedquery = varNames.pop();
×
353
  } // else var embedquery = false
354
  this.cursor.variables = this.rawVarList(varNames);
×
355
  return this.addSubQuery(embedquery);
×
356
};
357

358
/**
359
* Logical conjunction of the contained queries - all queries must match or the entire clause fails
360
* @param {...WOQLQuery} subqueries - A list of one or more woql queries to execute as a conjunction
361
* @returns {WOQLQuery} - A WOQLQuery object containing the conjunction of queries
362
*/
363

364
WOQLQuery.prototype.and = function (...subqueries) {
22✔
365
  if (this.cursor['@type'] && this.cursor['@type'] !== 'And') {
11✔
366
    const nj = new WOQLQuery().json(this.cursor);
2✔
367
    for (const k in this.cursor) delete this.cursor[k];
8✔
368
    subqueries.unshift(nj);
2✔
369
  }
370
  this.cursor['@type'] = 'And';
11✔
371
  if (typeof this.cursor.and === 'undefined') this.cursor.and = [];
11✔
372
  for (let i = 0; i < subqueries.length; i++) {
11✔
373
    const onevar = this.jobj(subqueries[i]);
19✔
374
    if (
19!
375
      onevar['@type'] === 'And'
19!
376
      && onevar.and
377
    ) {
378
      for (let j = 0; j < onevar.and.length; j++) {
×
379
        const qjson = onevar.and[j];
×
380
        if (qjson) {
×
381
          const subvar = this.jobj(qjson);
×
382
          this.cursor.and.push(subvar);
×
383
        }
384
      }
385
    } else {
386
      this.cursor.and.push(onevar);
19✔
387
    }
388
  }
389
  return this;
11✔
390
};
391

392
/**
393
 * Creates a logical OR of the arguments
394
 * @param {...WOQLQuery} subqueries - A list of one or more woql queries
395
 * to execute as alternatives
396
 * @returns {WOQLQuery} - A WOQLQuery object containing the logical Or of the subqueries
397
 */
398

399
WOQLQuery.prototype.or = function (...subqueries) {
1✔
400
  if (this.cursor['@type']) this.wrapCursorWithAnd();
1!
401
  this.cursor['@type'] = 'Or';
1✔
402
  if (typeof this.cursor.or === 'undefined') this.cursor.or = [];
1!
403
  for (let i = 0; i < subqueries.length; i++) {
1✔
404
    const onevar = this.jobj(subqueries[i]);
2!
405
    this.cursor.or.push(onevar);
2✔
406
  }
407
  return this;
1✔
408
};
409
/**
410
 * Specifies the database URL that will be the default database for the enclosed query
411
 * @param {typedef.GraphRef} graphRef- A valid graph resource identifier string
412
 * @param {WOQLQuery} [query] - The query
413
 * @returns {WOQLQuery} A WOQLQuery object containing the from expression
414
 */
415

416
/**
417
 * Specifies the database URL that will be the default database for the enclosed query
418
 * @param {typedef.GraphRef} graphRef- A valid graph resource identifier string
419
 * @param {WOQLQuery} [query] - The query
420
 * @returns {WOQLQuery} A WOQLQuery object containing the from expression
421
 */
422

423
WOQLQuery.prototype.from = function (graphRef, query) {
1✔
424
  if (this.cursor['@type']) this.wrapCursorWithAnd();
1!
425
  this.cursor['@type'] = 'From';
1✔
426
  if (!graphRef || typeof graphRef !== 'string') {
1!
UNCOV
427
    return this.parameterError(
×
428
      'The first parameter to from must be a Graph Filter Expression (string)',
429
    );
430
  }
431
  this.cursor.graph = this.jlt(graphRef);
1✔
432
  return this.addSubQuery(query);
1✔
433
};
434

435
/**
436
 * Specifies the graph resource to write the contained query into
437
 * @param {typedef.GraphRef} graphRef- A valid graph resource identifier string
438
 * @param {WOQLQuery} [subquery] - The query which will be written into the graph
439
 * @returns {WOQLQuery} A WOQLQuery which will be written into the graph in question
440
 */
441

442
WOQLQuery.prototype.into = function (graphRef, subquery) {
1✔
443
  // if (graph_descriptor && graph_descriptor === 'args')
444
  // return ['graph', 'query']
445
  if (this.cursor['@type']) this.wrapCursorWithAnd();
×
446
  this.cursor['@type'] = 'Into';
×
447
  if (!graphRef || typeof graphRef !== 'string') {
×
448
    return this.parameterError(
×
449
      'The first parameter to from must be a Graph Filter Expression (string)',
450
    );
451
  }
452
  this.cursor.graph = this.jlt(graphRef);
×
453
  return this.addSubQuery(subquery);
×
454
};
455

456
/**
457
 * Creates a triple pattern matching rule for the triple [S, P, O] (Subject, Predicate, Object)
458
 * @param {string|Var} subject - The IRI of a triple’s subject or a variable
459
 * @param {string|Var} predicate - The IRI of a property or a variable
460
 * @param {string|Var} object - The IRI of a node or a variable, or a literal
461
 * @returns {WOQLQuery}
462
 */
463

464
WOQLQuery.prototype.triple = function (subject, predicate, object) {
1✔
465
  // if (a && a === 'args')
466
  // return ['subject', 'predicate', 'object']
467
  if (this.cursor['@type']) this.wrapCursorWithAnd();
43✔
468
  this.cursor['@type'] = 'Triple';
43✔
469
  this.cursor.subject = this.cleanSubject(subject);
43✔
470
  this.cursor.predicate = this.cleanPredicate(predicate);
43✔
471
  this.cursor.object = this.cleanObject(object);
43✔
472
  return this;
43✔
473
};
474

475
/**
476
 * Creates a triple pattern matching rule for the triple [S, P, O] (Subject, Predicate,
477
 * Object) added in the current layer
478
 * @param {string|Var} subject - The IRI of a triple’s subject or a variable
479
 * @param {string|Var} predicate - The IRI of a property or a variable
480
 * @param {string|Var} object - The IRI of a node or a variable, or a literal
481
 * @returns {WOQLQuery}
482
 */
483

484
WOQLQuery.prototype.added_triple = function (subject, predicate, object) {
1✔
485
  // if (a && a === 'args')
486
  // return ['subject', 'predicate', 'object']
487
  if (this.cursor['@type']) this.wrapCursorWithAnd();
×
488
  this.cursor['@type'] = 'AddedTriple';
×
489
  this.cursor.subject = this.cleanSubject(subject);
×
490
  this.cursor.predicate = this.cleanPredicate(predicate);
×
491
  this.cursor.object = this.cleanObject(object);
×
492
  return this;
×
493
};
494

495
/**
496
 * Creates a triple pattern matching rule for the triple [S, P, O] (Subject, Predicate,
497
 * Object) added in the current commit
498
 * @param {string|Var} subject - The IRI of a triple’s subject or a variable
499
 * @param {string|Var} predicate - The IRI of a property or a variable
500
 * @param {string|Var} object - The IRI of a node or a variable, or a literal
501
 * @returns {WOQLQuery}
502
 */
503

504
WOQLQuery.prototype.removed_triple = function (subject, predicate, object) {
1✔
505
  if (this.cursor['@type']) this.wrapCursorWithAnd();
×
506
  this.cursor['@type'] = 'DeletedTriple';
×
507
  this.cursor.subject = this.cleanSubject(subject);
×
508
  this.cursor.predicate = this.cleanPredicate(predicate);
×
509
  this.cursor.object = this.cleanObject(object);
×
510
  return this;
×
511
};
512

513
/**
514
 * Creates a pattern matching rule for triple [Subject, Predicate, Object]
515
 * @param {string|Var} subject - The IRI of a triple’s subject or a variable
516
 * @param {string|Var} predicate - The IRI of a property or a variable
517
 * @param {string|Var} object - The IRI of a node or a variable, or a literal
518
 * @returns {WOQLQuery} A WOQLQuery which contains the a quad or a triple Statement
519
 */
520

521
WOQLQuery.prototype.link = function (subject, predicate, object) {
1✔
522
  if (this.cursor['@type']) this.wrapCursorWithAnd();
×
523
  this.cursor['@type'] = 'Triple';
×
524
  this.cursor.subject = this.cleanSubject(subject);
×
525
  this.cursor.predicate = this.cleanPredicate(predicate);
×
526
  this.cursor.object = this.cleanSubject(object);
×
527
  return this;
×
528
};
529

530
/**
531
 * Creates a pattern matching rule for triple [Subject, Predicate, Object]
532
 * add extra information about the type of the value object
533
 * @param {string|Var} subject - The IRI of a triple’s subject or a variable
534
 * @param {string|Var} predicate - The IRI of a property or a variable
535
 * @param {string | number | boolean | Var} objValue - an specific value
536
 * @returns {WOQLQuery} A WOQLQuery which contains the a quad or a triple Statement
537
 */
538

539
WOQLQuery.prototype.value = function (subject, predicate, objValue) {
1✔
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.cleanDataValue(objValue, 'xsd:string');
×
545
  return this;
×
546
};
547

548
/**
549
 * Creates a pattern matching rule for the quad [S, P, O, G] (Subject, Predicate, Object, Graph)
550
 * @param {string|Var} subject - The IRI of a triple’s subject or a variable
551
 * @param {string|Var} predicate - The IRI of a property or a variable
552
 * @param {string|Var} object - The IRI of a node or a variable, or a literal
553
 * @param {typedef.GraphRef} graphRef - A valid graph resource identifier string
554
 * @returns {WOQLQuery}
555
 */
556

557
WOQLQuery.prototype.quad = function (subject, predicate, object, graphRef) {
1✔
558
  if (this.cursor['@type']) this.wrapCursorWithAnd();
1!
559
  const args = this.triple(subject, predicate, object);
1✔
560
  // if (a && a === 'args')
561
  // return args.concat(['graph'])
562
  if (!graphRef) return this.parameterError('Quad takes four parameters, the last should be a graph filter');
1!
563
  this.cursor['@type'] = 'Triple';
1✔
564
  this.cursor.graph = this.cleanGraph(graphRef);
1✔
565
  return this;
1✔
566
};
567

568
/**
569
 * Creates a pattern matching rule for the quad [S, P, O, G] (Subject, Predicate,
570
 * Object, Graph) removed from 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
 * @param {typedef.GraphRef} graphRef- A valid graph resource identifier string
575
 * @returns {WOQLQuery}
576
 */
577

578
WOQLQuery.prototype.added_quad = function (subject, predicate, object, graphRef) {
1✔
579
  if (this.cursor['@type']) this.wrapCursorWithAnd();
×
580
  const args = this.triple(subject, predicate, object);
×
581
  // if (a && a === 'args')
582
  // return args.concat(['graph'])
583
  if (!graphRef) return this.parameterError('Quad takes four parameters, the last should be a graph filter');
×
584
  this.cursor['@type'] = 'AddedQuad';
×
585
  this.cursor.graph = this.cleanGraph(graphRef);
×
586
  return this;
×
587
};
588

589
/**
590
 * Creates a pattern matching rule for the quad [S, P, O, G] (Subject, Predicate,
591
 * Object, Graph) removed from the current commit
592
 * @param {string|Var} subject - The IRI of a triple’s subject or a variable
593
 * @param {string|Var} predicate - The IRI of a property or a variable
594
 * @param {string|Var} object - The IRI of a node or a variable, or a literal
595
 * @param {typedef.GraphRef} graphRef- A valid graph resource identifier string
596
 * @returns {WOQLQuery}
597
 */
598

599
WOQLQuery.prototype.removed_quad = function (subject, predicate, object, graphRef) {
1✔
600
  if (this.cursor['@type']) this.wrapCursorWithAnd();
×
601
  const args = this.triple(subject, predicate, object);
×
602
  // if (a && a === 'args')
603
  // return args.concat(['graph'])
604
  if (!graphRef) return this.parameterError('Quad takes four parameters, the last should be a graph filter');
×
605
  this.cursor['@type'] = 'RemovedQuad';
×
606
  this.cursor.graph = this.cleanGraph(graphRef);
×
607
  return this;
×
608
};
609

610
/**
611
 * Returns true if ClassA subsumes ClassB, according to the current DB schema
612
 * @param {string} classA - ClassA
613
 * @param {string} classB - ClassB
614
 * @returns {boolean} WOQLQuery
615
 */
616
WOQLQuery.prototype.sub = function (classA, classB) {
1✔
617
  if (!classA || !classB) return this.parameterError('Subsumption takes two parameters, both URIs');
1!
618
  if (this.cursor['@type']) this.wrapCursorWithAnd();
1!
619
  this.cursor['@type'] = 'Subsumption';
1✔
620
  this.cursor.parent = this.cleanNodeValue(classA);
1✔
621
  this.cursor.child = this.cleanNodeValue(classB);
1✔
622
  return this;
1✔
623
};
624

625
WOQLQuery.prototype.subsumption = WOQLQuery.prototype.sub;
1✔
626

627
/**
628
 * Matches if a is equal to b
629
 * @param {string|Var} varName - literal, variable or id
630
 * @param {string|Var} varValue - literal, variable or id
631
 * @returns {WOQLQuery}
632
 */
633
WOQLQuery.prototype.eq = function (varName, varValue) {
1✔
634
  // if (a && a === 'args') return ['left', 'right']
635
  if (typeof varName === 'undefined' || typeof varValue === 'undefined') return this.parameterError('Equals takes two parameters');
1!
636
  if (this.cursor['@type']) this.wrapCursorWithAnd();
1!
637
  this.cursor['@type'] = 'Equals';
1✔
638
  this.cursor.left = this.cleanObject(varName);
1✔
639
  this.cursor.right = this.cleanObject(varValue);
1✔
640
  return this;
1✔
641
};
642

643
WOQLQuery.prototype.equals = WOQLQuery.prototype.eq;
1✔
644

645
/**
646
 * Substring
647
 * @param {string|Var} string - String or variable
648
 * @param {number|Var} before - integer or variable (characters from start to begin)
649
 * @param {number|Var} [length] - integer or variable (length of substring)
650
 * @param {number|Var} [after] - integer or variable (number of characters after substring)
651
 * @param {string|Var} [subString] - String or variable
652
 * @returns {WOQLQuery}
653
 */
654
WOQLQuery.prototype.substr = function (string, before, length, after, subString) {
1✔
655
  // if (String && String === 'args')
656
  // return ['string', 'before', 'length', 'after', 'substring']
657
  if (!subString) {
×
658
    subString = after;
×
659
    after = 0;
×
660
  }
661
  if (!subString) {
×
662
    subString = length;
×
663
    length = subString.length + before;
×
664
  }
665
  if (!string || !subString || typeof subString !== 'string') {
×
666
    return this.parameterError(
×
667
      'Substr - the first and last parameters must be strings representing the full and substring variables / literals',
668
    );
669
  }
670
  if (this.cursor['@type']) this.wrapCursorWithAnd();
×
671
  this.cursor['@type'] = 'Substring';
×
672
  this.cursor.string = this.cleanDataValue(string, 'xsd:string');
×
673
  this.cursor.before = this.cleanDataValue(before, 'xsd:nonNegativeInteger');
×
674
  this.cursor.length = this.cleanDataValue(length, 'xsd:nonNegativeInteger');
×
675
  this.cursor.after = this.cleanDataValue(after, 'xsd:nonNegativeInteger');
×
676
  this.cursor.substring = this.cleanDataValue(subString, 'xsd:string');
×
677
  return this;
×
678
};
679

680
WOQLQuery.prototype.substring = WOQLQuery.prototype.substr;
1✔
681

682
/**
683
 * Use the document inteface to import documents
684
 * @deprecated
685
 * Retrieves the exernal resource defined by QueryResource and copies values
686
 * from it into variables defined in AsVars
687
 * @param {Vars | array<Var>} asvars - an array of AsVar variable mappings (see as for format below)
688
 * @param {WOQLQuery} queryResource - an external resource (remote, file, post) to query
689
 * @returns {WOQLQuery} A WOQLQuery which contains the get expression
690
 */
691
WOQLQuery.prototype.get = function (asvars, queryResource) {
1✔
692
  this.cursor['@type'] = 'Get';
1✔
693
  this.cursor.columns = asvars.json ? asvars.json() : new WOQLQuery().as(...asvars).json();
1!
694
  if (queryResource) {
1!
695
    this.cursor.resource = this.jobj(queryResource);
1✔
696
  } else {
697
    this.cursor.resource = {};
×
698
  }
699
  this.cursor = this.cursor.resource;
1✔
700
  return this;
1✔
701
};
702

703
/**
704
 * Use the document inteface to import documents
705
 * @deprecated
706
 * @put Outputs the results of a query to a file
707
 * @param {Vars | array<Var>} varsToExp - an array of AsVar variable
708
 * mappings (see as for format below)
709
 * @param {WOQLQuery} query - The query which will be executed to produce the results
710
 * @param {string} fileResource - an file resource local to the server
711
 * @returns {WOQLQuery} A WOQLQuery which contains the put expression
712
 */
713
WOQLQuery.prototype.put = function (varsToExp, query, fileResource) {
1✔
714
  if (this.cursor['@type']) this.wrapCursorWithAnd();
×
715
  this.cursor['@type'] = 'Put';
×
716
  if (Array.isArray(varsToExp) && typeof varsToExp[0] !== 'object') {
×
717
    const nasvars = [];
×
718
    for (let i = 0; i < varsToExp.length; i++) {
×
719
      const iasv = this.asv(i, varsToExp[i]);
×
720
      nasvars.push(iasv);
×
721
      this.cursor.columns = nasvars;
×
722
    }
723
  } else {
724
    this.cursor.columns = varsToExp.json
×
725
      ? varsToExp.json()
726
      : new WOQLQuery().as(...varsToExp).json();
727
  }
728
  this.cursor.query = this.jobj(query);
×
729
  if (fileResource) {
×
730
    this.cursor.resource = this.jobj(fileResource);
×
731
  } else {
732
    this.cursor.resource = {};
×
733
  }
734
  this.cursor = this.cursor.resource;
×
735
  return this;
×
736
};
737

738
/**
739
 * @param {...(array|string|Var)} varList variable number of arguments
740
 * @returns WOQLQuery
741
 */
742
WOQLQuery.prototype.as = function (...varList) {
3✔
743
  // if (varList && varList[0] == 'args')
744
  // return [['indexed_as_var', 'named_as_var']]
745
  if (!Array.isArray(this.query)) this.query = [];
1!
746
  if (Array.isArray(varList[0])) {
1!
747
    if (!varList[1]) {
×
748
      // indexed as vars
749
      for (var i = 0; i < varList[0].length; i++) {
×
750
        const iasv = this.asv(i, varList[0][i]);
×
751
        this.query.push(iasv);
×
752
      }
753
    } else {
754
      for (var i = 0; i < varList.length; i++) {
×
755
        const onemap = varList[i];
×
756
        if (Array.isArray(onemap) && onemap.length >= 2) {
×
757
          const type = onemap && onemap.length > 2 ? onemap[2] : false;
×
758
          const oasv = this.asv(onemap[0], onemap[1], type);
×
759
          this.query.push(oasv);
×
760
        }
761
      }
762
    }
763
  } else if (typeof varList[0] === 'number' || typeof varList[0] === 'string') {
1!
764
    if (varList[2] && typeof varList[2] === 'string') {
1!
765
      var oasv = this.asv(varList[0], varList[1], varList[2]);
1✔
766
    } else if (varList[1] && varList[1] instanceof Var) {
×
767
      var oasv = this.asv(varList[0], varList[1]);
×
768
    } else if (varList[1] && typeof varList[1] === 'string') {
×
769
      if (varList[1].substring(0, 4) === 'xsd:' || varList[1].substring(0, 4) === 'xdd:') {
×
770
        var oasv = this.asv(this.query.length, varList[0], varList[1]);
×
771
      } else {
772
        var oasv = this.asv(varList[0], varList[1]);
×
773
      }
774
    } else {
775
      var oasv = this.asv(this.query.length, varList[0]);
×
776
    }
777
    this.query.push(oasv);
1✔
778
  } else if (typeof varList[0] === 'object') {
×
779
    // check if it is an class object with an json method
780
    this.query.push(varList[0].json ? varList[0].json() : varList[0]);
×
781
  }
782
  return this;
1✔
783
};
784

785
/**
786
 * Identifies a remote resource by URL and specifies the format of the resource through the options
787
 * @param {object} remoteObj - The URL at which the remote resource can be accessed
788
 * @param {typedef.DataFormatObj} [formatObj] - The format of the resource data {}
789
 * @returns {WOQLQuery} A WOQLQuery which contains the remote resource identifier
790
 */
791

792
WOQLQuery.prototype.remote = function (remoteObj, formatObj) {
1✔
793
  if (this.cursor['@type']) this.wrapCursorWithAnd();
1!
794
  this.cursor['@type'] = 'QueryResource';
1✔
795
  this.cursor.source = { '@type': 'Source', url: remoteObj };
1✔
796
  this.cursor.format = 'csv'; // hard coded for now
1✔
797
  if (typeof opts !== 'undefined') this.cursor.options = formatObj;
1!
798
  return this;
1✔
799
};
800

801
/**
802
 * Identifies a resource as a local path on the client, to be sent to the server through a
803
 * HTTP POST request, with the format defined through the options
804
 * @param {string} url - The Path on the server at which the file resource can be accessed
805
 * @param {typedef.DataFormatObj} [formatObj] - imput options, optional
806
 * @param {string} [source] - It defines the source of the file, it can be 'url','post'
807
 * @returns {WOQLQuery} A WOQLQuery which contains the Post resource identifier
808
 */
809

810
WOQLQuery.prototype.post = function (url, formatObj, source = 'post') {
1!
811
  // if (fpath && fpath == 'args') return ['file', 'format']
812
  if (this.cursor['@type']) this.wrapCursorWithAnd();
×
813
  this.cursor['@type'] = 'QueryResource';
×
814
  this.cursor.source = { '@type': 'Source', [source]: url };
×
815
  this.cursor.format = 'csv'; // hard coded for now
×
816
  this.cursor.options = formatObj;
×
817
  if (typeof formatObj !== 'undefined') this.cursor.options = formatObj;
×
818
  return this;
×
819
};
820

821
/**
822
 * Deletes a single triple from the default graph of the database
823
 * @param {string|Var} subject - The IRI of a triple’s subject or a variable
824
 * @param {string|Var} predicate - The IRI of a property or a variable
825
 * @param {string|Var} object - The IRI of a node or a variable, or a literal
826
 * @returns {WOQLQuery} - A WOQLQuery which contains the Triple Deletion statement
827
 */
828

829
WOQLQuery.prototype.delete_triple = function (subject, predicate, object) {
1✔
830
  if (this.cursor['@type']) this.wrapCursorWithAnd();
1!
831
  const args = this.triple(subject, predicate, object);
1✔
832
  this.cursor['@type'] = 'DeleteTriple';
1✔
833
  return this.updated();
1✔
834
};
835

836
/**
837
 * Adds triples according to the the pattern [subject,predicate,object]
838
 * @param {string|Var} subject - The IRI of a triple’s subject or a variable
839
 * @param {string|Var} predicate - The IRI of a property or a variable
840
 * @param {string|Var} object - The IRI of a node or a variable, or a literal
841
 * @returns {WOQLQuery}
842
 */
843

844
WOQLQuery.prototype.add_triple = function (subject, predicate, object) {
1✔
845
  if (this.cursor['@type']) this.wrapCursorWithAnd();
2!
846
  const args = this.triple(subject, predicate, object);
2✔
847
  this.cursor['@type'] = 'AddTriple';
2✔
848
  return this.updated();
2✔
849
};
850

851
/**
852
 * Deletes a single triple from the graph [Subject, Predicate, Object, Graph]
853
 * @param {string|Var} subject - The IRI of a triple’s subject or a variable
854
 * @param {string|Var} predicate - The IRI of a property or a variable
855
 * @param {string|Var} object - The IRI of a node or a variable, or a literal
856
 * @param {typedef.GraphRef} graphRef - A valid graph resource identifier string
857
 * @returns {WOQLQuery} - A WOQLQuery which contains the Delete Quad Statement
858
 */
859
WOQLQuery.prototype.delete_quad = function (subject, predicate, object, graphRef) {
1✔
860
  if (this.cursor['@type']) this.wrapCursorWithAnd();
1!
861
  const args = this.triple(subject, predicate, object);
1✔
862
  // if (a && a == 'args') return args.concat(['graph'])
863
  if (!graphRef) {
1!
864
    return this.parameterError(
×
865
      'Delete Quad takes four parameters, the last should be a graph id',
866
    );
867
  }
868
  this.cursor['@type'] = 'DeleteTriple';
1✔
869
  this.cursor.graph = this.cleanGraph(graphRef);
1✔
870
  return this.updated();
1✔
871
};
872

873
/**
874
 * Adds quads according to the pattern [S,P,O,G]
875
 * @param {string|Var} subject - The IRI of a triple’s subject or a variable
876
 * @param {string|Var} predicate - The IRI of a property or a variable
877
 * @param {string|Var} object - The IRI of a node or a variable, or a literal
878
 * @param {typedef.GraphRef} graphRef - A valid graph resource identifier string
879
 * @returns {WOQLQuery}
880
 */
881

882
WOQLQuery.prototype.add_quad = function (subject, predicate, object, graphRef) {
1✔
883
  if (this.cursor['@type']) this.wrapCursorWithAnd();
2!
884
  const args = this.triple(subject, predicate, object);
2✔
885
  if (!graphRef) return this.parameterError('Add Quad takes four parameters, the last should be a graph id');
2!
886
  this.cursor['@type'] = 'AddTriple';
2✔
887
  this.cursor.graph = this.cleanGraph(graphRef);
2✔
888
  return this.updated();
2✔
889
};
890

891
/**
892
 * Remove whitespace from both sides of a string:
893
 * @param {string|Var} inputStr - A string or variable containing
894
 * the untrimmed version of the string
895
 * @param {string|Var} resultVarName - A string or variable
896
 * containing the trimmed version of the string
897
 * @returns {WOQLQuery} A WOQLQuery which contains the Trim pattern matching expression
898
 */
899

900
WOQLQuery.prototype.trim = function (inputStr, resultVarName) {
1✔
901
  if (this.cursor['@type']) this.wrapCursorWithAnd();
1!
902
  this.cursor['@type'] = 'Trim';
1✔
903
  this.cursor.untrimmed = this.cleanDataValue(inputStr);
1✔
904
  this.cursor.trimmed = this.cleanDataValue(resultVarName);
1✔
905
  return this;
1✔
906
};
907

908
/**
909
 * Evaluates the passed arithmetic expression and generates or matches the result value
910
 * @param {object| WOQLQuery | string} arithExp - query or JSON-LD representing the query
911
 * @param {string|Var} resultVarName - output variable
912
 * @returns {WOQLQuery}
913
 */
914

915
WOQLQuery.prototype.eval = function (arithExp, resultVarName) {
1✔
916
  if (this.cursor['@type']) this.wrapCursorWithAnd();
5!
917
  this.cursor['@type'] = 'Eval';
5✔
918
  this.cursor.expression = arithExp.json ? arithExp.json() : arithExp;
5✔
919
  this.cursor.result = this.cleanArithmeticValue(resultVarName);
5✔
920
  return this;
5✔
921
};
922

923
/**
924
 * Adds the numbers together
925
 * @param {...(string|number|Var)} args - a variable or numeric containing the values to add
926
 * @returns {WOQLQuery} A WOQLQuery which contains the addition expression
927
 */
928

929
WOQLQuery.prototype.plus = function (...args) {
2✔
930
  // if (args && args[0] == 'args') return ['first', 'second']
931
  if (this.cursor['@type']) this.wrapCursorWithAnd();
1!
932
  this.cursor['@type'] = 'Plus';
1✔
933
  this.cursor.left = this.arop(args.shift());
1✔
934
  if (args.length > 1) {
1!
935
    this.cursor.right = this.jobj(new WOQLQuery().plus(...args.map(this.arop)));
×
936
  } else {
937
    this.cursor.right = this.arop(args[0]);
1✔
938
  }
939
  return this;
1✔
940
};
941

942
/**
943
 *
944
 * Subtracts Numbers N1..Nn
945
 * @param {...(string|number|Var)} args - variable or numeric containing the value that will be
946
 * subtracted from
947
 * @returns {WOQLQuery} A WOQLQuery which contains the subtraction expression
948
 */
949
WOQLQuery.prototype.minus = function (...args) {
2✔
950
  // if (args && args[0] === 'args') return ['first', 'right']
951
  if (this.cursor['@type']) this.wrapCursorWithAnd();
1!
952
  this.cursor['@type'] = 'Minus';
1✔
953
  this.cursor.left = this.arop(args.shift());
1✔
954
  if (args.length > 1) {
1!
955
    this.cursor.right = this.jobj(new WOQLQuery().minus(...args.map(this.arop)));
×
956
  } else {
957
    this.cursor.right = this.arop(args[0]);
1✔
958
  }
959
  return this;
1✔
960
};
961

962
/**
963
 *
964
 * Multiplies numbers N1...Nn together
965
 * @param {...(string|number|Var)} args - a variable or numeric containing the value
966
 * @returns {WOQLQuery} A WOQLQuery which contains the multiplication expression
967
 */
968
WOQLQuery.prototype.times = function (...args) {
10✔
969
  // if (args && args[0] === 'args') return ['first', 'right']
970
  if (this.cursor['@type']) this.wrapCursorWithAnd();
5!
971
  this.cursor['@type'] = 'Times';
5✔
972
  this.cursor.left = this.arop(args.shift());
5✔
973
  if (args.length > 1) {
5!
974
    this.cursor.right = this.jobj(new WOQLQuery().times(...args.map(this.arop)));
×
975
  } else {
976
    this.cursor.right = this.arop(args[0]);
5✔
977
  }
978
  return this;
5✔
979
};
980

981
/**
982
 * Divides numbers N1...Nn by each other left, to right precedence
983
 * @param {...(string|number|Var )} args - numbers to tbe divided
984
 * @returns {WOQLQuery} A WOQLQuery which contains the division expression
985
 */
986
WOQLQuery.prototype.divide = function (...args) {
2✔
987
  // if (args && args[0] === 'args') return ['left', 'right']
988
  if (this.cursor['@type']) this.wrapCursorWithAnd();
1!
989
  this.cursor['@type'] = 'Divide';
1✔
990
  this.cursor.left = this.arop(args.shift());
1✔
991
  if (args.length > 1) {
1!
992
    this.cursor.right = this.jobj(new WOQLQuery().divide(...args.map(this.arop)));
×
993
  } else {
994
    this.cursor.right = this.arop(args[0]);
1✔
995
  }
996
  return this;
1✔
997
};
998

999
/**
1000
 * Division - integer division - args are divided left to right
1001
 * @param {...(string|number|Var)} args - numbers for division
1002
 * @returns {WOQLQuery} A WOQLQuery which contains the division expression
1003
 */
1004

1005
WOQLQuery.prototype.div = function (...args) {
2✔
1006
  // if (args && args[0] === 'args') return ['left', 'right']
1007
  if (this.cursor['@type']) this.wrapCursorWithAnd();
1!
1008
  this.cursor['@type'] = 'Div';
1✔
1009
  this.cursor.left = this.arop(args.shift());
1✔
1010
  if (args.length > 1) {
1!
1011
    this.cursor.right = this.jobj(new WOQLQuery().div(...args.map(this.arop)));
×
1012
  } else {
1013
    this.cursor.right = this.arop(args[0]);
1✔
1014
  }
1015
  return this;
1✔
1016
};
1017

1018
/**
1019
 * Exponent - raises varNum01 to the power of varNum02
1020
 * @param {string|number|Var} varNum -  a variable or numeric containing the number to be
1021
 * raised to the power of the second number
1022
 * @param {number} expNum -  a variable or numeric containing the exponent
1023
 * @returns {WOQLQuery} A WOQLQuery which contains the exponent expression
1024
 */
1025
WOQLQuery.prototype.exp = function (varNum, expNum) {
1✔
1026
  // if (a && a === 'args') return ['left', 'right']
1027
  if (this.cursor['@type']) this.wrapCursorWithAnd();
1!
1028
  this.cursor['@type'] = 'Exp';
1✔
1029
  this.cursor.left = this.arop(varNum);
1✔
1030
  this.cursor.right = this.arop(expNum);
1✔
1031
  return this;
1✔
1032
};
1033

1034
/**
1035
 * Generates the nearest lower integer to the passed number
1036
 * @param {string|number|Var} varNum - Variable or numeric containing the number to be floored
1037
 * @returns {WOQLQuery} A WOQLQuery which contains the floor expression
1038
 */
1039
WOQLQuery.prototype.floor = function (varNum) {
1✔
1040
  // if (a && a === 'args') return ['argument']
1041
  if (this.cursor['@type']) this.wrapCursorWithAnd();
×
1042
  this.cursor['@type'] = 'Floor';
×
1043
  this.cursor.argument = this.arop(varNum);
×
1044
  return this;
×
1045
};
1046

1047
/**
1048
 * Tests whether a given instance IRI has type Class, according to the current state of the DB
1049
 * @param {string|Var} instanceIRI - A string IRI or a variable that identify the class instance
1050
 * @param {string|Var} classId - A Class IRI or a variable
1051
 * @returns {WOQLQuery} A WOQLQuery object containing the type test
1052
 */
1053
WOQLQuery.prototype.isa = function (instanceIRI, classId) {
1✔
1054
  // if (a && a === 'args') return ['element', 'of_type']
1055
  if (this.cursor['@type']) this.wrapCursorWithAnd();
1!
1056
  this.cursor['@type'] = 'IsA';
1✔
1057
  this.cursor.element = this.cleanNodeValue(instanceIRI);
1✔
1058
  this.cursor.type = this.cleanNodeValue(classId);
1✔
1059
  return this;
1✔
1060
};
1061

1062
/**
1063
 * Generates a string Leverstein distance measure between stringA and stringB
1064
 * @param {string|Var} stringA - string literal or variable representing a string to be compared
1065
 * @param {string|Var } stringB - string literal or variable
1066
 * representing the other string to be compared
1067
 * @param {number|string|Var} distance - variable representing the distance between the variables
1068
 * @returns {WOQLQuery} A WOQLQuery which contains the Like pattern matching expression
1069
 */
1070
WOQLQuery.prototype.like = function (stringA, stringB, distance) {
1✔
1071
  // if (a && a === 'args')
1072
  // return ['left', 'right', 'like_similarity']
1073
  if (this.cursor['@type']) this.wrapCursorWithAnd();
×
1074
  this.cursor['@type'] = 'Like';
×
1075
  this.cursor.left = this.cleanDataValue(stringA, 'xsd:string');
×
1076
  this.cursor.right = this.cleanDataValue(stringB, 'xsd:string');
×
1077
  if (distance) {
×
1078
    this.cursor.similarity = this.cleanDataValue(distance, 'xsd:decimal');
×
1079
  }
1080
  return this;
×
1081
};
1082

1083
/**
1084
 * Compares the value of v1 against v2 and returns true if v1 is less than v2
1085
 * @param {string|number|Var} varNum01 - a variable or numeric containing
1086
 * the number to be compared
1087
 * @param {string|number|Var} varNum02 - a variable or numeric containing the second comporator
1088
 * @returns {WOQLQuery} A WOQLQuery which contains the comparison expression
1089
 */
1090
WOQLQuery.prototype.less = function (varNum01, varNum02) {
1✔
1091
  if (this.cursor['@type']) this.wrapCursorWithAnd();
×
1092
  this.cursor['@type'] = 'Less';
×
1093
  this.cursor.left = this.cleanDataValue(varNum01);
×
1094
  this.cursor.right = this.cleanDataValue(varNum02);
×
1095
  return this;
×
1096
};
1097

1098
/**
1099
 * Compares the value of v1 against v2 and returns true if v1 is greater than v2
1100
 * @param {string|number|Var} varNum01 - a variable or numeric containing the number to be compared
1101
 * @param {string|number|Var} varNum02 - a variable or numeric containing the second comporator
1102
 * @returns {WOQLQuery} A WOQLQuery which contains the comparison expression
1103
 */
1104
WOQLQuery.prototype.greater = function (varNum01, varNum02) {
1✔
1105
  if (this.cursor['@type']) this.wrapCursorWithAnd();
×
1106
  this.cursor['@type'] = 'Greater';
×
1107
  this.cursor.left = this.cleanDataValue(varNum01);
×
1108
  this.cursor.right = this.cleanDataValue(varNum02);
×
1109
  return this;
×
1110
};
1111

1112
/**
1113
 * Specifies that the Subquery is optional - if it does not match the query will not fail
1114
 * @param {WOQLQuery} [subquery] - A subquery which will be optionally matched
1115
 * @returns {WOQLQuery} A WOQLQuery object containing the optional sub Query
1116
 */
1117
WOQLQuery.prototype.opt = function (subquery) {
1✔
1118
  if (this.cursor['@type']) this.wrapCursorWithAnd();
2!
1119
  this.cursor['@type'] = 'Optional';
2✔
1120
  this.addSubQuery(subquery);
2✔
1121
  return this;
2✔
1122
};
1123

1124
WOQLQuery.prototype.optional = WOQLQuery.prototype.opt;
1✔
1125

1126
/**
1127
 * Generate a new IRI from the prefix and a hash of the variables which will be unique for any
1128
 * given combination of variables
1129
 * @param {string} prefix - A prefix for the IRI - typically formed of the doc prefix and the
1130
 * classtype of the entity (“doc:Person”)
1131
 * @param {array|string|Var} inputVarList - An array of variables and / or strings from which the
1132
 * unique hash will be generated
1133
 * @param {string|Var} resultVarName - Variable in which the unique ID is stored
1134
 * @returns {WOQLQuery} A WOQLQuery object containing the unique ID generating function
1135
 */
1136
WOQLQuery.prototype.unique = function (prefix, inputVarList, resultVarName) {
1✔
1137
  if (this.cursor['@type']) this.wrapCursorWithAnd();
×
1138
  this.cursor['@type'] = 'HashKey';
×
1139
  this.cursor.base = this.cleanDataValue(prefix, 'xsd:string');
×
1140
  this.cursor.key_list = this.cleanDataValue(inputVarList);
×
1141
  this.cursor.uri = this.cleanNodeValue(resultVarName);
×
1142
  return this;
×
1143
};
1144

1145
/**
1146
 * Generates the node's ID combined the variable list with a specific prefix (URL base).
1147
 * If the input variables's values are the same, the output value will be the same.
1148
 * @param {string} prefix
1149
 * @param {string |array}  inputVarList the variable input list for generate the id
1150
 * @param {string} outputVar  the output variable name
1151
 */
1152

1153
WOQLQuery.prototype.idgen = function (prefix, inputVarList, outputVar) {
1✔
1154
  if (this.cursor['@type']) this.wrapCursorWithAnd();
1!
1155
  this.cursor['@type'] = 'LexicalKey';
1✔
1156
  this.cursor.base = this.cleanDataValue(prefix, 'xsd:string');
1✔
1157
  // this.cursor['base'] = this.cleanObject(this.string(prefix))
1158
  this.cursor.key_list = this.dataValueList(inputVarList);
1✔
1159
  this.cursor.uri = this.cleanNodeValue(outputVar);
1✔
1160
  return this;
1✔
1161
};
1162

1163
WOQLQuery.prototype.idgenerator = WOQLQuery.prototype.idgen;
1✔
1164

1165
/**
1166
 * Changes a string to upper-case
1167
 * @param {string|Var} inputVarName - string or variable representing the uncapitalized string
1168
 * @param {string|Var} resultVarName -  variable that stores the capitalized string output
1169
 * @returns {WOQLQuery} A WOQLQuery which contains the Upper case pattern matching expression
1170
 */
1171
WOQLQuery.prototype.upper = function (inputVarName, resultVarName) {
1✔
1172
  if (this.cursor['@type']) this.wrapCursorWithAnd();
×
1173
  this.cursor['@type'] = 'Upper';
×
1174
  this.cursor.mixed = this.cleanDataValue(inputVarName);
×
1175
  this.cursor.upper = this.cleanDataValue(resultVarName);
×
1176
  return this;
×
1177
};
1178

1179
/**
1180
 * Changes a string to lower-case
1181
 * @param {string|Var} inputVarName -  string or variable representing the non-lowercased string
1182
 * @param {string|Var} resultVarName - variable that stores the lowercased string output
1183
 * @returns {WOQLQuery} A WOQLQuery which contains the Lower case pattern matching expression
1184
 */
1185

1186
WOQLQuery.prototype.lower = function (inputVarName, resultVarName) {
1✔
1187
  if (this.cursor['@type']) this.wrapCursorWithAnd();
×
1188
  this.cursor['@type'] = 'Lower';
×
1189
  this.cursor.mixed = this.cleanDataValue(inputVarName);
×
1190
  this.cursor.lower = this.cleanDataValue(resultVarName);
×
1191
  return this;
×
1192
};
1193

1194
/**
1195
 * Pads out the string input to be exactly len long by appending the pad character pad to
1196
 * form output
1197
 * @param {string|Var} inputVarName - The input string or variable in unpadded state
1198
 * @param {string|Var} pad - The characters to use to pad the string or a variable representing them
1199
 * @param {number | string | Var} len - The variable or integer value representing the length of
1200
 * the output string
1201
 * @param {string|Var} resultVarName - stores output
1202
 * @returns {WOQLQuery} A WOQLQuery which contains the Pad pattern matching expression
1203
 */
1204

1205
WOQLQuery.prototype.pad = function (inputVarName, pad, len, resultVarName) {
1✔
1206
  if (this.cursor['@type']) this.wrapCursorWithAnd();
×
1207
  this.cursor['@type'] = 'Pad';
×
1208
  this.cursor.string = this.cleanDataValue(inputVarName);
×
1209
  this.cursor.char = this.cleanDataValue(pad);
×
1210
  this.cursor.times = this.cleanDataValue(len, 'xsd:integer');
×
1211
  this.cursor.result = this.cleanDataValue(resultVarName);
×
1212
  return this;
×
1213
};
1214

1215
/**
1216
 * Splits a string (Input) into a list strings (Output) by removing separator
1217
 * @param {string|Var} inputVarName - A string or variable representing the unsplit string
1218
 * @param {string|Var} separator - A string or variable containing a sequence of charatcters
1219
 * to use as a separator
1220
 * @param {string|Var} resultVarName - variable that stores output list
1221
 * @returns {WOQLQuery} A WOQLQuery which contains the Split pattern matching expression
1222
 */
1223

1224
WOQLQuery.prototype.split = function (inputVarName, separator, resultVarName) {
1✔
1225
  if (this.cursor['@type']) this.wrapCursorWithAnd();
1!
1226
  this.cursor['@type'] = 'Split';
1✔
1227
  this.cursor.string = this.cleanDataValue(inputVarName);
1✔
1228
  this.cursor.pattern = this.cleanDataValue(separator);
1✔
1229
  this.cursor.list = this.cleanDataValue(resultVarName);
1✔
1230
  return this;
1✔
1231
};
1232

1233
/**
1234
 * Matches if List includes Element
1235
 * @param {string|object|Var} element - Either a variable, IRI or any simple datatype
1236
 * @param {string|array|Var} list - List ([string, literal] or string*) Either a variable
1237
 * representing a list or a list of variables or literals
1238
 * @returns {WOQLQuery} A WOQLQuery which contains the List inclusion pattern matching expression
1239
 */
1240
WOQLQuery.prototype.member = function (element, list) {
1✔
1241
  if (this.cursor['@type']) this.wrapCursorWithAnd();
1!
1242
  this.cursor['@type'] = 'Member';
1✔
1243
  this.cursor.member = this.cleanObject(element);
1✔
1244
  this.cursor.list = this.valueList(list);
1✔
1245
  return this;
1✔
1246
};
1247

1248
/**
1249
 * takes a variable number of string arguments and concatenates them into a single string
1250
 * @param {array|string|Var} varList -  a variable representing a list or a list of variables or
1251
 * strings - variables can be embedded in the string if they do not contain spaces
1252
 * @param {string|Var}  resultVarName - A variable or string containing the output string
1253
 * @returns {WOQLQuery} A WOQLQuery which contains the Concatenation pattern matching expression
1254
 */
1255

1256
WOQLQuery.prototype.concat = function (varList, resultVarName) {
1✔
1257
  if (typeof varList === 'string') {
1!
1258
    const slist = varList.split(/(v:)/);
1✔
1259
    const nlist = [];
1✔
1260
    if (slist[0]) nlist.push(slist[0]);
1!
1261
    for (let i = 1; i < slist.length; i += 2) {
1✔
1262
      if (slist[i]) {
2!
1263
        if (slist[i] === 'v:') {
2!
1264
          const slist2 = slist[i + 1].split(/([^\w_])/);
2✔
1265
          const x = slist2.shift();
2✔
1266
          nlist.push(`v:${x}`);
2✔
1267
          const rest = slist2.join('');
2✔
1268
          if (rest) nlist.push(rest);
2✔
1269
        }
1270
      }
1271
    }
1272
    varList = nlist;
1✔
1273
  }
1274
  if (Array.isArray(varList)) {
1!
1275
    if (this.cursor['@type']) this.wrapCursorWithAnd();
1!
1276
    this.cursor['@type'] = 'Concatenate';
1✔
1277
    this.cursor.list = this.cleanDataValue(varList, true);
1✔
1278
    this.cursor.result = this.cleanDataValue(resultVarName);
1✔
1279
  }
1280
  return this;
1✔
1281
};
1282

1283
WOQLQuery.prototype.concatenate = WOQLQuery.prototype.concat;
1✔
1284

1285
/**
1286
 * Joins a list variable together (Input) into a string variable (Output) by glueing the strings
1287
 * together with Glue
1288
 * @param {string|array|Var} varList - a variable representing a list or a list of strings
1289
 * and / or variables
1290
 * @param {string|Var} glue - A variable (v:glue) or (glue) string representing the characters
1291
 * to put in between the joined strings in input
1292
 * @param {string|Var} resultVarName - A variable or string containing the output string
1293
 * @returns {WOQLQuery} A WOQLQuery which contains the Join pattern matching expression
1294
 */
1295
WOQLQuery.prototype.join = function (varList, glue, resultVarName) {
1✔
1296
  if (this.cursor['@type']) this.wrapCursorWithAnd();
1!
1297
  this.cursor['@type'] = 'Join';
1✔
1298
  this.cursor.list = this.cleanDataValue(varList);
1✔
1299
  this.cursor.separator = this.cleanDataValue(glue);
1✔
1300
  this.cursor.result = this.cleanDataValue(resultVarName);
1✔
1301
  return this;
1✔
1302
};
1303

1304
/**
1305
 * computes the sum of the List of values passed. In contrast to other arithmetic functions,
1306
 * sum self-evaluates - it does not have to be passed to evaluate()
1307
 * @param {WOQLQuery} subquery -  a subquery or ([string or numeric]) - a list variable, or a
1308
 * list of variables or numeric literals
1309
 * @param {string|Var} total - the variable name with the sum result of the values in List
1310
 * @returns {WOQLQuery} - A WOQLQuery which contains the Sum expression
1311
 */
1312
WOQLQuery.prototype.sum = function (subquery, total) {
1✔
1313
  if (this.cursor['@type']) this.wrapCursorWithAnd();
×
1314
  this.cursor['@type'] = 'Sum';
×
1315
  this.cursor.list = this.cleanDataValue(subquery);
×
1316
  this.cursor.result = this.cleanObject(total);
×
1317
  return this;
×
1318
};
1319

1320
/**
1321
 *
1322
 * Specifies an offset position in the results to start listing results from
1323
 * @param {number|string|Var} start - A variable that refers to an interger or an integer literal
1324
 * @param {WOQLQuery} [subquery] - WOQL Query object, you can pass a subquery as an argument
1325
 * or a chained query
1326
 * @returns {WOQLQuery} A WOQLQuery whose results will be returned starting from
1327
 * the specified offset
1328
 */
1329

1330
WOQLQuery.prototype.start = function (start, subquery) {
1✔
1331
  // if (start && start === 'args') return ['start', 'query']
1332
  if (this.cursor['@type']) this.wrapCursorWithAnd();
2!
1333
  this.cursor['@type'] = 'Start';
2✔
1334
  this.cursor.start = start;
2✔
1335
  return this.addSubQuery(subquery);
2✔
1336
};
1337

1338
/**
1339
 * Specifies a maximum number of results that will be returned from the subquery
1340
 * @param {number|string} limit - A variable that refers to an non-negative integer or a
1341
 * non-negative integer
1342
 * @param {WOQLQuery} [subquery] - A subquery whose results will be limited
1343
 * @returns {WOQLQuery} A WOQLQuery whose results will be returned starting from
1344
 * the specified offset
1345
 */
1346

1347
WOQLQuery.prototype.limit = function (limit, subquery) {
1✔
1348
  if (this.cursor['@type']) this.wrapCursorWithAnd();
6!
1349
  this.cursor['@type'] = 'Limit';
6✔
1350
  this.cursor.limit = limit;
6✔
1351
  return this.addSubQuery(subquery);
6✔
1352
};
1353

1354
/**
1355
 * Matches the regular expression defined in Patern against the Test string, to produce
1356
 * the matched patterns in Matches
1357
 * @param {string} pattern - string or variable using normal PCRE regular expression syntax with
1358
 * the exception that special characters have to be escaped twice (to enable transport in JSONLD)
1359
 * @param {string|Var} inputVarName - string or variable containing the string to be tested for
1360
 * patterns with the regex
1361
 * @param {string|array|object|Var} resultVarList - variable representing the list of matches
1362
 * or a list of strings or variables
1363
 * @returns {WOQLQuery} A WOQLQuery which contains the Regular Expression pattern
1364
 * matching expression
1365
 */
1366

1367
WOQLQuery.prototype.re = function (pattern, inputVarName, resultVarList) {
1✔
1368
  if (this.cursor['@type']) this.wrapCursorWithAnd();
1!
1369
  this.cursor['@type'] = 'Regexp';
1✔
1370
  this.cursor.pattern = this.cleanDataValue(pattern);
1✔
1371
  this.cursor.string = this.cleanDataValue(inputVarName);
1✔
1372
  this.cursor.result = this.cleanDataValue(resultVarList);
1✔
1373
  return this;
1✔
1374
};
1375

1376
WOQLQuery.prototype.regexp = WOQLQuery.prototype.re;
1✔
1377

1378
/**
1379
 * Calculates the length of the list in va and stores it in vb
1380
 * @param {string|array} inputVarList - Either a variable representing a list or a list of
1381
 * variables or literals
1382
 * @param {string|Var} resultVarName -  A variable in which the length of the list is stored or
1383
 * the length of the list as a non-negative integer
1384
 * @returns {WOQLQuery} A WOQLQuery which contains the Length pattern matching expression
1385
 */
1386
WOQLQuery.prototype.length = function (inputVarList, resultVarName) {
1✔
1387
  if (this.cursor['@type']) this.wrapCursorWithAnd();
×
1388
  this.cursor['@type'] = 'Length';
×
1389
  this.cursor.list = this.cleanDataValue(inputVarList);
×
1390
  if (typeof vb === 'number') {
×
1391
    this.cursor.length = this.cleanObject(resultVarName, 'xsd:nonNegativeInteger');
×
1392
  } else if (typeof vb === 'string') {
×
1393
    this.cursor.length = this.varj(resultVarName);
×
1394
  }
1395
  return this;
×
1396
};
1397

1398
/**
1399
 *
1400
 * Logical negation of the contained subquery - if the subquery matches, the query
1401
 * will fail to match
1402
 * @param {string | WOQLQuery} [subquery] -  A subquery which will be negated
1403
 * @returns {WOQLQuery} A WOQLQuery object containing the negated sub Query
1404
 */
1405
WOQLQuery.prototype.not = function (subquery) {
1✔
1406
  if (this.cursor['@type']) this.wrapCursorWithAnd();
3!
1407
  this.cursor['@type'] = 'Not';
3✔
1408
  return this.addSubQuery(subquery);
3✔
1409
};
1410

1411
/**
1412
 * Results in one solution of the subqueries
1413
 * @param {string| WOQLQuery } [subquery] - WOQL Query objects
1414
 * @returns {WOQLQuery} A WOQLQuery object containing the once sub Query
1415
 */
1416
WOQLQuery.prototype.once = function (subquery) {
1✔
1417
  // if (query && query === 'args') return ['query']
1418
  if (this.cursor['@type']) this.wrapCursorWithAnd();
×
1419
  this.cursor['@type'] = 'Once';
×
1420
  return this.addSubQuery(subquery);
×
1421
};
1422

1423
/**
1424
 * Runs the query without backtracking on side-effects
1425
 * @param {string| WOQLQuery } [subquery] - WOQL Query objects
1426
 * @returns {WOQLQuery} A WOQLQuery object containing the immediately sub Query
1427
 */
1428
WOQLQuery.prototype.immediately = function (query) {
1✔
1429
  if (this.cursor['@type']) this.wrapCursorWithAnd();
×
1430
  this.cursor['@type'] = 'Immediately';
×
1431
  return this.addSubQuery(query);
×
1432
};
1433

1434
/**
1435
 * Creates a count of the results of the query
1436
 * @param {string|number|Var} countVarName - variable or integer count
1437
 * @param {WOQLQuery} [subquery]
1438
 * @returns {WOQLQuery} A WOQLQuery object containing the count sub Query
1439
 */
1440
WOQLQuery.prototype.count = function (countVarName, subquery) {
1✔
1441
  if (this.cursor['@type']) this.wrapCursorWithAnd();
×
1442
  this.cursor['@type'] = 'Count';
×
1443
  this.cursor.count = this.cleanObject(countVarName);
×
1444
  return this.addSubQuery(subquery);
×
1445
};
1446

1447
/**
1448
 * Casts the value of Input to a new value of type Type and stores the result in CastVar
1449
 * @param {string|number|object|Var} varName - Either a single variable or a
1450
 * literal of any basic type
1451
 * @param {string|Var} varType - Either a variable or a basic datatype (xsd / xdd)
1452
 * @param {string|Var} resultVarName - save the return variable
1453
 * @returns {WOQLQuery} A WOQLQuery which contains the casting expression
1454
 */
1455

1456
WOQLQuery.prototype.typecast = function (varName, varType, resultVarName) {
1✔
1457
  if (this.cursor['@type']) this.wrapCursorWithAnd();
2!
1458
  this.cursor['@type'] = 'Typecast';
2✔
1459
  this.cursor.value = this.cleanObject(varName);
2✔
1460
  this.cursor.type = this.cleanNodeValue(varType);
2✔
1461
  this.cursor.result = this.cleanObject(resultVarName);
2✔
1462
  return this;
2✔
1463
};
1464

1465
WOQLQuery.prototype.cast = WOQLQuery.prototype.typecast;
1✔
1466

1467
/**
1468
 * Orders the results of the contained subquery by a precedence list of variables
1469
 * @param  {...string|...Var|...array} orderedVarlist - A sequence of variables,
1470
 * by which to order the results,
1471
 * each optionally followed by either “asc” or “desc” to represent order as a list, by default
1472
 * it will sort the variable in ascending order
1473
 * @returns  {WOQLQuery} A WOQLQuery which contains the ordering expression
1474
 */
1475
WOQLQuery.prototype.order_by = function (...orderedVarlist) {
6✔
1476
  // if (orderedVarlist && orderedVarlist[0] === 'args')
1477
  // return ['variable_ordering', 'query']
1478
  if (this.cursor['@type']) this.wrapCursorWithAnd();
2!
1479
  this.cursor['@type'] = 'OrderBy';
2✔
1480
  this.cursor.ordering = [];
2✔
1481

1482
  if (!orderedVarlist || orderedVarlist.length === 0) {
2!
1483
    return this.parameterError(
×
1484
      'Order by must be passed at least one variables to order the query',
1485
    );
1486
  }
1487
  const embedquery = typeof orderedVarlist[orderedVarlist.length - 1] === 'object'
2!
1488
    && orderedVarlist[orderedVarlist.length - 1].json
1489
    ? orderedVarlist.pop()
1490
    : false;
1491

1492
  for (let i = 0; i < orderedVarlist.length; i++) {
2✔
1493
    let obj;
6✔
1494
    if ((typeof orderedVarlist[i] === 'string' || orderedVarlist[i] instanceof Var) && orderedVarlist[i] !== '') {
6!
1495
      obj = {
6✔
1496
        '@type': 'OrderTemplate',
1497
        variable: this.rawVar(orderedVarlist[i]),
1498
        order: 'asc',
1499
      };
1500
    } else if (orderedVarlist[i].length === 2 && orderedVarlist[i][1] === 'asc') {
×
1501
      obj = {
×
1502
        '@type': 'OrderTemplate',
1503
        variable: this.rawVar(orderedVarlist[i][0]),
1504
        order: 'asc',
1505
      };
1506
    } else if (orderedVarlist[i].length === 2 && orderedVarlist[i][1] === 'desc') {
×
1507
      obj = {
×
1508
        '@type': 'OrderTemplate',
1509
        variable: this.rawVar(orderedVarlist[i][0]),
1510
        order: 'desc',
1511
      };
1512
    }
1513

1514
    if (obj) this.cursor.ordering.push(obj);
6!
1515
  }
1516
  return this.addSubQuery(embedquery);
2✔
1517
};
1518

1519
/**
1520
 *
1521
 * Groups the results of the contained subquery on the basis of identical values for Groupvars,
1522
 * extracts the patterns defined in PatternVars and stores the results in GroupedVar
1523
 * @param {array|string|Var} gvarlist - Either a single variable or an array of variables
1524
 * @param {array|string|Var} groupedvar - Either a single variable or an array of variables
1525
 * @param {string|Var} output - output variable name
1526
 * @param {WOQLQuery} [groupquery] - The query whose results will be grouped
1527
 * @returns {WOQLQuery} A WOQLQuery which contains the grouping expression
1528
 */
1529

1530
WOQLQuery.prototype.group_by = function (gvarlist, groupedvar, output, groupquery) {
1✔
1531
  // if (gvarlist && gvarlist === 'args')
1532
  // return ['group_by', 'group_template', 'grouped', 'query']
1533
  if (this.cursor['@type']) this.wrapCursorWithAnd();
3!
1534
  this.cursor['@type'] = 'GroupBy';
3✔
1535
  this.cursor.group_by = [];
3✔
1536

1537
  if (typeof gvarlist === 'string' || gvarlist instanceof Var) gvarlist = [gvarlist];
3✔
1538
  this.cursor.group_by = this.rawVarList(gvarlist);
3✔
1539
  if (typeof groupedvar === 'string' || groupedvar instanceof Var) groupedvar = [groupedvar];
3✔
1540
  this.cursor.template = this.rawVarList(groupedvar);
3✔
1541
  this.cursor.grouped = this.varj(output);
3✔
1542
  return this.addSubQuery(groupquery);
3✔
1543
};
1544

1545
/**
1546
 * A function that always matches, always returns true
1547
 * @returns {WOQLQuery} A WOQLQuery object containing the true value that will match any pattern
1548
 */
1549
WOQLQuery.prototype.true = function () {
1✔
1550
  this.cursor['@type'] = 'True';
×
1551
  return this;
×
1552
};
1553

1554
/**
1555
 * Performs a path regular expression match on the graph
1556
 * @param {string|Var} subject -  An IRI or variable that refers to an IRI representing the subject,
1557
 * i.e. the starting point of the path
1558
 * @param {string} pattern -(string) - A path regular expression describing a pattern through
1559
 * multiple edges of the graph (see: https://terminusdb.com/docs/path-query-reference-guide)
1560
 * @param {string|Var} object - An IRI or variable that refers to an IRI representing the object,
1561
 * i.e. ending point of the path
1562
 * @param {string|Var} [resultVarName] - A variable in which the actual paths
1563
 * traversed will be stored
1564
 * @returns {WOQLQuery} - A WOQLQuery which contains the path regular expression matching expression
1565
 */
1566

1567
WOQLQuery.prototype.path = function (subject, pattern, object, resultVarName) {
1✔
1568
  if (this.cursor['@type']) this.wrapCursorWithAnd();
5!
1569
  this.cursor['@type'] = 'Path';
5✔
1570
  this.cursor.subject = this.cleanSubject(subject);
5✔
1571
  if (typeof pattern === 'string') pattern = this.compilePathPattern(pattern);
5!
1572
  this.cursor.pattern = pattern;
5✔
1573
  this.cursor.object = this.cleanObject(object);
5✔
1574
  if (typeof resultVarName !== 'undefined') {
5✔
1575
    this.cursor.path = this.varj(resultVarName);
4✔
1576
  }
1577
  return this;
5✔
1578
};
1579

1580
/**
1581
 * Extract the value of a key in a bound document.
1582
 * @param {string|Var} document - Document which is being accessed.
1583
 * @param {string|Var} field - The field from which the document which is being accessed.
1584
 * @param {string|Var} value - The value for the document and field.
1585
 * @returns {WOQLQuery} A WOQLQuery which contains the a dot Statement
1586
 */
1587

1588
WOQLQuery.prototype.dot = function (document, field, value) {
1✔
1589
  if (this.cursor['@type']) this.wrapCursorWithAnd();
×
1590
  this.cursor['@type'] = 'Dot';
×
1591
  this.cursor.document = this.expandValueVariable(document);
×
1592
  this.cursor.field = this.cleanDataValue(field, 'xsd:string');
×
1593
  this.cursor.value = this.expandValueVariable(value);
×
1594
  return this;
×
1595
};
1596

1597
/**
1598
 * Calculates the size in bytes of the contents of the resource identified in ResourceID
1599
 * @param {string|Var} resourceId - A valid resource identifier string (can refer to any graph /
1600
 * branch / commit / db)
1601
 * @param {string|Var} resultVarName - The variable name
1602
 */
1603

1604
WOQLQuery.prototype.size = function (resourceId, resultVarName) {
1✔
1605
  if (this.cursor['@type']) this.wrapCursorWithAnd();
×
1606
  this.cursor['@type'] = 'Size';
×
1607
  this.cursor.resource = this.cleanGraph(resourceId);
×
1608
  this.cursor.size = this.varj(resultVarName);
×
1609
  return this;
×
1610
};
1611

1612
/**
1613
 *
1614
 * Calculates the number of triples of the contents of the resource identified in ResourceID
1615
 * @param {string|Var} resourceId - A valid resource identifier string (can refer to any graph /
1616
 * branch / commit / db)
1617
 * @param {string|number|Var} tripleCount - An integer literal with the size in bytes or a
1618
 * variable containing that integer
1619
 * @returns {WOQLQuery} A WOQLQuery which contains the size expression
1620
 */
1621
WOQLQuery.prototype.triple_count = function (resourceId, TripleCount) {
1✔
1622
  if (this.cursor['@type']) this.wrapCursorWithAnd();
×
1623
  this.cursor['@type'] = 'TripleCount';
×
1624
  this.cursor.resource = this.cleanGraph(resourceId);
×
1625
  this.cursor.count = this.varj(TripleCount);
×
1626
  return this;
×
1627
};
1628

1629
/**
1630
 * Returns true if 'elementId' is of type 'elementType', according to the current DB schema
1631
 * @param {string|Var} elementId - the id of a schema graph element
1632
 * @param {string|Var} elementType - the element type
1633
 * @returns {WOQLQuery} A WOQLQuery object containing the type_of pattern matching rule
1634
 */
1635

1636
WOQLQuery.prototype.type_of = function (elementId, elementType) {
1✔
1637
  if (!elementId || !elementType) return this.parameterError('type_of takes two parameters, both values');
3!
1638
  if (this.cursor['@type']) this.wrapCursorWithAnd();
3!
1639
  this.cursor['@type'] = 'TypeOf';
3✔
1640
  this.cursor.value = this.cleanObject(elementId);
3✔
1641
  this.cursor.type = this.cleanSubject(elementType);
3✔
1642
  return this;
3✔
1643
};
1644

1645
module.exports = WOQLQuery;
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc