duckdb 0.4.1-dev17.0 → 0.4.1-dev182.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.
@@ -0,0 +1,185 @@
1
+ #include "duckdb.hpp"
2
+ #include "duckdb_node.hpp"
3
+ #include "napi.h"
4
+
5
+ #include <thread>
6
+
7
+ namespace node_duckdb {
8
+
9
+ Napi::Array EncodeDataChunk(Napi::Env env, duckdb::DataChunk &chunk, bool with_types, bool with_data) {
10
+ Napi::Array col_descs(Napi::Array::New(env, chunk.ColumnCount()));
11
+ for (idx_t col_idx = 0; col_idx < chunk.ColumnCount(); col_idx++) {
12
+ auto col_desc = Napi::Object::New(env);
13
+
14
+ // Make sure we only have flat vectors hereafter (for now)
15
+ auto &chunk_vec = chunk.data[col_idx];
16
+ if (with_data) {
17
+ chunk_vec.Normalify(chunk.size());
18
+ }
19
+
20
+ // Do a post-order DFS traversal
21
+ std::vector<std::tuple<bool, duckdb::Vector *, Napi::Object, size_t, size_t>> pending;
22
+ pending.emplace_back(false, &chunk_vec, Napi::Object::New(env), 0, 0);
23
+
24
+ while (!pending.empty()) {
25
+ // Unpack DFS node
26
+ auto &back = pending.back();
27
+ auto &visited = std::get<0>(back);
28
+ auto &vec = std::get<1>(back);
29
+ auto &desc = std::get<2>(back);
30
+ auto &parent_idx = std::get<3>(back);
31
+ auto &idx_in_parent = std::get<4>(back);
32
+
33
+ // Already visited?
34
+ if (visited) {
35
+ if (pending.size() == 1) {
36
+ col_desc = desc;
37
+ break;
38
+ }
39
+ std::get<2>(pending[parent_idx]).Get("children").As<Napi::Array>().Set(idx_in_parent, desc);
40
+ pending.pop_back();
41
+ continue;
42
+ }
43
+ visited = true;
44
+ auto current_idx = pending.size() - 1;
45
+
46
+ // Store types
47
+ auto &vec_type = vec->GetType();
48
+ if (with_types) {
49
+ desc.Set("sqlType", vec_type.ToString());
50
+ desc.Set("physicalType", TypeIdToString(vec_type.InternalType()));
51
+ }
52
+
53
+ // Create validity vector
54
+ if (with_data) {
55
+ vec->Normalify(chunk.size());
56
+ auto &validity = duckdb::FlatVector::Validity(*vec);
57
+ auto validity_buffer = Napi::Uint8Array::New(env, chunk.size());
58
+ for (idx_t row_idx = 0; row_idx < chunk.size(); row_idx++) {
59
+ validity_buffer[row_idx] = validity.RowIsValid(row_idx);
60
+ }
61
+ desc.Set("validity", validity_buffer);
62
+ }
63
+
64
+ // Create data buffer
65
+ switch (vec_type.id()) {
66
+ case duckdb::LogicalTypeId::TINYINT: {
67
+ if (with_data) {
68
+ auto array = Napi::Int8Array::New(env, chunk.size());
69
+ auto data = duckdb::FlatVector::GetData<int8_t>(*vec);
70
+ for (size_t i = 0; i < chunk.size(); ++i) {
71
+ array[i] = data[i];
72
+ }
73
+ desc.Set("data", array);
74
+ }
75
+ break;
76
+ }
77
+ case duckdb::LogicalTypeId::SMALLINT: {
78
+ if (with_data) {
79
+ auto array = Napi::Int16Array::New(env, chunk.size());
80
+ auto data = duckdb::FlatVector::GetData<int16_t>(*vec);
81
+ for (size_t i = 0; i < chunk.size(); ++i) {
82
+ array[i] = data[i];
83
+ }
84
+ desc.Set("data", array);
85
+ }
86
+ break;
87
+ }
88
+ case duckdb::LogicalTypeId::INTEGER: {
89
+ if (with_data) {
90
+ auto array = Napi::Int32Array::New(env, chunk.size());
91
+ auto data = duckdb::FlatVector::GetData<int32_t>(*vec);
92
+ for (size_t i = 0; i < chunk.size(); ++i) {
93
+ array[i] = data[i];
94
+ }
95
+ desc.Set("data", array);
96
+ }
97
+ break;
98
+ }
99
+ case duckdb::LogicalTypeId::DOUBLE: {
100
+ if (with_data) {
101
+ auto array = Napi::Float64Array::New(env, chunk.size());
102
+ auto data = duckdb::FlatVector::GetData<double>(*vec);
103
+ for (size_t i = 0; i < chunk.size(); ++i) {
104
+ array[i] = data[i];
105
+ }
106
+ desc.Set("data", array);
107
+ }
108
+ break;
109
+ }
110
+ case duckdb::LogicalTypeId::BIGINT:
111
+ case duckdb::LogicalTypeId::TIME:
112
+ case duckdb::LogicalTypeId::TIME_TZ:
113
+ case duckdb::LogicalTypeId::TIMESTAMP_MS:
114
+ case duckdb::LogicalTypeId::TIMESTAMP_NS:
115
+ case duckdb::LogicalTypeId::TIMESTAMP_SEC:
116
+ case duckdb::LogicalTypeId::TIMESTAMP: {
117
+ if (with_data) {
118
+ #if NAPI_VERSION > 5
119
+ auto array = Napi::BigInt64Array::New(env, chunk.size());
120
+ auto data = duckdb::FlatVector::GetData<int64_t>(*vec);
121
+ #else
122
+ auto array = Napi::Float64Array::New(env, chunk.size());
123
+ auto data = duckdb::FlatVector::GetData<int64_t>(*vec);
124
+ #endif
125
+ for (size_t i = 0; i < chunk.size(); ++i) {
126
+ array[i] = data[i];
127
+ }
128
+ desc.Set("data", array);
129
+ }
130
+ break;
131
+ }
132
+ case duckdb::LogicalTypeId::UBIGINT: {
133
+ if (with_data) {
134
+ #if NAPI_VERSION > 5
135
+ auto array = Napi::BigUint64Array::New(env, chunk.size());
136
+ auto data = duckdb::FlatVector::GetData<uint64_t>(*vec);
137
+ #else
138
+ auto array = Napi::Float64Array::New(env, chunk.size());
139
+ auto data = duckdb::FlatVector::GetData<int64_t>(*vec);
140
+ #endif
141
+ for (size_t i = 0; i < chunk.size(); ++i) {
142
+ array[i] = data[i];
143
+ }
144
+ desc.Set("data", array);
145
+ }
146
+ break;
147
+ }
148
+ case duckdb::LogicalTypeId::BLOB:
149
+ case duckdb::LogicalTypeId::VARCHAR: {
150
+ if (with_data) {
151
+ auto array = Napi::Array::New(env, chunk.size());
152
+ auto data = duckdb::FlatVector::GetData<duckdb::string_t>(*vec);
153
+ for (size_t i = 0; i < chunk.size(); ++i) {
154
+ array.Set(i, data[i].GetString());
155
+ }
156
+ desc.Set("data", array);
157
+ }
158
+ break;
159
+ }
160
+ case duckdb::LogicalTypeId::STRUCT: {
161
+ auto child_count = duckdb::StructType::GetChildCount(vec_type);
162
+ auto &entries = duckdb::StructVector::GetEntries(*vec);
163
+ desc.Set("children", Napi::Array::New(env, child_count));
164
+ for (size_t i = 0; i < child_count; ++i) {
165
+ auto c = child_count - 1 - i;
166
+ auto &entry = entries[c];
167
+ auto desc = Napi::Object::New(env);
168
+ auto name = duckdb::StructType::GetChildName(vec_type, c);
169
+ desc.Set("name", name);
170
+ pending.emplace_back(false, entry.get(), desc, current_idx, i);
171
+ }
172
+ break;
173
+ }
174
+ default:
175
+ Napi::TypeError::New(env, "Unsupported UDF argument type " + vec->GetType().ToString())
176
+ .ThrowAsJavaScriptException();
177
+ break;
178
+ }
179
+ }
180
+ col_descs.Set(col_idx, col_desc);
181
+ }
182
+ return col_descs;
183
+ }
184
+
185
+ } // namespace node_duckdb
package/src/database.cpp CHANGED
@@ -93,12 +93,12 @@ void Database::Schedule(Napi::Env env, std::unique_ptr<Task> task) {
93
93
  Process(env);
94
94
  }
95
95
 
96
- static void task_execute(napi_env e, void *data) {
96
+ static void TaskExecuteCallback(napi_env e, void *data) {
97
97
  auto holder = (TaskHolder *)data;
98
98
  holder->task->DoWork();
99
99
  }
100
100
 
101
- static void task_complete(napi_env e, napi_status status, void *data) {
101
+ static void TaskCompleteCallback(napi_env e, napi_status status, void *data) {
102
102
  std::unique_ptr<TaskHolder> holder((TaskHolder *)data);
103
103
  holder->db->TaskComplete(e);
104
104
  if (holder->task->callback.Value().IsFunction()) {
@@ -131,8 +131,8 @@ void Database::Process(Napi::Env env) {
131
131
  holder->task = move(task);
132
132
  holder->db = this;
133
133
 
134
- napi_create_async_work(env, NULL, Napi::String::New(env, "duckdb.Database.Task"), task_execute, task_complete,
135
- holder, &holder->request);
134
+ napi_create_async_work(env, nullptr, Napi::String::New(env, "duckdb.Database.Task"), TaskExecuteCallback,
135
+ TaskCompleteCallback, holder, &holder->request);
136
136
 
137
137
  napi_queue_async_work(env, holder->request);
138
138
  }
@@ -157,7 +157,7 @@ Napi::Value Database::Serialize(const Napi::CallbackInfo &info) {
157
157
  }
158
158
 
159
159
  struct WaitTask : public Task {
160
- WaitTask(Database &database_, Napi::Function callback_) : Task(database_, callback_) {
160
+ WaitTask(Database &database, Napi::Function callback) : Task(database, callback) {
161
161
  }
162
162
 
163
163
  void DoWork() override {
@@ -171,7 +171,7 @@ Napi::Value Database::Wait(const Napi::CallbackInfo &info) {
171
171
  }
172
172
 
173
173
  struct CloseTask : public Task {
174
- CloseTask(Database &database_, Napi::Function callback_) : Task(database_, callback_) {
174
+ CloseTask(Database &database, Napi::Function callback) : Task(database, callback) {
175
175
  }
176
176
 
177
177
  void DoWork() override {