Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Address #2954 for C++, C, Python, Node.js, and Java APIs #2958

Merged
merged 10 commits into from
Feb 28, 2024
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@
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.

Check warning on line 170 in tools/java_api/src/jni/kuzu_java.cpp

View check run for this annotation

Codecov / codecov/patch

tools/java_api/src/jni/kuzu_java.cpp#L170

Added line #L170 was not covered by tests
env->ThrowNew(Exception, error);
}
#endif
Expand Down Expand Up @@ -1254,3 +1255,11 @@
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 @@ -52,3 +54,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());
}
18 changes: 17 additions & 1 deletion tools/nodejs_api/src_js/database.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,28 @@ class Database {
databasePath,
bufferManagerSize,
enableCompression,
readOnly,
readOnly
);
this._isInitialized = false;
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
17 changes: 14 additions & 3 deletions tools/python_api/src_cpp/py_database.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
#include "include/py_database.h"

#include <memory>

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

#include <memory>

using namespace kuzu::common;

void PyDatabase::initialize(py::handle& m) {
Expand All @@ -28,7 +29,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)
Loading
Loading