Nim API Reference¶
DecentDb's native Nim API for embedded applications.
Opening a Database¶
import decentdb/engine
# Open with default cache (1024 pages = 4MB)
let db = openDb("myapp.ddb")
if not db.ok:
echo "Failed to open: ", db.err.message
quit(1)
# Open with custom cache size
let db2 = openDb("myapp.ddb", cachePages = 4096) # 16MB cache
Executing SQL¶
Basic Queries¶
import decentdb/engine
import decentdb/record/record
let db = openDb("myapp.ddb").value
# Execute DDL
let createRes = execSql(db, "CREATE TABLE users (id INT PRIMARY KEY, name TEXT)")
if not createRes.ok:
echo "Error: ", createRes.err.message
# Insert data
let insertRes = execSql(db, "INSERT INTO users VALUES (1, 'Alice')")
if insertRes.ok:
echo "Inserted, rows affected: ", insertRes.value.len
With Parameters¶
# Use positional parameters $1, $2, etc.
let params = @[
Value(kind: vkInt64, int64Val: 2),
Value(kind: vkText, bytes: toBytes("Bob"))
]
let res = execSql(db, "INSERT INTO users VALUES ($1, $2)", params)
Query Results¶
# SELECT returns rows as strings
let selectRes = execSql(db, "SELECT * FROM users")
if selectRes.ok:
for row in selectRes.value:
echo row # "1|Alice"
Transactions¶
Manual Transaction Control¶
# Begin transaction
let beginRes = execSql(db, "BEGIN")
if not beginRes.ok:
echo "Failed to begin transaction"
# Execute operations
let res1 = execSql(db, "INSERT INTO users VALUES (3, 'Carol')")
let res2 = execSql(db, "INSERT INTO users VALUES (4, 'Dave')")
# Commit or rollback
if res1.ok and res2.ok:
discard execSql(db, "COMMIT")
echo "Transaction committed"
else:
discard execSql(db, "ROLLBACK")
echo "Transaction rolled back"
Bulk Loading¶
For high-performance data import:
import decentdb/engine
let db = openDb("myapp.ddb").value
# Create table
discard execSql(db, "CREATE TABLE bulk_data (id INT PRIMARY KEY, data TEXT)")
# Prepare data
var rows: seq[seq[Value]] = @[]
for i in 1 .. 10000:
rows.add(@[
Value(kind: vkInt64, int64Val: i),
Value(kind: vkText, bytes: toBytes("data_" & $i))
])
# Configure bulk load
var opts = defaultBulkLoadOptions()
opts.disableIndexes = true # Faster: rebuild indexes after
opts.durability = dmDeferred # Batch fsync operations
opts.batchSize = 10000
opts.checkpointOnComplete = true # Checkpoint when done
# Load data
let bulkRes = bulkLoad(db, "bulk_data", rows, opts)
if bulkRes.ok:
echo "Loaded ", rows.len, " rows"
else:
echo "Bulk load failed: ", bulkRes.err.message
Working with Values¶
Creating Values¶
import decentdb/record/record
# NULL
let nullVal = Value(kind: vkNull)
# Integer
let intVal = Value(kind: vkInt64, int64Val: 42)
# Float
let floatVal = Value(kind: vkFloat64, float64Val: 3.14)
# Boolean
let boolVal = Value(kind: vkBool, boolVal: true)
# Text
proc toBytes(s: string): seq[byte] =
result = newSeq[byte](s.len)
for i, c in s:
result[i] = byte(c)
let textVal = Value(kind: vkText, bytes: toBytes("Hello"))
# Blob
let blobVal = Value(kind: vkBlob, bytes: toBytes("\x00\x01\x02"))
Converting Values to Strings¶
proc valueToString(v: Value): string =
case v.kind
of vkNull: "NULL"
of vkInt64: $v.int64Val
of vkFloat64: $v.float64Val
of vkBool: if v.boolVal: "true" else: "false"
of vkText, vkBlob:
result = ""
for b in v.bytes:
result.add(char(b))
Error Handling¶
All operations return a Result[T] type:
type Result[T] = object
ok: bool
value: T # Only valid if ok == true
err: DbError # Only valid if ok == false
type DbError = object
code: ErrorCode
message: string
context: string
Checking Results¶
let res = execSql(db, "SELECT * FROM nonexistent")
if not res.ok:
case res.err.code
of ERR_SQL:
echo "SQL error: ", res.err.message
of ERR_IO:
echo "IO error: ", res.err.message
of ERR_CORRUPTION:
echo "Database corruption detected!"
else:
echo "Error: ", res.err.message
Database Information¶
Database Properties¶
let db = openDb("myapp.ddb").value
echo "Path: ", db.path
echo "Page size: ", db.pageSize, " bytes"
echo "Format version: ", db.formatVersion
echo "Cache pages: ", db.cachePages
echo "Schema cookie: ", db.schemaCookie
Getting Table Information¶
let tableRes = db.catalog.getTable("users")
if tableRes.ok:
let table = tableRes.value
echo "Table: ", table.name
echo "Root page: ", table.rootPage
for col in table.columns:
echo " Column: ", col.name, " (", $col.kind, ")"
Closing the Database¶
Always close the database when done:
Complete Example¶
import decentdb/engine
import decentdb/record/record
import os
proc main() =
let dbPath = getTempDir() / "example.ddb"
# Open database
let dbRes = openDb(dbPath)
if not dbRes.ok:
echo "Failed to open: ", dbRes.err.message
return
let db = dbRes.value
# Create table
let createRes = execSql(db, "CREATE TABLE users (id INT PRIMARY KEY, name TEXT)")
if not createRes.ok:
echo "Create failed: ", createRes.err.message
discard closeDb(db)
return
# Insert data
let names = ["Alice", "Bob", "Carol"]
for i, name in names:
let params = @[
Value(kind: vkInt64, int64Val: int64(i + 1)),
Value(kind: vkText, bytes: toBytes(name))
]
let insertRes = execSql(db, "INSERT INTO users VALUES ($1, $2)", params)
if not insertRes.ok:
echo "Insert failed: ", insertRes.err.message
# Query data
let selectRes = execSql(db, "SELECT * FROM users ORDER BY id")
if selectRes.ok:
echo "Users:"
for row in selectRes.value:
echo " ", row
# Cleanup
discard closeDb(db)
removeFile(dbPath)
main()
Advanced Topics¶
Direct Pager Access¶
For low-level operations:
import decentdb/pager/pager
# Read a page directly
let pageRes = db.pager.readPage(1)
if pageRes.ok:
let page = pageRes.value
# Work with raw page bytes
Custom VFS¶
Implement your own virtual file system:
import decentdb/vfs/types
type MyVfs = ref object of Vfs
# Custom implementation
method open*(vfs: MyVfs, path: string, mode: FileMode, create: bool): Result[VfsFile] =
# Custom open implementation
...
See the VFS module for details.
Thread Safety¶
- Single writer: Only one thread can write at a time
- Multiple readers: Many threads can read concurrently
- Use proper synchronization in your application
Performance Tips¶
- Reuse database connections
- Use bulk load for large imports
- Prepare/cache frequently used queries
- Use appropriate cache size
- Create indexes for frequent queries
API Stability¶
DecentDb is currently pre-1.0 (starting at 0.0.1). Until 1.0.0, APIs may change, including breaking changes. Once 1.0.0 is released, we will follow Semantic Versioning for API compatibility.