Skip to content
Blog

C API

See the following link for the full documentation of the C library API.

Linking

Using the pre-built library

See Installation and Get Started for simple manual instructions for building with the C library.

Alternatively, here is an example configuration for integrating the pre-built library into a CMake project (substitute URL and URL_HASH and libkuzu.so as appropriate for your platform).

cmake_minimum_required(VERSION 3.11)
project(example LANGUAGES C)
ExternalProject_Add(kuzu-prebuilt
URL https://github.com/kuzudb/kuzu/releases/download/v0.5.0/libkuzu-linux-x86_64.tar.gz
URL_HASH SHA256=452599a03c4e6accb797d11bd780a2a88629bddf6635b1703993967d31a0467e
)
ExternalProject_Get_Property(kuzu-prebuilt SOURCE_DIR)
add_library(kuzu SHARED IMPORTED)
add_dependencies(kuzu kuzu-prebuilt)
set_target_properties(kuzu PROPERTIES IMPORTED_LOCATION ${SOURCE_DIR}/libkuzu.so)
target_include_directories(kuzu INTERFACE ${SOURCE_DIR})
add_executable(example main.c)
target_link_libraries(example kuzu)

Linking against Kùzu when built from source

See the requirements in https://docs.kuzudb.com/developer-guide/. It’s recommended that you use CMake if you want to link to the kuzu static library as shown in the example below.

CMake

The following example uses FetchContent to download and build kuzu as a dependency within a CMake project, and links it either statically or dynamically to an example executable (which can be configured with the EXAMPLE_SHARED option). See Get Started for an example of main.c.

cmake_minimum_required(VERSION 3.11)
project(example LANGUAGES C CXX)
set(BUILD_SHELL FALSE)
include(FetchContent)
FetchContent_Declare(kuzu
URL https://github.com/kuzudb/kuzu/archive/refs/tags/v0.5.0.zip
URL_HASH SHA256=47ff308079cbbfeccc38eeb1c5f455a8c00f9294034141b9084387518f0bbed9
)
FetchContent_MakeAvailable(kuzu)
add_executable(example main.c)
option(EXAMPLE_SHARED "Use dynamic linking" TRUE)
if (EXAMPLE_SHARED)
target_link_libraries(example kuzu_shared)
else()
target_link_libraries(example kuzu)
endif()

Other Build Systems

Using other build systems with the dynamic library is still relatively simple as all you need to make use of is the dynamic library and kuzu.h, both of which can be installed by CMake. E.g. your build system can run.

Terminal window
cmake -B build
cmake --build build
cmake --install build --prefix '<install-dest>'

And then link against <install-dest>/libkuzu.so (or libkuzu.dylib/libkuzu.lib depending on your platform) and add <install-dest> to your include directories.

The static library is more complicated (as noted above, it’s recommended that you use CMake to handle the details) and is not installed by default, but all static libraries will be available in the build directory. You need to define KUZU_STATIC_DEFINE, and link against the static Kùzu library in build/src, as well as antlr4_cypher, antlr4_runtime, brotlidec, brotlicommon, utf8proc, re2, serd, fastpfor, miniparquet, zstd, miniz, mbedtls, lz4 (all of which can be found in the third_party subdirectory of the CMake build directory. E.g. build/third_party/zstd/libzstd.a) and whichever standard library you’re using.

Handling Kùzu output using kuzu_query_result_get_next()

For the examples in this section we will be using the following schema:

CREATE NODE TABLE person(id INT64 PRIMARY KEY);

The kuzu_query_result_get_next() function returns a reference to the resulting flat tuple. Additionally, to reduce resource allocation all calls to kuzu_query_result_get_next() reuse the same flat tuple object. This means that for a query result, each call to kuzu_query_result_get_next() actually overwrites the flat tuple previously returned by the previous call.

Thus, we recommend processing each tuple immediately before making the next call to getNext:

kuzu_query_result result;
kuzu_connection_query(conn, "MATCH (p:person) RETURN p.*", result);
while (kuzu_query_result_has_next(result)) {
kuzu_flat_tuple tuple;
kuzu_query_result_get_next(result, tuple);
do_something(tuple);
}

If you wish to process the tuples later, you must explicitly make a copy of each tuple:

static kuzu_value* copy_flat_tuple(kuzu_flat_tuple* tuple, uint32_t tupleLen) {
kuzu_value* ret = malloc(sizeof(kuzu_value) * tupleLen);
for (uint32_t i = 0; i < tupleLen; i++) {
kuzu_flat_tuple_get_value(tuple, i, &ret[i]);
}
return ret;
}
void mainFunction() {
kuzu_query_result result;
kuzu_connection_query(conn, "MATCH (p:person) RETURN p.*", &result);
uint64_t num_tuples = kuzu_query_result_get_num_tuples(&result);
kuzu_value** tuples = (kuzu_value**)malloc(sizeof(kuzu_value*) * num_tuples);
for (uint64_t i = 0; i < num_tuples; ++i) {
kuzu_flat_tuple tuple;
kuzu_query_result_get_next(&result, &tuple);
tuples[i] = copy_flat_tuple(&tuple, kuzu_query_result_get_num_columns(&result));
kuzu_flat_tuple_destroy(&tuple);
}
for (uint64_t i = 0; i < num_tuples; ++i) {
for (uint64_t j = 0; j < kuzu_query_result_get_num_columns(&result); ++j) {
doSomething(tuples[i][j]);
kuzu_value_destroy(&tuples[i][j]);
}
free(tuples[i]);
}
free((void*)tuples);
kuzu_query_result_destroy(&result);
}