markers.go raw
1 package neo4j
2
3 import (
4 "context"
5 "fmt"
6
7 "next.orly.dev/pkg/nostr/encoders/hex"
8 )
9
10 // Markers provide metadata key-value storage using Neo4j Marker nodes
11 // We store markers as special nodes with label "Marker"
12
13 // SetMarker sets a metadata marker
14 func (n *N) SetMarker(key string, value []byte) error {
15 valueHex := hex.Enc(value)
16
17 cypher := `
18 MERGE (m:Marker {key: $key})
19 SET m.value = $value`
20
21 params := map[string]any{
22 "key": key,
23 "value": valueHex,
24 }
25
26 _, err := n.ExecuteWrite(context.Background(), cypher, params)
27 if err != nil {
28 return fmt.Errorf("failed to set marker: %w", err)
29 }
30
31 return nil
32 }
33
34 // GetMarker retrieves a metadata marker
35 func (n *N) GetMarker(key string) (value []byte, err error) {
36 cypher := "MATCH (m:Marker {key: $key}) RETURN m.value AS value"
37 params := map[string]any{"key": key}
38
39 result, err := n.ExecuteRead(context.Background(), cypher, params)
40 if err != nil {
41 return nil, fmt.Errorf("failed to get marker: %w", err)
42 }
43
44 ctx := context.Background()
45
46 if result.Next(ctx) {
47 record := result.Record()
48 if record != nil {
49 valueRaw, found := record.Get("value")
50 if found {
51 if valueStr, ok := valueRaw.(string); ok {
52 // Decode hex value
53 value, err = hex.Dec(valueStr)
54 if err != nil {
55 return nil, fmt.Errorf("failed to decode marker value: %w", err)
56 }
57 return value, nil
58 }
59 }
60 }
61 }
62
63 return nil, fmt.Errorf("marker not found: %s", key)
64 }
65
66 // HasMarker checks if a marker exists
67 func (n *N) HasMarker(key string) bool {
68 _, err := n.GetMarker(key)
69 return err == nil
70 }
71
72 // DeleteMarker removes a metadata marker
73 func (n *N) DeleteMarker(key string) error {
74 cypher := "MATCH (m:Marker {key: $key}) DELETE m"
75 params := map[string]any{"key": key}
76
77 _, err := n.ExecuteWrite(context.Background(), cypher, params)
78 if err != nil {
79 return fmt.Errorf("failed to delete marker: %w", err)
80 }
81
82 return nil
83 }
84