Skip to content

Commit b9e77c7

Browse files
authored
Feat/schema wasm (#295)
* feat: public schema() on WASM * chore: 0.1.4 * chore: fix typo
1 parent f29af8a commit b9e77c7

File tree

5 files changed

+48
-4
lines changed

5 files changed

+48
-4
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
[package]
44
name = "kite_sql"
5-
version = "0.1.3"
5+
version = "0.1.4"
66
edition = "2021"
77
authors = ["Kould <[email protected]>", "Xwg <[email protected]>"]
88
description = "SQL as a Function for Rust"

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ console.log(rows.map((r) => r.values.map((v) => v.Int32 ?? v)));
5555
## Examples
5656
5757
```rust
58+
use kite_sql::db::{DataBaseBuilder, ResultIter};
59+
5860
let kite_sql = DataBaseBuilder::path("./data").build()?;
5961

6062
kite_sql
@@ -64,7 +66,13 @@ kite_sql
6466
.run("insert into t1 values(0, 0), (1, 1)")?
6567
.done()?;
6668

67-
for tuple in kite_sql.run("select * from t1")? {
69+
let mut iter = kite_sql.run("select * from t1")?;
70+
71+
// Query schema is available on every result iterator.
72+
let column_names: Vec<_> = iter.schema().iter().map(|c| c.name()).collect();
73+
println!("columns: {column_names:?}");
74+
75+
for tuple in iter {
6876
println!("{:?}", tuple?);
6977
}
7078
```

examples/wasm_hello_world.test.mjs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,16 @@ async function main() {
1212
await db.execute("create table my_struct (c1 int primary key, c2 int)");
1313
await db.execute("insert into my_struct values(0, 0), (1, 1)");
1414

15-
const rows = db.run("select * from my_struct").rows();
15+
const iter = db.run("select * from my_struct");
16+
const schema = iter.schema();
17+
assert.deepEqual(
18+
schema.map(({ name, datatype, nullable }) => ({ name, datatype, nullable })),
19+
[
20+
{ name: "c1", datatype: "Integer", nullable: false },
21+
{ name: "c2", datatype: "Integer", nullable: true },
22+
],
23+
);
24+
const rows = iter.rows();
1625
assert.equal(rows.length, 2, "should return two rows");
1726

1827
const [first, second] = rows;

src/wasm.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,13 @@ struct WasmRow {
1313
values: Vec<DataValue>,
1414
}
1515

16+
#[derive(Serialize)]
17+
struct WasmSchemaColumn {
18+
name: String,
19+
datatype: String,
20+
nullable: bool,
21+
}
22+
1623
fn to_js_err(err: impl ToString) -> JsValue {
1724
js_sys::Error::new(&err.to_string()).into()
1825
}
@@ -89,6 +96,26 @@ impl WasmResultIter {
8996
}
9097
}
9198

99+
/// Returns the output schema as an array of `{ name, datatype, nullable }`.
100+
#[wasm_bindgen(js_name = schema)]
101+
pub fn schema(&self) -> Result<JsValue, JsValue> {
102+
let iter = self
103+
.inner
104+
.as_ref()
105+
.ok_or_else(|| to_js_err("iterator already consumed"))?;
106+
let columns: Vec<WasmSchemaColumn> = iter
107+
.schema()
108+
.iter()
109+
.map(|col| WasmSchemaColumn {
110+
name: col.name().to_string(),
111+
datatype: col.datatype().to_string(),
112+
nullable: col.nullable(),
113+
})
114+
.collect();
115+
serde_wasm_bindgen::to_value(&columns)
116+
.map_err(|e| to_js_err(format!("serialize schema: {e}")))
117+
}
118+
92119
/// Collect all remaining rows into an array and finish the iterator.
93120
#[wasm_bindgen(js_name = rows)]
94121
pub fn rows(&mut self) -> Result<JsValue, JsValue> {

0 commit comments

Comments
 (0)