Skip to content

Commit

Permalink
Address #2954 for C++, C, Python, Node.js, and Java APIs (#2958)
Browse files Browse the repository at this point in the history
  • Loading branch information
mewim committed Feb 28, 2024
1 parent d661d99 commit e056583
Show file tree
Hide file tree
Showing 24 changed files with 271 additions and 5 deletions.
3 changes: 2 additions & 1 deletion src/c_api/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ add_library(kuzu_c_api
prepared_statement.cpp
query_result.cpp
query_summary.cpp
value.cpp)
value.cpp
version.cpp)

set(ALL_OBJECT_FILES
${ALL_OBJECT_FILES} $<TARGET_OBJECTS:kuzu_c_api>
Expand Down
12 changes: 12 additions & 0 deletions src/c_api/version.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include "main/version.h"

#include "c_api/helpers.h"
#include "c_api/kuzu.h"

char* kuzu_get_version() {
return convertToOwnedCString(kuzu::main::Version::getVersion());
}

uint64_t kuzu_get_storage_version() {
return kuzu::main::Version::getStorageVersion();
}
11 changes: 11 additions & 0 deletions src/include/c_api/kuzu.h
Original file line number Diff line number Diff line change
Expand Up @@ -1269,4 +1269,15 @@ KUZU_C_API double kuzu_query_summary_get_compiling_time(kuzu_query_summary* quer
KUZU_C_API double kuzu_query_summary_get_execution_time(kuzu_query_summary* query_summary);

// TODO: Bind utility functions for kuzu_date_t, kuzu_timestamp_t, and kuzu_interval_t

// Version
/**
* @brief Returns the version of the Kùzu library.
*/
KUZU_C_API char* kuzu_get_version();

/**
* @brief Returns the storage version of the Kùzu library.
*/
KUZU_C_API uint64_t kuzu_get_storage_version();
#undef KUZU_C_API
1 change: 1 addition & 0 deletions src/include/main/kuzu.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@
#include "main/query_result.h" // IWYU pragma: export
#include "main/query_summary.h" // IWYU pragma: export
#include "main/storage_driver.h" // IWYU pragma: export
#include "main/version.h" // IWYU pragma: export
#include "processor/result/flat_tuple.h" // IWYU pragma: export
23 changes: 23 additions & 0 deletions src/include/main/version.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#pragma once
#include <cstdint>

#include "common/api.h"
namespace kuzu {
namespace main {

struct Version {
public:
/**
* @brief Get the version of the Kùzu library.
* @return const char* The version of the Kùzu library.
*/
KUZU_API static const char* getVersion();

/**
* @brief Get the storage version of the Kùzu library.
* @return uint64_t The storage version of the Kùzu library.
*/
KUZU_API static uint64_t getStorageVersion();
};
} // namespace main
} // namespace kuzu
1 change: 1 addition & 0 deletions src/main/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ add_library(kuzu_main
query_result.cpp
query_summary.cpp
storage_driver.cpp
version.cpp
db_config.cpp)

set(ALL_OBJECT_FILES
Expand Down
15 changes: 15 additions & 0 deletions src/main/version.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#include "main/version.h"

#include "storage/storage_info.h"

namespace kuzu {
namespace main {
const char* Version::getVersion() {
return KUZU_CMAKE_VERSION;
}

uint64_t Version::getStorageVersion() {
return storage::StorageVersionInfo::getStorageVersion();
}
} // namespace main
} // namespace kuzu
3 changes: 2 additions & 1 deletion test/c_api/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ add_kuzu_api_test(c_api_test
prepared_statement_test.cpp
query_result_test.cpp
rdf_variant_test.cpp
value_test.cpp)
value_test.cpp
version_test.cpp)
41 changes: 41 additions & 0 deletions test/c_api/version_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@

#include <filesystem>
#include <fstream>

#include "c_api/kuzu.h"
#include "c_api_test/c_api_test.h"
#include "gtest/gtest.h"
#include "main/version.h"

using namespace kuzu::main;
using namespace kuzu::testing;
using namespace kuzu::common;

class CApiVersionTest : public CApiTest {
public:
std::string getInputDir() override {
return TestHelper::appendKuzuRootPath("dataset/tinysnb/");
}
};

TEST_F(CApiVersionTest, GetVersion) {
auto version = kuzu_get_version();
ASSERT_NE(version, nullptr);
ASSERT_STREQ(version, KUZU_CMAKE_VERSION);
kuzu_destroy_string(version);
}

TEST_F(CApiVersionTest, GetStorageVersion) {
auto storageVersion = kuzu_get_storage_version();
auto catalog = std::filesystem::path(databasePath) / "catalog.kz";
std::ifstream catalogFile;
catalogFile.open(catalog, std::ios::binary);
char magic[5];
catalogFile.read(magic, 4);
magic[4] = '\0';
ASSERT_STREQ(magic, "KUZU");
uint64_t actualVersion;
catalogFile.read(reinterpret_cast<char*>(&actualVersion), sizeof(actualVersion));
catalogFile.close();
ASSERT_EQ(storageVersion, actualVersion);
}
11 changes: 10 additions & 1 deletion tools/java_api/src/jni/kuzu_java.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,8 @@ JNIEXPORT void JNICALL Java_com_kuzudb_KuzuNative_kuzu_1native_1reload_1library(
env->ReleaseStringUTFChars(lib_path, path);
if (handle == nullptr) {
jclass Exception = env->FindClass("java/lang/Exception");
auto error = dlerror(); // NOLINT(concurrency-mt-unsafe): load can only be executed in single thread.
auto error =
dlerror(); // NOLINT(concurrency-mt-unsafe): load can only be executed in single thread.
env->ThrowNew(Exception, error);
}
#endif
Expand Down Expand Up @@ -1255,3 +1256,11 @@ JNIEXPORT jobject JNICALL Java_com_kuzudb_KuzuNative_kuzu_1rdf_1variant_1get_1va
return nullptr;
}
}

JNIEXPORT jstring JNICALL Java_com_kuzudb_KuzuNative_kuzu_1get_1version(JNIEnv* env, jclass) {
return env->NewStringUTF(Version::getVersion());
}

JNIEXPORT jlong JNICALL Java_com_kuzudb_KuzuNative_kuzu_1get_1storage_1version(JNIEnv*, jclass) {
return static_cast<jlong>(Version::getStorageVersion());
}
4 changes: 4 additions & 0 deletions tools/java_api/src/main/java/com/kuzudb/KuzuNative.java
Original file line number Diff line number Diff line change
Expand Up @@ -221,4 +221,8 @@ protected static native long kuzu_data_type_create(
protected static native KuzuDataType kuzu_rdf_variant_get_data_type(KuzuValue rdf_variant);

protected static native <T> T kuzu_rdf_variant_get_value(KuzuValue rdf_variant);

protected static native String kuzu_get_version();

protected static native long kuzu_get_storage_version();
}
23 changes: 23 additions & 0 deletions tools/java_api/src/main/java/com/kuzudb/KuzuVersion.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.kuzudb;

/**
* KuzuVersion is a class to get the version of the Kùzu.
*/
public class KuzuVersion {

/**
* Get the version of the Kùzu.
* @return The version of the Kùzu.
*/
public static String getVersion() {
return KuzuNative.kuzu_get_version();
}

/**
* Get the storage version of the Kùzu.
* @return The storage version of the Kùzu.
*/
public static long getStorageVersion() {
return KuzuNative.kuzu_get_storage_version();
}
}
21 changes: 21 additions & 0 deletions tools/java_api/src/test/java/com/kuzudb/test/VersionTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.kuzudb.java_test;

import com.kuzudb.*;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

public class VersionTest extends TestBase {

@Test
void GetVersion() {
String version = KuzuVersion.getVersion();
assertTrue(!version.equals(""));
}

@Test
void GetStorageVersion() {
long storage_version = KuzuVersion.getStorageVersion();
assertTrue(storage_version > 0);
}
}
2 changes: 2 additions & 0 deletions tools/nodejs_api/src_cpp/include/node_database.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ class NodeDatabase : public Napi::ObjectWrap<NodeDatabase> {
Napi::Value InitAsync(const Napi::CallbackInfo& info);
void InitCppDatabase();
void setLoggingLevel(const Napi::CallbackInfo& info);
static Napi::Value GetVersion(const Napi::CallbackInfo& info);
static Napi::Value GetStorageVersion(const Napi::CallbackInfo& info);

private:
std::string databasePath;
Expand Down
14 changes: 14 additions & 0 deletions tools/nodejs_api/src_cpp/node_database.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ Napi::Object NodeDatabase::Init(Napi::Env env, Napi::Object exports) {
{
InstanceMethod("initAsync", &NodeDatabase::InitAsync),
InstanceMethod("setLoggingLevel", &NodeDatabase::setLoggingLevel),
StaticMethod("getVersion", &NodeDatabase::GetVersion),
StaticMethod("getStorageVersion", &NodeDatabase::GetStorageVersion),
});

exports.Set("NodeDatabase", t);
Expand Down Expand Up @@ -56,3 +58,15 @@ void NodeDatabase::setLoggingLevel(const Napi::CallbackInfo& info) {
auto loggingLevel = info[0].As<Napi::String>().Utf8Value();
database->setLoggingLevel(std::move(loggingLevel));
}

Napi::Value NodeDatabase::GetVersion(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();
Napi::HandleScope scope(env);
return Napi::String::New(env, Version::getVersion());
}

Napi::Value NodeDatabase::GetStorageVersion(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();
Napi::HandleScope scope(env);
return Napi::Number::New(env, Version::getStorageVersion());
}
16 changes: 16 additions & 0 deletions tools/nodejs_api/src_js/database.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,22 @@ class Database {
this._initPromise = null;
}

/**
* Get the version of the library.
* @returns {String} the version of the library.
*/
static getVersion() {
return KuzuNative.NodeDatabase.getVersion();
}

/**
* Get the storage version of the library.
* @returns {Number} the storage version of the library.
*/
static getStorageVersion() {
return KuzuNative.NodeDatabase.getStorageVersion();
}

/**
* Initialize the database. Calling this function is optional, as the
* database is initialized automatically when the first query is executed.
Expand Down
6 changes: 6 additions & 0 deletions tools/nodejs_api/src_js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,10 @@ module.exports = {
LoggingLevel,
PreparedStatement,
QueryResult,
get VERSION() {
return Database.getVersion();
},
get STORAGE_VERSION() {
return Database.getStorageVersion();
},
};
1 change: 1 addition & 0 deletions tools/nodejs_api/test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ describe("kuzu", () => {
importTest("Extension loading", "./test_extension.js");
importTest("Query parameters", "./test_parameter.js");
importTest("Concurrent query execution", "./test_concurrency.js");
importTest("Version", "./test_version.js");
});
13 changes: 13 additions & 0 deletions tools/nodejs_api/test/test_version.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const { assert } = require("chai");

describe("Get version", function () {
it("should get the version of the library", function () {
assert.isString(kuzu.VERSION);
assert.notEqual(kuzu.VERSION, "");
});

it("should get the storage version of the library", function () {
assert.isNumber(kuzu.STORAGE_VERSION);
assert.isAtLeast(kuzu.STORAGE_VERSION, 1);
});
});
4 changes: 4 additions & 0 deletions tools/python_api/src_cpp/include/py_database.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ class PyDatabase {

static void initialize(py::handle& m);

static py::str getVersion();

static uint64_t getStorageVersion();

explicit PyDatabase(const std::string& databasePath, uint64_t bufferPoolSize,
uint64_t maxNumThreads, bool compression, bool readOnly, uint64_t maxDBSize);

Expand Down
16 changes: 14 additions & 2 deletions tools/python_api/src_cpp/py_database.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
#include "include/py_database.h"
#include "pandas/pandas_scan.h"

#include <memory>

#include "main/version.h"
#include "pandas/pandas_scan.h"

using namespace kuzu::common;

void PyDatabase::initialize(py::handle& m) {
Expand All @@ -26,7 +28,17 @@ void PyDatabase::initialize(py::handle& m) {
.def("scan_node_table_as_float", &PyDatabase::scanNodeTable<float>, py::arg("table_name"),
py::arg("prop_name"), py::arg("indices"), py::arg("np_array"), py::arg("num_threads"))
.def("scan_node_table_as_bool", &PyDatabase::scanNodeTable<bool>, py::arg("table_name"),
py::arg("prop_name"), py::arg("indices"), py::arg("np_array"), py::arg("num_threads"));
py::arg("prop_name"), py::arg("indices"), py::arg("np_array"), py::arg("num_threads"))
.def_static("get_version", &PyDatabase::getVersion)
.def_static("get_storage_version", &PyDatabase::getStorageVersion);
}

py::str PyDatabase::getVersion() {
return py::str(Version::getVersion());
}

uint64_t PyDatabase::getStorageVersion() {
return Version::getStorageVersion();
}

PyDatabase::PyDatabase(const std::string& databasePath, uint64_t bufferPoolSize,
Expand Down
9 changes: 9 additions & 0 deletions tools/python_api/src_py/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,15 @@
from .query_result import *
from .types import *

def __getattr__(name):
if name == "version":
return Database.get_version()
elif name == "storage_version":
return Database.get_storage_version()
else:
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")


# Restore the original dlopen flags
if sys.platform == "linux":
sys.setdlopenflags(original_dlopen_flags)
22 changes: 22 additions & 0 deletions tools/python_api/src_py/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,28 @@ def __init__(self, database_path, buffer_pool_size=0, max_num_threads=0, compres
self._database = None
if not lazy_init:
self.init_database()

def get_version():
"""
Get the version of the database.
Returns
-------
str
The version of the database.
"""
return _kuzu.Database.get_version()

def get_storage_version():
"""
Get the storage version of the database.
Returns
-------
int
The storage version of the database.
"""
return _kuzu.Database.get_storage_version()

def __getstate__(self):
state = {
Expand Down
4 changes: 4 additions & 0 deletions tools/python_api/test/test_version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
def test_version():
import kuzu
assert kuzu.version != ""
assert kuzu.storage_version > 0

0 comments on commit e056583

Please sign in to comment.