new respond to send all create change delete different bug fixes

This commit is contained in:
Adrian Zuercher
2025-07-23 09:10:56 +02:00
parent 8be5c80a22
commit c37dd87a37
6 changed files with 78 additions and 58 deletions

View File

@@ -67,9 +67,7 @@ func (d *DBMHandler) Delete(c *gin.Context) {
} }
response := json_data.NewResponse() response := json_data.NewResponse()
if payload.Set != nil { if payload.Set != nil {
response.Set, err = d.DBM.RemoveDatapoint(payload.Set...) response.Set, err = d.DBM.RemoveDatapoint(payload.Set...)
if err != nil { if err != nil {
r := json_data.NewResponse() r := json_data.NewResponse()

View File

@@ -49,6 +49,7 @@ func (d *DBMHandler) Subscribe(req *json_dataModels.Request, id string) {
Path: dp.Path, Path: dp.Path,
Value: dp.Value, Value: dp.Value,
HasChild: dp.Datapoints != nil, HasChild: dp.Datapoints != nil,
Rights: dp.ReadWrite.GetRights(),
Driver: sub.Driver, Driver: sub.Driver,
Drivers: &dp.Drivers, Drivers: &dp.Drivers,
}) })

2
go.mod
View File

@@ -7,7 +7,7 @@ require (
github.com/gin-gonic/gin v1.10.0 github.com/gin-gonic/gin v1.10.0
github.com/google/uuid v1.6.0 github.com/google/uuid v1.6.0
github.com/gorilla/websocket v1.5.3 github.com/gorilla/websocket v1.5.3
github.com/tecamino/tecamino-json_data v0.0.17 github.com/tecamino/tecamino-json_data v0.0.19
github.com/tecamino/tecamino-logger v0.2.0 github.com/tecamino/tecamino-logger v0.2.0
) )

4
go.sum
View File

@@ -71,8 +71,8 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tecamino/tecamino-json_data v0.0.17 h1:M12UzKbfIgu/q3ERsEhGNDV3DYOvc0TioU288kQjDCA= github.com/tecamino/tecamino-json_data v0.0.19 h1:jaEiY38Rdur1ZKJ5/5H/7ZL5vn1NdUnM/0bQj2vByKc=
github.com/tecamino/tecamino-json_data v0.0.17/go.mod h1:LLlyD7Wwqplb2BP4PeO86EokEcTRidlW5MwgPd1T2JY= github.com/tecamino/tecamino-json_data v0.0.19/go.mod h1:LLlyD7Wwqplb2BP4PeO86EokEcTRidlW5MwgPd1T2JY=
github.com/tecamino/tecamino-logger v0.2.0 h1:NPH/Gg9qRhmVoW8b39i1eXu/LEftHc74nyISpcRG+XU= github.com/tecamino/tecamino-logger v0.2.0 h1:NPH/Gg9qRhmVoW8b39i1eXu/LEftHc74nyISpcRG+XU=
github.com/tecamino/tecamino-logger v0.2.0/go.mod h1:0M1E9Uei/qw3e3WA1x3lBo1eP3H5oeYE7GjYrMahnj8= github.com/tecamino/tecamino-logger v0.2.0/go.mod h1:0M1E9Uei/qw3e3WA1x3lBo1eP3H5oeYE7GjYrMahnj8=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=

View File

@@ -55,8 +55,8 @@ func (d *Datapoint) Set(path string, set json_dataModels.Set) (bool, error) {
changed = true changed = true
d.Value = d.Type.ConvertValue(set.Value) d.Value = d.Type.ConvertValue(set.Value)
} }
} }
if set.Rights != "" { if set.Rights != "" {
changed = true changed = true
d.ReadWrite = set.Rights.GetRights() d.ReadWrite = set.Rights.GetRights()
@@ -108,7 +108,8 @@ func (d *Datapoint) CreateDatapoints(sets ...json_dataModels.Set) (created []jso
if i == len(parts)-1 { if i == len(parts)-1 {
// Leaf node: create or update datapoint // Leaf node: create or update datapoint
if existing, ok := current.Datapoints[part]; ok { if existing, ok := current.Datapoints[part]; ok {
publish, err := existing.Set("", dp)
_, err := existing.Set("", dp)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
@@ -122,18 +123,18 @@ func (d *Datapoint) CreateDatapoints(sets ...json_dataModels.Set) (created []jso
Updated: true, Updated: true,
}) })
if publish { existing.Publish(OnChange)
existing.Publish(OnChange)
}
} else { } else {
ndp := Datapoint{ ndp := Datapoint{
Uuid: uuid.New(), Uuid: uuid.New(),
CreateDateTime: time.Now().UnixMilli(), CreateDateTime: time.Now().UnixMilli(),
Subscriptions: InitSubscribtion(), Subscriptions: InitSubscribtion(),
} }
// Create new // Create new
current.Datapoints[part] = &ndp current.Datapoints[part] = &ndp
publish, err := ndp.Set(strings.Join(parts, ":"), dp) _, err := ndp.Set(strings.Join(parts, ":"), dp)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
@@ -145,10 +146,9 @@ func (d *Datapoint) CreateDatapoints(sets ...json_dataModels.Set) (created []jso
Rights: ndp.ReadWrite, Rights: ndp.ReadWrite,
Driver: dp.Driver, Driver: dp.Driver,
}) })
if publish { ndp.Publish(OnCreate)
current.Publish(OnChange)
} //add uuid to flat map for faster lookup
//add uuid to flat map for faster lookuo
uuids[ndp.Uuid] = &ndp uuids[ndp.Uuid] = &ndp
} }
} }
@@ -178,6 +178,8 @@ func (d *Datapoint) CreateDatapoints(sets ...json_dataModels.Set) (created []jso
newDp.ReadWrite = dp.Rights.GetRights() newDp.ReadWrite = dp.Rights.GetRights()
} }
newDp.Publish(OnCreate)
current.Datapoints[part] = newDp current.Datapoints[part] = newDp
current = newDp current = newDp
@@ -214,7 +216,7 @@ func (d *Datapoint) ImportDatapoint(dp *Datapoint, path string) (uuids Uuids, er
dp.UpdateDateTime = time.Now().UnixMilli() dp.UpdateDateTime = time.Now().UnixMilli()
dp.Subscriptions = InitSubscribtion() dp.Subscriptions = InitSubscribtion()
current.Datapoints[part] = dp current.Datapoints[part] = dp
//add uuid to flat map for faster lookuo //add uuid to flat map for faster lookup
uuids[dp.Uuid] = dp uuids[dp.Uuid] = dp
dp.Publish(OnChange) dp.Publish(OnChange)
} }
@@ -270,47 +272,64 @@ func (d *Datapoint) UpdateValue(conns *ws.ClientHandler, value any) error {
return nil return nil
} }
func (d *Datapoint) RemoveDatapoint(conns *ws.ClientHandler, set json_dataModels.Set) (json_dataModels.Set, error) { func (d *Datapoint) RemoveDatapoint(conns *ws.ClientHandler, set json_dataModels.Set) (sets []json_dataModels.Set, err error) {
parts := strings.Split(set.Path, ":") parts := strings.Split(set.Path, ":")
if len(parts) < 1 { if len(parts) < 1 {
return json_dataModels.Set{}, fmt.Errorf("invalid path: '%s'", set.Path) return sets, fmt.Errorf("invalid path: '%s'", set.Path)
} }
current := d current := d
for i := 0; i < len(parts)-1; i++ { for i := 0; i < len(parts)-1; i++ {
next, ok := current.Datapoints[parts[i]] next, ok := current.Datapoints[parts[i]]
if !ok { if !ok {
return json_dataModels.Set{}, fmt.Errorf("path not found: '%s'", strings.Join(parts[:i+1], ":")) return sets, fmt.Errorf("path not found: '%s'", strings.Join(parts[:i+1], ":"))
} }
current = next current = next
} }
toDelete := parts[len(parts)-1] toDelete := parts[len(parts)-1]
if dp, ok := current.Datapoints[toDelete]; ok { if dp, ok := current.Datapoints[toDelete]; ok {
sets = append(sets, removeChildren(dp)...)
dp.Publish(OnDelete) dp.Publish(OnDelete)
sets = append(sets, json_dataModels.Set{
Uuid: dp.Uuid,
Path: dp.Path,
})
delete(current.Datapoints, toDelete) delete(current.Datapoints, toDelete)
return json_dataModels.Set{ return sets, nil
Uuid: set.Uuid,
Path: set.Path,
}, nil
} }
return json_dataModels.Set{}, fmt.Errorf("datapoint '%s' not found", set.Path) return sets, fmt.Errorf("datapoint '%s' not found", set.Path)
}
// removes all children and grandchlidren of datapoint
func removeChildren(dp *Datapoint) (sets []json_dataModels.Set) {
for name, d := range dp.Datapoints {
sets = append(sets, removeChildren(d)...)
d.Publish(OnDelete)
sets = append(sets, json_dataModels.Set{
Uuid: d.Uuid,
Path: d.Path,
})
delete(d.Datapoints, name)
}
return sets
} }
func (d *Datapoint) GetAllDatapoints(depth uint) (dps Datapoints) { func (d *Datapoint) GetAllDatapoints(depth uint) (dps Datapoints) {
var dfs func(dp *Datapoint, currentDepth uint) var dfs func(dp *Datapoint, currentDepth uint)
dfs = func(dp *Datapoint, currentDepth uint) { dfs = func(dp *Datapoint, currentDepth uint) {
if depth == 1 { switch depth {
return case 0:
} else if depth == 0 {
// Return all descendants // Return all descendants
for _, child := range dp.Datapoints { for _, child := range dp.Datapoints {
dps = append(dps, child) dps = append(dps, child)
dfs(child, currentDepth+1) dfs(child, currentDepth+1)
} }
return return
case 1:
return
} }
if currentDepth == depth-1 { if currentDepth == depth-1 {
@@ -379,22 +398,26 @@ func (d *Datapoint) RemoveSubscribtion(client *wsModels.Client) {
} }
func (d *Datapoint) Publish(eventType string) error { func (d *Datapoint) Publish(eventType string) error {
for client := range d.Subscriptions { r := json_data.NewResponse()
r := json_data.NewResponse() r.AddPublish(json_dataModels.Publish{
r.AddPublish(json_dataModels.Publish{ Event: eventType,
Event: eventType, Uuid: d.Uuid,
Uuid: d.Uuid, Path: d.Path,
Path: d.Path, Type: d.Type,
Type: d.Type, Value: d.Value,
Value: d.Value, })
})
b, err := json.Marshal(r) b, err := json.Marshal(r)
if err != nil { if err != nil {
return err return err
}
switch eventType {
case OnCreate, OnDelete:
ws.SendBroadcast(b)
default:
for client := range d.Subscriptions {
client.SendResponse(b)
} }
client.SendResponse(b)
} }
return nil return nil
} }

View File

@@ -87,18 +87,20 @@ func (d *DBM) UpdateDatapointValue(value any, uid uuid.UUID, path ...string) err
return d.Datapoints.UpdateDatapointValue(value, path[0]) return d.Datapoints.UpdateDatapointValue(value, path[0])
} }
func (d *DBM) RemoveDatapoint(sets ...json_dataModels.Set) ([]json_dataModels.Set, error) { func (d *DBM) RemoveDatapoint(sets ...json_dataModels.Set) (lsRemoved []json_dataModels.Set, err error) {
var lsRemoved []json_dataModels.Set
for _, set := range sets { for _, set := range sets {
removed, err := d.Datapoints.RemoveDatapoint(d.Conns, set) if set.Path == "" {
if err != nil { if dp, ok := d.Uuids[set.Uuid]; ok {
return lsRemoved, err set.Path = dp.Path
}
} }
lsRemoved = append(lsRemoved, removed) lsRemoved, err = d.Datapoints.RemoveDatapoint(d.Conns, set)
d.ModifyCountedDatapoints(1, true) if err != nil {
return
}
d.ModifyCountedDatapoints(uint64(len(lsRemoved)), true)
} }
return
return lsRemoved, nil
} }
func (d *DBM) QueryDatapoints(depth uint, uid uuid.UUID, key ...string) []*Datapoint { func (d *DBM) QueryDatapoints(depth uint, uid uuid.UUID, key ...string) []*Datapoint {
@@ -159,8 +161,6 @@ func (d *DBM) GoSystemTime() error {
func (d *DBM) GoSystemMemory() error { func (d *DBM) GoSystemMemory() error {
path := "System:UsedMemory" path := "System:UsedMemory"
var m runtime.MemStats
var mOld uint64
typ := json_dataModels.STR typ := json_dataModels.STR
rights := json_dataModels.Read rights := json_dataModels.Read
@@ -172,13 +172,11 @@ func (d *DBM) GoSystemMemory() error {
go func() { go func() {
for { for {
var m runtime.MemStats
runtime.ReadMemStats(&m) runtime.ReadMemStats(&m)
if m.Sys != mOld { mem := fmt.Sprintf("%.2f MB", float64(m.Alloc)/1024/1024)
mem := fmt.Sprintf("%.2f MB", float64(m.Sys)/1024/1024) if er := d.UpdateDatapointValue(mem, uuid.Nil, path); er != nil {
if er := d.UpdateDatapointValue(mem, uuid.Nil, path); er != nil { d.Log.Error("dmb.Handler.AddSystemDps.UpdateDatapointValue", er.Error())
d.Log.Error("dmb.Handler.AddSystemDps.UpdateDatapointValue", er.Error())
}
mOld = m.Sys
} }
time.Sleep(time.Second) time.Sleep(time.Second)
} }