-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathentity.go
116 lines (103 loc) · 2.74 KB
/
entity.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package neogo
import (
"reflect"
"github.com/rlch/neogo/internal"
)
// NewNode creates a new node with a random ID.
func NewNode[N any, PN interface {
INode
internal.IDSetter
*N
}]() PN {
n := PN(new(N))
n.GenerateID()
return n
}
// NodeWithID creates a new node with the given ID.
func NodeWithID[N any, PN interface {
INode
internal.IDSetter
*N
}](id string,
) PN {
n := PN(new(N))
n.SetID(id)
return n
}
var rAbstract = reflect.TypeOf((*IAbstract)(nil)).Elem()
func ExtractNodeLabels(i any) []string {
return internal.ExtractNodeLabels(i)
}
func ExtractRelationshipType(relationship any) string {
return internal.ExtractRelationshipType(relationship)
}
type (
// INode is an interface for nodes.
// See [Node] for the default implementation.
INode = internal.INode
// IAbstract is an interface for abstract nodes.
// See [Abstract] for the default implementation.
IAbstract = internal.IAbstract
// IRelationship is an interface for relationships.
// See [Relationship] for the default implementation.
IRelationship = internal.IRelationship
// Node is a base type for all nodes.
//
// The neo4j tag is used to specify the label for the node. Multiple labels
// may be specified idiomatically by nested [Node] types. See [internal/tests]
// for examples.
//
// type Person struct {
// neogo.Node `neo4j:"Person"`
//
// Name string `json:"name"`
// Age int `json:"age"`
// }
Node = internal.Node
// Abstract is a base type for all abstract nodes. An abstract node can have
// multiple concrete implementers, where each implementer must have a distinct
// label. This means that each node will have at least 2 labels.
//
// A useful design pattern for constructing abstract nodes is to create a base
// type which provides an implementation for [IAbstract] and embed [Abstract]
// + [Node], then embed that type in all concrete implementers:
//
// type Organism interface {
// internal.IAbstract
// }
//
// type BaseOrganism struct {
// internal.Abstract `neo4j:"Organism"`
// internal.Node
//
// Alive bool `json:"alive"`
// }
//
// func (b BaseOrganism) Implementers() []internal.IAbstract {
// return []internal.IAbstract{
// &Human{},
// &Dog{},
// }
// }
//
// type Human struct {
// BaseOrganism `neo4j:"Human"`
// Name string `json:"name"`
// }
//
// type Dog struct {
// BaseOrganism `neo4j:"Dog"`
// Borfs bool `json:"borfs"`
// }
Abstract = internal.Abstract
// Relationship is a base type for all relationships.
//
// The neo4j tag is used to specify the type for the relationship.
//
// type ActedIn struct {
// internal.Relationship `neo4j:"ACTED_IN"`
//
// Role string `json:"role"`
// }
Relationship = internal.Relationship
)