Skip to content
NarDBv0.2.0-dev

Go API

Embedding NarDB in a Go program — Exec, parameters and error values.

NarDB Shell, the future server and the LexerLang connector all use the same Go package. None of them touches the storage layer directly.

Go
import "nardb"

db, err := nardb.Open("./data/shop.ndbc", nardb.Options{})
if err != nil {
    return err
}
defer db.Close()

res, err := db.Exec(ctx, `
    from('members')
        .where({'email': $1})
        .fields('name', FORMAT('birth_date', 'dd-mm-yyyy'));
`, "osman@example.com")
if err != nil {
    return err
}
for _, row := range res[0].Rows {
    fmt.Println(row[0], row[1])
}

Open modes#

Options.ModeFile existsFile missing
nardb.OpenOrCreate (default)opens itcreates it
nardb.CreateNewfs.ErrExistcreates it
nardb.OpenExistingopens itfs.ErrNotExist

Opening the same file a second time returns nardb.ErrLocked, even within the same process. Share one *nardb.DB per process; a DB is safe for concurrent use.

Exec#

Go
func (db *DB) Exec(ctx context.Context, script string, args ...any) ([]Result, error)
  • Runs the statements in order and stops at the first error. The returned results are those of the statements that ran before it.
  • $1, $2 are replaced by the args; values are never embedded in the query text.
  • At most max_concurrent_queries calls to Exec run at the same time. query_timeout adds a deadline to ctx.
Go
type Result struct {
    Statement    string
    Message      string
    Columns      []string
    Rows         [][]string
    RowsAffected int
}

Rows come back as text for now. Dates use the field's format and password fields come back as ••••••. An API that returns typed values will come in a later version.

Errors carry a position: line 2, col 17: 'int' is ambiguous: ....

Other methods#

MethodWhat it does
Schemas() · DescribeSchema(name)Schemas, and a schema's fields, indexes and distribution
CreateUser(name, password) · VerifyUser · Users()Users
Pool() · SetPool(p)Pool settings
Stats()File and page statistics, DatabaseID

Error values#

Compare with errors.Is: ErrNotDatabase, ErrCorrupt, ErrFormatVersion, ErrUnsupportedFeature, ErrLocked, ErrUnsupportedPlatform, ErrClosed, ErrNotImplemented.

LexerLang#

The LexerLang connector is not written yet. The planned usage:

LexerLang
use nardb

$db = $app.services.once("nardb", func()
    return new nardb({path: path.pwd + "/data/app.ndbc"})
end func)

$member = $db.query("from('members').where({'email': $1}).fields('name').limit(1);", $email)

services.once is used because LexerLang pages run again on every request. Opening and closing the database file per request would be slow and would clash with the "one owner per file" rule.