@_linked/core 2.18.1 → 2.20.1
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/CHANGELOG.md +63 -0
- package/README.md +104 -3
- package/lib/esm/index.d.ts +3 -0
- package/lib/esm/index.js +1 -0
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/interfaces/IDataset.d.ts +23 -0
- package/lib/esm/interfaces/IFileStore.d.ts +64 -1
- package/lib/esm/interfaces/IFileStore.js +21 -1
- package/lib/esm/interfaces/IFileStore.js.map +1 -1
- package/lib/esm/queries/CountBuilder.d.ts +69 -0
- package/lib/esm/queries/CountBuilder.js +162 -0
- package/lib/esm/queries/CountBuilder.js.map +1 -0
- package/lib/esm/queries/CountQuery.d.ts +80 -0
- package/lib/esm/queries/CountQuery.js +7 -0
- package/lib/esm/queries/CountQuery.js.map +1 -0
- package/lib/esm/queries/IntermediateRepresentation.d.ts +31 -1
- package/lib/esm/queries/QueryBuilder.d.ts +80 -0
- package/lib/esm/queries/QueryBuilder.js +98 -13
- package/lib/esm/queries/QueryBuilder.js.map +1 -1
- package/lib/esm/queries/fromJSON.d.ts +5 -3
- package/lib/esm/queries/fromJSON.js +4 -1
- package/lib/esm/queries/fromJSON.js.map +1 -1
- package/lib/esm/queries/lower.d.ts +17 -2
- package/lib/esm/queries/lower.js +61 -0
- package/lib/esm/queries/lower.js.map +1 -1
- package/lib/esm/queries/queryDispatch.d.ts +35 -0
- package/lib/esm/queries/queryDispatch.js +36 -0
- package/lib/esm/queries/queryDispatch.js.map +1 -1
- package/lib/esm/shapes/Shape.d.ts +32 -0
- package/lib/esm/shapes/Shape.js +47 -0
- package/lib/esm/shapes/Shape.js.map +1 -1
- package/lib/esm/sparql/SparqlDataset.d.ts +11 -0
- package/lib/esm/sparql/SparqlDataset.js +19 -2
- package/lib/esm/sparql/SparqlDataset.js.map +1 -1
- package/lib/esm/sparql/index.d.ts +3 -3
- package/lib/esm/sparql/index.js +3 -3
- package/lib/esm/sparql/index.js.map +1 -1
- package/lib/esm/sparql/irToAlgebra.d.ts +32 -1
- package/lib/esm/sparql/irToAlgebra.js +74 -0
- package/lib/esm/sparql/irToAlgebra.js.map +1 -1
- package/lib/esm/sparql/resultMapping.d.ts +14 -1
- package/lib/esm/sparql/resultMapping.js +40 -0
- package/lib/esm/sparql/resultMapping.js.map +1 -1
- package/lib/esm/utils/LinkedFileStorage.d.ts +96 -3
- package/lib/esm/utils/LinkedFileStorage.js +164 -12
- package/lib/esm/utils/LinkedFileStorage.js.map +1 -1
- package/package.json +3 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lower.js","sourceRoot":"","sources":["../../../src/queries/lower.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;;;;;GAWG;AACH,OAAO,EAAC,gBAAgB,EAAC,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAC,oBAAoB,EAAC,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAC,sBAAsB,EAA4B,MAAM,mBAAmB,CAAC;AACpF,OAAO,EAAC,mBAAmB,EAAC,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAC,gBAAgB,EAAC,MAAM,iBAAiB,CAAC;AACjD,OAAO,EACL,8BAA8B,EAC9B,8BAA8B,EAC9B,8BAA8B,EAC9B,mCAAmC,EACnC,8BAA8B,EAC9B,iCAAiC,EACjC,mCAAmC,GACpC,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAC,OAAO,EAAC,MAAM,gBAAgB,CAAC;AACvC,OAAO,EAAC,cAAc,EAAC,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"lower.js","sourceRoot":"","sources":["../../../src/queries/lower.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,6 +4,7 @@ import type { UpdateQuery } from './UpdateQuery.js';
|
|
|
4
4
|
import type { DeleteQuery, DeleteResponse } from './DeleteQuery.js';
|
|
5
5
|
import type { IDataset } from '../interfaces/IDataset.js';
|
|
6
6
|
import type { AskQuery } from './AskQuery.js';
|
|
7
|
+
import type { CountQuery } from './CountQuery.js';
|
|
7
8
|
/**
|
|
8
9
|
* Abstraction boundary between the DSL layer (Shape) and the storage layer
|
|
9
10
|
* (LinkedStorage / IDataset). Both sides import this leaf module; neither
|
|
@@ -16,6 +17,15 @@ export interface QueryDispatch {
|
|
|
16
17
|
selectQuery<R = any>(query: SelectQuery): Promise<R>;
|
|
17
18
|
/** Answer an ask query — a boolean, not a result set. */
|
|
18
19
|
askQuery(query: AskQuery): Promise<boolean>;
|
|
20
|
+
/**
|
|
21
|
+
* Answer a count query — a number, not a result set.
|
|
22
|
+
*
|
|
23
|
+
* **Optional**, unlike `askQuery`. This interface is implemented by object
|
|
24
|
+
* literals in consuming packages (`setQueryDispatch({…})`), so requiring it would
|
|
25
|
+
* break every one of them at compile time. {@link resolveCount} turns a missing
|
|
26
|
+
* implementation into a precise runtime error instead.
|
|
27
|
+
*/
|
|
28
|
+
countQuery?(query: CountQuery): Promise<number>;
|
|
19
29
|
createQuery<R = any>(query: CreateQuery): Promise<R>;
|
|
20
30
|
updateQuery<R = any>(query: UpdateQuery): Promise<R>;
|
|
21
31
|
deleteQuery(query: DeleteQuery): Promise<DeleteResponse>;
|
|
@@ -41,6 +51,31 @@ type ExistenceTarget = {
|
|
|
41
51
|
* propagate for the same reason — "could not ask" is never `false`.
|
|
42
52
|
*/
|
|
43
53
|
export declare function resolveExistence(target: ExistenceTarget, query: AskQuery): Promise<boolean>;
|
|
54
|
+
/** A target that can answer a count query. */
|
|
55
|
+
type CountTarget = {
|
|
56
|
+
countQuery?(query: CountQuery): Promise<number>;
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Answer a count query against `target` — the single entry point for every
|
|
60
|
+
* number-answered query in the library, as {@link resolveExistence} is for boolean
|
|
61
|
+
* ones. `CountBuilder.exec()` and a router's `countQuery` both come here rather than
|
|
62
|
+
* calling `countQuery` directly, so the contract below is enforced once for every
|
|
63
|
+
* store.
|
|
64
|
+
*
|
|
65
|
+
* There is deliberately **no translation to a select query anywhere in this
|
|
66
|
+
* package.** A count goes to `IDataset.countQuery` and a SPARQL-backed store turns
|
|
67
|
+
* it into `SELECT (COUNT(DISTINCT ?s) AS ?count)`. A store that lacks an aggregate
|
|
68
|
+
* primitive implements `countQuery` itself, in whatever way its backend allows —
|
|
69
|
+
* that decision belongs to the store, and making it here (by fetching every row and
|
|
70
|
+
* measuring the array) would hide an unbounded read behind a cheap-looking call.
|
|
71
|
+
*
|
|
72
|
+
* `countQuery` must resolve to a **finite, non-negative integer**: anything else
|
|
73
|
+
* rejects rather than being coerced. Errors propagate for the same reason a failed
|
|
74
|
+
* ask is never `false` — and more sharply, because `0` is a *plausible* count. A
|
|
75
|
+
* count that reported an unreachable store as `0` would render an empty table that
|
|
76
|
+
* looks exactly like real data.
|
|
77
|
+
*/
|
|
78
|
+
export declare function resolveCount(target: CountTarget, query: CountQuery): Promise<number>;
|
|
44
79
|
export declare function setQueryDispatch(d: QueryDispatch): void;
|
|
45
80
|
export declare function getQueryDispatch(): QueryDispatch;
|
|
46
81
|
/** The mutating query kinds — the `IDataset` methods that are optional per-store. */
|
|
@@ -39,6 +39,42 @@ export function resolveExistence(target, query) {
|
|
|
39
39
|
return answer;
|
|
40
40
|
});
|
|
41
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* Answer a count query against `target` — the single entry point for every
|
|
44
|
+
* number-answered query in the library, as {@link resolveExistence} is for boolean
|
|
45
|
+
* ones. `CountBuilder.exec()` and a router's `countQuery` both come here rather than
|
|
46
|
+
* calling `countQuery` directly, so the contract below is enforced once for every
|
|
47
|
+
* store.
|
|
48
|
+
*
|
|
49
|
+
* There is deliberately **no translation to a select query anywhere in this
|
|
50
|
+
* package.** A count goes to `IDataset.countQuery` and a SPARQL-backed store turns
|
|
51
|
+
* it into `SELECT (COUNT(DISTINCT ?s) AS ?count)`. A store that lacks an aggregate
|
|
52
|
+
* primitive implements `countQuery` itself, in whatever way its backend allows —
|
|
53
|
+
* that decision belongs to the store, and making it here (by fetching every row and
|
|
54
|
+
* measuring the array) would hide an unbounded read behind a cheap-looking call.
|
|
55
|
+
*
|
|
56
|
+
* `countQuery` must resolve to a **finite, non-negative integer**: anything else
|
|
57
|
+
* rejects rather than being coerced. Errors propagate for the same reason a failed
|
|
58
|
+
* ask is never `false` — and more sharply, because `0` is a *plausible* count. A
|
|
59
|
+
* count that reported an unreachable store as `0` would render an empty table that
|
|
60
|
+
* looks exactly like real data.
|
|
61
|
+
*/
|
|
62
|
+
export function resolveCount(target, query) {
|
|
63
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
64
|
+
if (typeof (target === null || target === void 0 ? void 0 : target.countQuery) !== 'function') {
|
|
65
|
+
throw new Error('This dataset does not implement IDataset.countQuery(query). A count query is ' +
|
|
66
|
+
'answered with a number — a SPARQL store emits ' +
|
|
67
|
+
'SELECT (COUNT(DISTINCT ?s) AS ?count) — and is never rewritten as a select ' +
|
|
68
|
+
'on its behalf, which would read every matching row to measure the array.');
|
|
69
|
+
}
|
|
70
|
+
const answer = yield target.countQuery(query);
|
|
71
|
+
if (typeof answer !== 'number' || !Number.isInteger(answer) || answer < 0) {
|
|
72
|
+
throw new Error(`countQuery must resolve to a non-negative integer; got ${answer === null ? 'null' : typeof answer === 'number' ? String(answer) : typeof answer}. A count query will not coerce — a NaN or a missing value that fell through ` +
|
|
73
|
+
'as 0 would silently read as "no matches".');
|
|
74
|
+
}
|
|
75
|
+
return answer;
|
|
76
|
+
});
|
|
77
|
+
}
|
|
42
78
|
// Global-backed so it is SHARED across duplicate copies of this module. In dev,
|
|
43
79
|
// `@_linked/core` can be evaluated twice (Vite/`src` + Node/`lib` — an accepted
|
|
44
80
|
// 2-instance state, see report-011). The module REGISTRY already lives on the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queryDispatch.js","sourceRoot":"","sources":["../../../src/queries/queryDispatch.ts"],"names":[],"mappings":";;;;;;;;;
|
|
1
|
+
{"version":3,"file":"queryDispatch.js","sourceRoot":"","sources":["../../../src/queries/queryDispatch.ts"],"names":[],"mappings":";;;;;;;;;AAqCA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAgB,gBAAgB,CACpC,MAAuB,EACvB,KAAe;;QAEf,IAAI,OAAO,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,QAAQ,CAAA,KAAK,UAAU,EAAE,CAAC;YAC3C,MAAM,IAAI,KAAK,CACb,yEAAyE;gBACzE,8EAA8E;gBAC9E,4CAA4C,CAC7C,CAAC;QACJ,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC5C,IAAI,OAAO,MAAM,KAAK,SAAS,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CACb,2CAA2C,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,MAAM,IAAI;gBACvF,uEAAuE;gBACvE,wCAAwC,CACzC,CAAC;QACJ,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;CAAA;AAKD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAgB,YAAY,CAChC,MAAmB,EACnB,KAAiB;;QAEjB,IAAI,OAAO,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,UAAU,CAAA,KAAK,UAAU,EAAE,CAAC;YAC7C,MAAM,IAAI,KAAK,CACb,+EAA+E;gBAC/E,gDAAgD;gBAChD,6EAA6E;gBAC7E,0EAA0E,CAC3E,CAAC;QACJ,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAC9C,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1E,MAAM,IAAI,KAAK,CACb,0DACE,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,MAClF,+EAA+E;gBAC/E,2CAA2C,CAC5C,CAAC;QACJ,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;CAAA;AAED,gFAAgF;AAChF,gFAAgF;AAChF,8EAA8E;AAC9E,8EAA8E;AAC9E,8EAA8E;AAC9E,uEAAuE;AACvE,MAAM,cAAc,GAClB,OAAO,UAAU,KAAK,WAAW,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAE,EAAU,CAAC;AAC/D,IAAI,CAAC,CAAC,uBAAuB,IAAI,cAAc,CAAC,EAAE,CAAC;IACjD,cAAc,CAAC,qBAAqB,GAAG,EAAC,OAAO,EAAE,IAA4B,EAAC,CAAC;AACjF,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,CAAgB;IAC/C,cAAc,CAAC,qBAAqB,CAAC,OAAO,GAAG,CAAC,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,MAAM,QAAQ,GAAG,cAAc,CAAC,qBAAqB,CAAC,OAA+B,CAAC;IACtF,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CACb,6EAA6E,CAC9E,CAAC;IACJ,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAKD;;;;;;;;GAQG;AACH,MAAM,UAAU,uBAAuB,CACrC,IAAkB,EAClB,MAAiB;IAEjB,IAAI,CAAC,MAAM;QAAE,OAAO,gBAAgB,EAAE,CAAC;IACvC,IAAI,OAAO,MAAM,CAAC,GAAG,IAAI,OAAO,CAAC,KAAK,UAAU,EAAE,CAAC;QACjD,MAAM,IAAI,KAAK,CAAC,uCAAuC,IAAI,WAAW,CAAC,CAAC;IAC1E,CAAC;IACD,OAAO,MAAkC,CAAC;AAC5C,CAAC"}
|
|
@@ -116,6 +116,38 @@ export declare abstract class Shape {
|
|
|
116
116
|
* global query dispatch.
|
|
117
117
|
*/
|
|
118
118
|
static exists<S extends Shape>(this: ShapeConstructor<S> | typeof Shape, id: string | NodeReferenceValue | PendingQueryContext | null | undefined, target?: IDataset): Promise<boolean>;
|
|
119
|
+
/**
|
|
120
|
+
* How many instances of this shape exist — a real `number`.
|
|
121
|
+
*
|
|
122
|
+
* ```typescript
|
|
123
|
+
* const total = await Person.count();
|
|
124
|
+
* ```
|
|
125
|
+
*
|
|
126
|
+
* This is the unfiltered total. For a filtered one, compose on the builder, which
|
|
127
|
+
* is the form a paging table wants:
|
|
128
|
+
*
|
|
129
|
+
* ```typescript
|
|
130
|
+
* await Person.select().where(p => p.name.equals('Semmy')).count();
|
|
131
|
+
* ```
|
|
132
|
+
*
|
|
133
|
+
* Runs the cheapest correct query: against a SPARQL store,
|
|
134
|
+
* `SELECT (COUNT(DISTINCT ?a0) AS ?count) WHERE { ?a0 rdf:type <ShapeClass> }` —
|
|
135
|
+
* the shape's type triple and nothing else. Note the type triple: this counts
|
|
136
|
+
* instances **of this shape**, not nodes in general.
|
|
137
|
+
*
|
|
138
|
+
* **On the base class — `Shape.count()` — this throws.** Unlike
|
|
139
|
+
* {@link Shape.exists}, whose shapeless reading ("does this node exist at all?")
|
|
140
|
+
* is useful and cheap, a shapeless count would count every node in every dataset
|
|
141
|
+
* the router knows. No caller means that, so it is refused rather than answered.
|
|
142
|
+
*
|
|
143
|
+
* **Errors reject — they are never reported as `0`.** Do not wrap this in a
|
|
144
|
+
* `.catch(() => 0)`: `0` is a plausible count, so a broken one renders an empty
|
|
145
|
+
* table that looks exactly like real data.
|
|
146
|
+
*
|
|
147
|
+
* @param target Optional explicit dataset to run against; omitted uses the
|
|
148
|
+
* global query dispatch.
|
|
149
|
+
*/
|
|
150
|
+
static count<S extends Shape>(this: ShapeConstructor<S> | typeof Shape, target?: IDataset): Promise<number>;
|
|
119
151
|
/**
|
|
120
152
|
* Update properties of an instance of this shape.
|
|
121
153
|
* Chain `.for(id)` to target a specific entity.
|
package/lib/esm/shapes/Shape.js
CHANGED
|
@@ -9,6 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
};
|
|
10
10
|
import { QueryBuilder } from '../queries/QueryBuilder.js';
|
|
11
11
|
import { AskBuilder } from '../queries/AskBuilder.js';
|
|
12
|
+
import { CountBuilder } from '../queries/CountBuilder.js';
|
|
12
13
|
import { CreateBuilder } from '../queries/CreateBuilder.js';
|
|
13
14
|
import { UpdateBuilder } from '../queries/UpdateBuilder.js';
|
|
14
15
|
import { DeleteBuilder } from '../queries/DeleteBuilder.js';
|
|
@@ -148,6 +149,52 @@ export class Shape {
|
|
|
148
149
|
return QueryBuilder.from(this).for(id).exists(target);
|
|
149
150
|
});
|
|
150
151
|
}
|
|
152
|
+
/**
|
|
153
|
+
* How many instances of this shape exist — a real `number`.
|
|
154
|
+
*
|
|
155
|
+
* ```typescript
|
|
156
|
+
* const total = await Person.count();
|
|
157
|
+
* ```
|
|
158
|
+
*
|
|
159
|
+
* This is the unfiltered total. For a filtered one, compose on the builder, which
|
|
160
|
+
* is the form a paging table wants:
|
|
161
|
+
*
|
|
162
|
+
* ```typescript
|
|
163
|
+
* await Person.select().where(p => p.name.equals('Semmy')).count();
|
|
164
|
+
* ```
|
|
165
|
+
*
|
|
166
|
+
* Runs the cheapest correct query: against a SPARQL store,
|
|
167
|
+
* `SELECT (COUNT(DISTINCT ?a0) AS ?count) WHERE { ?a0 rdf:type <ShapeClass> }` —
|
|
168
|
+
* the shape's type triple and nothing else. Note the type triple: this counts
|
|
169
|
+
* instances **of this shape**, not nodes in general.
|
|
170
|
+
*
|
|
171
|
+
* **On the base class — `Shape.count()` — this throws.** Unlike
|
|
172
|
+
* {@link Shape.exists}, whose shapeless reading ("does this node exist at all?")
|
|
173
|
+
* is useful and cheap, a shapeless count would count every node in every dataset
|
|
174
|
+
* the router knows. No caller means that, so it is refused rather than answered.
|
|
175
|
+
*
|
|
176
|
+
* **Errors reject — they are never reported as `0`.** Do not wrap this in a
|
|
177
|
+
* `.catch(() => 0)`: `0` is a plausible count, so a broken one renders an empty
|
|
178
|
+
* table that looks exactly like real data.
|
|
179
|
+
*
|
|
180
|
+
* @param target Optional explicit dataset to run against; omitted uses the
|
|
181
|
+
* global query dispatch.
|
|
182
|
+
*/
|
|
183
|
+
static count(target) {
|
|
184
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
185
|
+
// `async`, so the base-class refusal rejects rather than throwing synchronously
|
|
186
|
+
// past the caller's `.catch()`.
|
|
187
|
+
if (this === Shape) {
|
|
188
|
+
throw new Error('Shape.count() has no meaning on the base class: there is no shape to ' +
|
|
189
|
+
'constrain by, so it would count every node in the store, under any type or ' +
|
|
190
|
+
'none. Call it on a shape subclass (`Person.count()`), or compose a filter ' +
|
|
191
|
+
'on the builder (`Person.select().where(…).count()`).');
|
|
192
|
+
}
|
|
193
|
+
return CountBuilder.of({
|
|
194
|
+
shapeClass: this,
|
|
195
|
+
}).exec(target);
|
|
196
|
+
});
|
|
197
|
+
}
|
|
151
198
|
static update(data) {
|
|
152
199
|
return UpdateBuilder.from(this).set(data);
|
|
153
200
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Shape.js","sourceRoot":"","sources":["../../../src/shapes/Shape.ts"],"names":[],"mappings":";;;;;;;;;AAcA,OAAO,EAAC,YAAY,EAAC,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAC,UAAU,EAAC,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"Shape.js","sourceRoot":"","sources":["../../../src/shapes/Shape.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { IDataset } from '../interfaces/IDataset.js';
|
|
2
2
|
import type { SelectQuery } from '../queries/SelectQuery.js';
|
|
3
3
|
import type { AskQuery } from '../queries/AskQuery.js';
|
|
4
|
+
import type { CountQuery } from '../queries/CountQuery.js';
|
|
4
5
|
import type { CreateQuery } from '../queries/CreateQuery.js';
|
|
5
6
|
import type { UpdateQuery } from '../queries/UpdateQuery.js';
|
|
6
7
|
import type { DeleteQuery, DeleteResponse } from '../queries/DeleteQuery.js';
|
|
@@ -60,6 +61,16 @@ export declare abstract class SparqlDataset implements IDataset {
|
|
|
60
61
|
* of the node under any type or none. Errors reject; never reported as `false`.
|
|
61
62
|
*/
|
|
62
63
|
askQuery(query: AskQuery): Promise<boolean>;
|
|
64
|
+
/**
|
|
65
|
+
* Count the matching instances — emitted as
|
|
66
|
+
* `SELECT (COUNT(DISTINCT ?a0) AS ?count) WHERE { … }`.
|
|
67
|
+
*
|
|
68
|
+
* A {@link CountQuery} carries only a pattern, so there is nothing to normalise
|
|
69
|
+
* away here: no projection, no ordering, and in particular no `LIMIT`/`OFFSET`,
|
|
70
|
+
* which the builder dropped before the query ever reached the IR. Errors reject;
|
|
71
|
+
* they are never reported as `0`.
|
|
72
|
+
*/
|
|
73
|
+
countQuery(query: CountQuery): Promise<number>;
|
|
63
74
|
createQuery(query: CreateQuery): Promise<CreateResult>;
|
|
64
75
|
updateQuery(query: UpdateQuery): Promise<UpdateResult>;
|
|
65
76
|
deleteQuery(query: DeleteQuery): Promise<DeleteResponse>;
|
|
@@ -7,8 +7,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import { selectToSparql, askToSparql, createToSparql, updateToSparql, upsertToSparql, updateWhereToSparql, deleteToSparql, deleteAllToSparql, deleteWhereToSparql, } from './irToAlgebra.js';
|
|
11
|
-
import { mapSparqlSelectResult, mapSparqlAskResult, mapSparqlCreateResult, mapSparqlUpdateResult, isSparqlSelectResults, } from './resultMapping.js';
|
|
10
|
+
import { selectToSparql, askToSparql, countToSparql, createToSparql, updateToSparql, upsertToSparql, updateWhereToSparql, deleteToSparql, deleteAllToSparql, deleteWhereToSparql, } from './irToAlgebra.js';
|
|
11
|
+
import { mapSparqlSelectResult, mapSparqlAskResult, mapSparqlCountResult, mapSparqlCreateResult, mapSparqlUpdateResult, isSparqlSelectResults, } from './resultMapping.js';
|
|
12
12
|
import { generateEntityUri } from './sparqlUtils.js';
|
|
13
13
|
import { lower } from '../queries/lower.js';
|
|
14
14
|
/**
|
|
@@ -68,6 +68,23 @@ export class SparqlDataset {
|
|
|
68
68
|
return mapSparqlAskResult(json);
|
|
69
69
|
});
|
|
70
70
|
}
|
|
71
|
+
/**
|
|
72
|
+
* Count the matching instances — emitted as
|
|
73
|
+
* `SELECT (COUNT(DISTINCT ?a0) AS ?count) WHERE { … }`.
|
|
74
|
+
*
|
|
75
|
+
* A {@link CountQuery} carries only a pattern, so there is nothing to normalise
|
|
76
|
+
* away here: no projection, no ordering, and in particular no `LIMIT`/`OFFSET`,
|
|
77
|
+
* which the builder dropped before the query ever reached the IR. Errors reject;
|
|
78
|
+
* they are never reported as `0`.
|
|
79
|
+
*/
|
|
80
|
+
countQuery(query) {
|
|
81
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
82
|
+
const ir = lower(query);
|
|
83
|
+
const sparql = countToSparql(ir, this.options);
|
|
84
|
+
const json = yield this.executeSparqlSelect(sparql);
|
|
85
|
+
return mapSparqlCountResult(json, ir);
|
|
86
|
+
});
|
|
87
|
+
}
|
|
71
88
|
createQuery(query) {
|
|
72
89
|
return __awaiter(this, void 0, void 0, function* () {
|
|
73
90
|
const ir = lower(query);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SparqlDataset.js","sourceRoot":"","sources":["../../../src/sparql/SparqlDataset.ts"],"names":[],"mappings":";;;;;;;;;
|
|
1
|
+
{"version":3,"file":"SparqlDataset.js","sourceRoot":"","sources":["../../../src/sparql/SparqlDataset.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export type * from './SparqlAlgebra.js';
|
|
2
2
|
export type { SparqlOptions } from './sparqlUtils.js';
|
|
3
3
|
export { formatUri, formatLiteral, escapeSparqlString, collectPrefixes, generateEntityUri, } from './sparqlUtils.js';
|
|
4
|
-
export { selectToAlgebra, askToAlgebra, createToAlgebra, updateToAlgebra, upsertToAlgebra, deleteToAlgebra, } from './irToAlgebra.js';
|
|
5
|
-
export { selectToSparql, askToSparql, createToSparql, updateToSparql, upsertToSparql, deleteToSparql, } from './irToAlgebra.js';
|
|
4
|
+
export { selectToAlgebra, askToAlgebra, countToAlgebra, createToAlgebra, updateToAlgebra, upsertToAlgebra, deleteToAlgebra, } from './irToAlgebra.js';
|
|
5
|
+
export { selectToSparql, askToSparql, countToSparql, createToSparql, updateToSparql, upsertToSparql, deleteToSparql, } from './irToAlgebra.js';
|
|
6
6
|
export { serializeAlgebraNode, serializeExpression, serializeTerm, selectPlanToSparql, askPlanToSparql, insertDataPlanToSparql, deleteInsertPlanToSparql, deleteWherePlanToSparql, } from './algebraToString.js';
|
|
7
|
-
export { mapSparqlSelectResult, mapSparqlAskResult, mapSparqlCreateResult, mapSparqlUpdateResult, isSparqlSelectResults, } from './resultMapping.js';
|
|
7
|
+
export { mapSparqlSelectResult, mapSparqlAskResult, mapSparqlCountResult, mapSparqlCreateResult, mapSparqlUpdateResult, isSparqlSelectResults, } from './resultMapping.js';
|
|
8
8
|
export type { SparqlJsonResults, SparqlAskResults, SparqlQueryResults, SparqlBinding, } from './resultMapping.js';
|
|
9
9
|
export { SparqlDataset, SparqlStore } from './SparqlDataset.js';
|
package/lib/esm/sparql/index.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
// Utilities
|
|
2
2
|
export { formatUri, formatLiteral, escapeSparqlString, collectPrefixes, generateEntityUri, } from './sparqlUtils.js';
|
|
3
3
|
// IR → Algebra conversion (Layer 1)
|
|
4
|
-
export { selectToAlgebra, askToAlgebra, createToAlgebra, updateToAlgebra, upsertToAlgebra, deleteToAlgebra, } from './irToAlgebra.js';
|
|
4
|
+
export { selectToAlgebra, askToAlgebra, countToAlgebra, createToAlgebra, updateToAlgebra, upsertToAlgebra, deleteToAlgebra, } from './irToAlgebra.js';
|
|
5
5
|
// High-level IR → SPARQL string (convenience wrappers)
|
|
6
|
-
export { selectToSparql, askToSparql, createToSparql, updateToSparql, upsertToSparql, deleteToSparql, } from './irToAlgebra.js';
|
|
6
|
+
export { selectToSparql, askToSparql, countToSparql, createToSparql, updateToSparql, upsertToSparql, deleteToSparql, } from './irToAlgebra.js';
|
|
7
7
|
// Algebra → SPARQL string serialization (layer 3)
|
|
8
8
|
export { serializeAlgebraNode, serializeExpression, serializeTerm, selectPlanToSparql, askPlanToSparql, insertDataPlanToSparql, deleteInsertPlanToSparql, deleteWherePlanToSparql, } from './algebraToString.js';
|
|
9
9
|
// Result mapping
|
|
10
|
-
export { mapSparqlSelectResult, mapSparqlAskResult, mapSparqlCreateResult, mapSparqlUpdateResult, isSparqlSelectResults, } from './resultMapping.js';
|
|
10
|
+
export { mapSparqlSelectResult, mapSparqlAskResult, mapSparqlCountResult, mapSparqlCreateResult, mapSparqlUpdateResult, isSparqlSelectResults, } from './resultMapping.js';
|
|
11
11
|
// Dataset base class
|
|
12
12
|
export { SparqlDataset, SparqlStore } from './SparqlDataset.js';
|
|
13
13
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/sparql/index.ts"],"names":[],"mappings":"AAIA,YAAY;AACZ,OAAO,EACL,SAAS,EACT,aAAa,EACb,kBAAkB,EAClB,eAAe,EACf,iBAAiB,GAClB,MAAM,kBAAkB,CAAC;AAE1B,oCAAoC;AACpC,OAAO,EACL,eAAe,EACf,YAAY,EACZ,eAAe,EACf,eAAe,EACf,eAAe,EACf,eAAe,GAChB,MAAM,kBAAkB,CAAC;AAE1B,uDAAuD;AACvD,OAAO,EACL,cAAc,EACd,WAAW,EACX,cAAc,EACd,cAAc,EACd,cAAc,EACd,cAAc,GACf,MAAM,kBAAkB,CAAC;AAE1B,kDAAkD;AAClD,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,aAAa,EACb,kBAAkB,EAClB,eAAe,EACf,sBAAsB,EACtB,wBAAwB,EACxB,uBAAuB,GACxB,MAAM,sBAAsB,CAAC;AAE9B,iBAAiB;AACjB,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,oBAAoB,CAAC;AAQ5B,qBAAqB;AACrB,OAAO,EAAC,aAAa,EAAE,WAAW,EAAC,MAAM,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/sparql/index.ts"],"names":[],"mappings":"AAIA,YAAY;AACZ,OAAO,EACL,SAAS,EACT,aAAa,EACb,kBAAkB,EAClB,eAAe,EACf,iBAAiB,GAClB,MAAM,kBAAkB,CAAC;AAE1B,oCAAoC;AACpC,OAAO,EACL,eAAe,EACf,YAAY,EACZ,cAAc,EACd,eAAe,EACf,eAAe,EACf,eAAe,EACf,eAAe,GAChB,MAAM,kBAAkB,CAAC;AAE1B,uDAAuD;AACvD,OAAO,EACL,cAAc,EACd,WAAW,EACX,aAAa,EACb,cAAc,EACd,cAAc,EACd,cAAc,EACd,cAAc,GACf,MAAM,kBAAkB,CAAC;AAE1B,kDAAkD;AAClD,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,aAAa,EACb,kBAAkB,EAClB,eAAe,EACf,sBAAsB,EACtB,wBAAwB,EACxB,uBAAuB,GACxB,MAAM,sBAAsB,CAAC;AAE9B,iBAAiB;AACjB,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,oBAAoB,EACpB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,oBAAoB,CAAC;AAQ5B,qBAAqB;AACrB,OAAO,EAAC,aAAa,EAAE,WAAW,EAAC,MAAM,oBAAoB,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { IRSelectQuery, IRAskQuery, IRCreateMutation, IRUpdateMutation, IRUpsertMutation, IRDeleteMutation, IRDeleteAllMutation, IRDeleteWhereMutation, IRUpdateWhereMutation } from '../queries/IntermediateRepresentation.js';
|
|
1
|
+
import type { IRSelectQuery, IRAskQuery, IRCountQuery, IRCreateMutation, IRUpdateMutation, IRUpsertMutation, IRDeleteMutation, IRDeleteAllMutation, IRDeleteWhereMutation, IRUpdateWhereMutation } from '../queries/IntermediateRepresentation.js';
|
|
2
2
|
import type { SparqlSelectPlan, SparqlAskPlan, SparqlInsertDataPlan, SparqlDeleteInsertPlan, SparqlAlgebraNode, SparqlTriple, SparqlTerm } from './SparqlAlgebra.js';
|
|
3
3
|
import { type SparqlOptions } from './sparqlUtils.js';
|
|
4
4
|
/**
|
|
@@ -90,6 +90,32 @@ export declare function updateWhereToAlgebra(query: IRUpdateWhereMutation, optio
|
|
|
90
90
|
* them, so the IR cannot carry them.
|
|
91
91
|
*/
|
|
92
92
|
export declare function askToAlgebra(query: IRAskQuery, options?: SparqlOptions): SparqlAskPlan;
|
|
93
|
+
/**
|
|
94
|
+
* Converts an {@link IRCountQuery} to a {@link SparqlSelectPlan} shaped as a
|
|
95
|
+
* root-level count:
|
|
96
|
+
*
|
|
97
|
+
* ```sparql
|
|
98
|
+
* SELECT (COUNT(DISTINCT ?a0) AS ?count) WHERE { … }
|
|
99
|
+
* ```
|
|
100
|
+
*
|
|
101
|
+
* The **pattern** is built by {@link selectToAlgebra}, so shape scans, traversals,
|
|
102
|
+
* filters and `MINUS` have exactly one implementation; only the pattern is kept and
|
|
103
|
+
* the select plan's projection is discarded. That discard is load-bearing:
|
|
104
|
+
* `selectToAlgebra` unconditionally projects the root alias as a plain variable, and
|
|
105
|
+
* then makes every plain projected variable a `GROUP BY` target once an aggregate is
|
|
106
|
+
* present — so reusing its projection would yield `SELECT ?a0 (COUNT(…) AS ?count) …
|
|
107
|
+
* GROUP BY ?a0`, one row per entity each counting 1.
|
|
108
|
+
*
|
|
109
|
+
* `DISTINCT` inside the aggregate is likewise load-bearing. A shape scan joined with
|
|
110
|
+
* property triples yields one row per property-value combination (which is why the
|
|
111
|
+
* plain select path emits `SELECT DISTINCT`), so `COUNT(?a0)` would count *rows* and
|
|
112
|
+
* a filter on a multi-valued property would inflate the total. `COUNT(DISTINCT ?a0)`
|
|
113
|
+
* counts subjects, which is what "how many instances match" means.
|
|
114
|
+
*
|
|
115
|
+
* There is no `groupBy`, `orderBy`, `limit` or `offset` on the returned plan — and
|
|
116
|
+
* nothing to guard against, because {@link IRCountQuery} cannot carry them.
|
|
117
|
+
*/
|
|
118
|
+
export declare function countToAlgebra(query: IRCountQuery, options?: SparqlOptions): SparqlSelectPlan;
|
|
93
119
|
/**
|
|
94
120
|
* Converts an IRSelectQuery to a SPARQL string.
|
|
95
121
|
*/
|
|
@@ -98,6 +124,11 @@ export declare function selectToSparql(query: IRSelectQuery, options?: SparqlOpt
|
|
|
98
124
|
* Converts an {@link IRAskQuery} to a SPARQL `ASK` string.
|
|
99
125
|
*/
|
|
100
126
|
export declare function askToSparql(query: IRAskQuery, options?: SparqlOptions): string;
|
|
127
|
+
/**
|
|
128
|
+
* Converts an {@link IRCountQuery} to a SPARQL `SELECT (COUNT(DISTINCT …) AS …)`
|
|
129
|
+
* string, through the same {@link selectPlanToSparql} every select uses.
|
|
130
|
+
*/
|
|
131
|
+
export declare function countToSparql(query: IRCountQuery, options?: SparqlOptions): string;
|
|
101
132
|
/**
|
|
102
133
|
* Converts an IRCreateMutation to a SPARQL string.
|
|
103
134
|
* Stub: will be implemented when algebraToString is available.
|
|
@@ -2235,6 +2235,72 @@ export function askToAlgebra(query, options) {
|
|
|
2235
2235
|
}, options);
|
|
2236
2236
|
return { type: 'ask', algebra };
|
|
2237
2237
|
}
|
|
2238
|
+
/**
|
|
2239
|
+
* Converts an {@link IRCountQuery} to a {@link SparqlSelectPlan} shaped as a
|
|
2240
|
+
* root-level count:
|
|
2241
|
+
*
|
|
2242
|
+
* ```sparql
|
|
2243
|
+
* SELECT (COUNT(DISTINCT ?a0) AS ?count) WHERE { … }
|
|
2244
|
+
* ```
|
|
2245
|
+
*
|
|
2246
|
+
* The **pattern** is built by {@link selectToAlgebra}, so shape scans, traversals,
|
|
2247
|
+
* filters and `MINUS` have exactly one implementation; only the pattern is kept and
|
|
2248
|
+
* the select plan's projection is discarded. That discard is load-bearing:
|
|
2249
|
+
* `selectToAlgebra` unconditionally projects the root alias as a plain variable, and
|
|
2250
|
+
* then makes every plain projected variable a `GROUP BY` target once an aggregate is
|
|
2251
|
+
* present — so reusing its projection would yield `SELECT ?a0 (COUNT(…) AS ?count) …
|
|
2252
|
+
* GROUP BY ?a0`, one row per entity each counting 1.
|
|
2253
|
+
*
|
|
2254
|
+
* `DISTINCT` inside the aggregate is likewise load-bearing. A shape scan joined with
|
|
2255
|
+
* property triples yields one row per property-value combination (which is why the
|
|
2256
|
+
* plain select path emits `SELECT DISTINCT`), so `COUNT(?a0)` would count *rows* and
|
|
2257
|
+
* a filter on a multi-valued property would inflate the total. `COUNT(DISTINCT ?a0)`
|
|
2258
|
+
* counts subjects, which is what "how many instances match" means.
|
|
2259
|
+
*
|
|
2260
|
+
* There is no `groupBy`, `orderBy`, `limit` or `offset` on the returned plan — and
|
|
2261
|
+
* nothing to guard against, because {@link IRCountQuery} cannot carry them.
|
|
2262
|
+
*/
|
|
2263
|
+
export function countToAlgebra(query, options) {
|
|
2264
|
+
if (!query.root) {
|
|
2265
|
+
throw new Error('countToAlgebra: query.root is undefined. A count needs a shape to scan — a ' +
|
|
2266
|
+
'shapeless count would count every node in the store.');
|
|
2267
|
+
}
|
|
2268
|
+
const inner = selectToAlgebra({
|
|
2269
|
+
kind: 'select',
|
|
2270
|
+
root: query.root,
|
|
2271
|
+
patterns: query.patterns,
|
|
2272
|
+
projection: [],
|
|
2273
|
+
where: query.where,
|
|
2274
|
+
subjectId: query.subjectId,
|
|
2275
|
+
subjectIds: query.subjectIds,
|
|
2276
|
+
}, options);
|
|
2277
|
+
if (inner.having) {
|
|
2278
|
+
// An aggregate in the WHERE clause (e.g. `p.friends.size().gt(2)`) lowers to
|
|
2279
|
+
// HAVING + GROUP BY on the select plan. Only `algebra` is carried over here, so
|
|
2280
|
+
// the HAVING would vanish and the count would be of the UNFILTERED match set —
|
|
2281
|
+
// a plausible-looking wrong number. Counting a HAVING-filtered group set needs
|
|
2282
|
+
// `SELECT (COUNT(DISTINCT ?a0) AS ?count) WHERE { SELECT ?a0 WHERE { … }
|
|
2283
|
+
// GROUP BY ?a0 HAVING(…) }`, and `SparqlSubSelect` carries no groupBy/having
|
|
2284
|
+
// today. Refuse it rather than answer it wrongly.
|
|
2285
|
+
throw new Error('Cannot count a query whose where clause contains an aggregate (e.g. ' +
|
|
2286
|
+
'`.where(p => p.friends.size().gt(2))`). That filter lowers to HAVING over a ' +
|
|
2287
|
+
'per-subject group, and counting the surviving groups needs a nested ' +
|
|
2288
|
+
'sub-SELECT that this layer does not emit yet. Filter without an aggregate, or ' +
|
|
2289
|
+
'count the rows of the select.');
|
|
2290
|
+
}
|
|
2291
|
+
const aggregate = {
|
|
2292
|
+
kind: 'aggregate_expr',
|
|
2293
|
+
name: 'count',
|
|
2294
|
+
args: [{ kind: 'variable_expr', name: query.root.alias }],
|
|
2295
|
+
distinct: true,
|
|
2296
|
+
};
|
|
2297
|
+
return {
|
|
2298
|
+
type: 'select',
|
|
2299
|
+
algebra: inner.algebra,
|
|
2300
|
+
projection: [{ kind: 'aggregate', expression: aggregate, alias: query.alias }],
|
|
2301
|
+
aggregates: [{ variable: query.alias, aggregate }],
|
|
2302
|
+
};
|
|
2303
|
+
}
|
|
2238
2304
|
// ---------------------------------------------------------------------------
|
|
2239
2305
|
// Convenience wrappers: IR → algebra → SPARQL string in one call
|
|
2240
2306
|
// ---------------------------------------------------------------------------
|
|
@@ -2252,6 +2318,14 @@ export function askToSparql(query, options) {
|
|
|
2252
2318
|
const plan = askToAlgebra(query, options);
|
|
2253
2319
|
return askPlanToSparql(plan, options);
|
|
2254
2320
|
}
|
|
2321
|
+
/**
|
|
2322
|
+
* Converts an {@link IRCountQuery} to a SPARQL `SELECT (COUNT(DISTINCT …) AS …)`
|
|
2323
|
+
* string, through the same {@link selectPlanToSparql} every select uses.
|
|
2324
|
+
*/
|
|
2325
|
+
export function countToSparql(query, options) {
|
|
2326
|
+
const plan = countToAlgebra(query, options);
|
|
2327
|
+
return selectPlanToSparql(plan, options);
|
|
2328
|
+
}
|
|
2255
2329
|
/**
|
|
2256
2330
|
* Converts an IRCreateMutation to a SPARQL string.
|
|
2257
2331
|
* Stub: will be implemented when algebraToString is available.
|