Add tests and docs for toBlob. Bump version.
FossilOrigin-Name: d7358c9d8961f2b70f83ca4e19d4c43408e59cc169f072a238745060edb09de9
This commit is contained in:
parent
7a85bfc7ac
commit
e532c50e99
6 changed files with 78 additions and 19 deletions
|
|
@ -1,5 +1,13 @@
|
||||||
# Release History for nim-kuzu
|
# Release History for nim-kuzu
|
||||||
|
|
||||||
|
---
|
||||||
|
## v0.3.0 [2025-04-19] Mahlon E. Smith <mahlon@martini.nu>
|
||||||
|
|
||||||
|
Enhancement:
|
||||||
|
|
||||||
|
- Add `toBlob` for quickly fetching a sequence of opaque bytes.
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
## v0.2.0 [2025-04-01] Mahlon E. Smith <mahlon@martini.nu>
|
## v0.2.0 [2025-04-01] Mahlon E. Smith <mahlon@martini.nu>
|
||||||
|
|
||||||
|
|
|
||||||
19
USAGE.md
19
USAGE.md
|
|
@ -501,3 +501,22 @@ for row in res:
|
||||||
# Bob has known Alice since 2009.
|
# Bob has known Alice since 2009.
|
||||||
# Alice has known Bob since 2010.
|
# Alice has known Bob since 2010.
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Blobs
|
||||||
|
|
||||||
|
Kuzu can store small chunks of opaque binary data. For these BLOB columns,
|
||||||
|
using `toBlob` will return the raw sequence of bytes.
|
||||||
|
|
||||||
|
```nim
|
||||||
|
var q = conn.query """
|
||||||
|
CREATE NODE TABLE Doot ( id SERIAL, data BLOB, PRIMARY KEY(id) )
|
||||||
|
"""
|
||||||
|
|
||||||
|
var stmt = conn.prepare( "CREATE (d:Doot {data: encode($str)})" )
|
||||||
|
q = stmt.execute( (str: "Hello!") )
|
||||||
|
q = conn.query( "MATCH (d:Doot) RETURN d.data" )
|
||||||
|
|
||||||
|
var blob = q.getNext[0].toBlob #=> @[72, 101, 108, 108, 111, 33]
|
||||||
|
```
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# vim: set et sta sw=4 ts=4 :
|
# vim: set et sta sw=4 ts=4 :
|
||||||
|
|
||||||
version = "0.2.0"
|
version = "0.3.0"
|
||||||
author = "Mahlon E. Smith"
|
author = "Mahlon E. Smith"
|
||||||
description = "Kuzu is an embedded graph database built for query speed and scalability."
|
description = "Kuzu is an embedded graph database built for query speed and scalability."
|
||||||
license = "BSD-3-Clause"
|
license = "BSD-3-Clause"
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# vim: set et sta sw=4 ts=4 :
|
# vim: set et sta sw=4 ts=4 :
|
||||||
|
|
||||||
const KUZU_VERSION* = "0.2.0"
|
const KUZU_VERSION* = "0.3.0"
|
||||||
const KUZU_EXPECTED_LIBVERSION* = "0.9.0"
|
const KUZU_EXPECTED_LIBVERSION* = "0.9.0"
|
||||||
const BLOB_MAXSIZE = 4096
|
const BLOB_MAXSIZE = 4096
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -131,6 +131,23 @@ func toList*( value: KuzuValue ): seq[ KuzuValue ] =
|
||||||
const toSeq* = toList
|
const toSeq* = toList
|
||||||
|
|
||||||
|
|
||||||
|
proc toBlob*( value: KuzuValue ): seq[ byte ] =
|
||||||
|
## Conversion from Kuzu type to Nim - returns a BLOB as a sequence of bytes.
|
||||||
|
if value.kind != KUZU_BLOB:
|
||||||
|
raise newException( KuzuTypeError, &"Mismatched types: {value.kind} != blob" )
|
||||||
|
|
||||||
|
result = @[]
|
||||||
|
var data: ptr byte
|
||||||
|
assert( kuzu_value_get_blob( addr value.handle, addr data ) == KuzuSuccess )
|
||||||
|
|
||||||
|
for idx in 0 .. BLOB_MAXSIZE:
|
||||||
|
var byte = cast[ptr byte](cast[uint](data) + idx.uint)[]
|
||||||
|
if byte == 0: break
|
||||||
|
result.add( byte )
|
||||||
|
|
||||||
|
kuzu_destroy_blob( data )
|
||||||
|
|
||||||
|
|
||||||
func toStruct*( value: KuzuValue ): KuzuStructValue =
|
func toStruct*( value: KuzuValue ): KuzuStructValue =
|
||||||
## Create a convenience class for struct-like KuzuValues.
|
## Create a convenience class for struct-like KuzuValues.
|
||||||
if not [
|
if not [
|
||||||
|
|
@ -186,20 +203,3 @@ func `$`*( struct: KuzuStructValue ): string =
|
||||||
result = $kuzu_value_to_string( addr struct.value.handle )
|
result = $kuzu_value_to_string( addr struct.value.handle )
|
||||||
|
|
||||||
|
|
||||||
proc toBlob*( value: KuzuValue ): seq[ byte ] =
|
|
||||||
## Conversion from Kuzu type to Nim - returns a BLOB as a sequence of bytes.
|
|
||||||
if value.kind != KUZU_BLOB:
|
|
||||||
raise newException( KuzuTypeError, &"Mismatched types: {value.kind} != blob" )
|
|
||||||
|
|
||||||
result = @[]
|
|
||||||
var data: ptr byte
|
|
||||||
assert( kuzu_value_get_blob( addr value.handle, addr data ) == KuzuSuccess )
|
|
||||||
|
|
||||||
for idx in 0 .. BLOB_MAXSIZE:
|
|
||||||
var byte = cast[ptr byte](cast[uint](data) + idx.uint)[]
|
|
||||||
if byte == 0: break
|
|
||||||
result.add( byte )
|
|
||||||
|
|
||||||
kuzu_destroy_blob( data )
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
32
tests/values/t_can_return_a_blob_object.nim
Normal file
32
tests/values/t_can_return_a_blob_object.nim
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
# vim: set et sta sw=4 ts=4 :
|
||||||
|
|
||||||
|
import kuzu
|
||||||
|
|
||||||
|
var db = newKuzuDatabase()
|
||||||
|
var conn = db.connect
|
||||||
|
|
||||||
|
var q = conn.query( "CREATE NODE TABLE Doot ( id SERIAL, data BLOB, PRIMARY KEY(id) )" )
|
||||||
|
|
||||||
|
# (188, 189, 186, 170)
|
||||||
|
q = conn.query( """CREATE (d:Doot {data: BLOB('\\xBC\\xBD\\xBA\\xAA')})""" )
|
||||||
|
|
||||||
|
var stmt = conn.prepare( "CREATE (d:Doot {data: encode($str)})" )
|
||||||
|
q = stmt.execute( (str: "Hello!") )
|
||||||
|
q = conn.query( "MATCH (d:Doot) RETURN d.data" )
|
||||||
|
|
||||||
|
var expected: seq[byte] = @[188, 189, 186, 170]
|
||||||
|
var val = q.getNext[0]
|
||||||
|
assert val.kind == KUZU_BLOB
|
||||||
|
assert val.toBlob == expected
|
||||||
|
|
||||||
|
expected = @[72, 101, 108, 108, 111, 33]
|
||||||
|
val = q.getNext[0]
|
||||||
|
assert val.kind == KUZU_BLOB
|
||||||
|
assert val.toBlob == expected
|
||||||
|
|
||||||
|
var str: string
|
||||||
|
for c in expected:
|
||||||
|
str.add( c.char )
|
||||||
|
|
||||||
|
assert str == "Hello!"
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue