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