graph-adapter.go raw
1 package neo4j
2
3 import (
4 "fmt"
5
6 "next.orly.dev/pkg/protocol/graph"
7 )
8
9 // GraphAdapter wraps a Neo4j database instance and implements graph.GraphDatabase interface.
10 type GraphAdapter struct {
11 db *N
12 }
13
14 // NewGraphAdapter creates a new GraphAdapter wrapping the given Neo4j database.
15 func NewGraphAdapter(db *N) *GraphAdapter {
16 return &GraphAdapter{db: db}
17 }
18
19 // TraversePubkeyPubkey implements graph.GraphDatabase.
20 // Neo4j uses Cypher queries for direct pubkey-to-pubkey traversal.
21 func (a *GraphAdapter) TraversePubkeyPubkey(seedPubkey []byte, maxDepth int, direction string) (graph.GraphResultI, error) {
22 switch direction {
23 case "out":
24 return a.db.TraverseFollows(seedPubkey, maxDepth)
25 case "in":
26 return a.db.TraverseFollowers(seedPubkey, maxDepth)
27 case "both":
28 // For bidirectional, execute both and merge
29 outResult, err := a.db.TraverseFollows(seedPubkey, maxDepth)
30 if err != nil {
31 return nil, err
32 }
33 inResult, err := a.db.TraverseFollowers(seedPubkey, maxDepth)
34 if err != nil {
35 return outResult, nil // Return what we have
36 }
37 // Merge inbound results into outbound
38 mergeResults(outResult, inResult)
39 return outResult, nil
40 default:
41 return nil, fmt.Errorf("invalid direction: %s", direction)
42 }
43 }
44
45 // TraversePubkeyEvent implements graph.GraphDatabase.
46 func (a *GraphAdapter) TraversePubkeyEvent(seedPubkey []byte, maxDepth int, direction string) (graph.GraphResultI, error) {
47 // Delegate to mentions for now (pe queries)
48 return a.db.FindMentions(seedPubkey, nil)
49 }
50
51 // TraverseEventEvent implements graph.GraphDatabase.
52 func (a *GraphAdapter) TraverseEventEvent(seedEventID []byte, maxDepth int, direction string) (graph.GraphResultI, error) {
53 return a.db.TraverseThread(seedEventID, maxDepth, direction)
54 }
55
56 // TraversePubkeyPubkeyBaseline implements graph.GraphDatabase.
57 // For Neo4j, baseline is the same as optimized since Neo4j handles its own query planning.
58 func (a *GraphAdapter) TraversePubkeyPubkeyBaseline(seedPubkey []byte, maxDepth int, direction string) (graph.GraphResultI, error) {
59 return a.TraversePubkeyPubkey(seedPubkey, maxDepth, direction)
60 }
61
62 // mergeResults merges source GraphResultI into target.
63 // This is a best-effort merge using the interface methods.
64 func mergeResults(target, source graph.GraphResultI) {
65 // Results are read-only through the interface — for Neo4j this is acceptable
66 // since Cypher can do bidirectional in a single query if needed.
67 _ = target
68 _ = source
69 }
70
71 // Verify GraphAdapter implements graph.GraphDatabase
72 var _ graph.GraphDatabase = (*GraphAdapter)(nil)
73