Skip to content

Commit

Permalink
Merge #65 from main: Allow to discover available fields for a document
Browse files Browse the repository at this point in the history
  • Loading branch information
ostafen committed Jul 29, 2022
1 parent d237743 commit 0925bb3
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 7 deletions.
11 changes: 11 additions & 0 deletions document.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,17 @@ func (doc *Document) SetAll(values map[string]interface{}) {
}
}

// GetAll returns a map of all available fields in the document. Nested fields are represented by sub-maps. This is a deep copy, but values are note cloned.
func (doc *Document) ToMap() map[string]interface{} {
return util.CopyMap(doc.fields)
}

// Fields returns a lexicographically sorted slice of all available field names in the document.
// Nested fields, if included, are represented using dot notation.
func (doc *Document) Fields(includeSubFields bool) []string {
return util.MapKeys(doc.fields, true, includeSubFields)
}

// ExpiresAt returns the document expiration instant
func (doc *Document) ExpiresAt() *time.Time {
exp, ok := doc.Get(expiresAtField).(time.Time)
Expand Down
49 changes: 49 additions & 0 deletions document_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,3 +152,52 @@ func TestDocumentValidation(t *testing.T) {
require.Error(t, err)
})
}

func TestDocumentToMap(t *testing.T) {
doc := c.NewDocumentOf(map[string]interface{}{
"f_1": map[string]interface{}{
"f_1_1": float64(0),
"f_1_2": "aString",
},
"f_2": map[string]interface{}{
"f_2_1": float64(1),
"f_2_2": "aString",
},
"f_3": int64(42),
})

fields := doc.ToMap()
require.Equal(t, float64(0), fields["f_1"].(map[string]interface{})["f_1_1"])
require.Equal(t, "aString", fields["f_2"].(map[string]interface{})["f_2_2"])
require.Equal(t, int64(42), fields["f_3"])
require.Equal(t, 3, len(fields))
}

func TestDocumentFields(t *testing.T) {
doc := c.NewDocumentOf(map[string]interface{}{
"f_1": map[string]interface{}{
"f_1_1": float64(0),
"f_1_2": "aString",
},
"f_2": map[string]interface{}{
"f_2_1": float64(1),
"f_2_2": "aString",
},
"f_3": int64(42),
})

keys := doc.Fields(false)
require.Contains(t, keys, "f_1")
require.Contains(t, keys, "f_2")
require.Contains(t, keys, "f_3")
require.Equal(t, 3, len(keys))

keys = doc.Fields(true)
require.Contains(t, keys, "f_1.f_1_1")
require.Contains(t, keys, "f_1.f_1_2")
require.Contains(t, keys, "f_2.f_2_1")
require.Contains(t, keys, "f_2.f_2_2")
require.Contains(t, keys, "f_3")
require.Equal(t, 5, len(keys))

}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ require (
github.com/kr/pretty v0.2.0 // indirect
github.com/satori/go.uuid v1.2.0
github.com/stretchr/testify v1.7.1
github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect
github.com/vmihailenco/msgpack/v5 v5.3.5
go.opencensus.io v0.23.0 // indirect
golang.org/x/net v0.0.0-20220630215102-69896b714898 // indirect
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e // indirect
Expand Down
2 changes: 1 addition & 1 deletion internal/code.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func orderedCodeSlice(buf []byte, s []interface{}) ([]byte, error) {

func orderedCodeObject(buf []byte, o map[string]interface{}) ([]byte, error) {
objEncoding := make([]byte, 0)
for _, key := range util.MapKeys(o, true) {
for _, key := range util.MapKeys(o, true, false) {
value := o[key]

encoded, err := orderedcode.Append(objEncoding, key)
Expand Down
4 changes: 2 additions & 2 deletions internal/compare.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@ func Compare(v1 interface{}, v2 interface{}) int {
}

func compareObjects(m1 map[string]interface{}, m2 map[string]interface{}) int {
m1Keys := util.MapKeys(m1, true)
m2Keys := util.MapKeys(m2, true)
m1Keys := util.MapKeys(m1, true, false)
m2Keys := util.MapKeys(m2, true, false)

for i := 0; i < len(m1Keys) && i < len(m2Keys); i++ {
k1 := m1Keys[i]
Expand Down
20 changes: 17 additions & 3 deletions util/map.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,24 @@ func CopyMap(m map[string]interface{}) map[string]interface{} {
return mapCopy
}

func MapKeys(m map[string]interface{}, sorted bool) []string {
func MapKeys(m map[string]interface{}, sorted bool, includeSubKeys bool) []string {
keys := make([]string, 0, len(m))
for key := range m {
keys = append(keys, key)
for key, value := range m {
added := false
if includeSubKeys {
subMap, isMap := value.(map[string]interface{})
if isMap {
subFields := MapKeys(subMap, false, includeSubKeys)
for _, subKey := range subFields {
keys = append(keys, key+"."+subKey)
}
added = true
}
}

if !added {
keys = append(keys, key)
}
}

if sorted {
Expand Down

0 comments on commit 0925bb3

Please sign in to comment.