n3 1.13.0 → 1.16.0
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.
- package/README.md +7 -2
- package/browser/n3.min.js +1 -1
- package/lib/N3DataFactory.js +6 -6
- package/lib/N3Lexer.js +25 -27
- package/lib/N3Store.js +32 -70
- package/lib/N3Util.js +1 -1
- package/package.json +1 -1
- package/src/N3DataFactory.js +6 -6
- package/src/N3Lexer.js +20 -9
- package/src/N3Store.js +34 -88
- package/src/N3Util.js +1 -1
package/lib/N3DataFactory.js
CHANGED
|
@@ -48,12 +48,6 @@ class Term {
|
|
|
48
48
|
|
|
49
49
|
get value() {
|
|
50
50
|
return this.id;
|
|
51
|
-
} // ### Implement hashCode for Immutable.js, since we implement `equals`
|
|
52
|
-
// https://immutable-js.com/docs/v4.0.0/ValueObject/#hashCode()
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
get hashCode() {
|
|
56
|
-
return 0;
|
|
57
51
|
} // ### Returns whether this object represents the same term as the other
|
|
58
52
|
|
|
59
53
|
|
|
@@ -63,6 +57,12 @@ class Term {
|
|
|
63
57
|
if (other instanceof Term) return this.id === other.id; // Otherwise, compare term type and value
|
|
64
58
|
|
|
65
59
|
return !!other && this.termType === other.termType && this.value === other.value;
|
|
60
|
+
} // ### Implement hashCode for Immutable.js, since we implement `equals`
|
|
61
|
+
// https://immutable-js.com/docs/v4.0.0/ValueObject/#hashCode()
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
hashCode() {
|
|
65
|
+
return 0;
|
|
66
66
|
} // ### Returns a plain object representation of this term
|
|
67
67
|
|
|
68
68
|
|
package/lib/N3Lexer.js
CHANGED
|
@@ -109,7 +109,7 @@ class N3Lexer {
|
|
|
109
109
|
_tokenizeToEnd(callback, inputFinished) {
|
|
110
110
|
// Continue parsing as far as possible; the loop will return eventually
|
|
111
111
|
let input = this._input;
|
|
112
|
-
|
|
112
|
+
let currentLineLength = input.length;
|
|
113
113
|
|
|
114
114
|
while (true) {
|
|
115
115
|
// Count and skip whitespace lines
|
|
@@ -117,14 +117,10 @@ class N3Lexer {
|
|
|
117
117
|
|
|
118
118
|
while (whiteSpaceMatch = this._newline.exec(input)) {
|
|
119
119
|
// Try to find a comment
|
|
120
|
-
if (
|
|
121
|
-
line: this._line,
|
|
122
|
-
type: 'comment',
|
|
123
|
-
value: comment[1],
|
|
124
|
-
prefix: ''
|
|
125
|
-
}); // Advance the input
|
|
120
|
+
if (this._comments && (comment = this._comment.exec(whiteSpaceMatch[0]))) emitToken('comment', comment[1], '', this._line, whiteSpaceMatch[0].length); // Advance the input
|
|
126
121
|
|
|
127
122
|
input = input.substr(whiteSpaceMatch[0].length, input.length);
|
|
123
|
+
currentLineLength = input.length;
|
|
128
124
|
this._line++;
|
|
129
125
|
} // Skip whitespace on current line
|
|
130
126
|
|
|
@@ -135,18 +131,9 @@ class N3Lexer {
|
|
|
135
131
|
// If the input is finished, emit EOF
|
|
136
132
|
if (inputFinished) {
|
|
137
133
|
// Try to find a final comment
|
|
138
|
-
if (
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
value: comment[1],
|
|
142
|
-
prefix: ''
|
|
143
|
-
});
|
|
144
|
-
callback(input = null, {
|
|
145
|
-
line: this._line,
|
|
146
|
-
type: 'eof',
|
|
147
|
-
value: '',
|
|
148
|
-
prefix: ''
|
|
149
|
-
});
|
|
134
|
+
if (this._comments && (comment = this._comment.exec(input))) emitToken('comment', comment[1], '', this._line, input.length);
|
|
135
|
+
input = null;
|
|
136
|
+
emitToken('eof', '', '', this._line, 0);
|
|
150
137
|
}
|
|
151
138
|
|
|
152
139
|
return this._input = input;
|
|
@@ -376,17 +363,28 @@ class N3Lexer {
|
|
|
376
363
|
} // Emit the parsed token
|
|
377
364
|
|
|
378
365
|
|
|
379
|
-
const
|
|
380
|
-
|
|
381
|
-
type: type,
|
|
382
|
-
value: value,
|
|
383
|
-
prefix: prefix
|
|
384
|
-
};
|
|
385
|
-
callback(null, token);
|
|
366
|
+
const length = matchLength || match[0].length;
|
|
367
|
+
const token = emitToken(type, value, prefix, line, length);
|
|
386
368
|
this.previousToken = token;
|
|
387
369
|
this._previousMarker = type; // Advance to next part to tokenize
|
|
388
370
|
|
|
389
|
-
input = input.substr(
|
|
371
|
+
input = input.substr(length, input.length);
|
|
372
|
+
} // Emits the token through the callback
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
function emitToken(type, value, prefix, line, length) {
|
|
376
|
+
const start = input ? currentLineLength - input.length : currentLineLength;
|
|
377
|
+
const end = start + length;
|
|
378
|
+
const token = {
|
|
379
|
+
type,
|
|
380
|
+
value,
|
|
381
|
+
prefix,
|
|
382
|
+
line,
|
|
383
|
+
start,
|
|
384
|
+
end
|
|
385
|
+
};
|
|
386
|
+
callback(null, token);
|
|
387
|
+
return token;
|
|
390
388
|
} // Signals the syntax error through the callback
|
|
391
389
|
|
|
392
390
|
|
package/lib/N3Store.js
CHANGED
|
@@ -92,17 +92,15 @@ class N3Store {
|
|
|
92
92
|
// `name0`, `name1`, and `name2` are the names of the keys at each level,
|
|
93
93
|
// used when reconstructing the resulting quad
|
|
94
94
|
// (for instance: _subject_, _predicate_, and _object_).
|
|
95
|
-
// Finally, `
|
|
96
|
-
// If `callback` is given, each result is passed through it
|
|
97
|
-
// and iteration halts when it returns truthy for any quad.
|
|
98
|
-
// If instead `array` is given, each result is added to the array.
|
|
95
|
+
// Finally, `graphId` will be the graph of the created quads.
|
|
99
96
|
|
|
100
97
|
|
|
101
|
-
_findInIndex(index0, key0, key1, key2, name0, name1, name2,
|
|
98
|
+
*_findInIndex(index0, key0, key1, key2, name0, name1, name2, graphId) {
|
|
102
99
|
let tmp, index1, index2; // Depending on the number of variables, keys or reverse index are faster
|
|
103
100
|
|
|
104
101
|
const varCount = !key0 + !key1 + !key2,
|
|
105
|
-
entityKeys = varCount > 1 ? Object.keys(this._ids) : this._entities;
|
|
102
|
+
entityKeys = varCount > 1 ? Object.keys(this._ids) : this._entities;
|
|
103
|
+
const graph = (0, _N3DataFactory.termFromId)(graphId, this._factory); // If a key is specified, use only that part of index 0.
|
|
106
104
|
|
|
107
105
|
if (key0) (tmp = index0, index0 = {})[key0] = tmp[key0];
|
|
108
106
|
|
|
@@ -129,17 +127,12 @@ class N3Store {
|
|
|
129
127
|
parts[name0] = (0, _N3DataFactory.termFromId)(entity0, this._factory);
|
|
130
128
|
parts[name1] = (0, _N3DataFactory.termFromId)(entity1, this._factory);
|
|
131
129
|
parts[name2] = (0, _N3DataFactory.termFromId)(entityKeys[values[l]], this._factory);
|
|
132
|
-
|
|
133
|
-
const quad = this._factory.quad(parts.subject, parts.predicate, parts.object, (0, _N3DataFactory.termFromId)(graph, this._factory));
|
|
134
|
-
|
|
135
|
-
if (array) array.push(quad);else if (callback(quad)) return true;
|
|
130
|
+
yield this._factory.quad(parts.subject, parts.predicate, parts.object, graph);
|
|
136
131
|
}
|
|
137
132
|
}
|
|
138
133
|
}
|
|
139
134
|
}
|
|
140
135
|
}
|
|
141
|
-
|
|
142
|
-
return array;
|
|
143
136
|
} // ### `_loop` executes the callback on all keys of index 0
|
|
144
137
|
|
|
145
138
|
|
|
@@ -288,13 +281,17 @@ class N3Store {
|
|
|
288
281
|
delete(quad) {
|
|
289
282
|
this.removeQuad(quad);
|
|
290
283
|
return this;
|
|
291
|
-
} // ### `has` determines whether a dataset includes a certain quad.
|
|
292
|
-
// Returns true or false as appropriate.
|
|
284
|
+
} // ### `has` determines whether a dataset includes a certain quad or quad pattern.
|
|
293
285
|
|
|
294
286
|
|
|
295
|
-
has(
|
|
296
|
-
|
|
297
|
-
|
|
287
|
+
has(subjectOrQuad, predicate, object, graph) {
|
|
288
|
+
if (subjectOrQuad && subjectOrQuad.subject) ({
|
|
289
|
+
subject: subjectOrQuad,
|
|
290
|
+
predicate,
|
|
291
|
+
object,
|
|
292
|
+
graph
|
|
293
|
+
} = subjectOrQuad);
|
|
294
|
+
return !this.readQuads(subjectOrQuad, predicate, object, graph).next().done;
|
|
298
295
|
} // ### `import` adds a stream of quads to the store
|
|
299
296
|
|
|
300
297
|
|
|
@@ -356,7 +353,7 @@ class N3Store {
|
|
|
356
353
|
});
|
|
357
354
|
|
|
358
355
|
stream._read = () => {
|
|
359
|
-
for (const quad of this.
|
|
356
|
+
for (const quad of this.readQuads(subject, predicate, object, graph)) stream.push(quad);
|
|
360
357
|
|
|
361
358
|
stream.push(null);
|
|
362
359
|
};
|
|
@@ -372,19 +369,24 @@ class N3Store {
|
|
|
372
369
|
|
|
373
370
|
|
|
374
371
|
getQuads(subject, predicate, object, graph) {
|
|
372
|
+
return [...this.readQuads(subject, predicate, object, graph)];
|
|
373
|
+
} // ### `readQuads` returns an generator of quads matching a pattern.
|
|
374
|
+
// Setting any field to `undefined` or `null` indicates a wildcard.
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+
*readQuads(subject, predicate, object, graph) {
|
|
375
378
|
// Convert terms to internal string representation
|
|
376
379
|
subject = subject && (0, _N3DataFactory.termToId)(subject);
|
|
377
380
|
predicate = predicate && (0, _N3DataFactory.termToId)(predicate);
|
|
378
381
|
object = object && (0, _N3DataFactory.termToId)(object);
|
|
379
382
|
graph = graph && (0, _N3DataFactory.termToId)(graph);
|
|
380
383
|
|
|
381
|
-
const
|
|
382
|
-
graphs = this._getGraphs(graph),
|
|
384
|
+
const graphs = this._getGraphs(graph),
|
|
383
385
|
ids = this._ids;
|
|
384
386
|
|
|
385
387
|
let content, subjectId, predicateId, objectId; // Translate IRIs to internal index keys.
|
|
386
388
|
|
|
387
|
-
if (isString(subject) && !(subjectId = ids[subject]) || isString(predicate) && !(predicateId = ids[predicate]) || isString(object) && !(objectId = ids[object])) return
|
|
389
|
+
if (isString(subject) && !(subjectId = ids[subject]) || isString(predicate) && !(predicateId = ids[predicate]) || isString(object) && !(objectId = ids[object])) return;
|
|
388
390
|
|
|
389
391
|
for (const graphId in graphs) {
|
|
390
392
|
// Only if the specified graph contains triples, there can be results
|
|
@@ -392,16 +394,14 @@ class N3Store {
|
|
|
392
394
|
// Choose the optimal index, based on what fields are present
|
|
393
395
|
if (subjectId) {
|
|
394
396
|
if (objectId) // If subject and object are given, the object index will be the fastest
|
|
395
|
-
this._findInIndex(content.objects, objectId, subjectId, predicateId, 'object', 'subject', 'predicate', graphId, null,
|
|
396
|
-
this._findInIndex(content.subjects, subjectId, predicateId, null, 'subject', 'predicate', 'object', graphId, null,
|
|
397
|
+
yield* this._findInIndex(content.objects, objectId, subjectId, predicateId, 'object', 'subject', 'predicate', graphId, null, true);else // If only subject and possibly predicate are given, the subject index will be the fastest
|
|
398
|
+
yield* this._findInIndex(content.subjects, subjectId, predicateId, null, 'subject', 'predicate', 'object', graphId, null, true);
|
|
397
399
|
} else if (predicateId) // If only predicate and possibly object are given, the predicate index will be the fastest
|
|
398
|
-
this._findInIndex(content.predicates, predicateId, objectId, null, 'predicate', 'object', 'subject', graphId, null,
|
|
399
|
-
this._findInIndex(content.objects, objectId, null, null, 'object', 'subject', 'predicate', graphId, null,
|
|
400
|
-
this._findInIndex(content.subjects, null, null, null, 'subject', 'predicate', 'object', graphId, null,
|
|
400
|
+
yield* this._findInIndex(content.predicates, predicateId, objectId, null, 'predicate', 'object', 'subject', graphId, null, true);else if (objectId) // If only object is given, the object index will be the fastest
|
|
401
|
+
yield* this._findInIndex(content.objects, objectId, null, null, 'object', 'subject', 'predicate', graphId, null, true);else // If nothing is given, iterate subjects and predicates first
|
|
402
|
+
yield* this._findInIndex(content.subjects, null, null, null, 'subject', 'predicate', 'object', graphId, null, true);
|
|
401
403
|
}
|
|
402
404
|
}
|
|
403
|
-
|
|
404
|
-
return quads;
|
|
405
405
|
} // ### `match` returns a new dataset that is comprised of all quads in the current instance matching the given arguments.
|
|
406
406
|
// The logic described in Quad Matching is applied for each quad in this dataset to check if it should be included in the output dataset.
|
|
407
407
|
// Note: This method always returns a new DatasetCore, even if that dataset contains no quads.
|
|
@@ -480,45 +480,7 @@ class N3Store {
|
|
|
480
480
|
|
|
481
481
|
|
|
482
482
|
some(callback, subject, predicate, object, graph) {
|
|
483
|
-
|
|
484
|
-
subject = subject && (0, _N3DataFactory.termToId)(subject);
|
|
485
|
-
predicate = predicate && (0, _N3DataFactory.termToId)(predicate);
|
|
486
|
-
object = object && (0, _N3DataFactory.termToId)(object);
|
|
487
|
-
graph = graph && (0, _N3DataFactory.termToId)(graph);
|
|
488
|
-
|
|
489
|
-
const graphs = this._getGraphs(graph),
|
|
490
|
-
ids = this._ids;
|
|
491
|
-
|
|
492
|
-
let content, subjectId, predicateId, objectId; // Translate IRIs to internal index keys.
|
|
493
|
-
|
|
494
|
-
if (isString(subject) && !(subjectId = ids[subject]) || isString(predicate) && !(predicateId = ids[predicate]) || isString(object) && !(objectId = ids[object])) return false;
|
|
495
|
-
|
|
496
|
-
for (const graphId in graphs) {
|
|
497
|
-
// Only if the specified graph contains triples, there can be results
|
|
498
|
-
if (content = graphs[graphId]) {
|
|
499
|
-
// Choose the optimal index, based on what fields are present
|
|
500
|
-
if (subjectId) {
|
|
501
|
-
if (objectId) {
|
|
502
|
-
// If subject and object are given, the object index will be the fastest
|
|
503
|
-
if (this._findInIndex(content.objects, objectId, subjectId, predicateId, 'object', 'subject', 'predicate', graphId, callback, null)) return true;
|
|
504
|
-
} else // If only subject and possibly predicate are given, the subject index will be the fastest
|
|
505
|
-
if (this._findInIndex(content.subjects, subjectId, predicateId, null, 'subject', 'predicate', 'object', graphId, callback, null)) return true;
|
|
506
|
-
} else if (predicateId) {
|
|
507
|
-
// If only predicate and possibly object are given, the predicate index will be the fastest
|
|
508
|
-
if (this._findInIndex(content.predicates, predicateId, objectId, null, 'predicate', 'object', 'subject', graphId, callback, null)) {
|
|
509
|
-
return true;
|
|
510
|
-
}
|
|
511
|
-
} else if (objectId) {
|
|
512
|
-
// If only object is given, the object index will be the fastest
|
|
513
|
-
if (this._findInIndex(content.objects, objectId, null, null, 'object', 'subject', 'predicate', graphId, callback, null)) {
|
|
514
|
-
return true;
|
|
515
|
-
}
|
|
516
|
-
} else // If nothing is given, iterate subjects and predicates first
|
|
517
|
-
if (this._findInIndex(content.subjects, null, null, null, 'subject', 'predicate', 'object', graphId, callback, null)) {
|
|
518
|
-
return true;
|
|
519
|
-
}
|
|
520
|
-
}
|
|
521
|
-
}
|
|
483
|
+
for (const quad of this.readQuads(subject, predicate, object, graph)) if (callback(quad)) return true;
|
|
522
484
|
|
|
523
485
|
return false;
|
|
524
486
|
} // ### `getSubjects` returns all subjects that match the pattern.
|
|
@@ -772,7 +734,7 @@ class N3Store {
|
|
|
772
734
|
|
|
773
735
|
|
|
774
736
|
*[Symbol.iterator]() {
|
|
775
|
-
yield* this.
|
|
737
|
+
yield* this.readQuads();
|
|
776
738
|
}
|
|
777
739
|
|
|
778
740
|
} // Determines whether the argument is a string
|
|
@@ -825,7 +787,7 @@ class DatasetCoreAndReadableStream extends _readableStream.Readable {
|
|
|
825
787
|
}
|
|
826
788
|
|
|
827
789
|
_read() {
|
|
828
|
-
for (const quad of this
|
|
790
|
+
for (const quad of this) this.push(quad);
|
|
829
791
|
|
|
830
792
|
this.push(null);
|
|
831
793
|
}
|
|
@@ -847,7 +809,7 @@ class DatasetCoreAndReadableStream extends _readableStream.Readable {
|
|
|
847
809
|
}
|
|
848
810
|
|
|
849
811
|
*[Symbol.iterator]() {
|
|
850
|
-
yield* this.
|
|
812
|
+
yield* this._filtered || this.n3Store.readQuads(this.subject, this.predicate, this.object, this.graph);
|
|
851
813
|
}
|
|
852
814
|
|
|
853
815
|
}
|
package/lib/N3Util.js
CHANGED
package/package.json
CHANGED
package/src/N3DataFactory.js
CHANGED
|
@@ -35,12 +35,6 @@ export class Term {
|
|
|
35
35
|
return this.id;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
// ### Implement hashCode for Immutable.js, since we implement `equals`
|
|
39
|
-
// https://immutable-js.com/docs/v4.0.0/ValueObject/#hashCode()
|
|
40
|
-
get hashCode() {
|
|
41
|
-
return 0;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
38
|
// ### Returns whether this object represents the same term as the other
|
|
45
39
|
equals(other) {
|
|
46
40
|
// If both terms were created by this library,
|
|
@@ -52,6 +46,12 @@ export class Term {
|
|
|
52
46
|
this.value === other.value;
|
|
53
47
|
}
|
|
54
48
|
|
|
49
|
+
// ### Implement hashCode for Immutable.js, since we implement `equals`
|
|
50
|
+
// https://immutable-js.com/docs/v4.0.0/ValueObject/#hashCode()
|
|
51
|
+
hashCode() {
|
|
52
|
+
return 0;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
55
|
// ### Returns a plain object representation of this term
|
|
56
56
|
toJSON() {
|
|
57
57
|
return {
|
package/src/N3Lexer.js
CHANGED
|
@@ -78,16 +78,17 @@ export default class N3Lexer {
|
|
|
78
78
|
_tokenizeToEnd(callback, inputFinished) {
|
|
79
79
|
// Continue parsing as far as possible; the loop will return eventually
|
|
80
80
|
let input = this._input;
|
|
81
|
-
|
|
81
|
+
let currentLineLength = input.length;
|
|
82
82
|
while (true) {
|
|
83
83
|
// Count and skip whitespace lines
|
|
84
84
|
let whiteSpaceMatch, comment;
|
|
85
85
|
while (whiteSpaceMatch = this._newline.exec(input)) {
|
|
86
86
|
// Try to find a comment
|
|
87
|
-
if (
|
|
88
|
-
|
|
87
|
+
if (this._comments && (comment = this._comment.exec(whiteSpaceMatch[0])))
|
|
88
|
+
emitToken('comment', comment[1], '', this._line, whiteSpaceMatch[0].length);
|
|
89
89
|
// Advance the input
|
|
90
90
|
input = input.substr(whiteSpaceMatch[0].length, input.length);
|
|
91
|
+
currentLineLength = input.length;
|
|
91
92
|
this._line++;
|
|
92
93
|
}
|
|
93
94
|
// Skip whitespace on current line
|
|
@@ -99,9 +100,10 @@ export default class N3Lexer {
|
|
|
99
100
|
// If the input is finished, emit EOF
|
|
100
101
|
if (inputFinished) {
|
|
101
102
|
// Try to find a final comment
|
|
102
|
-
if (
|
|
103
|
-
|
|
104
|
-
|
|
103
|
+
if (this._comments && (comment = this._comment.exec(input)))
|
|
104
|
+
emitToken('comment', comment[1], '', this._line, input.length);
|
|
105
|
+
input = null;
|
|
106
|
+
emitToken('eof', '', '', this._line, 0);
|
|
105
107
|
}
|
|
106
108
|
return this._input = input;
|
|
107
109
|
}
|
|
@@ -345,14 +347,23 @@ export default class N3Lexer {
|
|
|
345
347
|
}
|
|
346
348
|
|
|
347
349
|
// Emit the parsed token
|
|
348
|
-
const
|
|
349
|
-
|
|
350
|
+
const length = matchLength || match[0].length;
|
|
351
|
+
const token = emitToken(type, value, prefix, line, length);
|
|
350
352
|
this.previousToken = token;
|
|
351
353
|
this._previousMarker = type;
|
|
354
|
+
|
|
352
355
|
// Advance to next part to tokenize
|
|
353
|
-
input = input.substr(
|
|
356
|
+
input = input.substr(length, input.length);
|
|
354
357
|
}
|
|
355
358
|
|
|
359
|
+
// Emits the token through the callback
|
|
360
|
+
function emitToken(type, value, prefix, line, length) {
|
|
361
|
+
const start = input ? currentLineLength - input.length : currentLineLength;
|
|
362
|
+
const end = start + length;
|
|
363
|
+
const token = { type, value, prefix, line, start, end };
|
|
364
|
+
callback(null, token);
|
|
365
|
+
return token;
|
|
366
|
+
}
|
|
356
367
|
// Signals the syntax error through the callback
|
|
357
368
|
function reportSyntaxError(self) { callback(self._syntaxError(/^\S*/.exec(input)[0])); }
|
|
358
369
|
}
|
package/src/N3Store.js
CHANGED
|
@@ -84,15 +84,13 @@ export default class N3Store {
|
|
|
84
84
|
// `name0`, `name1`, and `name2` are the names of the keys at each level,
|
|
85
85
|
// used when reconstructing the resulting quad
|
|
86
86
|
// (for instance: _subject_, _predicate_, and _object_).
|
|
87
|
-
// Finally, `
|
|
88
|
-
|
|
89
|
-
// and iteration halts when it returns truthy for any quad.
|
|
90
|
-
// If instead `array` is given, each result is added to the array.
|
|
91
|
-
_findInIndex(index0, key0, key1, key2, name0, name1, name2, graph, callback, array) {
|
|
87
|
+
// Finally, `graphId` will be the graph of the created quads.
|
|
88
|
+
*_findInIndex(index0, key0, key1, key2, name0, name1, name2, graphId) {
|
|
92
89
|
let tmp, index1, index2;
|
|
93
90
|
// Depending on the number of variables, keys or reverse index are faster
|
|
94
91
|
const varCount = !key0 + !key1 + !key2,
|
|
95
92
|
entityKeys = varCount > 1 ? Object.keys(this._ids) : this._entities;
|
|
93
|
+
const graph = termFromId(graphId, this._factory);
|
|
96
94
|
|
|
97
95
|
// If a key is specified, use only that part of index 0.
|
|
98
96
|
if (key0) (tmp = index0, index0 = {})[key0] = tmp[key0];
|
|
@@ -114,18 +112,12 @@ export default class N3Store {
|
|
|
114
112
|
parts[name0] = termFromId(entity0, this._factory);
|
|
115
113
|
parts[name1] = termFromId(entity1, this._factory);
|
|
116
114
|
parts[name2] = termFromId(entityKeys[values[l]], this._factory);
|
|
117
|
-
|
|
118
|
-
parts.subject, parts.predicate, parts.object, termFromId(graph, this._factory));
|
|
119
|
-
if (array)
|
|
120
|
-
array.push(quad);
|
|
121
|
-
else if (callback(quad))
|
|
122
|
-
return true;
|
|
115
|
+
yield this._factory.quad(parts.subject, parts.predicate, parts.object, graph);
|
|
123
116
|
}
|
|
124
117
|
}
|
|
125
118
|
}
|
|
126
119
|
}
|
|
127
120
|
}
|
|
128
|
-
return array;
|
|
129
121
|
}
|
|
130
122
|
|
|
131
123
|
// ### `_loop` executes the callback on all keys of index 0
|
|
@@ -274,11 +266,11 @@ export default class N3Store {
|
|
|
274
266
|
return this;
|
|
275
267
|
}
|
|
276
268
|
|
|
277
|
-
// ### `has` determines whether a dataset includes a certain quad.
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
return
|
|
269
|
+
// ### `has` determines whether a dataset includes a certain quad or quad pattern.
|
|
270
|
+
has(subjectOrQuad, predicate, object, graph) {
|
|
271
|
+
if (subjectOrQuad && subjectOrQuad.subject)
|
|
272
|
+
({ subject: subjectOrQuad, predicate, object, graph } = subjectOrQuad);
|
|
273
|
+
return !this.readQuads(subjectOrQuad, predicate, object, graph).next().done;
|
|
282
274
|
}
|
|
283
275
|
|
|
284
276
|
// ### `import` adds a stream of quads to the store
|
|
@@ -341,7 +333,7 @@ export default class N3Store {
|
|
|
341
333
|
const stream = new Readable({ objectMode: true });
|
|
342
334
|
|
|
343
335
|
stream._read = () => {
|
|
344
|
-
for (const quad of this.
|
|
336
|
+
for (const quad of this.readQuads(subject, predicate, object, graph))
|
|
345
337
|
stream.push(quad);
|
|
346
338
|
stream.push(null);
|
|
347
339
|
};
|
|
@@ -357,20 +349,26 @@ export default class N3Store {
|
|
|
357
349
|
// ### `getQuads` returns an array of quads matching a pattern.
|
|
358
350
|
// Setting any field to `undefined` or `null` indicates a wildcard.
|
|
359
351
|
getQuads(subject, predicate, object, graph) {
|
|
352
|
+
return [...this.readQuads(subject, predicate, object, graph)];
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// ### `readQuads` returns an generator of quads matching a pattern.
|
|
356
|
+
// Setting any field to `undefined` or `null` indicates a wildcard.
|
|
357
|
+
*readQuads(subject, predicate, object, graph) {
|
|
360
358
|
// Convert terms to internal string representation
|
|
361
359
|
subject = subject && termToId(subject);
|
|
362
360
|
predicate = predicate && termToId(predicate);
|
|
363
361
|
object = object && termToId(object);
|
|
364
362
|
graph = graph && termToId(graph);
|
|
365
363
|
|
|
366
|
-
const
|
|
364
|
+
const graphs = this._getGraphs(graph), ids = this._ids;
|
|
367
365
|
let content, subjectId, predicateId, objectId;
|
|
368
366
|
|
|
369
367
|
// Translate IRIs to internal index keys.
|
|
370
368
|
if (isString(subject) && !(subjectId = ids[subject]) ||
|
|
371
369
|
isString(predicate) && !(predicateId = ids[predicate]) ||
|
|
372
370
|
isString(object) && !(objectId = ids[object]))
|
|
373
|
-
return
|
|
371
|
+
return;
|
|
374
372
|
|
|
375
373
|
for (const graphId in graphs) {
|
|
376
374
|
// Only if the specified graph contains triples, there can be results
|
|
@@ -379,28 +377,27 @@ export default class N3Store {
|
|
|
379
377
|
if (subjectId) {
|
|
380
378
|
if (objectId)
|
|
381
379
|
// If subject and object are given, the object index will be the fastest
|
|
382
|
-
this._findInIndex(content.objects, objectId, subjectId, predicateId,
|
|
383
|
-
'object', 'subject', 'predicate', graphId, null,
|
|
380
|
+
yield* this._findInIndex(content.objects, objectId, subjectId, predicateId,
|
|
381
|
+
'object', 'subject', 'predicate', graphId, null, true);
|
|
384
382
|
else
|
|
385
383
|
// If only subject and possibly predicate are given, the subject index will be the fastest
|
|
386
|
-
this._findInIndex(content.subjects, subjectId, predicateId, null,
|
|
387
|
-
'subject', 'predicate', 'object', graphId, null,
|
|
384
|
+
yield* this._findInIndex(content.subjects, subjectId, predicateId, null,
|
|
385
|
+
'subject', 'predicate', 'object', graphId, null, true);
|
|
388
386
|
}
|
|
389
387
|
else if (predicateId)
|
|
390
388
|
// If only predicate and possibly object are given, the predicate index will be the fastest
|
|
391
|
-
this._findInIndex(content.predicates, predicateId, objectId, null,
|
|
392
|
-
'predicate', 'object', 'subject', graphId, null,
|
|
389
|
+
yield* this._findInIndex(content.predicates, predicateId, objectId, null,
|
|
390
|
+
'predicate', 'object', 'subject', graphId, null, true);
|
|
393
391
|
else if (objectId)
|
|
394
392
|
// If only object is given, the object index will be the fastest
|
|
395
|
-
this._findInIndex(content.objects, objectId, null, null,
|
|
396
|
-
'object', 'subject', 'predicate', graphId, null,
|
|
393
|
+
yield* this._findInIndex(content.objects, objectId, null, null,
|
|
394
|
+
'object', 'subject', 'predicate', graphId, null, true);
|
|
397
395
|
else
|
|
398
396
|
// If nothing is given, iterate subjects and predicates first
|
|
399
|
-
this._findInIndex(content.subjects, null, null, null,
|
|
400
|
-
'subject', 'predicate', 'object', graphId, null,
|
|
397
|
+
yield* this._findInIndex(content.subjects, null, null, null,
|
|
398
|
+
'subject', 'predicate', 'object', graphId, null, true);
|
|
401
399
|
}
|
|
402
400
|
}
|
|
403
|
-
return quads;
|
|
404
401
|
}
|
|
405
402
|
|
|
406
403
|
// ### `match` returns a new dataset that is comprised of all quads in the current instance matching the given arguments.
|
|
@@ -481,60 +478,9 @@ export default class N3Store {
|
|
|
481
478
|
// and returns `true` if it returns truthy for any of them.
|
|
482
479
|
// Setting any field to `undefined` or `null` indicates a wildcard.
|
|
483
480
|
some(callback, subject, predicate, object, graph) {
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
object = object && termToId(object);
|
|
488
|
-
graph = graph && termToId(graph);
|
|
489
|
-
|
|
490
|
-
const graphs = this._getGraphs(graph), ids = this._ids;
|
|
491
|
-
let content, subjectId, predicateId, objectId;
|
|
492
|
-
|
|
493
|
-
// Translate IRIs to internal index keys.
|
|
494
|
-
if (isString(subject) && !(subjectId = ids[subject]) ||
|
|
495
|
-
isString(predicate) && !(predicateId = ids[predicate]) ||
|
|
496
|
-
isString(object) && !(objectId = ids[object]))
|
|
497
|
-
return false;
|
|
498
|
-
|
|
499
|
-
for (const graphId in graphs) {
|
|
500
|
-
// Only if the specified graph contains triples, there can be results
|
|
501
|
-
if (content = graphs[graphId]) {
|
|
502
|
-
// Choose the optimal index, based on what fields are present
|
|
503
|
-
if (subjectId) {
|
|
504
|
-
if (objectId) {
|
|
505
|
-
// If subject and object are given, the object index will be the fastest
|
|
506
|
-
if (this._findInIndex(content.objects, objectId, subjectId, predicateId,
|
|
507
|
-
'object', 'subject', 'predicate', graphId, callback, null))
|
|
508
|
-
return true;
|
|
509
|
-
}
|
|
510
|
-
else
|
|
511
|
-
// If only subject and possibly predicate are given, the subject index will be the fastest
|
|
512
|
-
if (this._findInIndex(content.subjects, subjectId, predicateId, null,
|
|
513
|
-
'subject', 'predicate', 'object', graphId, callback, null))
|
|
514
|
-
return true;
|
|
515
|
-
}
|
|
516
|
-
else if (predicateId) {
|
|
517
|
-
// If only predicate and possibly object are given, the predicate index will be the fastest
|
|
518
|
-
if (this._findInIndex(content.predicates, predicateId, objectId, null,
|
|
519
|
-
'predicate', 'object', 'subject', graphId, callback, null)) {
|
|
520
|
-
return true;
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
else if (objectId) {
|
|
524
|
-
// If only object is given, the object index will be the fastest
|
|
525
|
-
if (this._findInIndex(content.objects, objectId, null, null,
|
|
526
|
-
'object', 'subject', 'predicate', graphId, callback, null)) {
|
|
527
|
-
return true;
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
else
|
|
531
|
-
// If nothing is given, iterate subjects and predicates first
|
|
532
|
-
if (this._findInIndex(content.subjects, null, null, null,
|
|
533
|
-
'subject', 'predicate', 'object', graphId, callback, null)) {
|
|
534
|
-
return true;
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
}
|
|
481
|
+
for (const quad of this.readQuads(subject, predicate, object, graph))
|
|
482
|
+
if (callback(quad))
|
|
483
|
+
return true;
|
|
538
484
|
return false;
|
|
539
485
|
}
|
|
540
486
|
|
|
@@ -820,7 +766,7 @@ export default class N3Store {
|
|
|
820
766
|
// Can be used where iterables are expected: for...of loops, array spread operator,
|
|
821
767
|
// `yield*`, and destructuring assignment (order is not guaranteed).
|
|
822
768
|
*[Symbol.iterator]() {
|
|
823
|
-
yield* this.
|
|
769
|
+
yield* this.readQuads();
|
|
824
770
|
}
|
|
825
771
|
}
|
|
826
772
|
|
|
@@ -851,7 +797,7 @@ class DatasetCoreAndReadableStream extends Readable {
|
|
|
851
797
|
}
|
|
852
798
|
|
|
853
799
|
_read() {
|
|
854
|
-
for (const quad of this
|
|
800
|
+
for (const quad of this)
|
|
855
801
|
this.push(quad);
|
|
856
802
|
this.push(null);
|
|
857
803
|
}
|
|
@@ -873,6 +819,6 @@ class DatasetCoreAndReadableStream extends Readable {
|
|
|
873
819
|
}
|
|
874
820
|
|
|
875
821
|
*[Symbol.iterator]() {
|
|
876
|
-
yield* this.
|
|
822
|
+
yield* this._filtered || this.n3Store.readQuads(this.subject, this.predicate, this.object, this.graph);
|
|
877
823
|
}
|
|
878
824
|
}
|
package/src/N3Util.js
CHANGED
|
@@ -34,7 +34,7 @@ export function inDefaultGraph(quad) {
|
|
|
34
34
|
|
|
35
35
|
// Creates a function that prepends the given IRI to a local name
|
|
36
36
|
export function prefix(iri, factory) {
|
|
37
|
-
return prefixes({ '': iri }, factory)('');
|
|
37
|
+
return prefixes({ '': iri.value || iri }, factory)('');
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
// Creates a function that allows registering and expanding prefixes
|