Perform magic checks on a database file for better error messaging.

This commit is contained in:
Mahlon E. Smith 2025-07-18 20:23:20 -07:00
parent 6881d15358
commit 72da9341fd
Signed by: mahlon
SSH key fingerprint: SHA256:dP84sRGKZRpOOiPD/+GuOq+SHSxEw9qi5BWLQobaHm0
11 changed files with 75 additions and 9 deletions

3
.gitignore vendored
View file

@ -1,10 +1,13 @@
experiments/imdb/*
!experiments/imdb/*.nim
!experiments/imdb/Makefile
nimble.paths
config.nims
tmp/*
kuzu
nimcache/*
tests/*
!tests/*/t_*.nim
testresults/*
testresults.html

View file

@ -358,8 +358,10 @@ Manually rewind the `KuzuQueryResult` via `rewind()`.
## Multiple Query Results
A query can potentially return any number of separate statements. Iterate over
linked `KuzuQueryResult` objects with the `sets()` iterator.
A query can potentially return any number of separate statements. In the case
of more potential `RETURN`s, the query will only contain the first. Iterate
over linked `KuzuQueryResult` objects with the `sets()` iterator to retreive the
remaining:
```nim
import kuzu

Binary file not shown.

View file

@ -18,9 +18,7 @@ task makewrapper, "Generate the C wrapper using Futhark":
task test, "Run the test suite.":
exec "testament --megatest:off all"
exec "testament html"
task clean, "Remove all non-repository artifacts.":
exec "fossil clean -x"
exec """find tests/ -type f \! -name \*.nim -delete"""
task docs, "Generate automated documentation.":
exec "nim md2html --project --outdir:docs README.md"

View file

@ -13,6 +13,8 @@ else:
include "kuzu/0.11.0.nim"
import
std/files,
std/paths,
std/strformat,
std/strutils

View file

@ -7,18 +7,50 @@ proc `=destroy`*( db: KuzuDatabaseObj ) =
kuzu_database_destroy( addr db.handle )
func newKuzuDatabase*( path="", config=kuzuConfig() ): KuzuDatabase =
proc validateDatabase( db: KuzuDatabase ): void =
## Perform basic validity checks against an existing on disk database
## for better error messaging.
if not Path( db.path ).fileExists: return
var buf = newSeq[char]( 5 )
let f = open( db.path )
discard f.readChars( buf )
f.close
let magic = buf[0..3].join
let storage_version = buf[4].uint
if magic != "KUZU":
raise newException( KuzuException, "Unable to open database: " &
&""""{db.path}" Doesn't appear to be a Kuzu file.""" )
if storageVersion != kuzuGetStorageVersion():
raise newException( KuzuException, "Unable to open database: " &
&" mismatched storage versions - file is {storageVersion}, expected {kuzuGetStorageVersion()}." )
proc newKuzuDatabase*( path="", config=kuzuConfig() ): KuzuDatabase =
## Create a new Kuzu database handle. Creates an in-memory
## database by default, but writes to disk if a +path+ is supplied.
result = new KuzuDatabase
result.config = config
result.path = if path != "" and path != ":memory:": path else: "(in-memory)"
if path != "" and path != ":memory:":
result.path = path
result.kind = disk
else:
result.path = "(in-memory)"
result.kind = memory
result.handle = kuzu_database()
if result.kind == disk:
result.validateDatabase()
if kuzu_database_init( path, config, addr result.handle ) == KuzuSuccess:
result.valid = true
else:
raise newException( KuzuException, "Unable to open database." )

View file

@ -1,9 +1,13 @@
# vim: set et sta sw=4 ts=4 :
type
KuzuDBType* = enum
disk, memory
KuzuDatabaseObj = object
handle: kuzu_database
path*: string
kind*: KuzuDBType
config*: kuzu_system_config
valid = false
KuzuDatabase* = ref KuzuDatabaseObj

View file

@ -4,4 +4,5 @@ import kuzu
var db = newKuzuDatabase()
assert db.path == "(in-memory)"
assert db.kind == memory

View file

@ -0,0 +1,23 @@
# vim: set et sta sw=4 ts=4 :
import
std/files,
std/paths,
std/re
import kuzu
const NOT_A_DATABASE_PATH = Path( "tmp/not-a-db" )
NOT_A_DATABASE_PATH.removeFile()
var fh = NOT_A_DATABASE_PATH.string.open( fmWrite )
fh.write( "Hi." )
fh.close
try:
discard newKuzuDatabase( $NOT_A_DATABASE_PATH )
except KuzuException as err:
assert err.msg.contains( re"""Unable to open database: "tmp/not-a-db" Doesn't appear to be a Kuzu file""" )
NOT_A_DATABASE_PATH.removeFile()

View file

@ -12,6 +12,7 @@ DATABASE_PATH.removeFile()
var db = newKuzuDatabase( $DATABASE_PATH )
assert db.path == $DATABASE_PATH
assert db.kind == disk
assert db.config == kuzuConfig()
assert db.config.read_only == false