# HG changeset patch
# User drewp@bigasterisk.com
# Date 1647069575 28800
# Node ID ab7dca42afbdc4e2affd4db02ccdd7413969d869
# Parent 76c1a29a328fe024fdd04a4af007c3ebc52bd7ca
rewrite ViewConfig
diff -r 76c1a29a328f -r ab7dca42afbd src/ViewConfig.test.ts
--- /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: .
+ @prefix demo: .
+ @prefix rdfs: .
+ @prefix : .
+
+ <> 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")]);
+ });
+});
diff -r 76c1a29a328f -r ab7dca42afbd src/ViewConfig.ts
--- /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(seq: Iterable): 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";
+ }
+}
diff -r 76c1a29a328f -r ab7dca42afbd src/fetchAndParse.ts
--- 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 {
+ const res = await fetch(url);
+ const body = await res.text();
+ return n3Graph(body, store);
+}
-export async function fetchAndParse(url: string): Promise {
- 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 {
+ 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;
+ });
}
diff -r 76c1a29a328f -r ab7dca42afbd src/view_loader.ts
--- 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(seq: Iterable): 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;
- 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;
- }
-}