view src/MultiStore.ts @ 146:9347277e8311

try a bit harder to notice <sg-source> children after <streamed-graph> startup
author drewp@bigasterisk.com
date Mon, 08 May 2023 13:52:50 -0700
parents 379c4294dd0f
children
line wrap: on
line source

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, PatchDirection } 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) {
    for (let ts of this.stores) {
      if (ts==s.store) {
        return;
      }
    }
    this.stores.push(s.store);
    const p = new Patch(PatchDirection.ADD); // todo
    s.sourceGraphChanged.subscribe((p) => {
      this.sourceGraphDataChanged(p); // todo
    });
  }

  lostStore(s: Store) {
    throw new Error("notimplemented");
  }

  sourceGraphDataChanged(p: Patch) {

    this.tempCombinedGraph = new Store();
    for (let st of this.stores) {
      for (let q of st.getQuads(null, null, null, null)) {
        this.tempCombinedGraph.addQuad(q);
      }
    }
    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");
  }
}