hide Track fields, access via methods

This commit is contained in:
Helmut Merz 2024-05-02 11:38:17 +02:00
parent 2181c628c0
commit 12dbfe17ab
3 changed files with 81 additions and 57 deletions

View file

@ -23,7 +23,7 @@ func MakeMessage(c *tracking.Container, h ...string) *tracking.Track {
} }
func (msg *message) Domain() string { func (msg *message) Domain() string {
return msg.Head["domain"] return msg.Head()["domain"]
} }
// message container // message container

View file

@ -26,17 +26,40 @@ type AdapterFactory func(*Track) Adapted
type Track struct { type Track struct {
trackId lib.Ident trackId lib.Ident
Head lib.StrMap head lib.StrMap
TimeStamp *time.Time timeStamp *time.Time
Data lib.Map data lib.Map
container *Container container *Container
adapter AdapterFactory adapter AdapterFactory
} }
func MakeTrack(cont *Container, h ...string) *Track {
tr := Track{
head: lib.StrMap{},
data: lib.Map{},
container: cont,
adapter: func(tr *Track) Adapted { return tr },
}
tr.SetHead(h...)
return &tr
}
func (tr *Track) TrackId() lib.Ident { func (tr *Track) TrackId() lib.Ident {
return tr.trackId return tr.trackId
} }
func (tr *Track) Head() lib.StrMap {
return tr.head
}
func (tr *Track) TimeStamp() *time.Time {
return tr.timeStamp
}
func (tr *Track) Data() lib.Map {
return tr.data
}
func (tr *Track) Container() *Container { func (tr *Track) Container() *Container {
return tr.container return tr.container
} }
@ -45,14 +68,47 @@ func (tr *Track) Uid() string {
return fmt.Sprintf("%s-%d", tr.container.Prefix, tr.trackId) return fmt.Sprintf("%s-%d", tr.container.Prefix, tr.trackId)
} }
func MakeTrack(cont *Container, h ...string) *Track { func (tr *Track) SetHead(h ...string) {
tr := Track{ for i, k := range tr.container.HeadFields {
Head: lib.StrMap{}, if i >= len(h) {
container: cont, break
adapter: func(tr *Track) Adapted { return tr }, }
if h[i] != "" {
tr.head[k] = h[i]
}
} }
tr.SetHead(h...) }
return &tr
func (tr *Track) SetTimeStamp(ts *time.Time) {
tr.timeStamp = ts
}
func (tr *Track) SetData(data lib.Map) {
tr.data = data
}
func (tr *Track) ScanP(rows *sql.Rows) error {
tr.head = lib.StrMap{}
var d []any
for range tr.container.HeadFields {
var hv string
d = append(d, &hv)
}
var ts, rd string
d = append(d, &ts, &rd, &tr.trackId)
err := rows.Scan(d...)
if err != nil {
log.Error(err).Msg("storage.tracking.ScanP: rows.Scan")
}
for i, k := range tr.container.HeadFields {
tr.head[k] = *d[i].(*string)
}
tr.timeStamp = ParseDateTime(ts)
err = json.Unmarshal([]byte(rd), &tr.data)
if err != nil {
log.Error(err).Msg("storage.tracking.ScanP: json.Unmarshal")
}
return err
} }
func (tr *Track) SetAdapterFactory(af AdapterFactory) *Track { func (tr *Track) SetAdapterFactory(af AdapterFactory) *Track {
@ -64,38 +120,6 @@ func Adapt[T Adapted](tr *Track) T {
return tr.adapter(tr).(T) return tr.adapter(tr).(T)
} }
func (tr *Track) SetHead(h ...string) {
for i, k := range tr.container.HeadFields {
if i >= len(h) {
break
}
if h[i] != "" {
tr.Head[k] = h[i]
}
}
}
func (tr *Track) ScanP(rows *sql.Rows) error {
tr.Head = lib.StrMap{}
var d []any
for range tr.container.HeadFields {
var hv string
d = append(d, &hv)
}
var ts, rd string
d = append(d, &ts, &rd, &tr.trackId)
err := rows.Scan(d...)
for i, k := range tr.container.HeadFields {
tr.Head[k] = *d[i].(*string)
}
tr.TimeStamp = ParseDateTime(ts)
err = json.Unmarshal([]byte(rd), &tr.Data)
if err != nil {
log.Error(err).Msg("storage.tracking.ScanP")
}
return err
}
// basic container implementation // basic container implementation
type ContDef struct { type ContDef struct {
@ -214,7 +238,7 @@ func (cont *Container) Query(quSpec *querySpec) []*Track {
func (cont *Container) NewTrack(h []string, data lib.Map) *Track { func (cont *Container) NewTrack(h []string, data lib.Map) *Track {
tr := cont.ItemFactory(cont, h...) tr := cont.ItemFactory(cont, h...)
tr.Data = data tr.data = data
cont.Insert(tr) cont.Insert(tr)
return tr return tr
} }
@ -231,14 +255,14 @@ func (cont *Container) Insert(tr *Track) *Track {
sql := storage.BuildSql(SqlInsert, quSpec) sql := storage.BuildSql(SqlInsert, quSpec)
var values []any var values []any
for _, k := range cont.HeadFields { for _, k := range cont.HeadFields {
values = append(values, tr.Head[k]) values = append(values, tr.head[k])
} }
b, _ := json.Marshal(tr.Data) b, _ := json.Marshal(tr.data)
values = append(values, b) values = append(values, b)
var tsstr string var tsstr string
proc := func(r *sqllib.Rows) error { proc := func(r *sqllib.Rows) error {
err := r.Scan(&tr.trackId, &tsstr) err := r.Scan(&tr.trackId, &tsstr)
tr.TimeStamp = ParseDateTime(tsstr) tr.timeStamp = ParseDateTime(tsstr)
return err return err
} }
if err := cont.Storage.Query(proc, sql, values...); err == nil { if err := cont.Storage.Query(proc, sql, values...); err == nil {
@ -248,9 +272,9 @@ func (cont *Container) Insert(tr *Track) *Track {
} }
func (cont *Container) Update(tr *Track) *Track { func (cont *Container) Update(tr *Track) *Track {
if tr.TimeStamp == nil { if tr.timeStamp == nil {
ts := time.Now() ts := time.Now()
tr.TimeStamp = &ts tr.timeStamp = &ts
} }
quSpec := &querySpec{ quSpec := &querySpec{
Scols: append(cont.HeadFields, "timestamp", "data"), Scols: append(cont.HeadFields, "timestamp", "data"),
@ -259,10 +283,10 @@ func (cont *Container) Update(tr *Track) *Track {
sql := storage.BuildSql(SqlUpdate, quSpec) sql := storage.BuildSql(SqlUpdate, quSpec)
vals := []any{tr.trackId} vals := []any{tr.trackId}
for _, k := range cont.HeadFields { for _, k := range cont.HeadFields {
vals = append(vals, tr.Head[k]) vals = append(vals, tr.head[k])
} }
vals = append(vals, tr.TimeStamp) vals = append(vals, tr.timeStamp)
b, _ := json.Marshal(tr.Data) b, _ := json.Marshal(tr.data)
vals = append(vals, b) vals = append(vals, b)
n, _ := cont.Storage.Exec(sql, vals...) n, _ := cont.Storage.Exec(sql, vals...)
if n == 1 { if n == 1 {

View file

@ -70,16 +70,16 @@ func TrackingTest(t *testing.T, cfg *sql.Cfg, db *sql.Storage) {
cont.CreateTable() cont.CreateTable()
track := cont.NewTrack(lib.StrSlice{"t01", "john"}, nil) track := cont.NewTrack(lib.StrSlice{"t01", "john"}, nil)
t.AssertEqual(track.TrackId(), lib.Ident(1)) t.AssertEqual(track.TrackId(), lib.Ident(1))
t.AssertEqual(track.TimeStamp.Year(), time.Now().Year()) t.AssertEqual(track.TimeStamp().Year(), time.Now().Year())
tr2 := cont.Get(1) tr2 := cont.Get(1)
//fmt.Printf("%+v\n", tr2.TimeStamp()) //fmt.Printf("%+v\n", tr2.TimeStamp())
t.AssertEqual(tr2.Head["userName"], "john") t.AssertEqual(tr2.Head()["userName"], "john")
tr3 := cont.QueryLast("", "john") tr3 := cont.QueryLast("", "john")
t.AssertEqual(tr3.Head["taskId"], "t01") t.AssertEqual(tr3.Head()["taskId"], "t01")
tr3.Data = lib.Map{"desc": "go-scopes documentation"} tr3.SetData(lib.Map{"desc": "go-scopes documentation"})
cont.Update(tr3) cont.Update(tr3)
tr4 := tracking.Get(db, "rec-1") tr4 := tracking.Get(db, "rec-1")
t.AssertEqual(tr4.Data["desc"], "go-scopes documentation") t.AssertEqual(tr4.Data()["desc"], "go-scopes documentation")
} }
func MessageTest(t *testing.T, cfg *sql.Cfg, db *sql.Storage) { func MessageTest(t *testing.T, cfg *sql.Cfg, db *sql.Storage) {