-
Notifications
You must be signed in to change notification settings - Fork 86
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Yash Oza
committed
Apr 28, 2023
1 parent
175665d
commit 30bf5f8
Showing
28 changed files
with
1,797 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
cmake_minimum_required(VERSION 3.25) | ||
project (kuzujs) | ||
|
||
set(CMAKE_CXX_STANDARD 20) | ||
|
||
add_definitions(-DNAPI_VERSION=5) | ||
|
||
if (CMAKE_BUILD_TYPE EQUAL "DEBUG") | ||
find_library(KUZU NAMES kuzu PATHS ../../build/debug/src) | ||
set(THIRD_PARTY_BIN_PATH ../../build/debug/third_party) | ||
else() | ||
find_library(KUZU NAMES kuzu PATHS ../../build/release/src) | ||
set(THIRD_PARTY_BIN_PATH ../../build/release/third_party) | ||
endif() | ||
|
||
get_filename_component(NODE_ADDON_API_INCLUDE_PATH ./node_modules/node-addon-api ABSOLUTE) | ||
get_filename_component(KUZU_INCLUDE_PATH ../../src/include ABSOLUTE) | ||
get_filename_component(ANTLR4_CYPHER_INCLUDE_PATH ../../third_party/antlr4_cypher/include ABSOLUTE) | ||
get_filename_component(ANTLR4_RUNTIME_INCLUDE_PATH ../../third_party/antlr4_runtime/src ABSOLUTE) | ||
get_filename_component(SPDLOG_INCLUDE_PATH ../../third_party/spdlog ABSOLUTE) | ||
get_filename_component(NLOHMANN_JSON_INCLUDE_PATH ../../third_party/nlohmann_json ABSOLUTE) | ||
get_filename_component(UTF8PROC_INCLUDE_PATH ../../third_party/utf8proc/include ABSOLUTE) | ||
get_filename_component(CONCURRENT_QUEUE_INCLUDE_PATH ../../third_party/concurrentqueue ABSOLUTE) | ||
get_filename_component(THIRD_PARTY_PATH ../../third_party ABSOLUTE) | ||
|
||
include_directories(${CMAKE_JS_INC}) | ||
include_directories(${NODE_ADDON_API_INCLUDE_PATH}) | ||
include_directories(${KUZU_INCLUDE_PATH}) | ||
include_directories(${ANTLR4_CYPHER_INCLUDE_PATH}) | ||
include_directories(${ANTLR4_RUNTIME_INCLUDE_PATH}) | ||
include_directories(${SPDLOG_INCLUDE_PATH}) | ||
include_directories(${NLOHMANN_JSON_INCLUDE_PATH}) | ||
include_directories(${UTF8PROC_INCLUDE_PATH}) | ||
include_directories(${CONCURRENT_QUEUE_INCLUDE_PATH}) | ||
|
||
file(GLOB SOURCE_FILES ./src_cpp/*) | ||
file(GLOB CMAKE_JS_SRC ./src_nodejs/*) | ||
file(COPY ${CMAKE_JS_SRC} DESTINATION ./kuzu) | ||
|
||
add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES} ${CMAKE_JS_SRC}) | ||
set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "" SUFFIX ".node") | ||
target_link_libraries(${PROJECT_NAME} PRIVATE ${CMAKE_JS_LIB} ${KUZU}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
## Install dependency | ||
``` | ||
npm i | ||
``` | ||
|
||
## Build | ||
``` | ||
npm run build | ||
``` | ||
|
||
## Clean | ||
``` | ||
npm run clean | ||
``` | ||
|
||
## Run test | ||
``` | ||
npm run test | ||
``` | ||
|
||
## Run sample | ||
``` | ||
node sample.js | ||
``` | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
{ | ||
"name": "kuzu", | ||
"version": "0.0.1", | ||
"description": "Node.js API for Kùzu graph database management system", | ||
"main": "index.js", | ||
"homepage": "https://kuzudb.com/", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/kuzudb/kuzu.git" | ||
}, | ||
"scripts": { | ||
"build": "(cd ../..; make release) && cmake-js compile && npm run js", | ||
"clean": "cmake-js clean && rm -rf cmake_install.cmake Makefile", | ||
"js": "cp src_nodejs/* build/kuzu/", | ||
"all": "npm run clean && npm run build && node sample.js", | ||
"test": "mocha", | ||
"buildtest": "npm run build && mocha" | ||
}, | ||
"author": "Kùzu Team", | ||
"license": "MIT", | ||
"dependencies": { | ||
"chai": "^4.3.7", | ||
"cmake-js": "^7.1.1", | ||
"mocha": "^10.2.0", | ||
"node-addon-api": "^6.0.0", | ||
"tmp": "^0.2.1" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
// Make sure the test directory is removed as it will be recreated | ||
const fs = require("fs"); | ||
const {Database, Connection} = require("./build/kuzu"); | ||
|
||
try { | ||
fs.rmSync("./testDb", { recursive: true }); | ||
} catch (e) { | ||
// ignore | ||
} | ||
|
||
async function executeAllCallback(err, queryResult) { | ||
if (err) { | ||
console.log(err); | ||
} else { | ||
await queryResult.all({"callback": (err, result) => { | ||
if (err) { | ||
console.log("All result with Callback failed"); | ||
console.log(err); | ||
} else { | ||
console.log(result); | ||
console.log("All result received Callback"); | ||
} | ||
}}); | ||
} | ||
} | ||
|
||
async function executeAllPromise(err, queryResult) { | ||
if (err) { | ||
console.log(err); | ||
} else { | ||
await queryResult.all().then(result => { | ||
console.log(result); | ||
console.log("All result received Promise"); | ||
}).catch(error => { | ||
console.log("All with Promise failed"); | ||
console.log(error); | ||
}); | ||
} | ||
} | ||
|
||
// Basic Case with all callback | ||
const database = new Database("testDb", 1000000000); | ||
console.log("The database looks like: ", database); | ||
const connection = new Connection(database); | ||
console.log ("The connection looks like: ", connection); | ||
connection.execute("create node table person (ID INt64, fName StRING, gender INT64, isStudent BoOLEAN, isWorker BOOLEAN, age INT64, eyeSight DOUBLE, birthdate DATE, registerTime TIMESTAMP, lastJobDuration interval, workedHours INT64[], usedNames STRING[], courseScoresPerTerm INT64[][], grades INT64[], height DOUBLE, PRIMARY KEY (ID));", {"callback": executeAllCallback}).then(async r => { | ||
await connection.execute("COPY person FROM \"../../dataset/tinysnb/vPerson.csv\" (HEADER=true);", {"callback": executeAllPromise}) | ||
const executeQuery = "MATCH (a:person) RETURN a.fName, a.age, a.eyeSight, a.isStudent;"; | ||
const parameterizedExecuteQuery = "MATCH (a:person) WHERE a.age > $1 and a.isStudent = $2 and a.fName < $3 RETURN a.fName, a.age, a.eyeSight, a.isStudent;"; | ||
|
||
connection.execute(executeQuery, {"callback": executeAllPromise}); | ||
connection.execute(parameterizedExecuteQuery, { | ||
"callback": executeAllPromise, | ||
"params": [["1", 29], ["2", true], ["3", "B"]] | ||
}); | ||
|
||
// Extensive Case | ||
connection.setMaxNumThreadForExec(2); | ||
connection.execute(executeQuery, {"callback": executeAllCallback}); | ||
|
||
// Execute with each callback | ||
connection.execute(executeQuery, { | ||
"callback": async (err, result) => { | ||
if (err) { | ||
console.log(err); | ||
} else { | ||
await result.each( | ||
(err, rowResult) => { | ||
if (err) { | ||
console.log(err) | ||
} else { | ||
console.log(rowResult); | ||
} | ||
}, | ||
() => { | ||
console.log("all of the each's are done callback"); | ||
} | ||
); | ||
} | ||
} | ||
}); | ||
|
||
// Execute with promise + await | ||
connection.execute(executeQuery).then(async queryResult => { | ||
await queryResult.all({ | ||
"callback": (err, result) => { | ||
if (err) { | ||
console.log(err); | ||
} else { | ||
console.log(result); | ||
console.log("All result received for execution with a promise"); | ||
} | ||
} | ||
}); | ||
}).catch(error => { | ||
console.log("Execution with a promise failed"); | ||
console.log(error); | ||
}); | ||
|
||
async function asyncAwaitExecute(executeQuery) { | ||
const queryResult = await connection.execute(executeQuery); | ||
return queryResult; | ||
} | ||
|
||
await asyncAwaitExecute(executeQuery).then(async queryResult => { | ||
await queryResult.all({ | ||
"callback": (err, result) => { | ||
if (err) { | ||
console.log(err); | ||
} else { | ||
console.log(result); | ||
console.log("All result received for execution with await"); | ||
} | ||
} | ||
}); | ||
}).catch(error => { | ||
console.log("Execution with await failed"); | ||
console.log(error); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
#include "include/execute_async_worker.h" | ||
|
||
#include <chrono> | ||
#include <thread> | ||
|
||
#include "include/node_query_result.h" | ||
|
||
using namespace Napi; | ||
|
||
ExecuteAsyncWorker::ExecuteAsyncWorker(Function& callback, shared_ptr<kuzu::main::Connection>& connection, | ||
std::string query, NodeQueryResult * nodeQueryResult, unordered_map<std::string, shared_ptr<kuzu::common::Value>>& params) | ||
: AsyncWorker(callback), connection(connection), query(query), nodeQueryResult(nodeQueryResult) | ||
, params(params) {}; | ||
|
||
void ExecuteAsyncWorker::Execute() { | ||
try { | ||
shared_ptr<kuzu::main::QueryResult> queryResult; | ||
if (!params.empty()) { | ||
auto preparedStatement = std::move(connection->prepare(query)); | ||
queryResult = connection->executeWithParams(preparedStatement.get(), params); | ||
} else { | ||
queryResult = connection->query(query); | ||
} | ||
|
||
if (!queryResult->isSuccess()) { | ||
SetError("Query async execute unsuccessful: " + queryResult->getErrorMessage()); | ||
} | ||
nodeQueryResult->SetQueryResult(queryResult); | ||
} | ||
catch(const std::exception &exc) { | ||
SetError("Unsuccessful async execute: " + std::string(exc.what())); | ||
} | ||
}; | ||
|
||
void ExecuteAsyncWorker::OnOK() { | ||
Callback().Call({Env().Null()}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
#pragma once | ||
#include <napi.h> | ||
#include "main/kuzu.h" | ||
#include "node_query_result.h" | ||
|
||
using namespace std; | ||
|
||
class ExecuteAsyncWorker : public Napi::AsyncWorker { | ||
|
||
public: | ||
ExecuteAsyncWorker(Napi::Function& callback, shared_ptr<kuzu::main::Connection>& connection, | ||
std::string query, NodeQueryResult * nodeQueryResult, unordered_map<std::string, shared_ptr<kuzu::common::Value>> & params); | ||
virtual ~ExecuteAsyncWorker() {}; | ||
|
||
void Execute(); | ||
void OnOK(); | ||
|
||
private: | ||
NodeQueryResult * nodeQueryResult; | ||
std::string query; | ||
shared_ptr<kuzu::main::Connection> connection; | ||
unordered_map<std::string, shared_ptr<kuzu::common::Value>> params; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
#include <napi.h> | ||
#include <iostream> | ||
#include "main/kuzu.h" | ||
|
||
using namespace std; | ||
|
||
class NodeConnection : public Napi::ObjectWrap<NodeConnection> { | ||
public: | ||
static Napi::Object Init(Napi::Env env, Napi::Object exports); | ||
NodeConnection(const Napi::CallbackInfo& info); | ||
~NodeConnection() = default; | ||
|
||
private: | ||
Napi::Value GetConnection(const Napi::CallbackInfo& info); | ||
Napi::Value TransferConnection(const Napi::CallbackInfo& info); | ||
Napi::Value Execute(const Napi::CallbackInfo& info); | ||
void SetMaxNumThreadForExec(const Napi::CallbackInfo& info); | ||
Napi::Value GetNodePropertyNames(const Napi::CallbackInfo& info); | ||
shared_ptr<kuzu::main::Database> database; | ||
shared_ptr<kuzu::main::Connection> connection; | ||
uint64_t numThreads = 0; | ||
|
||
struct ThreadSafeConnectionContext { | ||
ThreadSafeConnectionContext(Napi::Env env, shared_ptr<kuzu::main::Connection> & connection, | ||
shared_ptr<kuzu::main::Database> & database, uint64_t numThreads) : | ||
deferred(Napi::Promise::Deferred::New(env)), | ||
connection(connection), | ||
database(database), | ||
numThreads(numThreads){}; | ||
|
||
// Native Promise returned to JavaScript | ||
Napi::Promise::Deferred deferred; | ||
|
||
uint64_t numThreads = 0; | ||
|
||
bool passed = true; | ||
|
||
shared_ptr<kuzu::main::Connection> connection; | ||
kuzu::main::Connection * connection2; | ||
shared_ptr<kuzu::main::Database> database; | ||
|
||
// Native thread | ||
std::thread nativeThread; | ||
|
||
Napi::ThreadSafeFunction tsfn; | ||
}; | ||
ThreadSafeConnectionContext * context; | ||
static void threadEntry(ThreadSafeConnectionContext * context); | ||
static void FinalizerCallback(Napi::Env env, void* finalizeData, ThreadSafeConnectionContext* context); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
#include <napi.h> | ||
#include <iostream> | ||
#include "main/kuzu.h" | ||
|
||
using namespace std; | ||
|
||
class NodeDatabase : public Napi::ObjectWrap<NodeDatabase> { | ||
public: | ||
static Napi::Object Init(Napi::Env env, Napi::Object exports); | ||
NodeDatabase(const Napi::CallbackInfo& info); | ||
~NodeDatabase() = default; | ||
friend class NodeConnection; | ||
|
||
private: | ||
shared_ptr<kuzu::main::Database> database; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
#ifndef KUZU_NODE_QUERY_RESULT_H | ||
#define KUZU_NODE_QUERY_RESULT_H | ||
|
||
#include <napi.h> | ||
#include <iostream> | ||
#include "main/kuzu.h" | ||
#include "binder/bound_statement_result.h" | ||
#include "planner/logical_plan/logical_plan.h" | ||
#include "processor/result/factorized_table.h" | ||
|
||
using namespace std; | ||
|
||
class NodeQueryResult: public Napi::ObjectWrap<NodeQueryResult> { | ||
public: | ||
static Napi::Object Init(Napi::Env env, Napi::Object exports); | ||
void SetQueryResult(shared_ptr<kuzu::main::QueryResult> & inputQueryResult); | ||
NodeQueryResult(const Napi::CallbackInfo& info); | ||
~NodeQueryResult() = default; | ||
|
||
private: | ||
void Close(const Napi::CallbackInfo& info); | ||
Napi::Value All(const Napi::CallbackInfo& info); | ||
Napi::Value Each(const Napi::CallbackInfo& info); | ||
Napi::Value GetColumnDataTypes(const Napi::CallbackInfo& info); | ||
Napi::Value GetColumnNames(const Napi::CallbackInfo& info); | ||
shared_ptr<kuzu::main::QueryResult> queryResult; | ||
}; | ||
|
||
|
||
#endif |
Oops, something went wrong.