Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 1 addition & 6 deletions model/rag/chat.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,7 @@ func (c *ChatConversation) Clone() couchdb.Doc {
cloned := *c
cloned.Messages = make([]ChatMessage, len(c.Messages))
copy(cloned.Messages, c.Messages)
if c.Rels != nil {
cloned.Rels = make(jsonapi.RelationshipMap, len(c.Rels))
for k, v := range c.Rels {
cloned.Rels[k] = v
}
}
cloned.Rels = c.Rels.Clone()
return &cloned
}
func (c *ChatConversation) Included() []jsonapi.Object { return nil }
Expand Down
7 changes: 1 addition & 6 deletions model/rag/index_status_doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,7 @@ func (s *IndexStatus) Clone() couchdb.Doc {
at := *s.LastErrorDate
cloned.LastErrorDate = &at
}
if s.Rels != nil {
cloned.Rels = make(jsonapi.RelationshipMap, len(s.Rels))
for k, v := range s.Rels {
cloned.Rels[k] = v
}
}
cloned.Rels = s.Rels.Clone()
return &cloned
}

Expand Down
19 changes: 19 additions & 0 deletions model/rag/index_status_doc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,22 @@ func TestIndexStatusClone(t *testing.T) {
assert.Equal(t, at, *doc.LastSuccessDate)
assert.Contains(t, doc.Rels, "doc")
}

func TestIndexStatusCloneDecodedRelationship(t *testing.T) {
raw, err := json.Marshal(NewIndexStatus("a1b2c3"))
require.NoError(t, err)

var doc IndexStatus
require.NoError(t, json.Unmarshal(raw, &doc))

cloned := doc.Clone().(*IndexStatus)
clonedFile := cloned.Rels["doc"]
clonedData, ok := clonedFile.Data.(map[string]interface{})
require.True(t, ok)
clonedData["_id"] = "d4e5f6"

originalFile := doc.Rels["doc"]
originalData, ok := originalFile.Data.(map[string]interface{})
require.True(t, ok)
assert.Equal(t, "a1b2c3", originalData["_id"])
}
9 changes: 5 additions & 4 deletions pkg/couchdb/couchdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,15 +117,16 @@ func (j *JSONDoc) SetRev(rev string) {
// Clone is used to create a copy of the document
func (j *JSONDoc) Clone() Doc {
cloned := JSONDoc{Type: j.Type}
cloned.M = deepClone(j.M)
cloned.M = CloneJSONMap(j.M)
return &cloned
}

func deepClone(m map[string]interface{}) map[string]interface{} {
// CloneJSONMap returns a recursive copy of a JSON object.
func CloneJSONMap(m map[string]interface{}) map[string]interface{} {
clone := make(map[string]interface{}, len(m))
for k, v := range m {
if vv, ok := v.(map[string]interface{}); ok {
clone[k] = deepClone(vv)
clone[k] = CloneJSONMap(vv)
} else if vv, ok := v.([]interface{}); ok {
clone[k] = deepCloneSlice(vv)
} else {
Expand All @@ -139,7 +140,7 @@ func deepCloneSlice(s []interface{}) []interface{} {
clone := make([]interface{}, len(s))
for i, v := range s {
if vv, ok := v.(map[string]interface{}); ok {
clone[i] = deepClone(vv)
clone[i] = CloneJSONMap(vv)
} else if vv, ok := v.([]interface{}); ok {
clone[i] = deepCloneSlice(vv)
} else {
Expand Down
17 changes: 17 additions & 0 deletions pkg/jsonapi/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,23 @@ func (r *Relationship) ResourceIdentifier() (*couchdb.DocReference, bool) {
// See http://jsonapi.org/format/#document-resource-object-relationships
type RelationshipMap map[string]Relationship

// Clone returns a copy of the relationship map. Relationship data decoded from
// JSON is cloned recursively.
func (r RelationshipMap) Clone() RelationshipMap {
if r == nil {
return nil
}

cloned := make(RelationshipMap, len(r))
for name, relationship := range r {
if data, ok := relationship.Data.(map[string]interface{}); ok {
relationship.Data = couchdb.CloneJSONMap(data)
}
cloned[name] = relationship
}
return cloned
}

// ObjectMarshalling is a JSON-API object
// See http://jsonapi.org/format/#document-resource-objects
type ObjectMarshalling struct {
Expand Down
36 changes: 36 additions & 0 deletions pkg/jsonapi/data_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package jsonapi

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestRelationshipMapClone(t *testing.T) {
var empty RelationshipMap
assert.Nil(t, empty.Clone())

relationships := RelationshipMap{
"file": {
Data: map[string]interface{}{
"_id": "file-1",
"metadata": map[string]interface{}{
"label": "original",
},
},
},
}

cloned := relationships.Clone()
clonedFile := cloned["file"]
clonedData := clonedFile.Data.(map[string]interface{})
clonedData["_id"] = "file-2"
clonedData["metadata"].(map[string]interface{})["label"] = "changed"
delete(cloned, "file")

originalFile := relationships["file"]
originalData := originalFile.Data.(map[string]interface{})
assert.Contains(t, relationships, "file")
assert.Equal(t, "file-1", originalData["_id"])
assert.Equal(t, "original", originalData["metadata"].(map[string]interface{})["label"])
}
Loading