@jahed/sparql-engine
Version:
SPARQL query engine for servers and web browsers.
126 lines (113 loc) • 3.56 kB
text/typescript
// SPDX-License-Identifier: MIT
import type { NamedNode } from "@rdfjs/types";
import { termToString } from "rdf-string";
import Graph from "./graph.ts";
import UnionGraph from "./union-graph.ts";
/**
* An abstraction over an RDF datasets, i.e., a collection of RDF graphs.
* @abstract
*/
export default abstract class Dataset<G extends Graph = Graph> {
private _graphFactory: (iri: NamedNode) => G | Promise<G>;
/**
* Constructor
*/
constructor() {
this._graphFactory = () => {
throw new Error("Named graphs not supported.");
};
}
abstract get iris(): NamedNode[];
/**
* Set the Default Graph of the Dataset
* @param g - Default Graph
*/
abstract setDefaultGraph(g: G): void;
/**
* Get the Default Graph of the Dataset
* @return The Default Graph of the Dataset
*/
abstract getDefaultGraph(): G;
/**
* Add a Named Graph to the Dataset
* @param iri - IRI of the Named Graph
* @param g - RDF Graph
*/
abstract addNamedGraph(g: G): void;
/**
* Get a Named Graph using its IRI
* @param iri - IRI of the Named Graph to retrieve
* @return The corresponding Named Graph
*/
abstract getNamedGraph(iri: NamedNode): Promise<G>;
/**
* Delete a Named Graph using its IRI
* @param iri - IRI of the Named Graph to delete
*/
abstract deleteNamedGraph(iri: NamedNode): void;
/**
* Return True if the Dataset contains a Named graph with the provided IRI
* @param iri - IRI of the Named Graph
* @return True if the Dataset contains a Named graph with the provided IRI
*/
abstract hasNamedGraph(iri: NamedNode): boolean;
/**
* Get an UnionGraph, i.e., the dynamic union of several graphs,
* from the RDF Graphs in the Dataset.
* @param iris - Iris of the named graphs to include in the union
* @param includeDefault - True if the default graph should be included
* @return The dynamic union of several graphs in the Dataset
*/
async getUnionGraph(
iris: NamedNode[],
includeDefault: boolean = false
): Promise<UnionGraph> {
let graphs: G[] = [];
if (includeDefault) {
graphs.push(this.getDefaultGraph());
}
for (const iri of iris) {
graphs.push(await this.getNamedGraph(iri));
}
return new UnionGraph(graphs);
}
/**
* Returns all Graphs in the Dataset, including the Default one
* @param includeDefault - True if the default graph should be included
* @return The list of all graphs in the Dataset
*/
async *getAllGraphs(includeDefault: boolean = true): AsyncGenerator<G> {
if (includeDefault) {
yield this.getDefaultGraph();
}
for (const iri of this.iris) {
yield this.getNamedGraph(iri);
}
}
/**
* Set the Graph Factory used by te dataset to create new RDF graphs on-demand
* @param factory - Graph Factory
*/
setGraphFactory(factory: (iri: NamedNode) => G | Promise<G>) {
this._graphFactory = factory;
}
/**
* Create a new RDF Graph, using the current Graph Factory.
* This Graph factory can be set using the "setGraphFactory" method.
* @param iri - IRI of the graph to create
* @return A new RDF Graph
*/
async createGraph(iri: NamedNode): Promise<G> {
const graph = await this._graphFactory(iri);
if (!graph.iri.equals(iri)) {
const error = new Error("graph.iri must match given iri.");
console.log({
error,
iri: termToString(iri),
graphIri: termToString(graph.iri),
});
throw error;
}
return graph;
}
}