duckdb 1.2.1-dev4.0 → 1.2.1-dev6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/connection.cpp +57 -35
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "duckdb",
3
3
  "main": "./lib/duckdb.js",
4
4
  "types": "./lib/duckdb.d.ts",
5
- "version": "1.2.1-dev4.0",
5
+ "version": "1.2.1-dev6.0",
6
6
  "description": "DuckDB node.js API",
7
7
  "gypfile": true,
8
8
  "dependencies": {
@@ -17,12 +17,12 @@ Napi::FunctionReference Connection::Init(Napi::Env env, Napi::Object exports) {
17
17
  Napi::HandleScope scope(env);
18
18
 
19
19
  Napi::Function t = DefineClass(
20
- env, "Connection",
21
- {InstanceMethod("prepare", &Connection::Prepare), InstanceMethod("exec", &Connection::Exec),
22
- InstanceMethod("register_udf_bulk", &Connection::RegisterUdf),
23
- InstanceMethod("register_buffer", &Connection::RegisterBuffer),
24
- InstanceMethod("unregister_udf", &Connection::UnregisterUdf), InstanceMethod("close", &Connection::Close),
25
- InstanceMethod("unregister_buffer", &Connection::UnRegisterBuffer)});
20
+ env, "Connection",
21
+ {InstanceMethod("prepare", &Connection::Prepare), InstanceMethod("exec", &Connection::Exec),
22
+ InstanceMethod("register_udf_bulk", &Connection::RegisterUdf),
23
+ InstanceMethod("register_buffer", &Connection::RegisterBuffer),
24
+ InstanceMethod("unregister_udf", &Connection::UnregisterUdf), InstanceMethod("close", &Connection::Close),
25
+ InstanceMethod("unregister_buffer", &Connection::UnRegisterBuffer)});
26
26
 
27
27
  exports.Set("Connection", t);
28
28
 
@@ -234,14 +234,14 @@ void DuckDBNodeUDFLauncher(Napi::Env env, Napi::Function jsudf, std::nullptr_t *
234
234
 
235
235
  struct RegisterUdfTask : public Task {
236
236
  RegisterUdfTask(Connection &connection, std::string name, std::string return_type_name, Napi::Function callback)
237
- : Task(connection, callback), name(std::move(name)), return_type_name(std::move(return_type_name)) {
237
+ : Task(connection, callback), name(std::move(name)), return_type_name(std::move(return_type_name)) {
238
238
  }
239
239
 
240
240
  void DoWork() override {
241
241
  auto &connection = Get<Connection>();
242
242
  auto &udf_ptr = connection.udfs[name];
243
243
  duckdb::scalar_function_t udf_function = [&udf_ptr](duckdb::DataChunk &args, duckdb::ExpressionState &state,
244
- duckdb::Vector &result) -> void {
244
+ duckdb::Vector &result) -> void {
245
245
  // here we can do only DuckDB stuff because we do not have a functioning env
246
246
 
247
247
  // Flatten all args to simplify udfs
@@ -271,7 +271,7 @@ struct RegisterUdfTask : public Task {
271
271
  auto return_type = cast.cast_type;
272
272
 
273
273
  connection.connection->CreateVectorizedFunction(name, vector<duckdb::LogicalType> {}, return_type, udf_function,
274
- duckdb::LogicalType::ANY);
274
+ duckdb::LogicalType::ANY);
275
275
  }
276
276
  std::string name;
277
277
  std::string return_type_name;
@@ -296,7 +296,7 @@ Napi::Value Connection::RegisterUdf(const Napi::CallbackInfo &info) {
296
296
  }
297
297
 
298
298
  auto udf = duckdb_node_udf_function_t::New(env, udf_callback, "duckdb_node_udf" + name, 0, 1, nullptr,
299
- [](Napi::Env, void *, std::nullptr_t *ctx) {});
299
+ [](Napi::Env, void *, std::nullptr_t *ctx) {});
300
300
 
301
301
  // we have to unref the udf because otherwise there is a circular ref with the connection somehow(?)
302
302
  // this took far too long to figure out
@@ -304,14 +304,14 @@ Napi::Value Connection::RegisterUdf(const Napi::CallbackInfo &info) {
304
304
  udfs[name] = udf;
305
305
 
306
306
  database_ref->Schedule(info.Env(),
307
- duckdb::make_uniq<RegisterUdfTask>(*this, name, return_type_name, completion_callback));
307
+ duckdb::make_uniq<RegisterUdfTask>(*this, name, return_type_name, completion_callback));
308
308
 
309
309
  return Value();
310
310
  }
311
311
 
312
312
  struct UnregisterUdfTask : public Task {
313
313
  UnregisterUdfTask(Connection &connection, std::string name, Napi::Function callback)
314
- : Task(connection, callback), name(std::move(name)) {
314
+ : Task(connection, callback), name(std::move(name)) {
315
315
  }
316
316
 
317
317
  void DoWork() override {
@@ -354,7 +354,7 @@ Napi::Value Connection::UnregisterUdf(const Napi::CallbackInfo &info) {
354
354
 
355
355
  struct ExecTask : public Task {
356
356
  ExecTask(Connection &connection, std::string sql, Napi::Function callback)
357
- : Task(connection, callback), sql(std::move(sql)) {
357
+ : Task(connection, callback), sql(std::move(sql)) {
358
358
  }
359
359
 
360
360
  void DoWork() override {
@@ -395,8 +395,8 @@ struct ExecTask : public Task {
395
395
 
396
396
  struct ExecTaskWithCallback : public ExecTask {
397
397
  ExecTaskWithCallback(Connection &connection, std::string sql, Napi::Function js_callback,
398
- std::function<void(void)> cpp_callback)
399
- : ExecTask(connection, sql, js_callback), cpp_callback(cpp_callback) {
398
+ std::function<void(void)> cpp_callback)
399
+ : ExecTask(connection, sql, js_callback), cpp_callback(cpp_callback) {
400
400
  }
401
401
 
402
402
  void Callback() override {
@@ -456,24 +456,41 @@ Napi::Value Connection::Exec(const Napi::CallbackInfo &info) {
456
456
  }
457
457
 
458
458
  struct CreateArrowViewTask : public Task {
459
- CreateArrowViewTask(Connection &connection, duckdb::vector<duckdb::Value>& parameters, std::string &view_name)
460
- : Task(connection), parameters(parameters), view_name(view_name) {
459
+ CreateArrowViewTask(Connection &connection, duckdb::vector<duckdb::Value>& parameters, std::string &view_name, Napi::Function callback)
460
+ : Task(connection, callback), parameters(parameters), view_name(view_name) {
461
461
  }
462
462
 
463
463
  void DoWork() override {
464
464
  auto &connection = Get<Connection>();
465
- auto &con = *connection.connection;
466
- // Now we create a table function relation
467
- auto table_function_relation = duckdb::make_shared_ptr<duckdb::TableFunctionRelation>(con.context,"scan_arrow_ipc",parameters);
468
- // Creates a relation for a temporary view that does replace
469
- auto view_relation = table_function_relation->CreateView(view_name,true,true);
470
-
471
- view_relation->Execute();
472
-
465
+ success = true;
466
+ try {
467
+ auto &con = *connection.connection;
468
+ // Now we create a table function relation
469
+ auto table_function_relation = duckdb::make_shared_ptr<duckdb::TableFunctionRelation>(con.context,"scan_arrow_ipc",parameters);
470
+ // Creates a relation for a temporary view that does replace
471
+ auto view_relation = table_function_relation->CreateView(view_name,true,true);
472
+ auto res = view_relation->Execute();
473
+ if (res->HasError()) {
474
+ success = false;
475
+ error = res->GetErrorObject();
476
+ }
477
+ } catch (duckdb::Exception &e) {
478
+ success = false;
479
+ error = duckdb::ErrorData(e);
480
+ return;
481
+ }
473
482
  }
474
483
 
484
+ void Callback() override {
485
+ auto env = object.Env();
486
+ Napi::HandleScope scope(env);
487
+ callback.Value().MakeCallback(object.Value(), {success ? env.Null() : Utils::CreateError(env, error)});
488
+ };
489
+
475
490
  duckdb::vector<duckdb::Value> parameters;
476
491
  std::string view_name;
492
+ bool success;
493
+ duckdb::ErrorData error;
477
494
  };
478
495
 
479
496
  // Register Arrow IPC buffers for scanning from DuckDB
@@ -512,20 +529,25 @@ Napi::Value Connection::RegisterBuffer(const Napi::CallbackInfo &info) {
512
529
  Napi::Uint8Array arr = v.As<Napi::Uint8Array>();
513
530
  auto raw_ptr = reinterpret_cast<uint64_t>(arr.ArrayBuffer().Data());
514
531
  auto length = (uint64_t)arr.ElementLength();
515
- duckdb::child_list_t<duckdb::Value> buffer_values;
516
- // This is a little bit evil, but allows us to support both libraries in between 1.2 and 1.3
517
- if (db.ExtensionIsLoaded("nanoarrow")){
518
- buffer_values.push_back({"ptr", duckdb::Value::POINTER(raw_ptr)});
519
- } else {
520
- buffer_values.push_back({"ptr", duckdb::Value::UBIGINT(raw_ptr)});
521
- }
532
+ duckdb::child_list_t<duckdb::Value> buffer_values;
533
+ // This is a little bit evil, but allows us to support both libraries in between 1.2 and 1.3
534
+ if (db.ExtensionIsLoaded("nanoarrow")){
535
+ buffer_values.push_back({"ptr", duckdb::Value::POINTER(raw_ptr)});
536
+ } else {
537
+ buffer_values.push_back({"ptr", duckdb::Value::UBIGINT(raw_ptr)});
538
+ }
522
539
  buffer_values.push_back({"size", duckdb::Value::UBIGINT(length)});
523
540
  values.push_back(duckdb::Value::STRUCT(buffer_values));
524
541
  }
525
542
  duckdb::vector<duckdb::Value> list_value;
526
- list_value.push_back(duckdb::Value::LIST(values));
543
+ list_value.push_back(duckdb::Value::LIST(values));
544
+
545
+ Napi::Function callback;
546
+ if (info.Length() > 3 && info[3].IsFunction()) {
547
+ callback = info[3].As<Napi::Function>();
548
+ }
527
549
 
528
- database_ref->Schedule(info.Env(), duckdb::make_uniq<CreateArrowViewTask>(*this, list_value, name));
550
+ database_ref->Schedule(info.Env(), duckdb::make_uniq<CreateArrowViewTask>(*this, list_value, name, callback));
529
551
 
530
552
  return Value();
531
553
  }
@@ -551,7 +573,7 @@ Napi::Value Connection::UnRegisterBuffer(const Napi::CallbackInfo &info) {
551
573
  };
552
574
 
553
575
  database_ref->Schedule(info.Env(),
554
- duckdb::make_uniq<ExecTaskWithCallback>(*this, final_query, callback, cpp_callback));
576
+ duckdb::make_uniq<ExecTaskWithCallback>(*this, final_query, callback, cpp_callback));
555
577
 
556
578
  return Value();
557
579
  }