3
0

Add updated & oldValue capabilities to record values

This commit is contained in:
Denis Arh 2020-02-25 08:16:23 +01:00
parent db601523a6
commit b9a49645f3
2 changed files with 49 additions and 18 deletions

View File

@ -3,6 +3,7 @@ package types
import (
"database/sql/driver"
"encoding/json"
"fmt"
"time"
"github.com/pkg/errors"
@ -18,7 +19,8 @@ type (
Place uint `db:"place" json:"-"`
DeletedAt *time.Time `db:"deleted_at" json:"deletedAt,omitempty"`
updated bool
updated bool
oldValue string
}
)
@ -118,17 +120,12 @@ func (set RecordValueSet) GetUpdated() (out RecordValueSet) {
return out
}
// Replace old value set with new one
// Merge merges old value set with new one and expects unchanged values to be in the new set
//
// Will remove all values that are not set in new set
// This satisfies current requirements where record values are always
// manipulated as a whole (not partial)
//
// This satisfies current requirements where record is always
// manipulated as a whole
func (set RecordValueSet) Replace(new RecordValueSet) (out RecordValueSet) {
if len(new) == 0 {
return nil
}
func (set RecordValueSet) Merge(new RecordValueSet) (out RecordValueSet) {
if len(set) == 0 {
for i := range new {
new[i].updated = true
@ -143,27 +140,41 @@ func (set RecordValueSet) Replace(new RecordValueSet) (out RecordValueSet) {
out = append(out, &RecordValue{
Name: set[s].Name,
Value: set[s].Value,
Ref: set[s].Ref,
Place: set[s].Place,
DeletedAt: &time.Time{},
updated: true,
oldValue: set[s].Value,
})
}
for n := range new {
if ex := out.Get(new[n].Name, new[n].Place); ex != nil {
// Reset deleted flag
ex.DeletedAt = nil
ex.DeletedAt = new[n].DeletedAt
// Did value change?
ex.updated = ex.updated || ex.Value != new[n].Value
if ex.oldValue == new[n].Value {
ex.updated = false
} else if !ex.updated {
// Did value change?
ex.updated = ex.Value != new[n].Value
ex.oldValue = ex.Value
}
ex.Value = new[n].Value
ex.Ref = new[n].Ref
} else {
// Value not previously set, make new
out = append(out, &RecordValue{
Name: new[n].Name,
Value: new[n].Value,
Ref: new[n].Ref,
Place: new[n].Place,
updated: true,
// verbose & explicit for clarity
oldValue: "",
DeletedAt: nil,
})
}
}
@ -189,6 +200,26 @@ func (set RecordValueSet) Value() (driver.Value, error) {
return json.Marshal(set)
}
// Simple RVS as string output utility fn that
// can help with debugging
func (set RecordValueSet) String() (o string) {
const tpl = "%-10s %2d %-20s %-20d %-20s %v %v\n"
for _, v := range set {
o += fmt.Sprintf(
tpl,
v.Name,
v.Place,
v.Value,
v.Ref,
v.oldValue,
v.updated,
v.DeletedAt,
)
}
return o
}
func (set RecordValueSet) Len() int { return len(set) }
func (set RecordValueSet) Swap(i, j int) { set[i], set[j] = set[j], set[i] }
func (set RecordValueSet) Less(i, j int) bool { return set[i].Place < set[j].Place }

View File

@ -42,7 +42,7 @@ func TestRecordValueSet_Set(t *testing.T) {
}
}
func TestRecordValueSet_Replace(t *testing.T) {
func TestRecordValueSet_Merge(t *testing.T) {
tests := []struct {
name string
set RecordValueSet
@ -59,25 +59,25 @@ func TestRecordValueSet_Replace(t *testing.T) {
name: "update with nil",
set: RecordValueSet{{Name: "n", Value: "v"}},
new: nil,
want: nil,
want: RecordValueSet{{Name: "n", Value: "v", oldValue: "v", DeletedAt: &time.Time{}, updated: true}},
},
{
name: "update with new value",
set: RecordValueSet{{Name: "n", Value: "1"}},
new: RecordValueSet{{Name: "n", Value: "2"}},
want: RecordValueSet{{Name: "n", Value: "2", updated: true}},
want: RecordValueSet{{Name: "n", Value: "2", oldValue: "1", updated: true}},
},
{
name: "update with less values",
set: RecordValueSet{{Name: "n", Value: "1"}, {Name: "deleted", Value: "d"}},
new: RecordValueSet{{Name: "n", Value: "2"}},
want: RecordValueSet{{Name: "n", Value: "2", updated: true}, {Name: "deleted", Value: "d", updated: true, DeletedAt: &time.Time{}}},
want: RecordValueSet{{Name: "n", Value: "2", oldValue: "1", updated: true}, {Name: "deleted", Value: "d", oldValue: "d", updated: true, DeletedAt: &time.Time{}}},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := tt.set.Replace(tt.new); !reflect.DeepEqual(got, tt.want) {
if got := tt.set.Merge(tt.new); !reflect.DeepEqual(got, tt.want) {
t.Errorf("Update() = %+v, want %+v", got, tt.want)
}
})