@mvarble/postgres-planar-graph
v0.0.0
Published
Interface planar graphs with a postgres database.
Downloads
2
Readme
postgres-planar-graph
Interface planar graphs with a postgres database.
Schema
This package assumes we are interacting with tables that have been generated by:
CREATE TABLE graph_node(
id SERIAL PRIMARY KEY,
graph INTEGER NOT NULL,
x FLOAT,
y FLOAT
);
CREATE TABLE graph_edge(
id SERIAL PRIMARY KEY,
graph INTEGER NOT NULL,
head INTEGER REFERENCES graph_node(id) NOT NULL,
tail INTEGER REFERENCES graph_node(id) NOT NULL,
index INTEGER
);
REST API
We will suppose we are dealing with a server that has the following request/response structure.
GET requests
By performing a GET request with a graph
parameter for querying a planar graph, you will get an object of the form:
{
id,
nodes: [
{ id, graph, location? },
...,
{ id, graph, location? },
],
edges: [
{ id, graph, head, tail, index? },
...,
{ id, graph, head, tail, index? },
]
}
corresponding to a parsed version of the rows of the tables graph_node
and graph_edge
in which the graph.id
matches the query parameter of the GET request.
The parsing is such that *.dbKey
corresponds to graph_*.id
, node.location
corresponds to the array [graph_node.x, graph_node.y]
, and the others *.*
match the database graph_*.*
.
POST requests
We will assume that performing a POST request to the server with the following body shape will resolve the associated CRUD operations on the server.
{
createNodes: [
{ tempId, graph, location? },
...
{ tempId, graph, location? },
],
updateNodes: [
{ id, graph, location? },
...
{ id, graph, location? },
],
deleteNodes: [id, ..., id],
createEdges: [
{ graph, head/tempHead, tail/tempTail, index? },
...
{ graph, head/tempHead, tail/tempTail, index? },
],
updateEdges: [
{ id, graph, head/tempHead, tail/tempTail, index? },
...
{ id, graph, head/tempHead, tail/tempTail, index? },
],
deleteNodes: [id, ..., id],
}
The purpose of node.tempId
is to allow edges to be defined from edge.tempHead
and edge.tempTail
when the head and tail nodes are not yet resolved in the database, respectively.
In other words, the server will run:
INSERT INTO route_node (graph, x, y)
VALUES (...), (...), ... (...)
RETURNING id;
and then convert any edge.tempHead
/edge.tempTail
to edge.head
/edge.tail
by comparing node.tempId
to the returned value of the operation above.
API
With the discussion above, one can see how the following functions exported by this module are helpful for interacting applications like viewport-planar-graph with such a database.
createRequest
requestBody = createRequest(oldGraph, graph)
This function will compare two objects oldGraph
and graph
, where oldGraph
is of the shape provided by a GET request to the API, and graph
is the same, except in regards to the id
/head
/tail
attributes possibly being their tempId
/tempHead
/tempTail
counterparts.
The returned requestBody
is that of the POST request.
isPOSTRequest
bool = isPOSTRequest(request)
This function will return the truth value of request
having the shape of the POST request.
isDBGraph
bool = isDBGraph(dbGraph)
This function will return the truth value of dbGraph
having the shape of the GET request.
It also checks if each of the edge.head
and edge.tail
attributes match some node.id
.
isGraph
bool = isGraph(Graph)
This function will return the truth value of graph
having the shape of the GET request, except in regards to the id
/head
/tail
keys potentially being their tempId
/tempHead
/tempTail
counterparts.
It also performs the checks of whether (1) each edge.head
and edge.tail
attributes match to some node.id
and (2) each edge.tempHead
and edge.tempTail
attributes match to some node.tempId
.
mapIds
newRequest = mapIds(request, rows)
This function does the job of getting the array rows
returned by
INSERT INTO route_node (graph, x, y)
VALUES (...) /* data of request.createNodes */
RETURNING id;
and returning and object newRequest
in which the edges with edge.tempHead
/edge.tempTail
will have the corresponding edge.head
/edge.tail
resolved.