nervusdb_v2_api/lib.rs
1use std::collections::BTreeMap;
2
3/// External identifier for a node, assigned by the user.
4///
5/// This is a stable ID that users can use to reference nodes across transactions.
6/// Maps to an internal `InternalNodeId` for storage efficiency.
7pub type ExternalId = u64;
8
9/// Internal node identifier used for storage and lookups.
10///
11/// This is an auto-incremented ID used internally. Users typically work with
12/// `ExternalId` through the ID map.
13pub type InternalNodeId = u32;
14
15/// Label identifier for node classification.
16///
17/// Used to identify node types/labels in the graph.
18pub type LabelId = u32;
19
20/// Relationship type identifier.
21///
22/// Used to identify relationship types (e.g., `:KNOWS`, `:1`).
23pub type RelTypeId = u32;
24
25/// Property value types for nodes and edges.
26///
27/// Supports basic and complex types needed for Cypher property expressions:
28/// - Null: NULL values
29/// - Bool: true/false
30/// - Int: 64-bit signed integers
31/// - Float: 64-bit floating point
32/// - String: UTF-8 strings
33/// - DateTime: 64-bit signed microseconds since Unix epoch
34/// - Blob: Raw binary data
35/// - List: Ordered list of PropertyValues
36/// - Map: String-keyed map of PropertyValues
37#[derive(Debug, Clone, PartialEq)]
38pub enum PropertyValue {
39 Null,
40 Bool(bool),
41 Int(i64),
42 Float(f64),
43 String(String),
44 DateTime(i64),
45 Blob(Vec<u8>),
46 List(Vec<PropertyValue>),
47 Map(BTreeMap<String, PropertyValue>),
48}
49
50/// A directed edge from a source node to a destination node with a relationship type.
51///
52/// Used as the key type for neighbor lookups and edge operations.
53#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
54pub struct EdgeKey {
55 pub src: InternalNodeId,
56 pub rel: RelTypeId,
57 pub dst: InternalNodeId,
58}
59
60/// Provides access to a snapshot of the graph at a point in time.
61///
62/// Implementors must ensure that the returned snapshot is immutable and
63/// reflects a consistent state of the graph.
64pub trait GraphStore {
65 type Snapshot: GraphSnapshot;
66
67 /// Creates a snapshot of the current graph state.
68 ///
69 /// The snapshot is independent of any writes that occur after creation.
70 fn snapshot(&self) -> Self::Snapshot;
71}
72
73/// A read-only snapshot of the graph state.
74///
75/// Snapshots are immutable and provide consistent views of the graph
76/// at the time of creation. Multiple snapshots can coexist.
77pub trait GraphSnapshot {
78 /// Iterator type for neighbors of a node.
79 type Neighbors<'a>: Iterator<Item = EdgeKey> + 'a
80 where
81 Self: 'a;
82
83 /// Get outgoing neighbors of a node, optionally filtered by relationship type.
84 ///
85 /// Returns an iterator over `EdgeKey`s representing outgoing edges.
86 /// If `rel` is `Some`, only edges of that type are returned.
87 /// If `rel` is `None`, all outgoing edges are returned.
88 fn neighbors(&self, src: InternalNodeId, rel: Option<RelTypeId>) -> Self::Neighbors<'_>;
89
90 /// Get an iterator over all non-tombstoned nodes.
91 ///
92 /// Returns an iterator over all internal node IDs that are not tombstoned.
93 /// The default implementation returns an empty iterator.
94 fn nodes(&self) -> Box<dyn Iterator<Item = InternalNodeId> + '_> {
95 Box::new(std::iter::empty())
96 }
97
98 /// Lookup nodes using an index.
99 ///
100 /// Returns `Some(Vec<InternalNodeId>)` if the index exists and the lookup succeeds.
101 /// Returns `None` if the index does not exist.
102 ///
103 /// # Arguments
104 /// * `label` - The label name (e.g., "Person")
105 /// * `field` - The property field name (e.g., "name")
106 /// * `value` - The value to match
107 fn lookup_index(
108 &self,
109 _label: &str,
110 _field: &str,
111 _value: &PropertyValue,
112 ) -> Option<Vec<InternalNodeId>> {
113 None
114 }
115
116 /// Resolve an internal node ID to its external ID.
117 ///
118 /// Returns `Some(external_id)` if the node exists and has an external ID,
119 /// or `None` if the node doesn't exist or has no external ID.
120 fn resolve_external(&self, _iid: InternalNodeId) -> Option<ExternalId> {
121 None
122 }
123
124 /// Get the label ID for a node.
125 ///
126 /// Returns `Some(label_id)` if the node exists, `None` otherwise.
127 fn node_label(&self, _iid: InternalNodeId) -> Option<LabelId> {
128 None
129 }
130
131 /// Check if a node is tombstoned (soft-deleted).
132 ///
133 /// Tombstoned nodes are not returned by `neighbors()` or `nodes()`.
134 fn is_tombstoned_node(&self, _iid: InternalNodeId) -> bool {
135 false
136 }
137
138 /// Get a property value for a node.
139 /// Returns the value from the most recent transaction that set it.
140 fn node_property(&self, _iid: InternalNodeId, _key: &str) -> Option<PropertyValue> {
141 None
142 }
143
144 /// Get a property value for an edge.
145 /// Returns the value from the most recent transaction that set it.
146 fn edge_property(&self, _edge: EdgeKey, _key: &str) -> Option<PropertyValue> {
147 None
148 }
149
150 /// Get all properties for a node.
151 /// Returns properties merged from all runs (newest takes precedence).
152 fn node_properties(&self, _iid: InternalNodeId) -> Option<BTreeMap<String, PropertyValue>> {
153 None
154 }
155
156 /// Get all properties for an edge.
157 /// Get all edge properties merged from all runs (newest takes precedence).
158 fn edge_properties(&self, _edge: EdgeKey) -> Option<BTreeMap<String, PropertyValue>> {
159 None
160 }
161
162 /// Resolve a label name to its ID.
163 fn resolve_label_id(&self, _name: &str) -> Option<LabelId> {
164 None
165 }
166
167 /// Resolve a relationship type name to its ID.
168 fn resolve_rel_type_id(&self, _name: &str) -> Option<RelTypeId> {
169 None
170 }
171
172 /// Resolve a label ID to its name.
173 fn resolve_label_name(&self, _id: LabelId) -> Option<String> {
174 None
175 }
176
177 /// Resolve a relationship type ID to its name.
178 fn resolve_rel_type_name(&self, _id: RelTypeId) -> Option<String> {
179 None
180 }
181
182 /// Get the estimated number of nodes, optionally filtered by label.
183 fn node_count(&self, _label: Option<LabelId>) -> u64 {
184 0
185 }
186
187 /// Get the estimated number of edges, optionally filtered by relationship type.
188 fn edge_count(&self, _rel: Option<RelTypeId>) -> u64 {
189 0
190 }
191}