implement family tree queries

This commit is contained in:
2025-04-13 20:15:51 +02:00
parent 120e7a9862
commit 85a42d2658
6 changed files with 201 additions and 5 deletions

View File

@@ -0,0 +1,45 @@
package memgraph
import (
"context"
"github.com/neo4j/neo4j-go-driver/v5/neo4j"
)
// returned map has "people" which is a slice of OptimizedPersonNode and relationships wich a slice of Relatioship type.
func GetFamilyTreeById(ctx context.Context, userId int) neo4j.ManagedTransactionWork {
return func(tx neo4j.ManagedTransaction) (any, error) {
result, err := tx.Run(ctx, GetBloodRelativesCypherQuery, map[string]any{
"id": userId,
})
if err != nil {
return nil, err
}
record, err := result.Single(ctx)
if err != nil {
return nil, err
}
return record.AsMap(), nil
}
}
// returned map has "people" which is a slice of OptimizedPersonNode and relationships wich a slice of Relatioship type.
func GetFamilyTreeWithSpousesById(ctx context.Context, userId int) neo4j.ManagedTransactionWork {
return func(tx neo4j.ManagedTransaction) (any, error) {
result, err := tx.Run(ctx, GetFamilyTreeWithSpousesCypherQuery, map[string]any{
"id": userId,
})
if err != nil {
return nil, err
}
record, err := result.Single(ctx)
if err != nil {
return nil, err
}
return record.AsMap(), nil
}
}

View File

@@ -0,0 +1,145 @@
package memgraph
import (
"context"
"errors"
"testing"
"github.com/neo4j/neo4j-go-driver/v5/neo4j"
"github.com/stretchr/testify/assert"
"github.com/vcscsvcscs/GenerationsHeritage/apps/db-adapter/internal/memgraph/mock"
)
func TestGetFamilyTreeById(t *testing.T) {
testCases := []struct {
name string
mockTxSetup func() *mock.Transaction
expectedResult map[string]any
expectedError error
}{
{
name: "Successful case",
mockTxSetup: func() *mock.Transaction {
mockTx := new(mock.Transaction)
mockResult := new(mock.Result)
mockRecord := &neo4j.Record{
Values: []any{"value"},
Keys: []string{"key"},
}
mockResult.On("Single", context.Background()).Return(mockRecord, nil)
mockTx.On("Run", context.Background(), GetBloodRelativesCypherQuery, map[string]any{"id": 123}).Return(mockResult, nil)
return mockTx
},
expectedResult: map[string]any{"key": "value"},
expectedError: nil,
},
{
name: "Error during Run",
mockTxSetup: func() *mock.Transaction {
mockTx := new(mock.Transaction)
mockTx.On("Run", context.Background(), GetBloodRelativesCypherQuery, map[string]any{"id": 123}).Return(nil, errors.New("run error"))
return mockTx
},
expectedResult: nil,
expectedError: errors.New("run error"),
},
{
name: "Error during Single",
mockTxSetup: func() *mock.Transaction {
mockTx := new(mock.Transaction)
mockResult := new(mock.Result)
mockResult.On("Single", context.Background()).Return(nil, errors.New("single error"))
mockTx.On("Run", context.Background(), GetBloodRelativesCypherQuery, map[string]any{"id": 123}).Return(mockResult, nil)
return mockTx
},
expectedResult: nil,
expectedError: errors.New("single error"),
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
ctx := context.Background()
userId := 123
mockTx := tc.mockTxSetup()
work := GetFamilyTreeById(ctx, userId)
result, err := work(mockTx)
if tc.expectedError != nil {
assert.Error(t, err)
assert.Nil(t, result)
} else {
assert.NoError(t, err)
assert.Equal(t, tc.expectedResult, result)
}
})
}
}
func TestGetFamilyTreeWithSpousesById(t *testing.T) {
testCases := []struct {
name string
mockTxSetup func() *mock.Transaction
expectedResult map[string]any
expectedError error
}{
{
name: "Successful case",
mockTxSetup: func() *mock.Transaction {
mockTx := new(mock.Transaction)
mockResult := new(mock.Result)
mockRecord := &neo4j.Record{
Values: []any{"value"},
Keys: []string{"key"},
}
mockResult.On("Single", context.Background()).Return(mockRecord, nil)
mockTx.On("Run", context.Background(), GetFamilyTreeWithSpousesCypherQuery, map[string]any{"id": 123}).Return(mockResult, nil)
return mockTx
},
expectedResult: map[string]any{"key": "value"},
expectedError: nil,
},
{
name: "Error during Run",
mockTxSetup: func() *mock.Transaction {
mockTx := new(mock.Transaction)
mockTx.On("Run", context.Background(), GetFamilyTreeWithSpousesCypherQuery, map[string]any{"id": 123}).Return(nil, errors.New("run error"))
return mockTx
},
expectedResult: nil,
expectedError: errors.New("run error"),
},
{
name: "Error during Single",
mockTxSetup: func() *mock.Transaction {
mockTx := new(mock.Transaction)
mockResult := new(mock.Result)
mockResult.On("Single", context.Background()).Return(nil, errors.New("single error"))
mockTx.On("Run", context.Background(), GetFamilyTreeWithSpousesCypherQuery, map[string]any{"id": 123}).Return(mockResult, nil)
return mockTx
},
expectedResult: nil,
expectedError: errors.New("single error"),
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
ctx := context.Background()
userId := 123
mockTx := tc.mockTxSetup()
work := GetFamilyTreeWithSpousesById(ctx, userId)
result, err := work(mockTx)
if tc.expectedError != nil {
assert.Error(t, err)
assert.Nil(t, result)
} else {
assert.NoError(t, err)
assert.Equal(t, tc.expectedResult, result)
}
})
}
}

View File

@@ -88,10 +88,12 @@ var CreateSpouseRelationshipCypherQuery string
//go:embed queries/delete_relationship.cypher
var DeleteRelationshipCypherQuery string
// Requires id parameter.
// Requires id1, id2, relationship parameter.
//
//go:embed queries/get_family_tree_by_id.cypher
var GetFamilyTreeByIdCypherQuery string
// return relationship
//
//go:embed queries/update_relationship.cypher
var UpdateRelationshipCypherQuery string
// Requires id1, id2 parameter.
//

View File

@@ -8,7 +8,7 @@ WITH collections.to_set(collect(n)+collect(family)+collect(children)+collect(dir
collections.to_set(collect(c) + collect(p) + collect(s) + collect(ds)) as relationships
UNWIND people as ppl
RETURN collect({
id: id(ppl),
id: id(ppl),
first_name: ppl.first_name,
middle_name: ppl.middle_name,
last_name: ppl.last_name,

View File

@@ -1,3 +1,3 @@
MATCH (n)-[r]-(o)
MATCH (n)-[r]->(o)
WHERE id(n) = $id1 AND id(o) = $id2
RETURN r as relationship

View File

@@ -0,0 +1,4 @@
MATCH (n)-[r]->(o)
WHERE id(n) = $id1 AND id(o) = $id2
SET r += $relationship
RETURN r as relationship