Notes/node.go
Magnus Åhall c255b58335 Wip
2023-06-17 09:11:14 +02:00

184 lines
3.0 KiB
Go

package main
import (
// External
"github.com/jmoiron/sqlx"
// Standard
)
type Node struct {
ID int
UserID int `db:"user_id"`
ParentID int `db:"parent_id"`
Name string
Content string
Children []Node
Crumbs []Node
Complete bool
}
func (session Session) RootNode() (node Node, err error) {// {{{
var rows *sqlx.Rows
rows, err = db.Queryx(`
SELECT
id,
user_id,
0 AS parent_id,
name
FROM node
WHERE
user_id = $1 AND
parent_id IS NULL
`,
session.UserID,
)
if err != nil {
return
}
defer rows.Close()
node.Name = "Start"
node.UserID = session.UserID
node.Complete = true
node.Children = []Node{}
node.Crumbs = []Node{}
for rows.Next() {
row := Node{}
if err = rows.StructScan(&row); err != nil {
return
}
node.Children = append(node.Children, Node{
ID: row.ID,
UserID: row.UserID,
ParentID: row.ParentID,
Name: row.Name,
})
}
return
}// }}}
func (session Session) Node(nodeID int) (node Node, err error) {// {{{
if nodeID == 0 {
return session.RootNode()
}
var rows *sqlx.Rows
rows, err = db.Queryx(`
WITH RECURSIVE recurse AS (
SELECT
id,
user_id,
COALESCE(parent_id, 0) AS parent_id,
name,
content,
0 AS level
FROM node
WHERE
user_id = $1 AND
id = $2
UNION
SELECT
n.id,
n.user_id,
n.parent_id,
n.name,
'' AS content,
r.level + 1 AS level
FROM node n
INNER JOIN recurse r ON n.parent_id = r.id AND r.level = 0
WHERE
n.user_id = $1
)
SELECT * FROM recurse ORDER BY level ASC
`,
session.UserID,
nodeID,
)
if err != nil {
return
}
defer rows.Close()
type resultRow struct {
Node
Level int
}
for rows.Next() {
row := resultRow{}
if err = rows.StructScan(&row); err != nil {
return
}
if row.Level == 0 {
node = Node{}
node.Children = []Node{}
node.ID = row.ID
node.UserID = row.UserID
node.ParentID = row.ParentID
node.Name = row.Name
node.Content = row.Content
node.Complete = true
}
if row.Level == 1 {
node.Children = append(node.Children, Node{
ID: row.ID,
UserID: row.UserID,
ParentID: row.ParentID,
Name: row.Name,
})
}
}
node.Crumbs, err = session.NodeCrumbs(node.ID)
return
}// }}}
func (session Session) NodeCrumbs(nodeID int) (nodes []Node, err error) {// {{{
var rows *sqlx.Rows
rows, err = db.Queryx(`
WITH RECURSIVE nodes AS (
SELECT
id,
COALESCE(parent_id, 0) AS parent_id,
name
FROM node
WHERE
id = $1
UNION
SELECT
n.id,
COALESCE(n.parent_id, 0) AS parent_id,
n.name
FROM node n
INNER JOIN nodes nr ON n.id = nr.parent_id
)
SELECT * FROM nodes
`, nodeID)
if err != nil {
return
}
defer rows.Close()
nodes = []Node{}
for rows.Next() {
node := Node{}
if err = rows.StructScan(&node); err != nil {
return
}
nodes = append(nodes, node)
}
return
}// }}}
// vim: foldmethod=marker