Skip to content

Instantly share code, notes, and snippets.

@tdolsen
Last active April 30, 2023 02:49
Show Gist options
  • Save tdolsen/6823f5e512ec8b88ff367a2a0dafcf71 to your computer and use it in GitHub Desktop.
Save tdolsen/6823f5e512ec8b88ff367a2a0dafcf71 to your computer and use it in GitHub Desktop.
Implementation of Closure Table hierarchy in EdgeDB.

EdgeDB Closure Table

A barebone implementation of hierarchical object structures using EdgeDB.

Very rudimentary and only provisionally tested. Has no indexes yet, doesn't use links, and probably other inefficiencies.

Use at your own peril.

module tree {
type Closure {
required property parent -> uuid;
required property child -> uuid;
required property depth -> int64;
}
type Node {}
}
with module tree,
C := (select Closure filter .parent = <uuid>$nodeId)
delete Closure filter .child in C.child;
with module tree,
NID := <uuid>$nodeId,
PID := <optional uuid>$parentId,
N := (insert Closure { parent := NID, child := NID, depth := 0 }),
P := (select Closure filter .child = PID),
C := (
for C in (select (P.parent, N.child, P.depth + N.depth + 1))
union (insert Closure { parent := C.0, child := C.1, depth := C.2})
)
select N union C;
with module tree,
NID := <uuid>$nodeId,
PID := <uuid>$newParentId,
N := (select Closure filter .child = NID and .parent = NID),
P := (select Closure filter .child = NID and .parent != .child),
C := (select Closure filter .parent = NID),
NP := (select Closure filter .child = PID),
D := (delete Closure filter .child = C.child and .parent = P.parent),
T := (
for X in (select (NP.parent, C.child, NP.depth + C.depth + 1))
union (insert Closure { parent := X.0, child := X.1, depth := X.2})
)
select (select N union T) { parent, child, depth };
with module tree,
NID := <uuid>$nodeId,
DEPTH := <optional int64>$maxDepth,
P := (
select Closure filter all({
.child = NID,
.parent != NID,
.depth <= DEPTH,
})
)
select Node filter .id = P.parent;
with module tree,
NID := <uuid>$nodeId,
DEPTH := <optional int64>$maxDepth,
C := (
select Closure filter all({
.child != NID,
.parent = NID,
.depth <= DEPTH,
})
)
select Node filter .id = C.child;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment