Use a template for type conversion checks.

FossilOrigin-Name: 2ea0a91c86c6e756460ba4c2345b9f56de03ff6ddd2c5a111a0b51a7d3739786
This commit is contained in:
Mahlon E. Smith 2025-04-26 21:12:45 +00:00
parent 30d60f2cd2
commit b0cdb4cfa2
3 changed files with 37 additions and 36 deletions

View file

@ -29,8 +29,8 @@ table to ensure you're using the correct version for your Kuzu
installation. I'll make a modest effort for backwards compatibility, and other installation. I'll make a modest effort for backwards compatibility, and other
versions might work. Don't count too heavily on it. :-) versions might work. Don't count too heavily on it. :-)
| Kuzu Library Version | Nim Kuzu Version | | Kuzu Library Version | Nim Kuzu Minimum Version |
| -------------------- | ---------------- | | -------------------- | ------------------------ |
| v0.8.2 | v0.1.0 | | v0.8.2 | v0.1.0 |
| v0.9.0 | v0.2.0 | | v0.9.0 | v0.2.0 |

View file

@ -17,6 +17,13 @@ func getType( value: KuzuValue ) =
kuzu_data_type_destroy( addr logical_type ) kuzu_data_type_destroy( addr logical_type )
template checkType( kind: kuzu_data_type_id, valid_types: set ) =
## Raises a KuzuTypeError if the type conversion is incompatible.
if kind notin valid_types:
let msg = "Mismatched types: " & $kind & " != " & $valid_types
raise newException( KuzuTypeError, msg )
func `$`*( value: KuzuValue ): string = func `$`*( value: KuzuValue ): string =
## Stringify a value. ## Stringify a value.
result = $kuzu_value_to_string( addr value.handle ) result = $kuzu_value_to_string( addr value.handle )
@ -24,78 +31,67 @@ func `$`*( value: KuzuValue ): string =
func toBool*( value: KuzuValue ): bool = func toBool*( value: KuzuValue ): bool =
## Conversion from Kuzu type to Nim. ## Conversion from Kuzu type to Nim.
if value.kind != KUZU_BOOL: checkType( value.kind, {KUZU_BOOL} )
raise newException( KuzuTypeError, &"Mismatched types: {value.kind} != bool" )
assert( kuzu_value_get_bool( addr value.handle, addr result ) == KuzuSuccess ) assert( kuzu_value_get_bool( addr value.handle, addr result ) == KuzuSuccess )
func toInt8*( value: KuzuValue ): int8 = func toInt8*( value: KuzuValue ): int8 =
## Conversion from Kuzu type to Nim. ## Conversion from Kuzu type to Nim.
if value.kind != KUZU_INT8: checkType( value.kind, {KUZU_INT8} )
raise newException( KuzuTypeError, &"Mismatched types: {value.kind} != int8" )
assert( kuzu_value_get_int8( addr value.handle, addr result ) == KuzuSuccess ) assert( kuzu_value_get_int8( addr value.handle, addr result ) == KuzuSuccess )
func toInt16*( value: KuzuValue ): int16 = func toInt16*( value: KuzuValue ): int16 =
## Conversion from Kuzu type to Nim. ## Conversion from Kuzu type to Nim.
if value.kind != KUZU_INT16: checkType( value.kind, {KUZU_INT16} )
raise newException( KuzuTypeError, &"Mismatched types: {value.kind} != int16" )
assert( kuzu_value_get_int16( addr value.handle, addr result ) == KuzuSuccess ) assert( kuzu_value_get_int16( addr value.handle, addr result ) == KuzuSuccess )
func toInt32*( value: KuzuValue ): int32 = func toInt32*( value: KuzuValue ): int32 =
## Conversion from Kuzu type to Nim. ## Conversion from Kuzu type to Nim.
if value.kind != KUZU_INT32: checkType( value.kind, {KUZU_INT32} )
raise newException( KuzuTypeError, &"Mismatched types: {value.kind} != int32" )
assert( kuzu_value_get_int32( addr value.handle, addr result ) == KuzuSuccess ) assert( kuzu_value_get_int32( addr value.handle, addr result ) == KuzuSuccess )
func toInt64*( value: KuzuValue ): int64 = func toInt64*( value: KuzuValue ): int64 =
## Conversion from Kuzu type to Nim. ## Conversion from Kuzu type to Nim.
if value.kind != KUZU_INT64: checkType( value.kind, {KUZU_INT64} )
raise newException( KuzuTypeError, &"Mismatched types: {value.kind} != int64" )
assert( kuzu_value_get_int64( addr value.handle, addr result ) == KuzuSuccess ) assert( kuzu_value_get_int64( addr value.handle, addr result ) == KuzuSuccess )
func toUint8*( value: KuzuValue ): uint8 = func toUint8*( value: KuzuValue ): uint8 =
## Conversion from Kuzu type to Nim. ## Conversion from Kuzu type to Nim.
if value.kind != KUZU_UINT8: checkType( value.kind, {KUZU_UINT8} )
raise newException( KuzuTypeError, &"Mismatched types: {value.kind} != uint8" )
assert( kuzu_value_get_uint8( addr value.handle, addr result ) == KuzuSuccess ) assert( kuzu_value_get_uint8( addr value.handle, addr result ) == KuzuSuccess )
func toUint16*( value: KuzuValue ): uint16 = func toUint16*( value: KuzuValue ): uint16 =
## Conversion from Kuzu type to Nim. ## Conversion from Kuzu type to Nim.
if value.kind != KUZU_UINT16: checkType( value.kind, {KUZU_UINT16} )
raise newException( KuzuTypeError, &"Mismatched types: {value.kind} != uint16" )
assert( kuzu_value_get_uint16( addr value.handle, addr result ) == KuzuSuccess ) assert( kuzu_value_get_uint16( addr value.handle, addr result ) == KuzuSuccess )
func toUint32*( value: KuzuValue ): uint32 = func toUint32*( value: KuzuValue ): uint32 =
## Conversion from Kuzu type to Nim. ## Conversion from Kuzu type to Nim.
if value.kind != KUZU_UINT32: checkType( value.kind, {KUZU_UINT32} )
raise newException( KuzuTypeError, &"Mismatched types: {value.kind} != uint32" )
assert( kuzu_value_get_uint32( addr value.handle, addr result ) == KuzuSuccess ) assert( kuzu_value_get_uint32( addr value.handle, addr result ) == KuzuSuccess )
func toUint64*( value: KuzuValue ): uint64 = func toUint64*( value: KuzuValue ): uint64 =
## Conversion from Kuzu type to Nim. ## Conversion from Kuzu type to Nim.
if value.kind != KUZU_UINT64: checkType( value.kind, {KUZU_UINT64} )
raise newException( KuzuTypeError, &"Mismatched types: {value.kind} != uint64" )
assert( kuzu_value_get_uint64( addr value.handle, addr result ) == KuzuSuccess ) assert( kuzu_value_get_uint64( addr value.handle, addr result ) == KuzuSuccess )
func toDouble*( value: KuzuValue ): float = func toDouble*( value: KuzuValue ): float =
## Conversion from Kuzu type to Nim. ## Conversion from Kuzu type to Nim.
if value.kind != KUZU_DOUBLE: checkType( value.kind, {KUZU_DOUBLE} )
raise newException( KuzuTypeError, &"Mismatched types: {value.kind} != double" )
assert( kuzu_value_get_double( addr value.handle, addr result ) == KuzuSuccess ) assert( kuzu_value_get_double( addr value.handle, addr result ) == KuzuSuccess )
func toFloat*( value: KuzuValue ): float = func toFloat*( value: KuzuValue ): float =
## Conversion from Kuzu type to Nim. ## Conversion from Kuzu type to Nim.
if value.kind != KUZU_FLOAT: checkType( value.kind, {KUZU_FLOAT} )
raise newException( KuzuTypeError, &"Mismatched types: {value.kind} != float" )
var rv: cfloat var rv: cfloat
assert( kuzu_value_get_float( addr value.handle, addr rv ) == KuzuSuccess ) assert( kuzu_value_get_float( addr value.handle, addr rv ) == KuzuSuccess )
result = rv result = rv
@ -103,8 +99,7 @@ func toFloat*( value: KuzuValue ): float =
func toTimestamp*( value: KuzuValue ): int = func toTimestamp*( value: KuzuValue ): int =
## Conversion from Kuzu type to Nim. ## Conversion from Kuzu type to Nim.
if value.kind != KUZU_TIMESTAMP: checkType( value.kind, {KUZU_TIMESTAMP} )
raise newException( KuzuTypeError, &"Mismatched types: {value.kind} != timestamp" )
var rv: kuzu_timestamp_t var rv: kuzu_timestamp_t
assert( kuzu_value_get_timestamp( addr value.handle, addr rv ) == KuzuSuccess ) assert( kuzu_value_get_timestamp( addr value.handle, addr rv ) == KuzuSuccess )
result = rv.value result = rv.value
@ -112,8 +107,7 @@ func toTimestamp*( value: KuzuValue ): int =
func toList*( value: KuzuValue ): seq[ KuzuValue ] = func toList*( value: KuzuValue ): seq[ KuzuValue ] =
## Return a sequence from KUZU_LIST values. ## Return a sequence from KUZU_LIST values.
if value.kind != KUZU_LIST: checkType( value.kind, {KUZU_LIST} )
raise newException( KuzuTypeError, &"Mismatched types: {value.kind} != list" )
result = @[] result = @[]
var size: uint64 var size: uint64
assert( kuzu_value_get_list_size( addr value.handle, addr size ) == KuzuSuccess ) assert( kuzu_value_get_list_size( addr value.handle, addr size ) == KuzuSuccess )
@ -133,8 +127,7 @@ const toSeq* = toList
func toBlob*( value: KuzuValue ): seq[ byte ] = func toBlob*( value: KuzuValue ): seq[ byte ] =
## Conversion from Kuzu type to Nim - returns a BLOB as a sequence of bytes. ## Conversion from Kuzu type to Nim - returns a BLOB as a sequence of bytes.
if value.kind != KUZU_BLOB: checkType( value.kind, {KUZU_BLOB} )
raise newException( KuzuTypeError, &"Mismatched types: {value.kind} != blob" )
result = @[] result = @[]
var data: ptr byte var data: ptr byte
@ -150,14 +143,13 @@ func toBlob*( value: KuzuValue ): seq[ byte ] =
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 [ checkType( value.kind, {
KUZU_STRUCT, KUZU_STRUCT,
KUZU_NODE, KUZU_NODE,
KUZU_REL, KUZU_REL,
KUZU_RECURSIVE_REL, KUZU_RECURSIVE_REL,
KUZU_UNION KUZU_UNION
].contains( value.kind ): })
raise newException( KuzuTypeError, &"Mismatched types: {value.kind} != struct" )
result = new KuzuStructValue result = new KuzuStructValue
result.value = value result.value = value

View file

@ -19,6 +19,15 @@ assert val.kind == KUZU_NODE
try: try:
discard val.toInt32 discard val.toInt32
except KuzuTypeError as err: except KuzuTypeError as err:
assert err.msg.contains( re"""Mismatched types: KUZU_NODE != int32""" ) assert err.msg.contains( re"""Mismatched types: KUZU_NODE != {KUZU_INT32}""" )
q = conn.query( "RETURN 1" )
val = q.getNext[0]
try:
discard val.toStruct
except KuzuTypeError as err:
assert err.msg.contains( re"""Mismatched types: KUZU_INT.* != {KUZU_NODE, KUZU_REL,.*}""" )