diff src/MultiStore.ts @ 128:5a1a79f54779

big rewrite
author drewp@bigasterisk.com
date Fri, 05 May 2023 21:26:36 -0700
parents
children 27fad20dc101
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/MultiStore.ts	Fri May 05 21:26:36 2023 -0700
@@ -0,0 +1,218 @@
+import { EventEmitter } from "events";
+import {
+  BlankNode,
+  OTerm,
+  Quad,
+  QuadPredicate,
+  Store,
+  Term,
+  extractListOptions,
+} from "n3";
+import * as RDF from "rdf-js";
+import { SubEvent } from "sub-events";
+import { Patch } from "./Patch";
+import { SourceGraph } from "./SourceGraph";
+
+// queries over multiple Store objects
+export class MultiStore implements Store {
+  // emitted when there's been a net change to the graph data
+  graphChanged: SubEvent<Patch> = new SubEvent();
+
+  // sources of statements
+  private stores: Store[] = [];
+  private tempCombinedGraph: Store;
+
+  constructor() {
+    this.tempCombinedGraph = new Store();
+  }
+
+  newStore(s: SourceGraph) {
+    this.stores.push(s.store);
+    const p = new Patch(); // todo
+    s.sourceGraphChanged.subscribe((p) => {
+      console.log("patchlife1: ");
+      this.sourceGraphDataChanged(p); // todo
+    });
+  }
+
+  lostStore(s: Store) {
+    throw new Error("notimplemented");
+  }
+
+  sourceGraphDataChanged(p: Patch) {
+    console.log("patchlife2: multistore saw a graph change", p);
+
+    this.tempCombinedGraph = new Store();
+    for (let st of this.stores) {
+      for (let q of st.getQuads(null, null, null, null)) {
+        this.tempCombinedGraph.addQuad(q);
+      }
+    }
+    console.log("patchlife3: tempgraph is rebuilt");
+    this.graphChanged.emit(p);
+  }
+
+  //
+  // Store interface follows:
+  //
+  forEach(qfn: (qfn: Quad) => void, s: OTerm, p: OTerm, o: OTerm, g: OTerm) {
+    this.tempCombinedGraph.forEach(qfn, s, p, o, g);
+  }
+  countQuads(s: OTerm, p: OTerm, o: OTerm, g: OTerm): number {
+    return this.tempCombinedGraph.countQuads(s, p, o, g);
+    // const seen: Set<Quad> = new Set();
+    // let count = 0;
+    // for (let src of this.sources.currentSourceGraphs) {
+    //   for (let q of src.store.getQuads(s, p, o, g)) {
+    //     if (!seen.has(q)) {
+    //       count++;
+    //       seen.add(q);
+    //     }
+    //   }
+    // }
+    // return count;
+  }
+
+  get size(): number {
+    return this.countQuads(null, null, null, null);
+  }
+  has(quad: Quad): boolean {
+    throw new Error("notimplemented");
+  }
+  getQuads(
+    subject: OTerm,
+    predicate: OTerm,
+    object: OTerm | OTerm[],
+    graph: OTerm
+  ): Quad[] {
+    return this.tempCombinedGraph.getQuads(subject, predicate, object, graph);
+  }
+  match(
+    subject?: Term | null,
+    predicate?: Term | null,
+    object?: Term | null,
+    graph?: Term | null
+  ): RDF.Stream<Quad> & RDF.DatasetCore<Quad, Quad> {
+    throw new Error("notimplemented");
+  }
+
+  every(
+    callback: QuadPredicate<Quad>,
+    subject: OTerm,
+    predicate: OTerm,
+    object: OTerm,
+    graph: OTerm
+  ): boolean {
+    throw new Error("notimplemented");
+  }
+  some(
+    callback: QuadPredicate<Quad>,
+    subject: OTerm,
+    predicate: OTerm,
+    object: OTerm,
+    graph: OTerm
+  ): boolean {
+    throw new Error("notimplemented");
+  }
+  getSubjects(
+    predicate: OTerm,
+    object: OTerm,
+    graph: OTerm
+  ): Array<Quad["subject"]> {
+    throw new Error("notimplemented");
+  }
+  forSubjects(
+    callback: (result: Quad["subject"]) => void,
+    predicate: OTerm,
+    object: OTerm,
+    graph: OTerm
+  ): void {
+    throw new Error("notimplemented");
+  }
+  getPredicates(
+    subject: OTerm,
+    object: OTerm,
+    graph: OTerm
+  ): Array<Quad["predicate"]> {
+    throw new Error("notimplemented");
+    return [];
+  }
+  forPredicates(
+    callback: (result: Quad["predicate"]) => void,
+    subject: OTerm,
+    object: OTerm,
+    graph: OTerm
+  ): void {
+    throw new Error("notimplemented");
+  }
+  getObjects(
+    subject: OTerm,
+    predicate: OTerm,
+    graph: OTerm
+  ): Array<Quad["object"]> {
+    return this.tempCombinedGraph.getObjects(subject, predicate, graph);
+  }
+  forObjects(
+    callback: (result: Quad["object"]) => void,
+    subject: OTerm,
+    predicate: OTerm,
+    graph: OTerm
+  ): void {
+    throw new Error("notimplemented");
+  }
+  getGraphs(
+    subject: OTerm,
+    predicate: OTerm,
+    object: OTerm
+  ): Array<Quad["graph"]> {
+    throw new Error("notimplemented");
+  }
+  forGraphs(
+    callback: (result: Quad["graph"]) => void,
+    subject: OTerm,
+    predicate: OTerm,
+    object: OTerm
+  ): void {
+    throw new Error("notimplemented");
+  }
+  extractLists(options?: extractListOptions): Record<string, RDF.Term[]> {
+    throw new Error("notimplemented");
+  }
+  [Symbol.iterator](): Iterator<Quad> {
+    throw new Error("notimplemented");
+  }
+
+  add(): this {
+    throw new Error("MultiStore is readonly");
+  }
+  addQuad() {
+    throw new Error("notimplemented");
+  }
+  addQuads(): void {
+    throw new Error("MultiStore is readonly");
+  }
+  delete(): this {
+    throw new Error("MultiStore is readonly");
+  }
+  import(): EventEmitter {
+    throw new Error("MultiStore is readonly");
+  }
+  removeQuad(): void {
+    throw new Error("MultiStore is readonly");
+  }
+  removeQuads(): void {
+    throw new Error("MultiStore is readonly");
+  }
+  remove(): EventEmitter {
+    throw new Error("MultiStore is readonly");
+  }
+  removeMatches(): EventEmitter {
+    throw new Error("MultiStore is readonly");
+  }
+  deleteGraph(): EventEmitter {
+    throw new Error("MultiStore is readonly");
+  }
+  createBlankNode(): BlankNode {
+    throw new Error("MultiStore is readonly");
+  }
+}