Documentation
¶
Overview ¶
Package api provides the public database API for gograph, a graph database engine. It offers a high-level interface for executing Cypher queries and managing graph data including nodes, relationships, and their properties.
Package api provides the public database API for gograph, a graph database engine. It offers a high-level interface for executing Cypher queries and managing graph data including nodes, relationships, and their properties.
Basic Usage:
// Open a database
db, err := api.Open("/path/to/db")
if err != nil {
log.Fatal(err)
}
defer db.Close()
// Execute a query that modifies data
result, err := db.Exec(ctx, "CREATE (n:Person {name: $name})", map[string]interface{}{
"name": "Alice",
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("Created %d nodes\n", result.NodesCreated)
// Query data
rows, err := db.Query(ctx, "MATCH (n:Person) RETURN n.name")
if err != nil {
log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
var name string
if err := rows.Scan(&name); err != nil {
log.Fatal(err)
}
fmt.Println(name)
}
Thread Safety:
DB is safe for concurrent use by multiple goroutines. However, individual transactions should not be shared between goroutines.
Package api provides the public database API for gograph, a graph database engine.
Index ¶
- Variables
- type DB
- func (db *DB) BeginTx(ctx context.Context, opts *TxOptions) (*Tx, error)
- func (db *DB) Close() error
- func (db *DB) Exec(ctx context.Context, cypherQuery string, args ...interface{}) (Result, error)
- func (db *DB) IsClosed() bool
- func (db *DB) IsClosedLocked() bool
- func (db *DB) Lock()
- func (db *DB) Query(ctx context.Context, cypherQuery string, args ...interface{}) (*Rows, error)
- func (db *DB) RLock()
- func (db *DB) RUnlock()
- func (db *DB) Store() *storage.DB
- func (db *DB) Unlock()
- type DBOption
- type EdgeData
- type GraphStore
- func (gs *GraphStore) GetNeighbors(nodeID string, depth int, limit int) ([]*NeighborResult, error)
- func (gs *GraphStore) GetNeighborsByTypes(nodeID string, depth int, limit int, relTypes []string) ([]*NeighborResult, error)
- func (gs *GraphStore) GetNode(nodeID string) (*graph.Node, error)
- func (gs *GraphStore) UpsertEdges(edges []*EdgeData) error
- func (gs *GraphStore) UpsertNodes(nodes []*NodeData) error
- type NeighborResult
- type NodeData
- type Result
- type Rows
- type Tx
- type TxOptions
Constants ¶
This section is empty.
Variables ¶
var ( ErrNodeNotFound = errors.New("node not found") ErrInvalidNodeID = errors.New("invalid node id") ErrInvalidEdgeData = errors.New("invalid edge data") )
var ErrDBClosed = errors.New("database is closed")
ErrDBClosed is returned when attempting to perform operations on a closed database.
var ErrNoMoreRows = errors.New("no more rows")
ErrNoMoreRows is returned by Scan when there are no more rows to read.
Functions ¶
This section is empty.
Types ¶
type DB ¶
type DB struct {
// contains filtered or unexported fields
}
DB represents a graph database instance. It provides methods for executing Cypher queries and managing transactions. A DB instance is safe for concurrent use by multiple goroutines.
DB manages the lifecycle of the underlying storage and provides a high-level interface for graph operations. It handles query parsing, execution, and result formatting.
Example:
db, err := api.Open("/path/to/db")
if err != nil {
log.Fatal(err)
}
defer db.Close()
// Execute queries
result, err := db.Exec(ctx, "CREATE (n:Person {name: 'Alice'})")
if err != nil {
log.Fatal(err)
}
// Query data
rows, err := db.Query(ctx, "MATCH (n:Person) RETURN n.name")
if err != nil {
log.Fatal(err)
}
defer rows.Close()
func Open ¶
Open opens a database at the specified path and returns a DB instance. The path is used as the storage location for the underlying Pebble database. Optional DBOption functions can be provided to configure the database.
Parameters:
- path: The directory path where the database files will be stored
- opts: Optional configuration options
Returns a new DB instance or an error if the database cannot be opened.
Example:
// Open with default options
db, err := api.Open("/var/lib/gograph/mydb")
// Open with observability
obs := cypher.NewObservability()
db, err := api.Open("/var/lib/gograph/mydb", api.WithObservability(obs))
func (*DB) BeginTx ¶
BeginTx starts a new transaction with the specified options. If opts is nil, a read-write transaction is started. A transaction allows grouping multiple operations into a single atomic unit.
Parameters:
- ctx: Context for cancellation and timeouts
- opts: Transaction options. Pass nil for default read-write transaction.
Returns a new Tx transaction object, or an error if the transaction cannot be started.
Example:
// Begin a transaction
tx, err := db.BeginTx(ctx, nil)
if err != nil {
log.Fatal(err)
}
// Perform operations
_, err = tx.Exec("CREATE (n:Person {name: 'Alice'})")
if err != nil {
tx.Rollback()
log.Fatal(err)
}
// Commit
if err := tx.Commit(); err != nil {
log.Fatal(err)
}
func (*DB) Close ¶
Close closes the database and releases all associated resources. Any pending operations will be completed before closing.
Returns an error if the database is already closed.
Example:
db, err := api.Open("/path/to/db")
if err != nil {
log.Fatal(err)
}
defer db.Close()
func (*DB) Exec ¶
Exec executes a Cypher query that modifies data (CREATE, SET, DELETE, REMOVE) and returns a Result containing the count of affected nodes and relationships. The query can include optional positional parameters passed as arguments.
Parameters:
- ctx: Context for cancellation and timeouts
- cypherQuery: The Cypher query string to execute
- args: Optional query parameters. If the first argument is a map[string]interface{}, it is used as the parameter map.
Returns a Result containing affected counts, or an error if the query fails.
Example:
// Simple create
result, err := db.Exec(ctx, "CREATE (n:Person {name: 'Alice'})")
// With parameters
result, err := db.Exec(ctx,
"CREATE (n:Person {name: $name, age: $age})",
map[string]interface{}{
"name": "Alice",
"age": 30,
},
)
fmt.Printf("Created %d nodes\n", result.NodesCreated)
func (*DB) IsClosed ¶
IsClosed returns true if the database has been closed.
Example:
if !db.IsClosed() {
db.Close()
}
func (*DB) IsClosedLocked ¶ added in v0.2.1
IsClosedLocked returns true if the database is closed. This should only be called while holding a lock.
func (*DB) Lock ¶ added in v0.2.1
func (db *DB) Lock()
Lock acquires a write lock on the database. This is used internally for synchronization.
func (*DB) Query ¶
Query executes a Cypher query that returns rows of data (MATCH ... RETURN) and returns a Rows iterator for scanning the results. The query can include optional positional parameters passed as arguments.
Parameters:
- ctx: Context for cancellation and timeouts
- cypherQuery: The Cypher query string to execute
- args: Optional query parameters. If the first argument is a map[string]interface{}, it is used as the parameter map.
Returns a Rows iterator for scanning results, or an error if the query fails.
Example:
rows, err := db.Query(ctx, "MATCH (n:Person) RETURN n.name, n.age")
if err != nil {
log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
var name string
var age int
if err := rows.Scan(&name, &age); err != nil {
log.Fatal(err)
}
fmt.Printf("Name: %s, Age: %d\n", name, age)
}
func (*DB) RLock ¶ added in v0.2.1
func (db *DB) RLock()
RLock acquires a read lock on the database. This is used internally for synchronization.
func (*DB) RUnlock ¶ added in v0.2.1
func (db *DB) RUnlock()
RUnlock releases the read lock on the database. This is used internally for synchronization.
type DBOption ¶
type DBOption func(*DB)
DBOption configures optional parameters for database operations. It is used with the Open function to customize database behavior.
func WithObservability ¶
func WithObservability(o *cypher.Observability) DBOption
WithObservability enables observability features for the database executor, allowing tracing and metrics collection during query execution.
Parameters:
- o: The Observability instance to use
Returns a DBOption that can be passed to Open.
Example:
obs := cypher.NewObservability()
db, err := api.Open("/path/to/db", api.WithObservability(obs))
type GraphStore ¶ added in v0.2.1
type GraphStore struct {
// contains filtered or unexported fields
}
func NewGraphStore ¶ added in v0.2.1
func NewGraphStore(db *DB) *GraphStore
func (*GraphStore) GetNeighbors ¶ added in v0.2.1
func (gs *GraphStore) GetNeighbors(nodeID string, depth int, limit int) ([]*NeighborResult, error)
func (*GraphStore) GetNeighborsByTypes ¶ added in v0.2.2
func (gs *GraphStore) GetNeighborsByTypes(nodeID string, depth int, limit int, relTypes []string) ([]*NeighborResult, error)
GetNeighborsByTypes returns neighbors of a node filtered by specific relationship types. This is more efficient than filtering after GetNeighbors because it uses adjacency list prefix scanning instead of loading all relationships.
Parameters:
- nodeID: The ID of the starting node
- depth: The maximum traversal depth (1 = direct neighbors only)
- limit: Maximum number of results (0 = unlimited)
- relTypes: Only follow edges matching these relationship types (empty = all types)
func (*GraphStore) GetNode ¶ added in v0.2.1
func (gs *GraphStore) GetNode(nodeID string) (*graph.Node, error)
func (*GraphStore) UpsertEdges ¶ added in v0.2.1
func (gs *GraphStore) UpsertEdges(edges []*EdgeData) error
func (*GraphStore) UpsertNodes ¶ added in v0.2.1
func (gs *GraphStore) UpsertNodes(nodes []*NodeData) error
type NeighborResult ¶ added in v0.2.1
type NeighborResult struct {
Node *graph.Node
Edge *graph.Relationship
}
type Result ¶
Result contains the count of affected graph elements after executing a data-modifying Cypher query (CREATE, SET, DELETE, REMOVE).
It provides information about how many nodes and relationships were created, modified, or deleted during the query execution.
Example:
result, err := db.Exec(ctx, "CREATE (n:Person) SET n.name = 'Alice'")
if err != nil {
log.Fatal(err)
}
fmt.Printf("Nodes created: %d\n", result.NodesCreated)
fmt.Printf("Nodes affected: %d\n", result.NodesAffected)
type Rows ¶
type Rows struct {
// contains filtered or unexported fields
}
Rows represents a result set iterator from a Cypher query. It provides methods to iterate over the rows and scan column values into Go variables.
Rows is returned by Query and Tx.Query methods. It must be closed when no longer needed to release resources.
Example:
rows, err := db.Query(ctx, "MATCH (n:Person) RETURN n.name, n.age")
if err != nil {
log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
var name string
var age int
if err := rows.Scan(&name, &age); err != nil {
log.Fatal(err)
}
fmt.Printf("Name: %s, Age: %d\n", name, age)
}
func (*Rows) Close ¶
Close releases the Rows resources. It is idempotent and safe to call multiple times.
Example:
defer rows.Close()
func (*Rows) Columns ¶
Columns returns the column names of the result set.
Returns a slice of column names in the order they appear in the query.
Example:
columns := rows.Columns()
for _, col := range columns {
fmt.Println(col)
}
func (*Rows) Next ¶
Next advances the iterator to the next row. It returns true if there is a next row, or false if there are no more rows.
Example:
for rows.Next() {
// Process row
}
func (*Rows) Scan ¶
Scan copies the column values of the current row into the dest variables. The number of dest arguments must be less than or equal to the number of columns in the result set.
Supported destination types:
- *string: For string values
- *int: For integer values (int or int64)
- *int64: For integer values
- *float64: For floating point values
- *bool: For boolean values
- *interface{}: For any value type
Parameters:
- dest: Pointers to variables to receive the column values
Returns ErrNoMoreRows if there are no more rows to read.
Example:
for rows.Next() {
var name string
var age int
if err := rows.Scan(&name, &age); err != nil {
log.Fatal(err)
}
fmt.Printf("Name: %s, Age: %d\n", name, age)
}
type Tx ¶
type Tx struct {
// contains filtered or unexported fields
}
Tx represents a database transaction. It provides methods for executing Cypher queries within a transaction. A transaction is safe for concurrent use by multiple goroutines, though serial execution is recommended.
Transactions provide ACID guarantees:
- Atomicity: All operations succeed or all fail
- Consistency: Database remains in a consistent state
- Isolation: Transactions don't interfere with each other
- Durability: Committed changes persist
Example:
tx, err := db.BeginTx(ctx, nil)
if err != nil {
log.Fatal(err)
}
defer func() {
if err != nil {
tx.Rollback()
}
}()
// Perform multiple operations
_, err = tx.Exec("CREATE (n:Person {name: 'Alice'})")
_, err = tx.Exec("CREATE (n:Person {name: 'Bob'})")
// Commit all operations
err = tx.Commit()
func (*Tx) Commit ¶
Commit commits the transaction, making all changes permanent. After commit, the transaction cannot be used anymore.
Returns an error if the transaction is already closed or if the commit fails.
Example:
if err := tx.Commit(); err != nil {
log.Fatal(err)
}
func (*Tx) Exec ¶
Exec executes a Cypher query within the transaction and returns a Result containing the count of affected nodes and relationships. The query can include optional positional parameters passed as arguments.
Parameters:
- cypherQuery: The Cypher query string to execute
- args: Optional query parameters
Returns a Result containing affected counts, or an error if the query fails or the transaction is closed.
Example:
result, err := tx.Exec("CREATE (n:Person {name: 'Alice'})")
if err != nil {
tx.Rollback()
log.Fatal(err)
}
func (*Tx) Query ¶
Query executes a Cypher query within the transaction and returns a Rows iterator for scanning the results. The query can include optional positional parameters passed as arguments.
Parameters:
- cypherQuery: The Cypher query string to execute
- args: Optional query parameters
Returns a Rows iterator for scanning results, or an error if the query fails or the transaction is closed.
Example:
rows, err := tx.Query("MATCH (n:Person) RETURN n.name")
if err != nil {
tx.Rollback()
log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
var name string
rows.Scan(&name)
fmt.Println(name)
}