Skip to content

Commit

Permalink
Merge pull request #14 from chdb-io/exception-on-error
Browse files Browse the repository at this point in the history
Use libchdb API v2 to throw exception while SQL error
  • Loading branch information
auxten authored Aug 28, 2024
2 parents 7cb8ee7 + dbda562 commit f75803c
Show file tree
Hide file tree
Showing 8 changed files with 878 additions and 525 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ session.query("USE testdb; INSERT INTO testtable VALUES (1), (2), (3);")
ret = session.query("SELECT * FROM testtable;")
console.log("Session Query Result:", ret);

// If an error occurs, it will be thrown
try {
session.query("SELECT * FROM non_existent_table;", "CSV");
}
catch (e) {
console.log("Error:", e.message);
}

// Clean up the session
session.cleanup();

Expand Down
8 changes: 8 additions & 0 deletions example.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,13 @@ session.query("USE testdb; INSERT INTO testtable VALUES (1), (2), (3);")
ret = session.query("SELECT * FROM testtable;")
console.log("Session Query Result:", ret);

// Test error handling
try {
session.query("SELECT * FROM non_existent_table;", "CSV");
}
catch (e) {
console.log("Error:", e.message);
}

// Clean up the session
session.cleanup();
2 changes: 1 addition & 1 deletion lib/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
npm install

# install dependencies
./update_libchdb.sh
curl -sL https://lib.chdb.io | bash

# build the dynamic library
node-gyp build
Expand Down
56 changes: 41 additions & 15 deletions lib/chdb_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,32 @@ void construct_arg(char *dest, const char *prefix, const char *value,
}

// Generalized query function
char *general_query(int argc, char *args[]) {
struct local_result *result = query_stable(argc, args);
char *general_query(int argc, char *args[], char **error_message) {
struct local_result_v2 *result = query_stable_v2(argc, args);

if (result == NULL) {
return NULL;
}

if (result->error_message != NULL) {
if (error_message != NULL) {
*error_message = strdup(result->error_message);
}
free_result_v2(result);
return NULL;
} else {
return result->buf;
if (result->buf == NULL) {
free_result_v2(result);
return NULL;
}
char *output = strdup(result->buf); // copy the result buffer
free_result_v2(result);
return output;
}
}

// Query function without session
char *Query(const char *query, const char *format) {
char *Query(const char *query, const char *format, char **error_message) {
char dataFormat[MAX_FORMAT_LENGTH];
char *dataQuery;
char *args[MAX_ARG_COUNT] = {"clickhouse", "--multiquery", NULL, NULL};
Expand All @@ -45,14 +59,14 @@ char *Query(const char *query, const char *format) {
strlen(query) + strlen("--query=") + 1);
args[3] = dataQuery;

char *result = general_query(argc, args);
char *result = general_query(argc, args, error_message);
free(dataQuery);
return result;
}

// QuerySession function will save the session to the path
// queries with same path will use the same session
char *QuerySession(const char *query, const char *format, const char *path) {
char *QuerySession(const char *query, const char *format, const char *path,
char **error_message) {
char dataFormat[MAX_FORMAT_LENGTH];
char dataPath[MAX_PATH_LENGTH];
char *dataQuery;
Expand All @@ -73,7 +87,7 @@ char *QuerySession(const char *query, const char *format, const char *path) {
construct_arg(dataPath, "--path=", path, MAX_PATH_LENGTH);
args[4] = dataPath;

char *result = general_query(argc, args);
char *result = general_query(argc, args, error_message);
free(dataQuery);
return result;
}
Expand All @@ -91,8 +105,17 @@ Napi::String QueryWrapper(const Napi::CallbackInfo &info) {
std::string query = info[0].As<Napi::String>().Utf8Value();
std::string format = info[1].As<Napi::String>().Utf8Value();

char *error_message = nullptr;
// Call the native function
char *result = Query(query.c_str(), format.c_str());
char *result = Query(query.c_str(), format.c_str(), &error_message);

if (result == NULL) {
if (error_message != NULL) {
Napi::Error::New(env, error_message).ThrowAsJavaScriptException();
free(error_message);
}
return Napi::String::New(env, "");
}

// Return the result
return Napi::String::New(env, result);
Expand All @@ -113,13 +136,16 @@ Napi::String QuerySessionWrapper(const Napi::CallbackInfo &info) {
std::string format = info[1].As<Napi::String>().Utf8Value();
std::string path = info[2].As<Napi::String>().Utf8Value();

// std::cerr << query << std::endl;
// std::cerr << format << std::endl;
// std::cerr << path << std::endl;
char *error_message = nullptr;
// Call the native function
char *result = QuerySession(query.c_str(), format.c_str(), path.c_str());
char *result =
QuerySession(query.c_str(), format.c_str(), path.c_str(), &error_message);

if (result == NULL) {
// std::cerr << "result is null" << std::endl;
if (error_message != NULL) {
Napi::Error::New(env, error_message).ThrowAsJavaScriptException();
free(error_message);
}
return Napi::String::New(env, "");
}

Expand All @@ -134,4 +160,4 @@ Napi::Object Init(Napi::Env env, Napi::Object exports) {
return exports;
}

NODE_API_MODULE(NODE_GYP_MODULE_NAME, Init)
NODE_API_MODULE(NODE_GYP_MODULE_NAME, Init)
Loading

0 comments on commit f75803c

Please sign in to comment.