duckdb 0.3.5-dev750.0 → 0.3.5-dev762.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.
package/src/statement.cpp CHANGED
@@ -121,6 +121,89 @@ static duckdb::Value bind_parameter(const Napi::Value source) {
121
121
  return duckdb::Value();
122
122
  }
123
123
 
124
+ static Napi::Value convert_col_val(Napi::Env &env, duckdb::Value dval, duckdb::LogicalTypeId id) {
125
+ Napi::Value value;
126
+
127
+ // TODO templateroo here
128
+ switch (id) {
129
+ case duckdb::LogicalTypeId::BOOLEAN: {
130
+ value = Napi::Boolean::New(env, duckdb::BooleanValue::Get(dval));
131
+ } break;
132
+ case duckdb::LogicalTypeId::INTEGER: {
133
+ value = Napi::Number::New(env, duckdb::IntegerValue::Get(dval));
134
+ } break;
135
+ case duckdb::LogicalTypeId::FLOAT: {
136
+ value = Napi::Number::New(env, duckdb::FloatValue::Get(dval));
137
+ } break;
138
+ case duckdb::LogicalTypeId::DOUBLE: {
139
+ value = Napi::Number::New(env, duckdb::DoubleValue::Get(dval));
140
+ } break;
141
+ case duckdb::LogicalTypeId::BIGINT: {
142
+ value = Napi::Number::New(env, duckdb::BigIntValue::Get(dval));
143
+ } break;
144
+ case duckdb::LogicalTypeId::HUGEINT: {
145
+ value = Napi::Number::New(env, dval.GetValue<double>());
146
+ } break;
147
+ case duckdb::LogicalTypeId::DECIMAL: {
148
+ value = Napi::Number::New(env, dval.GetValue<double>());
149
+ } break;
150
+ case duckdb::LogicalTypeId::INTERVAL: {
151
+ auto interval = duckdb::IntervalValue::Get(dval);
152
+ auto object_value = Napi::Object::New(env);
153
+ object_value.Set("months", interval.months);
154
+ object_value.Set("days", interval.days);
155
+ object_value.Set("micros", interval.micros);
156
+ value = object_value;
157
+ } break;
158
+ #if (NAPI_VERSION > 4)
159
+ case duckdb::LogicalTypeId::DATE: {
160
+ const auto scale = duckdb::Interval::SECS_PER_DAY * duckdb::Interval::MSECS_PER_SEC;
161
+ value = Napi::Date::New(env, double(dval.GetValue<int32_t>() * scale));
162
+ } break;
163
+ case duckdb::LogicalTypeId::TIMESTAMP:
164
+ case duckdb::LogicalTypeId::TIMESTAMP_TZ: {
165
+ value = Napi::Date::New(env, double(dval.GetValue<int64_t>() / duckdb::Interval::MICROS_PER_MSEC));
166
+ } break;
167
+ #endif
168
+ case duckdb::LogicalTypeId::VARCHAR: {
169
+ value = Napi::String::New(env, duckdb::StringValue::Get(dval));
170
+ } break;
171
+ case duckdb::LogicalTypeId::BLOB: {
172
+ auto &blob = duckdb::StringValue::Get(dval);
173
+ value = Napi::Buffer<char>::Copy(env, blob.c_str(), blob.length());
174
+ } break;
175
+ case duckdb::LogicalTypeId::SQLNULL: {
176
+ value = env.Null();
177
+ } break;
178
+ case duckdb::LogicalTypeId::LIST: {
179
+ auto child_type = duckdb::ListType::GetChildType(dval.type());
180
+ auto &child_values = duckdb::ListValue::GetChildren(dval);
181
+ auto object_value = Napi::Array::New(env);
182
+ for (duckdb::idx_t child_idx = 0; child_idx < child_values.size(); child_idx++) {
183
+ auto child_value = child_values.at(child_idx);
184
+ object_value.Set(child_idx, convert_col_val(env, child_value, child_type.id()));
185
+ }
186
+ value = object_value;
187
+ } break;
188
+ case duckdb::LogicalTypeId::STRUCT: {
189
+ auto &child_types = duckdb::StructType::GetChildTypes(dval.type());
190
+ auto &child_values = duckdb::StructValue::GetChildren(dval);
191
+ auto object_value = Napi::Object::New(env);
192
+ for (duckdb::idx_t child_idx = 0; child_idx < child_values.size(); child_idx++) {
193
+ auto child_value = child_values.at(child_idx);
194
+ auto child_type = child_types.at(child_idx);
195
+ object_value.Set(child_type.first, convert_col_val(env, child_value, child_type.second.id()));
196
+ }
197
+ value = object_value;
198
+ } break;
199
+ default:
200
+ Napi::Error::New(env, "Data type is not supported " + dval.type().ToString()).ThrowAsJavaScriptException();
201
+ return env.Null();
202
+ }
203
+
204
+ return value;
205
+ }
206
+
124
207
  static Napi::Value convert_chunk(Napi::Env &env, std::vector<std::string> names, duckdb::DataChunk &chunk) {
125
208
  Napi::EscapableHandleScope scope(env);
126
209
  std::vector<Napi::String> node_names;
@@ -134,76 +217,13 @@ static Napi::Value convert_chunk(Napi::Env &env, std::vector<std::string> names,
134
217
  Napi::Object row_result = Napi::Object::New(env);
135
218
 
136
219
  for (duckdb::idx_t col_idx = 0; col_idx < chunk.ColumnCount(); col_idx++) {
137
- Napi::Value value;
138
- // set up a new Napi::Object for some data types, e.g. INTERVAL
139
- Napi::Object object_value;
140
-
141
- bool is_object_value {false};
142
-
143
- auto dval = chunk.GetValue(col_idx, row_idx);
220
+ duckdb::Value dval = chunk.GetValue(col_idx, row_idx);
144
221
  if (dval.IsNull()) {
145
222
  row_result.Set(node_names[col_idx], env.Null());
146
223
  continue;
147
224
  }
148
225
 
149
- // TODO templateroo here
150
- switch (chunk.data[col_idx].GetType().id()) {
151
- case duckdb::LogicalTypeId::BOOLEAN: {
152
- value = Napi::Boolean::New(env, duckdb::BooleanValue::Get(dval));
153
- } break;
154
- case duckdb::LogicalTypeId::INTEGER: {
155
- value = Napi::Number::New(env, duckdb::IntegerValue::Get(dval));
156
- } break;
157
- case duckdb::LogicalTypeId::FLOAT: {
158
- value = Napi::Number::New(env, duckdb::FloatValue::Get(dval));
159
- } break;
160
- case duckdb::LogicalTypeId::DOUBLE: {
161
- value = Napi::Number::New(env, duckdb::DoubleValue::Get(dval));
162
- } break;
163
- case duckdb::LogicalTypeId::BIGINT: {
164
- value = Napi::Number::New(env, duckdb::BigIntValue::Get(dval));
165
- } break;
166
- case duckdb::LogicalTypeId::HUGEINT: {
167
- value = Napi::Number::New(env, dval.GetValue<double>());
168
- } break;
169
- case duckdb::LogicalTypeId::INTERVAL: {
170
- auto interval = duckdb::IntervalValue::Get(dval);
171
- is_object_value = true;
172
- object_value = Napi::Object::New(env);
173
- object_value.Set("months", interval.months);
174
- object_value.Set("days", interval.days);
175
- object_value.Set("micros", interval.micros);
176
- } break;
177
- #if (NAPI_VERSION > 4)
178
- case duckdb::LogicalTypeId::DATE: {
179
- const auto scale = duckdb::Interval::SECS_PER_DAY * duckdb::Interval::MSECS_PER_SEC;
180
- value = Napi::Date::New(env, double(dval.GetValue<int32_t>() * scale));
181
- } break;
182
- case duckdb::LogicalTypeId::TIMESTAMP:
183
- case duckdb::LogicalTypeId::TIMESTAMP_TZ: {
184
- value = Napi::Date::New(env, double(dval.GetValue<int64_t>() / duckdb::Interval::MICROS_PER_MSEC));
185
- } break;
186
- #endif
187
- case duckdb::LogicalTypeId::VARCHAR: {
188
- value = Napi::String::New(env, duckdb::StringValue::Get(dval));
189
- } break;
190
- case duckdb::LogicalTypeId::BLOB: {
191
- auto &blob = duckdb::StringValue::Get(dval);
192
- value = Napi::Buffer<char>::Copy(env, blob.c_str(), blob.length());
193
- } break;
194
- case duckdb::LogicalTypeId::SQLNULL: {
195
- value = env.Null();
196
- } break;
197
- default:
198
- Napi::Error::New(env, "Data type is not supported " + dval.type().ToString())
199
- .ThrowAsJavaScriptException();
200
- return env.Null();
201
- }
202
- if (is_object_value == true) {
203
- row_result.Set(node_names[col_idx], object_value);
204
- } else {
205
- row_result.Set(node_names[col_idx], value);
206
- }
226
+ row_result.Set(node_names[col_idx], convert_col_val(env, dval, chunk.data[col_idx].GetType().id()));
207
227
  }
208
228
  result.Set(row_idx, row_result);
209
229
  }
@@ -25,12 +25,35 @@ describe("data type support", function () {
25
25
  INTERVAL 1 MINUTE as minutes,
26
26
  INTERVAL 5 DAY as days,
27
27
  INTERVAL 4 MONTH as months,
28
- INTERVAL 4 MONTH + INTERVAL 5 DAY + INTERVAL 1 MINUTE as combined;`).each((err, row) => {
28
+ INTERVAL 4 MONTH + INTERVAL 5 DAY + INTERVAL 1 MINUTE as combined;`
29
+ ).each((err, row) => {
29
30
  assert(err === null);
30
- assert.deepEqual(row.minutes, { months: 0, days: 0, micros: 60 * 1000 * 1000});
31
- assert.deepEqual(row.days, { months: 0, days: 5, micros: 0});
32
- assert.deepEqual(row.months, {months: 4, days: 0, micros: 0});
33
- assert.deepEqual(row.combined, {months: 4, days: 5, micros: 60 * 1000 * 1000});
31
+ assert.deepEqual(row.minutes, {
32
+ months: 0,
33
+ days: 0,
34
+ micros: 60 * 1000 * 1000,
35
+ });
36
+ assert.deepEqual(row.days, { months: 0, days: 5, micros: 0 });
37
+ assert.deepEqual(row.months, { months: 4, days: 0, micros: 0 });
38
+ assert.deepEqual(row.combined, {
39
+ months: 4,
40
+ days: 5,
41
+ micros: 60 * 1000 * 1000,
42
+ });
43
+ done();
44
+ });
45
+ });
46
+ it("supports STRUCT values", function (done) {
47
+ db.prepare(`SELECT {'x': 1, 'y': 2, 'z': {'a': 'b'}} as struct`).each(
48
+ (err, row) => {
49
+ assert.deepEqual(row.struct, { x: 1, y: 2, z: { a: "b" } });
50
+ done();
51
+ }
52
+ );
53
+ });
54
+ it("supports LIST values", function (done) {
55
+ db.prepare(`SELECT ['duck', 'duck', 'goose'] as list`).each((err, row) => {
56
+ assert.deepEqual(row.list, ["duck", "duck", "goose"]);
34
57
  done();
35
58
  });
36
59
  });
@@ -55,4 +78,17 @@ describe("data type support", function () {
55
78
  done();
56
79
  });
57
80
  });
81
+ it("supports DECIMAL values", function (done) {
82
+ db.run("CREATE TABLE decimal_table (d DECIMAL(24, 6))");
83
+ const stmt = db.prepare("INSERT INTO decimal_table VALUES (?)");
84
+ const values = [0, -1, 23534642362547.543463];
85
+ values.forEach((d) => {
86
+ stmt.run(d);
87
+ });
88
+ db.prepare("SELECT d from decimal_table;").all((err, res) => {
89
+ assert(err === null);
90
+ assert(res.every((v, i) => v.d === values[i]));
91
+ done();
92
+ });
93
+ });
58
94
  });