Skip to content

Commit f68191b

Browse files
authored
Add nodejs example (#111)
* Add nodejs example * Add test
1 parent 0df0ca7 commit f68191b

File tree

5 files changed

+147
-1
lines changed

5 files changed

+147
-1
lines changed

.github/workflows/test.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,3 +157,20 @@ jobs:
157157
rustup default 1.78.0
158158
wasm-pack test --chrome --headless --features relaxed-idb
159159
wasm-pack test --chrome --headless --features relaxed-idb,sqlite3mc
160+
161+
test_nodejs:
162+
strategy:
163+
matrix:
164+
os: [ubuntu-latest]
165+
runs-on: ${{ matrix.os }}
166+
steps:
167+
- uses: actions/checkout@v4
168+
- name: Install wasm-pack
169+
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
170+
- name: Setup emscripten
171+
uses: ./.github/actions/setup-emscripten
172+
- name: Test
173+
run: |
174+
cd examples/nodejs
175+
wasm-pack build --target nodejs
176+
node pkg/nodejs.js

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@ members = [
55
"sqlite-wasm-libc",
66

77
"examples/custom-libc",
8-
"examples/implement-a-vfs"
8+
"examples/implement-a-vfs",
9+
"examples/nodejs"
910
]

examples/nodejs/Cargo.toml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[package]
2+
name = "nodejs"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]
7+
wasm-bindgen = "0.2.104"
8+
sqlite-wasm-rs = { path = "../../sqlite-wasm-rs" }
9+
wasm-bindgen-futures = "0.4.54"
10+
11+
[lib]
12+
crate-type = ["cdylib"]

examples/nodejs/README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# `nodejs`
2+
3+
`sqlite-wasm-rs` can be used in nodejs (memvfs)
4+
5+
## Usage
6+
7+
```sh
8+
wasm-pack build --target nodejs
9+
node pkg/nodejs.js
10+
```

examples/nodejs/src/lib.rs

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
use std::ffi::CStr;
2+
3+
use sqlite_wasm_rs::{
4+
sqlite3, sqlite3_column_count, sqlite3_column_double, sqlite3_column_int, sqlite3_column_text,
5+
sqlite3_column_type, sqlite3_exec, sqlite3_finalize, sqlite3_open_v2, sqlite3_prepare_v3,
6+
sqlite3_step, SQLITE_FLOAT, SQLITE_INTEGER, SQLITE_OK, SQLITE_OPEN_CREATE,
7+
SQLITE_OPEN_READWRITE, SQLITE_ROW, SQLITE_TEXT,
8+
};
9+
use wasm_bindgen::prelude::wasm_bindgen;
10+
11+
#[wasm_bindgen]
12+
extern "C" {
13+
// Use `js_namespace` here to bind `console.log(..)` instead of just
14+
// `log(..)`
15+
#[wasm_bindgen(js_namespace = console)]
16+
fn log(s: &str);
17+
}
18+
19+
macro_rules! console_log {
20+
// Note that this is using the `log` function imported above during
21+
// `bare_bones`
22+
($($t:tt)*) => (log(&format_args!($($t)*).to_string()))
23+
}
24+
25+
#[wasm_bindgen(start)]
26+
async fn main() {
27+
let mut db = std::ptr::null_mut();
28+
let ret = unsafe {
29+
sqlite3_open_v2(
30+
c"file:test_memory_vfs.db?vfs=memvfs".as_ptr().cast(),
31+
&mut db as *mut _,
32+
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
33+
std::ptr::null(),
34+
)
35+
};
36+
assert_eq!(SQLITE_OK, ret);
37+
console_log!("db: {db:?}");
38+
prepare_simple_db(db);
39+
check_result(db);
40+
}
41+
42+
fn prepare_simple_db(db: *mut sqlite3) {
43+
let sql = c"
44+
CREATE TABLE IF NOT EXISTS employees (
45+
id INTEGER PRIMARY KEY,
46+
name TEXT NOT NULL,
47+
salary REAL NOT NULL
48+
);
49+
50+
INSERT INTO employees (name, salary) VALUES ('Alice', 50000);
51+
INSERT INTO employees (name, salary) VALUES ('Bob', 60000);
52+
UPDATE employees SET salary = 55000 WHERE id = 1;
53+
";
54+
let ret = unsafe {
55+
sqlite3_exec(
56+
db,
57+
sql.as_ptr().cast(),
58+
None,
59+
std::ptr::null_mut(),
60+
std::ptr::null_mut(),
61+
)
62+
};
63+
assert_eq!(SQLITE_OK, ret);
64+
}
65+
66+
pub fn check_result(db: *mut sqlite3) {
67+
let sql = c"SELECT * FROM employees;";
68+
let mut stmt = std::ptr::null_mut();
69+
let ret = unsafe {
70+
sqlite3_prepare_v3(
71+
db,
72+
sql.as_ptr().cast(),
73+
-1,
74+
0,
75+
&mut stmt as *mut _,
76+
std::ptr::null_mut(),
77+
)
78+
};
79+
assert_eq!(ret, SQLITE_OK);
80+
81+
let ret = [(1, "Alice", 55000.0), (2, "Bob", 60000.0)];
82+
let mut idx = 0;
83+
84+
unsafe {
85+
while sqlite3_step(stmt) == SQLITE_ROW {
86+
let count = sqlite3_column_count(stmt);
87+
for col in 0..count {
88+
let ty = sqlite3_column_type(stmt, col);
89+
match ty {
90+
SQLITE_INTEGER => assert_eq!(ret[idx].0, sqlite3_column_int(stmt, col)),
91+
SQLITE_TEXT => {
92+
let s = CStr::from_ptr(sqlite3_column_text(stmt, col).cast())
93+
.to_str()
94+
.unwrap();
95+
assert!(s == ret[idx].1);
96+
}
97+
SQLITE_FLOAT => assert_eq!(ret[idx].2, sqlite3_column_double(stmt, col)),
98+
_ => unreachable!(),
99+
}
100+
}
101+
idx += 1;
102+
}
103+
console_log!("{ret:?}");
104+
sqlite3_finalize(stmt);
105+
}
106+
}

0 commit comments

Comments
 (0)