api

package
v0.2.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 30, 2026 License: MIT Imports: 7 Imported by: 1

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

Constants

This section is empty.

Variables

View Source
var (
	ErrNodeNotFound    = errors.New("node not found")
	ErrInvalidNodeID   = errors.New("invalid node id")
	ErrInvalidEdgeData = errors.New("invalid edge data")
)
View Source
var ErrDBClosed = errors.New("database is closed")

ErrDBClosed is returned when attempting to perform operations on a closed database.

View Source
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

func Open(path string, opts ...DBOption) (*DB, error)

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

func (db *DB) BeginTx(ctx context.Context, opts *TxOptions) (*Tx, error)

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

func (db *DB) Close() error

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

func (db *DB) Exec(ctx context.Context, cypherQuery string, args ...interface{}) (Result, error)

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

func (db *DB) IsClosed() bool

IsClosed returns true if the database has been closed.

Example:

if !db.IsClosed() {
    db.Close()
}

func (*DB) IsClosedLocked added in v0.2.1

func (db *DB) IsClosedLocked() bool

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

func (db *DB) Query(ctx context.Context, cypherQuery string, args ...interface{}) (*Rows, error)

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.

func (*DB) Store added in v0.2.1

func (db *DB) Store() *storage.DB

Store returns the underlying storage database. This is primarily for advanced use cases and testing.

func (*DB) Unlock added in v0.2.1

func (db *DB) Unlock()

Unlock releases the write 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 EdgeData added in v0.2.1

type EdgeData struct {
	FromNodeID string
	ToNodeID   string
	Type       string
	Properties map[string]interface{}
}

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 NodeData added in v0.2.1

type NodeData struct {
	ID         string
	Labels     []string
	Properties map[string]interface{}
}

type Result

type Result = cypher.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

func (r *Rows) Close() error

Close releases the Rows resources. It is idempotent and safe to call multiple times.

Example:

defer rows.Close()

func (*Rows) Columns

func (r *Rows) Columns() []string

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

func (r *Rows) Next() bool

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

func (r *Rows) Scan(dest ...interface{}) error

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

func (tx *Tx) Commit() error

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

func (tx *Tx) Exec(cypherQuery string, args ...interface{}) (Result, error)

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

func (tx *Tx) Query(cypherQuery string, args ...interface{}) (*Rows, error)

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)
}

func (*Tx) Rollback

func (tx *Tx) Rollback() error

Rollback aborts the transaction and discards all changes. If the transaction is already closed, Rollback returns nil. Rollback is safe to call multiple times.

Example:

defer func() {
    if err != nil {
        tx.Rollback()
    }
}()

type TxOptions

type TxOptions struct {
	// ReadOnly indicates whether the transaction should be read-only.
	// A read-only transaction cannot modify data but may have better performance.
	ReadOnly bool
}

TxOptions specifies configuration options for a transaction.

Directories

Path Synopsis
Package format provides result formatters for gograph query output.
Package format provides result formatters for gograph query output.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL