commit bd6d5f675d5794f069464b1cfc78d56623512ce4
parent e0ffeaf3b5b4d6fc8732449e33f8b5f2fa0e2602
Author: Jacob R. Edwards <jacob@jacobedwards.org>
Date: Wed, 7 Aug 2024 15:06:11 -0700
Fix floorplan patching
Use json.Marshal and json.Unmarshal to just make it easy.
Floorplan addresses and synopses are now pointers and are null
instead of an empty string when unset. (A database migration file
was added to update the database with this new change.)
Diffstat:
4 files changed, 30 insertions(+), 33 deletions(-)
diff --git a/cmd/api/floorplans.go b/cmd/api/floorplans.go
@@ -1,7 +1,7 @@
package main
import (
- "errors"
+ "encoding/json"
"net/http"
"github.com/gin-gonic/gin"
@@ -10,8 +10,8 @@ import (
type SettableFloorplan struct {
Name string `json:"name" binding:"required"`
- Address string `json:"address"`
- Synopsis string `json:"synopsis"`
+ Address *string `json:"address"`
+ Synopsis *string `json:"synopsis"`
}
type Point struct {
@@ -48,40 +48,41 @@ func (e *Env) UpdateFloorplan(c *gin.Context) {
tx, err := e.backend.DB.Begin()
if err != nil {
- RespondError(c, 400, "Unable to begin transaction")
+ RespondError(c, 400, "Unable to begin transaction: %s", err.Error())
return
}
fp, err := e.backend.GetFloorplan(tx, user, name)
if err != nil {
tx.Rollback()
- RespondError(c, 400, "Unable to get floorplan")
+ RespondError(c, 400, "Unable to get floorplan: %s", err.Error())
return
}
- settable := toSettable(fp)
- if err = applyPatchset(settable, patches); err != nil {
+ patchable := backendToPatchable(fp)
+ if err = applyPatchset(patchable, patches); err != nil {
tx.Rollback()
- RespondError(c, 400, "Unable to patch floorplan")
+ RespondError(c, 400, "Unable to patch floorplan: %s", err.Error())
return
}
- newvals, err := fromSettable(user, settable)
+ settable, err := patchableToSettable(patchable)
if err != nil {
tx.Rollback()
- RespondError(c, 400, "Unable to care anymore")
+ RespondError(c, 400, "Unable to push update: %s", err.Error())
return
}
- fp, err = e.backend.UpdateFloorplan(tx, user, name, newvals)
+ newfp := backend.Floorplan{User: user, Name: settable.Name, Synopsis: settable.Synopsis, Address: settable.Address}
+ fp, err = e.backend.UpdateFloorplan(tx, user, name, &newfp)
if err != nil {
tx.Rollback()
- RespondError(c, 400, "Unable to push update")
+ RespondError(c, 400, "Unable to push update: %s", err.Error())
return
}
err = tx.Commit()
if err != nil {
- RespondError(c, 400, "Unable to commit update")
+ RespondError(c, 400, "Unable to commit update: %s", err.Error())
}
Respond(c, 200, fp)
}
@@ -166,25 +167,20 @@ func (e *Env) GetFloorplanPoints(c *gin.Context) {
}
}
-func fromSettable(user string, data map[string]interface{}) (*backend.Floorplan, error) {
- for k := range data {
- switch data[k].(type) {
- case string:
- default:
- return nil, errors.New("Invalid Type")
- }
+func patchableToSettable(data map[string]interface{}) (*SettableFloorplan, error) {
+ // Seems stupidly inefficient, but I can't find a better way at the moment
+ jsondata, err := json.Marshal(data)
+ if err != nil {
+ return nil, err
}
- return &backend.Floorplan{
- User: user,
- Name: data["name"].(string),
- Address: data["address"].(string),
- Synopsis: data["synopsis"].(string),
- }, nil
+
+ fp := &SettableFloorplan{}
+ return fp, json.Unmarshal(jsondata, fp)
}
-func toSettable(f *backend.Floorplan) map[string]interface{} {
+func backendToPatchable(f *backend.Floorplan) map[string]interface{} {
return map[string](interface{}){
- "name": f.Name,
+ "name": &f.Name,
"address": f.Address,
"synopsis": f.Synopsis,
}
diff --git a/cmd/api/migration/2024-08-07T21:56:31.sql b/cmd/api/migration/2024-08-07T21:56:31.sql
@@ -0,0 +1,2 @@
+UPDATE floorplans SET synopsis = null WHERE synopsis = '' ;
+UPDATE floorplans SET address = null WHERE address = '' ;
diff --git a/cmd/api/patch.go b/cmd/api/patch.go
@@ -6,7 +6,7 @@ type Patch struct {
Op string `json:"op" binding:"required"`
Path string `json:"path" binding:"required"`
From string `json:"from"`
- Value interface{} `json:"value" binding:"required"`
+ Value interface{} `json:"value"`
}
func applyPatchset(data map[string]interface{}, patches []Patch) error {
diff --git a/internal/backend/floorplan.go b/internal/backend/floorplan.go
@@ -9,8 +9,8 @@ type Floorplan struct {
id int
User string `json:"user"`
Name string `json:"name"`
- Address string `json:"address"`
- Synopsis string `json:"synopsis"`
+ Address *string `json:"address"`
+ Synopsis *string `json:"synopsis"`
Updated time.Time `json:"updated"`
Created time.Time `json:"created"`
}
@@ -150,4 +150,4 @@ func scanPoint(row Scanner) (Point, error) {
err := row.Scan(&point.Id, &point.X, &point.Y)
return point, err
-}
-\ No newline at end of file
+}