@lithdew/chdb-bun
Version:
Native chDB bindings for Bun.
154 lines (119 loc) • 4.96 kB
Markdown
Native chDB bindings for [Bun](https://bun.sh).
[](https://clickhouse.com/chdb) is a fast, reliable, and scalable in-process OLAP SQL database built on top of Clickhouse.
The [official chDB bindings for Bun](https://github.com/chdb-io/chdb-bun) are out-of-date. It:
1. requires [libchdb](https://github.com/chdb-io/chdb) to be installed on the system,
2. requires `gcc` or `clang` to be available on the system for building C code,
3. does not support the latest version of chdb, which includes several performance improvements and bug fixes and features such as:
- [a connection-based API](https://github.com/chdb-io/chdb?tab=readme-ov-file#%EF%B8%8F-connection-based-api-recommended),
- [streaming queries](https://github.com/chdb-io/chdb?tab=readme-ov-file#%EF%B8%8F-streaming-query), and
- query runtime statistics, and
4. does not automatically release/destroy resources when garbage-collected.
- Built using [bun:ffi](https://bun.sh/docs/api/ffi).
- Supports the latest version of [libchdb](https://github.com/chdb-io/chdb).
- Streaming query support.
- Connection-based API support.
- Connections are closed and cleaned up if garbage-collected via. [FinalizationRegistry](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/FinalizationRegistry).
- Streams are closed and cleaned up if garbage-collected via. [FinalizationRegistry](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/FinalizationRegistry).
```bash
bun install @lithdew/chdb-bun && bun pm trust @lithdew/chdb-bun
```
```typescript
import { query, Connection } from "@lithdew/chdb-bun";
```
For single, self-contained queries:
```typescript
try {
const result = query(
"SELECT number, toString(number) FROM system.numbers LIMIT 3",
"Pretty"
);
console.log("Query Result:\n", result.data);
console.log("Statistics:", result.stats);
// Output:
// Query Result:
// ┌─number─┬─toString(number)─┐
// │ 0 │ 0 │
// │ 1 │ 1 │
// │ 2 │ 2 │
// └────────┴──────────────────┘
// Statistics: { elapsed: 0.001234, rowsRead: 3n, bytesRead: 24n }
} catch (e) {
console.error("Stateless query execution failed:", e);
}
```
For scenarios involving persistent storage, multiple queries within a session, or UDFs.
```typescript
try {
const conn = new Connection(":memory:"); // Establishes an in-memory database session
conn.query(
"CREATE TABLE IF NOT EXISTS users (id UInt32, name String) ENGINE = Memory;"
);
conn.query("INSERT INTO users VALUES (1, 'Alice'), (2, 'Bob');");
const result = conn.query("SELECT * FROM users ORDER BY id", "JSONEachRow");
console.log("Users:\n", result.data);
// Output:
// Users:
// {"id":1,"name":"Alice"}
// {"id":2,"name":"Bob"}
} catch (e) {
console.error("In-memory connection operation failed:", e);
}
```
Data is persisted to the specified file path.
```typescript
try {
const conn = new Connection("my_database.db"); // Relative path
// Alternatively, an absolute path: new Connection("/path/to/my_database.db")
// Or using the file: prefix: new Connection("file:my_database.db")
conn.query(
"CREATE TABLE IF NOT EXISTS events (timestamp DateTime, event_name String) ENGINE = MergeTree ORDER BY timestamp;"
);
conn.query(
"INSERT INTO events VALUES (now(), 'AppStart'), (now() + 1, 'UserLogin');"
);
const events = conn.query("SELECT * FROM events", "CSVWithNames");
console.log("Events:\n", events.data);
} catch (e) {
console.error("File-based connection operation failed:", e);
}
```
Process large result sets efficiently by iterating over data chunks.
```typescript
try {
const conn = new Connection(":memory:");
conn.query(
"CREATE TABLE IF NOT EXISTS large_data (value Int64) ENGINE = Memory;"
);
conn.query(
"INSERT INTO large_data SELECT number FROM system.numbers LIMIT 200000;"
); // Populates with 200,000 rows
const stream = conn.stream("SELECT * FROM large_data", "CSV");
let totalRowsStreamed = 0n;
let chunkCount = 0;
for (const chunk of stream) {
chunkCount++;
// chunk.data contains a segment of the result set
console.log(
`Chunk ${chunkCount} statistics: ${chunk.stats.rowsRead} rows, ${chunk.stats.bytesRead} bytes, duration ${chunk.stats.elapsed}s`
);
totalRowsStreamed += chunk.stats.rowsRead;
}
console.log(
`\nTotal rows processed via stream: ${totalRowsStreamed} across ${chunkCount} chunks.`
);
} catch (e) {
console.error("Streaming query execution failed:", e);
}
```
Errors originating from chDB operations will throw a `CHDBError`.