Skip to content

Commit

Permalink
Add GetNodeProperty and GetRelationshipProperty top-level APIs
Browse files Browse the repository at this point in the history
These are generic helpers to extract properties from nodes and
relationships in a type-safe way.

Relates to #373
  • Loading branch information
fbiville committed Dec 13, 2022
1 parent 127bbf8 commit 39e263c
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 0 deletions.
51 changes: 51 additions & 0 deletions neo4j/graph.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Copyright (c) "Neo4j"
* Neo4j Sweden AB [https://neo4j.com]
*
* This file is part of Neo4j.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package neo4j

import (
"fmt"
)

// GetNodeProperty returns the value matching the property of the given neo4j.Node
// If the property does not exist, an error is returned
// If the property type does not match the type specification, an error is also returned
func GetNodeProperty[T any](entity Node, key string) (T, error) {
return getProperty[T](entity.Props, key)
}

// GetRelationshipProperty returns the value matching the property of the given neo4j.Relationship
// If the property does not exist, an error is returned
// If the property type does not match the type specification, an error is also returned
func GetRelationshipProperty[T any](entity Relationship, key string) (T, error) {
return getProperty[T](entity.Props, key)
}

func getProperty[T any](props map[string]any, key string) (T, error) {
rawValue, found := props[key]
if !found {
return *new(T), fmt.Errorf("could not find any property named %s", key)
}
value, ok := rawValue.(T)
if !ok {
zeroValue := *new(T)
return zeroValue, fmt.Errorf("expected value to have type %T but found type %T", zeroValue, rawValue)
}
return value, nil
}
58 changes: 58 additions & 0 deletions neo4j/graph_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright (c) "Neo4j"
* Neo4j Sweden AB [https://neo4j.com]
*
* This file is part of Neo4j.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package neo4j_test

import (
"github.com/neo4j/neo4j-go-driver/v5/neo4j"
"testing"
"testing/quick"
)

func TestGetNodeProperty(outer *testing.T) {
check := func(key string, value int) bool {
entity := neo4j.Node{Props: singleProp(key, value)}

validValue, noErr := neo4j.GetNodeProperty[int](entity, key)
_, err := neo4j.GetNodeProperty[string](entity, key)

return validValue == value && noErr == nil && err != nil
}
if err := quick.Check(check, nil); err != nil {
outer.Error(err)
}
}

func TestGetRelationshipProperty(outer *testing.T) {
check := func(key string, value string) bool {
entity := neo4j.Relationship{Props: singleProp(key, value)}

validValue, noErr := neo4j.GetRelationshipProperty[string](entity, key)
_, err := neo4j.GetRelationshipProperty[int64](entity, key)

return validValue == value && noErr == nil && err != nil
}
if err := quick.Check(check, nil); err != nil {
outer.Error(err)
}
}

func singleProp[T any](key string, value T) map[string]any {
return map[string]any{key: value}
}

0 comments on commit 39e263c

Please sign in to comment.