commit 82631a30079a6f37280a626d842326a323c4a810
parent 1e8fdf249beaee2e40577ffacc53255890f371d5
Author: Jacob R. Edwards <jacob@jacobedwards.org>
Date: Fri, 23 Aug 2024 14:39:05 -0700
Add checks and options to point removal in the backend
The removePoint method now does checks to ensure that no pointmap
references the point before deletion. It can also delete all pointmaps
that reference it if given the 'recurse' or 'unmap' option, and
will furthermore delete all orphaned points if given the 'recurse'
option.
Orphaned points is a new concept that means any point not connected
by pointmaps to the origin point. The origin point is the first
point in the diffs that currently exists.
Diffstat:
1 file changed, 67 insertions(+), 2 deletions(-)
diff --git a/files/floorplans/floorplan/backend.js b/files/floorplans/floorplan/backend.js
@@ -448,7 +448,25 @@ export class FloorplanBackend {
}
removePoint(id, options) {
- return this.removeData("points", id, options)
+ options = options ?? {}
+
+ if (!this.mappedPoints[id]) {
+ return this.removeData("points", id, options)
+ }
+
+ if (!options.unmap && !options.recurse) {
+ throw new Error("Point is mapped")
+ }
+
+ for (let other in this.mappedPoints[id]) {
+ this.unmapPoints(this.mappedPoints[id][other])
+ }
+
+ this.removeData("points", id, options)
+
+ if (options.recurse) {
+ this.removeOrphans()
+ }
}
// Returns map id
@@ -472,7 +490,11 @@ export class FloorplanBackend {
}
unmapPoints(id, options) {
- return removeData("pointmaps", id, options)
+ options = options ?? {}
+ this.removeData("pointmaps", id, options)
+ if (options.recurse) {
+ this.removeOrphans()
+ }
}
reqId(type, id) {
@@ -626,6 +648,49 @@ export class FloorplanBackend {
}
return this.mappedPoints[a][b]
}
+
+ removeOrphans() {
+ let origin = this.originPoint()
+ if (origin == undefined) {
+ return
+ }
+
+ let connected = this.connected(origin)
+ let again = false
+ for (let id in this.cache.points) {
+ if (!connected[id]) {
+ this.removePoint(id, { unmap: true })
+ again = true
+ }
+ }
+ if (again) {
+ this.removeOrphans()
+ }
+ }
+
+ originPoint() {
+ for (let i in this.history.diffs) {
+ let ref = parsePath(this.history.diffs[i].path)
+ if (ref.type === "points" && this.cache.points[ref.id] != undefined) {
+ return ref.id
+ }
+ }
+
+ return undefined
+ }
+
+ connected(p, map) {
+ if (!map) {
+ map = {}
+ }
+ map[p] = true
+ for (let other in this.mappedPoints[p]) {
+ if (!map[other]) {
+ this.connected(other, map)
+ }
+ }
+ return map
+ }
}
function gendiff(path, a, b) {