Initial rendering of the node tree

This commit is contained in:
Magnus Åhall 2025-07-02 18:02:09 +02:00
commit c5bec0afa6
7477 changed files with 8513 additions and 0 deletions

124
node.go Normal file
View file

@ -0,0 +1,124 @@
package main
import (
// External
"github.com/jmoiron/sqlx"
// Standard
"time"
)
type Node struct {
ID int
Name string
ParentID int `db:"parent_id"`
TypeID int `db:"type_id"`
TypeName string `db:"type_name"`
TypeIcon string `db:"type_icon"`
Updated time.Time
Data any
RawData []byte `db:"raw_data"`
NumChildren int `db:"num_children"`
Children []*Node
}
func GetNode(startNodeID, maxDepth int) (topNode *Node, err error) {
nodes := make(map[int]*Node)
var rows *sqlx.Rows
rows, err = GetNodeRows(startNodeID, maxDepth)
if err != nil {
return
}
defer rows.Close()
first := true
for rows.Next() {
var node Node
err = rows.StructScan(&node)
if err != nil {
return
}
if first {
topNode = &node
first = false
}
ComposeTree(nodes, &node)
}
return
}
func GetNodeRows(startNodeID, maxDepth int) (rows *sqlx.Rows, err error) {
rows, err = db.Queryx(`
WITH RECURSIVE nodes AS (
SELECT
COALESCE(
(SELECT parent FROM connection WHERE child = $1),
0
) AS parent_id,
$1::int AS id,
0 AS depth
UNION
SELECT
c.parent,
c.child,
ns.depth+1 AS depth
FROM connection c
INNER JOIN nodes ns ON ns.depth < $2 AND c.parent = ns.id
)
SEARCH DEPTH FIRST BY id SET ordercol
SELECT
ns.parent_id,
n.id,
n.name,
n.type_id,
t.name AS type_name,
COALESCE(t.schema->>'icon', '') AS type_icon,
n.updated,
n.data AS raw_data,
COUNT(c.child) AS num_children
FROM nodes ns
INNER JOIN public.node n ON ns.id = n.id
INNER JOIN public.type t ON n.type_id = t.id
LEFT JOIN public.connection c ON c.parent = n.id
GROUP BY
ns.depth,
ns.parent_id,
n.id,
t.name,
t.schema,
ns.ordercol
ORDER BY ordercol
`,
startNodeID,
maxDepth,
)
return
}
func ComposeTree(nodes map[int]*Node, node *Node) {
if node.Children == nil {
node.Children = []*Node{}
}
parentNode, found := nodes[node.ParentID]
if found {
if parentNode.Children == nil {
parentNode.Children = []*Node{node}
} else {
parentNode.Children = append(parentNode.Children, node)
}
}
nodes[node.ID] = node
}