diff --git a/storage/message/message.go b/storage/message/message.go index 781f463..204d6e4 100644 --- a/storage/message/message.go +++ b/storage/message/message.go @@ -23,7 +23,7 @@ func MakeMessage(c *tracking.Container, h ...string) *tracking.Track { } func (msg *message) Domain() string { - return msg.Head["domain"] + return msg.Head()["domain"] } // message container diff --git a/storage/tracking/tracking.go b/storage/tracking/tracking.go index e1819b5..77ac1a3 100644 --- a/storage/tracking/tracking.go +++ b/storage/tracking/tracking.go @@ -26,17 +26,40 @@ type AdapterFactory func(*Track) Adapted type Track struct { trackId lib.Ident - Head lib.StrMap - TimeStamp *time.Time - Data lib.Map + head lib.StrMap + timeStamp *time.Time + data lib.Map container *Container 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 { 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 { return tr.container } @@ -45,14 +68,47 @@ func (tr *Track) Uid() string { return fmt.Sprintf("%s-%d", tr.container.Prefix, tr.trackId) } -func MakeTrack(cont *Container, h ...string) *Track { - tr := Track{ - Head: lib.StrMap{}, - container: cont, - adapter: func(tr *Track) Adapted { return tr }, +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] + } } - 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 { @@ -64,38 +120,6 @@ func Adapt[T Adapted](tr *Track) 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 type ContDef struct { @@ -214,7 +238,7 @@ func (cont *Container) Query(quSpec *querySpec) []*Track { func (cont *Container) NewTrack(h []string, data lib.Map) *Track { tr := cont.ItemFactory(cont, h...) - tr.Data = data + tr.data = data cont.Insert(tr) return tr } @@ -231,14 +255,14 @@ func (cont *Container) Insert(tr *Track) *Track { sql := storage.BuildSql(SqlInsert, quSpec) var values []any 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) var tsstr string proc := func(r *sqllib.Rows) error { err := r.Scan(&tr.trackId, &tsstr) - tr.TimeStamp = ParseDateTime(tsstr) + tr.timeStamp = ParseDateTime(tsstr) return err } 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 { - if tr.TimeStamp == nil { + if tr.timeStamp == nil { ts := time.Now() - tr.TimeStamp = &ts + tr.timeStamp = &ts } quSpec := &querySpec{ Scols: append(cont.HeadFields, "timestamp", "data"), @@ -259,10 +283,10 @@ func (cont *Container) Update(tr *Track) *Track { sql := storage.BuildSql(SqlUpdate, quSpec) vals := []any{tr.trackId} for _, k := range cont.HeadFields { - vals = append(vals, tr.Head[k]) + vals = append(vals, tr.head[k]) } - vals = append(vals, tr.TimeStamp) - b, _ := json.Marshal(tr.Data) + vals = append(vals, tr.timeStamp) + b, _ := json.Marshal(tr.data) vals = append(vals, b) n, _ := cont.Storage.Exec(sql, vals...) if n == 1 { diff --git a/tests/storage_test.go b/tests/storage_test.go index 2ce9925..c0352b4 100644 --- a/tests/storage_test.go +++ b/tests/storage_test.go @@ -70,16 +70,16 @@ func TrackingTest(t *testing.T, cfg *sql.Cfg, db *sql.Storage) { cont.CreateTable() track := cont.NewTrack(lib.StrSlice{"t01", "john"}, nil) 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) //fmt.Printf("%+v\n", tr2.TimeStamp()) - t.AssertEqual(tr2.Head["userName"], "john") + t.AssertEqual(tr2.Head()["userName"], "john") tr3 := cont.QueryLast("", "john") - t.AssertEqual(tr3.Head["taskId"], "t01") - tr3.Data = lib.Map{"desc": "go-scopes documentation"} + t.AssertEqual(tr3.Head()["taskId"], "t01") + tr3.SetData(lib.Map{"desc": "go-scopes documentation"}) cont.Update(tr3) 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) {