changeset 102:ab7dca42afbd

rewrite ViewConfig
author drewp@bigasterisk.com
date Fri, 11 Mar 2022 23:19:35 -0800
parents 76c1a29a328f
children f12feced00ce
files src/ViewConfig.test.ts src/ViewConfig.ts src/fetchAndParse.ts src/view_loader.ts
diffstat 4 files changed, 119 insertions(+), 84 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ViewConfig.test.ts	Fri Mar 11 23:19:35 2022 -0800
@@ -0,0 +1,25 @@
+import { Util } from "n3";
+import { ViewConfig } from "./ViewConfig";
+
+describe("ViewModel", () => {
+  it("gets a table description", async () => {
+    const vc = new ViewConfig();
+
+    await vc.readFromGraph(`
+        @prefix ex: <http://example.com/> .
+        @prefix demo: <http://example.com/demo/> .
+        @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+        @prefix : <http://bigasterisk.com/netRoutes/ns#> .
+
+        <> a ex:View ; rdfs:label "repos" .
+        <> ex:table demo:table1 .
+        demo:table1 
+        ex:primaryType :FilteredNic;
+        ex:joinType :Traffic .
+        `);
+    const NET = Util.prefix("http://bigasterisk.com/netRoutes/ns#");
+
+    expect(vc.tables[0].primary).toEqual(NET("FilteredNic"));
+    expect(vc.tables[0].joins).toEqual([NET("Traffic")]);
+  });
+});
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ViewConfig.ts	Fri Mar 11 23:19:35 2022 -0800
@@ -0,0 +1,70 @@
+// Load requested view (rdf data) and provide access to it
+import { DataFactory, NamedNode, Store } from "n3";
+import { fetchAndParse, n3Graph } from "./fetchAndParse";
+import { EX, RDF } from "./namespaces";
+import { labelOrTail, uriValue } from "./rdf_value";
+const Uri = DataFactory.namedNode;
+
+function firstElem<E>(seq: Iterable<E>): E {
+  for (let e of seq) {
+    return e;
+  }
+  throw new Error("no elems");
+}
+
+export interface TableDesc {
+  uri: NamedNode;
+  primary: NamedNode;
+  joins: NamedNode[];
+}
+
+export class ViewConfig {
+  graph: Store;
+  viewRoot!: NamedNode;
+  url?: string;
+  tables: TableDesc[] = [];
+
+  constructor() {
+    this.graph = new Store();
+  }
+
+  async readFromUrl(url: string | "") {
+    if (!url) {
+      return;
+    }
+    await fetchAndParse(url, this.graph);
+
+    this._read();
+  }
+
+  async readFromGraph(n3: string) {
+    this.graph = await n3Graph(n3);
+    this._read();
+  }
+
+  _read() {
+    this.viewRoot = firstElem(
+      this.graph.getSubjects(RDF("type"), EX("View"), null)
+    ) as NamedNode;
+    for (let table of this.graph.getObjects(this.viewRoot, EX("table"), null)) {
+      const tableType = uriValue(this.graph, table, EX("primaryType"));
+      const joins: NamedNode[] = [];
+      for (let joinType of this.graph.getObjects(table, EX("joinType"), null)) {
+        joins.push(joinType as NamedNode);
+      }
+      joins.sort();
+      this.tables.push({
+        uri: table as NamedNode,
+        primary: tableType,
+        joins: joins,
+      });
+    }
+    this.tables.sort();
+  }
+
+  label(): string {
+    return this.url !== undefined
+      ? labelOrTail(this.graph, Uri(this.url))
+      : "unnamed";
+  }
+}
--- a/src/fetchAndParse.ts	Fri Feb 11 23:24:41 2022 -0800
+++ b/src/fetchAndParse.ts	Fri Mar 11 23:19:35 2022 -0800
@@ -1,21 +1,27 @@
-import { Store, Parser } from "n3";
+import { Store, Parser, Quad, Prefixes } from "n3";
+
+export async function fetchAndParse(
+  url: string,
+  store?: Store
+): Promise<Store> {
+  const res = await fetch(url);
+  const body = await res.text();
+  return n3Graph(body, store);
+}
 
-export async function fetchAndParse(url: string): Promise<Store> {
-    const store = new Store();
-    const res = await fetch(url);
-    const body = await res.text();
-    const parser = new Parser({ format: "N3" });
-    await new Promise((done, rej) => {
-        parser.parse(body, (err, quad, prefixes) => {
-            if (err) {
-                throw err;
-            }
-            if (quad) {
-                store.addQuad(quad);
-            } else {
-                done(null);
-            }
-        });
+export async function n3Graph(n3: string, store?: Store): Promise<Store> {
+  if (store === undefined) {
+    store = new Store();
+  }
+
+  const parser = new Parser({ format: "N3" });
+  return new Promise((res, rej) => {
+    parser.parse(n3, (error, quad: Quad, prefixes: Prefixes) => {
+      if (quad) {
+        store!.addQuad(quad);
+      } else {
+        res(store!);
+      }
     });
-    return store;
+  });
 }
--- a/src/view_loader.ts	Fri Feb 11 23:24:41 2022 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-// Load requested view and provide access to it
-import { Store, NamedNode, DataFactory } from "n3";
-import { fetchAndParse } from "./fetchAndParse";
-import { RDF, EX } from "./namespaces";
-import { labelOrTail, uriValue } from "./rdf_value";
-const Uri = DataFactory.namedNode;
-
-function firstElem<E>(seq: Iterable<E>): E {
-  for (let e of seq) {
-    return e;
-  }
-  throw new Error("no elems");
-}
-
-export interface TableDesc {
-  uri: NamedNode;
-  primary: NamedNode;
-  joins: NamedNode[];
-}
-
-
-export class View {
-  graph: Store;
-  ready: Promise<null>;
-  viewRoot!: NamedNode;
-
-  constructor(public url: string | "") {
-    (window as any).v = this; //debug
-    this.graph = new Store();
-    this.ready = new Promise((res, rej) => {
-      if (url) {
-        fetchAndParse(url).then((s2) => {
-          this.graph = s2;
-          res(null);
-        });
-      } else {
-        res(null);
-      }
-    });
-    this.ready.then(() => {
-      this.viewRoot = firstElem(
-        this.graph.getSubjects(RDF("type"), EX("View"), null)
-      ) as NamedNode;
-    });
-  }
-
-  label() {
-    return labelOrTail(this.graph, Uri(this.url));
-  }
-
-  // filtered+ordered list of types to show at the top level
-  toplevelTables(typesPresent: NamedNode[]): TableDesc[] {
-    const ret: TableDesc[] = [];
-    for (let table of this.graph.getObjects(this.viewRoot, EX("table"), null)) {
-      const tableType = uriValue(this.graph, table, EX("primaryType"));
-      const joins: NamedNode[] = [];
-      for (let joinType of this.graph.getObjects(table, EX("joinType"), null)) {
-        joins.push(joinType as NamedNode);
-      }
-      joins.sort();
-      ret.push({ uri: table as NamedNode, primary: tableType, joins: joins });
-    }
-    ret.sort();
-    return ret;
-  }
-}