Skip to content

Commit

Permalink
feat(bindings/nodejs): support nested types Array,Map,Tuple
Browse files Browse the repository at this point in the history
  • Loading branch information
everpcpc committed Apr 17, 2024
1 parent b7bc39e commit be2e4eb
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 9 deletions.
37 changes: 31 additions & 6 deletions bindings/nodejs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
extern crate napi_derive;

use chrono::{NaiveDate, NaiveDateTime, NaiveTime};
use napi::bindgen_prelude::*;
use napi::{bindgen_prelude::*, Env};
use once_cell::sync::Lazy;
use tokio_stream::StreamExt;

Expand Down Expand Up @@ -71,10 +71,17 @@ pub struct Value(databend_driver::Value);

impl ToNapiValue for Value {
unsafe fn to_napi_value(env: sys::napi_env, val: Self) -> Result<sys::napi_value> {
let ctx = Env::from(env);
match val.0 {
databend_driver::Value::Null => Null::to_napi_value(env, Null),
databend_driver::Value::EmptyArray => String::to_napi_value(env, "[]".to_string()),
databend_driver::Value::EmptyMap => String::to_napi_value(env, "{}".to_string()),
databend_driver::Value::EmptyArray => {
let arr = ctx.create_array(0)?;
Array::to_napi_value(env, arr)
}
databend_driver::Value::EmptyMap => {
let obj = ctx.create_object()?;
Object::to_napi_value(env, obj)
}
databend_driver::Value::Boolean(b) => bool::to_napi_value(env, b),
databend_driver::Value::Binary(b) => Buffer::to_napi_value(env, b.into()),
databend_driver::Value::String(s) => String::to_napi_value(env, s),
Expand All @@ -90,9 +97,27 @@ impl ToNapiValue for Value {
NaiveDateTime::new(v, NaiveTime::from_hms_opt(0, 0, 0).unwrap()),
)
}
databend_driver::Value::Array(_) => String::to_napi_value(env, format!("{}", val.0)),
databend_driver::Value::Map(_) => String::to_napi_value(env, format!("{}", val.0)),
databend_driver::Value::Tuple(_) => String::to_napi_value(env, format!("{}", val.0)),
databend_driver::Value::Array(inner) => {
let mut arr = ctx.create_array(inner.len() as u32)?;
for (i, v) in inner.into_iter().enumerate() {
arr.set(i as u32, Value(v))?;
}
Array::to_napi_value(env, arr)
}
databend_driver::Value::Map(inner) => {
let mut obj = ctx.create_object()?;
for (k, v) in inner.into_iter() {
obj.set(k.to_string(), Value(v))?;
}
Object::to_napi_value(env, obj)
}
databend_driver::Value::Tuple(inner) => {
let mut arr = ctx.create_array(inner.len() as u32)?;
for (i, v) in inner.into_iter().enumerate() {
arr.set(i as u32, Value(v))?;
}
Array::to_napi_value(env, arr)
}
databend_driver::Value::Bitmap(s) => String::to_napi_value(env, s),
databend_driver::Value::Variant(s) => String::to_napi_value(env, s),
databend_driver::Value::Geometry(s) => String::to_napi_value(env, s),
Expand Down
17 changes: 14 additions & 3 deletions bindings/nodejs/tests/binding.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,20 @@ Then("Select string {string} should be equal to {string}", async function (input

Then("Select types should be expected native types", async function () {
// NumberValue::Decimal
const row = await this.conn.queryRow(`SELECT 15.7563::Decimal(8,4), 2.0+3.0`);
const excepted = ["15.7563", "5.0"];
assert.deepEqual(row.values(), excepted);
const row1 = await this.conn.queryRow(`SELECT 15.7563::Decimal(8,4), 2.0+3.0`);
assert.deepEqual(row1.values(), ["15.7563", "5.0"]);

// Array
const row2 = await this.conn.queryRow(`SELECT [10::Decimal(15,2), 1.1+2.3]`);
assert.deepEqual(row2.values(), [["10.00", "3.40"]]);

// Map
const row3 = await this.conn.queryRow(`SELECT {'xx':to_date('2020-01-01')}`);
assert.deepEqual(row3.values(), [{ xx: new Date("2020-01-01") }]);

// Tuple
const row4 = await this.conn.queryRow(`SELECT (10, '20', to_datetime('2024-04-16 12:34:56.789'))`);
assert.deepEqual(row4.values(), [[10, "20", new Date("2024-04-16T12:34:56.789Z")]]);
});

Then("Select numbers should iterate all rows", async function () {
Expand Down

0 comments on commit be2e4eb

Please sign in to comment.