Skip to content

Commit

Permalink
BLOB API for C and Java
Browse files Browse the repository at this point in the history
  • Loading branch information
mewim committed Jul 7, 2023
1 parent 15ced33 commit 298ce21
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 4 deletions.
7 changes: 7 additions & 0 deletions src/c_api/value.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,13 @@ char* kuzu_value_get_string(kuzu_value* value) {
return c_string;
}

uint8_t* kuzu_value_get_blob(kuzu_value* value) {
auto string_val = static_cast<Value*>(value->_value)->getValue<std::string>();
auto* c_blob = (uint8_t*)malloc(string_val.size() + 1);
strcpy((char*)c_blob, string_val.c_str());
return c_blob;
}

char* kuzu_value_to_string(kuzu_value* value) {
auto string_val = static_cast<Value*>(value->_value)->toString();
auto* c_string = (char*)malloc(string_val.size() + 1);
Expand Down
8 changes: 7 additions & 1 deletion src/include/c_api/kuzu.h
Original file line number Diff line number Diff line change
Expand Up @@ -649,7 +649,7 @@ KUZU_C_API int16_t kuzu_value_get_int16(kuzu_value* value);
*/
KUZU_C_API int32_t kuzu_value_get_int32(kuzu_value* value);
/**
* @brief Returns the int64 value of the given value. The value must be of type INT64.
* @brief Returns the int64 value of the given value. The value must be of type INT64 or SERIAL.
* @param value The value to return.
*/
KUZU_C_API int64_t kuzu_value_get_int64(kuzu_value* value);
Expand Down Expand Up @@ -688,6 +688,12 @@ KUZU_C_API kuzu_interval_t kuzu_value_get_interval(kuzu_value* value);
* @param value The value to return.
*/
KUZU_C_API char* kuzu_value_get_string(kuzu_value* value);
/**
* @brief Returns the blob value of the given value. The returned buffer is null-terminated similar
* to a string. The value must be of type BLOB.
* @param value The value to return.
*/
KUZU_C_API uint8_t* kuzu_value_get_blob(kuzu_value* value);
/**
* @brief Converts the given value to string.
* @param value The value to convert.
Expand Down
3 changes: 2 additions & 1 deletion src/include/common/types/value.h
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,8 @@ inline internalID_t Value::getValue() const {
*/
KUZU_API template<>
inline std::string Value::getValue() const {
assert(dataType.getLogicalTypeID() == LogicalTypeID::STRING);
assert(dataType.getLogicalTypeID() == LogicalTypeID::STRING ||
dataType.getLogicalTypeID() == LogicalTypeID::BLOB);
return strVal;
}

Expand Down
22 changes: 22 additions & 0 deletions test/c_api/value_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,28 @@ TEST_F(CApiValueTest, GetString) {
kuzu_query_result_destroy(result);
}

TEST_F(CApiValueTest, GetBlob) {
auto connection = getConnection();
auto result =
kuzu_connection_query(connection, (char*)R"(RETURN BLOB('\\xAA\\xBB\\xCD\\x1A');)");
ASSERT_TRUE(kuzu_query_result_is_success(result));
ASSERT_TRUE(kuzu_query_result_has_next(result));
auto flatTuple = kuzu_query_result_get_next(result);
auto value = kuzu_flat_tuple_get_value(flatTuple, 0);
ASSERT_TRUE(value->_is_owned_by_cpp);
ASSERT_FALSE(kuzu_value_is_null(value));
auto blob = kuzu_value_get_blob(value);
ASSERT_EQ(blob[0], 0xAA);
ASSERT_EQ(blob[1], 0xBB);
ASSERT_EQ(blob[2], 0xCD);
ASSERT_EQ(blob[3], 0x1A);
ASSERT_EQ(blob[4], 0x00);
free(blob);
kuzu_value_destroy(value);
kuzu_flat_tuple_destroy(flatTuple);
kuzu_query_result_destroy(result);
}

TEST_F(CApiValueTest, ToSting) {
auto connection = getConnection();
auto result = kuzu_connection_query(connection,
Expand Down
10 changes: 8 additions & 2 deletions tools/java_api/src/jni/kuzu_java.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -927,12 +927,18 @@ JNIEXPORT jobject JNICALL Java_com_kuzudb_KuzuNative_kuzu_1value_1get_1value(
jobject ret = env->NewObject(retClass, ctor, iid.tableID, iid.offset);
return ret;
}
case LogicalTypeID::STRING:
case LogicalTypeID::BLOB: {
case LogicalTypeID::STRING: {
std::string str = v->getValue<std::string>();
jstring ret = env->NewStringUTF(str.c_str());
return ret;
}
case LogicalTypeID::BLOB: {
auto str = v->getValue<std::string>();
auto byteBuffer = str.c_str();
auto ret = env->NewByteArray(str.size());
env->SetByteArrayRegion(ret, 0, str.size(), (jbyte*)byteBuffer);
return ret;
}
default: {
// Throw exception here?
return nullptr;
Expand Down
18 changes: 18 additions & 0 deletions tools/java_api/src/test/java/com/kuzudb/test/ValueTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,24 @@ void ValueGetString() throws KuzuObjectRefDestroyedException {
result.destroy();
}

@Test
void ValueGetBlob() throws KuzuObjectRefDestroyedException {
KuzuQueryResult result = conn.query("RETURN BLOB('\\\\xAA\\\\xBB\\\\xCD\\\\x1A');");
assertTrue(result.isSuccess());
assertTrue(result.hasNext());
KuzuFlatTuple flatTuple = result.getNext();
KuzuValue value = flatTuple.getValue(0);
assertTrue(value.isOwnedByCPP());
assertFalse(value.isNull());

byte[] bytes = value.getValue();
assertTrue(bytes.length == 4);
assertTrue(bytes[0] == (byte) 0xAA);
assertTrue(bytes[1] == (byte) 0xBB);
assertTrue(bytes[2] == (byte) 0xCD);
assertTrue(bytes[3] == (byte) 0x1A);
}

@Test
void ValueToString() throws KuzuObjectRefDestroyedException {
KuzuQueryResult result = conn.query("MATCH (a:person) RETURN a.fName, a.isStudent, a.workedHours");
Expand Down

0 comments on commit 298ce21

Please sign in to comment.