pub struct Session { /* private fields */ }Expand description
Your handle to the database - execute queries and manage transactions.
Get one from GrafeoDB::session(). Each session
tracks its own transaction state, so you can have multiple concurrent
sessions without them interfering.
Implementations§
Source§impl Session
impl Session
Sourcepub fn execute(&self, query: &str) -> Result<QueryResult>
pub fn execute(&self, query: &str) -> Result<QueryResult>
Executes a GQL query.
§Errors
Returns an error if the query fails to parse or execute.
§Examples
use grafeo_engine::GrafeoDB;
let db = GrafeoDB::new_in_memory();
let session = db.session();
// Create a node
session.execute("INSERT (:Person {name: 'Alice', age: 30})")?;
// Query nodes
let result = session.execute("MATCH (n:Person) RETURN n.name, n.age")?;
for row in result {
println!("{:?}", row);
}Sourcepub fn execute_with_params(
&self,
query: &str,
params: HashMap<String, Value>,
) -> Result<QueryResult>
pub fn execute_with_params( &self, query: &str, params: HashMap<String, Value>, ) -> Result<QueryResult>
Executes a GQL query with parameters.
§Errors
Returns an error if the query fails to parse or execute.
Sourcepub fn begin_tx(&mut self) -> Result<()>
pub fn begin_tx(&mut self) -> Result<()>
Begins a new transaction.
§Errors
Returns an error if a transaction is already active.
§Examples
use grafeo_engine::GrafeoDB;
let db = GrafeoDB::new_in_memory();
let mut session = db.session();
session.begin_tx()?;
session.execute("INSERT (:Person {name: 'Alice'})")?;
session.execute("INSERT (:Person {name: 'Bob'})")?;
session.commit()?; // Both inserts committed atomicallySourcepub fn rollback(&mut self) -> Result<()>
pub fn rollback(&mut self) -> Result<()>
Aborts the current transaction.
Discards all changes since begin_tx.
§Errors
Returns an error if no transaction is active.
§Examples
use grafeo_engine::GrafeoDB;
let db = GrafeoDB::new_in_memory();
let mut session = db.session();
session.begin_tx()?;
session.execute("INSERT (:Person {name: 'Alice'})")?;
session.rollback()?; // Insert is discardedSourcepub fn in_transaction(&self) -> bool
pub fn in_transaction(&self) -> bool
Returns whether a transaction is active.
Sourcepub fn set_auto_commit(&mut self, auto_commit: bool)
pub fn set_auto_commit(&mut self, auto_commit: bool)
Sets auto-commit mode.
Sourcepub fn auto_commit(&self) -> bool
pub fn auto_commit(&self) -> bool
Returns whether auto-commit is enabled.
Sourcepub fn create_node(&self, labels: &[&str]) -> NodeId
pub fn create_node(&self, labels: &[&str]) -> NodeId
Creates a node directly (bypassing query execution).
This is a low-level API for testing and direct manipulation. If a transaction is active, the node will be versioned with the transaction ID.
Sourcepub fn create_node_with_props<'a>(
&self,
labels: &[&str],
properties: impl IntoIterator<Item = (&'a str, Value)>,
) -> NodeId
pub fn create_node_with_props<'a>( &self, labels: &[&str], properties: impl IntoIterator<Item = (&'a str, Value)>, ) -> NodeId
Creates a node with properties.
If a transaction is active, the node will be versioned with the transaction ID.
Sourcepub fn create_edge(&self, src: NodeId, dst: NodeId, edge_type: &str) -> EdgeId
pub fn create_edge(&self, src: NodeId, dst: NodeId, edge_type: &str) -> EdgeId
Creates an edge between two nodes.
This is a low-level API for testing and direct manipulation. If a transaction is active, the edge will be versioned with the transaction ID.
Sourcepub fn get_node(&self, id: NodeId) -> Option<Node>
pub fn get_node(&self, id: NodeId) -> Option<Node>
Gets a node by ID directly, bypassing query planning.
This is the fastest way to retrieve a single node when you know its ID. Skips parsing, binding, optimization, and physical planning entirely.
§Performance
- Time complexity: O(1) average case
- No lock contention (uses DashMap internally)
- ~20-30x faster than equivalent MATCH query
§Example
let session = db.session();
let node_id = session.create_node(&["Person"]);
// Direct lookup - O(1), no query planning
let node = session.get_node(node_id);
assert!(node.is_some());Sourcepub fn get_node_property(&self, id: NodeId, key: &str) -> Option<Value>
pub fn get_node_property(&self, id: NodeId, key: &str) -> Option<Value>
Gets a single property from a node by ID, bypassing query planning.
More efficient than get_node() when you only need one property,
as it avoids loading the full node with all properties.
§Performance
- Time complexity: O(1) average case
- No query planning overhead
§Example
let session = db.session();
let id = session.create_node_with_props(&["Person"], [("name", "Alice".into())]);
// Direct property access - O(1)
let name = session.get_node_property(id, "name");
assert_eq!(name, Some(Value::String("Alice".into())));Sourcepub fn get_edge(&self, id: EdgeId) -> Option<Edge>
pub fn get_edge(&self, id: EdgeId) -> Option<Edge>
Gets an edge by ID directly, bypassing query planning.
§Performance
- Time complexity: O(1) average case
- No lock contention
Sourcepub fn get_neighbors_outgoing(&self, node: NodeId) -> Vec<(NodeId, EdgeId)>
pub fn get_neighbors_outgoing(&self, node: NodeId) -> Vec<(NodeId, EdgeId)>
Gets outgoing neighbors of a node directly, bypassing query planning.
Returns (neighbor_id, edge_id) pairs for all outgoing edges.
§Performance
- Time complexity: O(degree) where degree is the number of outgoing edges
- Uses adjacency index for direct access
- ~10-20x faster than equivalent MATCH query
§Example
let session = db.session();
let alice = session.create_node(&["Person"]);
let bob = session.create_node(&["Person"]);
session.create_edge(alice, bob, "KNOWS");
// Direct neighbor lookup - O(degree)
let neighbors = session.get_neighbors_outgoing(alice);
assert_eq!(neighbors.len(), 1);
assert_eq!(neighbors[0].0, bob);Sourcepub fn get_neighbors_incoming(&self, node: NodeId) -> Vec<(NodeId, EdgeId)>
pub fn get_neighbors_incoming(&self, node: NodeId) -> Vec<(NodeId, EdgeId)>
Gets incoming neighbors of a node directly, bypassing query planning.
Returns (neighbor_id, edge_id) pairs for all incoming edges.
§Performance
- Time complexity: O(degree) where degree is the number of incoming edges
- Uses backward adjacency index for direct access
Sourcepub fn get_neighbors_outgoing_by_type(
&self,
node: NodeId,
edge_type: &str,
) -> Vec<(NodeId, EdgeId)>
pub fn get_neighbors_outgoing_by_type( &self, node: NodeId, edge_type: &str, ) -> Vec<(NodeId, EdgeId)>
Sourcepub fn node_exists(&self, id: NodeId) -> bool
pub fn node_exists(&self, id: NodeId) -> bool
Checks if a node exists, bypassing query planning.
§Performance
- Time complexity: O(1)
- Fastest existence check available
Sourcepub fn edge_exists(&self, id: EdgeId) -> bool
pub fn edge_exists(&self, id: EdgeId) -> bool
Checks if an edge exists, bypassing query planning.
Sourcepub fn get_degree(&self, node: NodeId) -> (usize, usize)
pub fn get_degree(&self, node: NodeId) -> (usize, usize)
Gets the degree (number of edges) of a node.
Returns (outgoing_degree, incoming_degree).
Sourcepub fn get_nodes_batch(&self, ids: &[NodeId]) -> Vec<Option<Node>>
pub fn get_nodes_batch(&self, ids: &[NodeId]) -> Vec<Option<Node>>
Batch lookup of multiple nodes by ID.
More efficient than calling get_node() in a loop because it
amortizes overhead.
§Performance
- Time complexity: O(n) where n is the number of IDs
- Better cache utilization than individual lookups