@rip-lang/db 0.9.0 → 1.0.1
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/INTERNALS.md +324 -0
- package/README.md +93 -237
- package/bin/rip-db +3 -3
- package/build.zig +88 -0
- package/db.rip +162 -74
- package/lib/darwin-arm64/duckdb.node +0 -0
- package/lib/duckdb.mjs +246 -333
- package/package.json +11 -8
- package/src/duckdb.zig +1156 -0
- package/PROTOCOL.md +0 -258
- package/db.html +0 -76
- package/lib/duckdb-binary.rip +0 -528
package/README.md
CHANGED
|
@@ -2,320 +2,176 @@
|
|
|
2
2
|
|
|
3
3
|
# Rip DB - @rip-lang/db
|
|
4
4
|
|
|
5
|
-
> **
|
|
5
|
+
> **DuckDB server with the official DuckDB UI**
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
High-performance DuckDB HTTP server using native Zig bindings. Includes full
|
|
8
|
+
compatibility with the official DuckDB UI — no WASM, pure native speed.
|
|
8
9
|
|
|
9
|
-
##
|
|
10
|
+
## Quick Start
|
|
10
11
|
|
|
11
12
|
```bash
|
|
12
|
-
# Install
|
|
13
|
+
# Install
|
|
13
14
|
bun add -g @rip-lang/db
|
|
14
15
|
|
|
15
|
-
# Run
|
|
16
|
+
# Run (opens DuckDB UI at http://localhost:4213)
|
|
16
17
|
rip-db
|
|
17
18
|
|
|
18
|
-
#
|
|
19
|
-
rip-db
|
|
19
|
+
# With a database file
|
|
20
|
+
rip-db mydata.duckdb
|
|
20
21
|
|
|
21
|
-
#
|
|
22
|
-
rip-db
|
|
22
|
+
# Custom port
|
|
23
|
+
rip-db --port=8080
|
|
23
24
|
```
|
|
24
25
|
|
|
25
|
-
|
|
26
|
+
Open http://localhost:4213 to use the official DuckDB UI.
|
|
26
27
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
## Features
|
|
29
|
+
|
|
30
|
+
- **Official DuckDB UI** — Beautiful query interface at `/`
|
|
31
|
+
- **Native Zig bindings** — Zero-copy binary protocol, no JS serialization overhead
|
|
32
|
+
- **JSON API** — Simple REST endpoints for programmatic access
|
|
33
|
+
- **Single process** — DuckDB's multi-threaded engine handles concurrency
|
|
30
34
|
|
|
31
35
|
## API Endpoints
|
|
32
36
|
|
|
33
|
-
###
|
|
37
|
+
### DuckDB UI (Binary Protocol)
|
|
34
38
|
|
|
35
|
-
|
|
39
|
+
The official DuckDB UI works out of the box at `http://localhost:4213/`.
|
|
36
40
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
| Endpoint | Method | Purpose |
|
|
42
|
+
|----------|--------|---------|
|
|
43
|
+
| `/` | GET | Official DuckDB UI |
|
|
44
|
+
| `/ddb/run` | POST | Execute SQL (binary) |
|
|
45
|
+
| `/ddb/tokenize` | POST | Syntax highlighting |
|
|
46
|
+
| `/ddb/interrupt` | POST | Cancel query |
|
|
47
|
+
|
|
48
|
+
### JSON API
|
|
49
|
+
|
|
50
|
+
For programmatic access:
|
|
51
|
+
|
|
52
|
+
**POST /sql** — Execute SQL with JSON body
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
curl -X POST http://localhost:4213/sql \
|
|
56
|
+
-H "Content-Type: application/json" \
|
|
57
|
+
-d '{"sql": "SELECT * FROM users WHERE id = 1"}'
|
|
43
58
|
```
|
|
44
59
|
|
|
45
|
-
|
|
60
|
+
Response (JSONCompact format):
|
|
46
61
|
```json
|
|
47
62
|
{
|
|
48
|
-
"meta": [
|
|
49
|
-
|
|
50
|
-
{"name": "name", "type": "VARCHAR"},
|
|
51
|
-
{"name": "email", "type": "VARCHAR"}
|
|
52
|
-
],
|
|
53
|
-
"data": [
|
|
54
|
-
[1, "Alice", "alice@example.com"]
|
|
55
|
-
],
|
|
63
|
+
"meta": [{"name": "id", "type": "INTEGER"}, {"name": "name", "type": "VARCHAR"}],
|
|
64
|
+
"data": [[1, "Alice"]],
|
|
56
65
|
"rows": 1,
|
|
57
66
|
"time": 0.001
|
|
58
67
|
}
|
|
59
68
|
```
|
|
60
69
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
Execute SQL with raw body (duck-ui compatible). Used by [duck-ui](https://demo.duckui.com).
|
|
64
|
-
|
|
65
|
-
**Request:**
|
|
66
|
-
```
|
|
67
|
-
POST / HTTP/1.1
|
|
68
|
-
Content-Type: application/x-www-form-urlencoded
|
|
70
|
+
**POST /** — Raw SQL in body (duck-ui compatible)
|
|
69
71
|
|
|
70
|
-
|
|
72
|
+
```bash
|
|
73
|
+
curl -X POST http://localhost:4213/ -d "SELECT 42 as answer"
|
|
71
74
|
```
|
|
72
75
|
|
|
73
|
-
**
|
|
74
|
-
|
|
75
|
-
### GET /health
|
|
76
|
-
|
|
77
|
-
Simple health check (no database query).
|
|
76
|
+
**GET /health** — Health check
|
|
78
77
|
|
|
79
78
|
```json
|
|
80
|
-
{
|
|
79
|
+
{"ok": true}
|
|
81
80
|
```
|
|
82
81
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
Database info including table list.
|
|
82
|
+
**GET /status** — Database info
|
|
86
83
|
|
|
87
84
|
```json
|
|
88
|
-
{
|
|
89
|
-
"ok": true,
|
|
90
|
-
"database": "mydb.duckdb",
|
|
91
|
-
"tables": ["users", "orders", "products"],
|
|
92
|
-
"time": "2026-02-02T14:30:00.000Z"
|
|
93
|
-
}
|
|
85
|
+
{"ok": true, "database": "mydata.duckdb", "tables": ["users", "orders"]}
|
|
94
86
|
```
|
|
95
87
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
List all tables in the database.
|
|
88
|
+
**GET /tables** — List tables
|
|
99
89
|
|
|
100
90
|
```json
|
|
101
|
-
{
|
|
102
|
-
"ok": true,
|
|
103
|
-
"tables": ["users", "orders", "products"]
|
|
104
|
-
}
|
|
91
|
+
{"ok": true, "tables": ["users", "orders"]}
|
|
105
92
|
```
|
|
106
93
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
Get schema for a specific table.
|
|
94
|
+
**GET /schema/:table** — Table schema
|
|
110
95
|
|
|
111
96
|
```json
|
|
112
|
-
{
|
|
113
|
-
"ok": true,
|
|
114
|
-
"table": "users",
|
|
115
|
-
"columns": [
|
|
116
|
-
{ "column_name": "id", "data_type": "INTEGER", "is_nullable": "NO" },
|
|
117
|
-
{ "column_name": "name", "data_type": "VARCHAR", "is_nullable": "YES" },
|
|
118
|
-
{ "column_name": "email", "data_type": "VARCHAR", "is_nullable": "YES" }
|
|
119
|
-
]
|
|
120
|
-
}
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
### GET /ui
|
|
124
|
-
|
|
125
|
-
Built-in SQL console. Open in browser:
|
|
126
|
-
|
|
127
|
-
```
|
|
128
|
-
http://localhost:4000/ui
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
## DuckDB UI Compatibility
|
|
132
|
-
|
|
133
|
-
rip-db implements the official DuckDB UI binary protocol, making it compatible with
|
|
134
|
-
DuckDB's built-in UI. This means you can use the beautiful DuckDB UI with rip-db!
|
|
135
|
-
|
|
136
|
-
### Binary Protocol Endpoints
|
|
137
|
-
|
|
138
|
-
| Endpoint | Method | Purpose |
|
|
139
|
-
|-------------------|--------|----------------------------|
|
|
140
|
-
| `/ddb/run` | POST | Execute SQL (binary result)|
|
|
141
|
-
| `/ddb/interrupt` | POST | Cancel running query |
|
|
142
|
-
| `/ddb/tokenize` | POST | Syntax highlighting |
|
|
143
|
-
| `/info` | GET | Version info |
|
|
144
|
-
|
|
145
|
-
### How It Works
|
|
146
|
-
|
|
147
|
-
```
|
|
148
|
-
┌─────────────┐ Binary Protocol ┌─────────────┐
|
|
149
|
-
│ DuckDB UI │ ◀─────────────────────▶│ rip-db │
|
|
150
|
-
│ (Browser) │ │ Server │
|
|
151
|
-
└─────────────┘ └─────────────┘
|
|
97
|
+
{"ok": true, "table": "users", "columns": [{"column_name": "id", "data_type": "INTEGER"}]}
|
|
152
98
|
```
|
|
153
99
|
|
|
154
|
-
|
|
155
|
-
binary format. The UI has no idea it's talking to rip-db instead of native DuckDB!
|
|
156
|
-
|
|
157
|
-
For protocol details, see [PROTOCOL.md](./PROTOCOL.md).
|
|
158
|
-
|
|
159
|
-
## Examples
|
|
100
|
+
## Building from Source
|
|
160
101
|
|
|
161
|
-
|
|
102
|
+
Requires Zig 0.15+ and DuckDB development files.
|
|
162
103
|
|
|
163
104
|
```bash
|
|
164
|
-
|
|
165
|
-
-H "Content-Type: application/json" \
|
|
166
|
-
-d '{"sql": "CREATE TABLE users (id INTEGER PRIMARY KEY, name VARCHAR, email VARCHAR)"}'
|
|
167
|
-
```
|
|
105
|
+
cd packages/db
|
|
168
106
|
|
|
169
|
-
|
|
107
|
+
# Build for current platform (outputs to lib/{os}-{arch}/duckdb.node)
|
|
108
|
+
zig build -Doptimize=ReleaseFast --prefix .
|
|
170
109
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
-H "Content-Type: application/json" \
|
|
174
|
-
-d '{"sql": "INSERT INTO users VALUES (?, ?, ?)", "params": [1, "Alice", "alice@example.com"]}'
|
|
110
|
+
# Run tests
|
|
111
|
+
zig build test
|
|
175
112
|
```
|
|
176
113
|
|
|
177
|
-
|
|
114
|
+
Set `DUCKDB_DIR` if DuckDB is not at `/opt/homebrew`:
|
|
178
115
|
|
|
179
116
|
```bash
|
|
180
|
-
|
|
181
|
-
-H "Content-Type: application/json" \
|
|
182
|
-
-d '{"sql": "SELECT * FROM users WHERE name LIKE ?", "params": ["%Ali%"]}'
|
|
117
|
+
DUCKDB_DIR=/path/to/duckdb zig build
|
|
183
118
|
```
|
|
184
119
|
|
|
185
|
-
###
|
|
120
|
+
### Cross-Compiling
|
|
121
|
+
|
|
122
|
+
Zig can cross-compile to other platforms:
|
|
186
123
|
|
|
187
124
|
```bash
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
125
|
+
zig build -Dtarget=x86_64-linux-gnu # Linux x64
|
|
126
|
+
zig build -Dtarget=aarch64-linux-gnu # Linux ARM64
|
|
127
|
+
zig build -Dtarget=x86_64-windows # Windows x64
|
|
128
|
+
zig build -Dtarget=aarch64-macos # macOS ARM64
|
|
129
|
+
zig build -Dtarget=x86_64-macos # macOS x64
|
|
191
130
|
```
|
|
192
131
|
|
|
193
|
-
|
|
132
|
+
**Note:** Cross-compiling requires DuckDB libraries for each target platform.
|
|
133
|
+
For production, use CI/CD with native builds on each OS (GitHub Actions runners).
|
|
194
134
|
|
|
195
|
-
|
|
135
|
+
## Architecture
|
|
196
136
|
|
|
197
|
-
| Field | Type | Description |
|
|
198
|
-
|-------|------|-------------|
|
|
199
|
-
| `meta` | object[] | Column metadata: `[{name, type}, ...]` |
|
|
200
|
-
| `data` | any[][] | Row data as arrays |
|
|
201
|
-
| `rows` | number | Number of rows returned |
|
|
202
|
-
| `time` | number | Execution time in seconds |
|
|
203
|
-
| `error` | string | Error message (on failure) |
|
|
204
|
-
|
|
205
|
-
**Success response:**
|
|
206
|
-
```json
|
|
207
|
-
{
|
|
208
|
-
"meta": [{"name": "id", "type": "INTEGER"}, {"name": "name", "type": "VARCHAR"}],
|
|
209
|
-
"data": [[1, "Alice"], [2, "Bob"]],
|
|
210
|
-
"rows": 2,
|
|
211
|
-
"time": 0.001
|
|
212
|
-
}
|
|
213
137
|
```
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
138
|
+
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
|
|
139
|
+
│ DuckDB UI │ binary │ rip-db │ FFI │ DuckDB │
|
|
140
|
+
│ (Browser) │◀────────▶│ (Bun) │◀────────▶│ (native) │
|
|
141
|
+
└─────────────┘ └─────────────┘ └─────────────┘
|
|
218
142
|
```
|
|
219
143
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
Our custom Zig-based DuckDB bindings deliver exceptional performance:
|
|
144
|
+
- **Single FFI call** per query (not per-value)
|
|
145
|
+
- **Zero-copy** for numeric columns
|
|
146
|
+
- **Binary serialization in Zig** — no JavaScript overhead
|
|
147
|
+
- **Pre-allocated buffers** — no allocations per query
|
|
225
148
|
|
|
226
|
-
|
|
227
|
-
|-----------|---------|------------|
|
|
228
|
-
| Point lookup (WHERE id=?) | 0.09ms | 11,000 qps |
|
|
229
|
-
| Range scan (LIMIT 100) | 0.20ms | 5,000 qps |
|
|
230
|
-
| Aggregation (COUNT/AVG/MAX) | 0.12ms | 8,400 qps |
|
|
231
|
-
| JOIN + GROUP BY | 0.25ms | 4,000 qps |
|
|
232
|
-
| INSERT (single row) | 0.13ms | 7,700 qps |
|
|
149
|
+
See [INTERNALS.md](./INTERNALS.md) for protocol details.
|
|
233
150
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
| Operation | Our DuckDB | MySQL/PG (localhost) | Speedup |
|
|
237
|
-
|-----------|------------|----------------------|---------|
|
|
238
|
-
| Point lookup | **0.09ms** | 0.3-1ms | 3-10x faster |
|
|
239
|
-
| Range scan | **0.20ms** | 1-5ms | 5-25x faster |
|
|
240
|
-
| Aggregation | **0.12ms** | 2-20ms | 17-170x faster |
|
|
241
|
-
| JOIN + GROUP BY | **0.25ms** | 5-50ms | 20-200x faster |
|
|
242
|
-
| INSERT | **0.13ms** | 0.5-2ms | 4-15x faster |
|
|
243
|
-
|
|
244
|
-
**Why so fast?**
|
|
245
|
-
- **Zero network latency** — DuckDB runs in-process
|
|
246
|
-
- **No connection overhead** — No auth, handshake, or protocol parsing
|
|
247
|
-
- **Columnar engine** — DuckDB is optimized for analytical queries
|
|
248
|
-
- **Direct FFI** — Zig bindings call DuckDB's C API directly
|
|
249
|
-
|
|
250
|
-
## Architecture & Concurrency
|
|
251
|
-
|
|
252
|
-
### Single Process, High Concurrency
|
|
253
|
-
|
|
254
|
-
DuckDB only allows **one process** to access a database file at a time (for write access). This means rip-db runs as a **single process** — it does NOT use rip-server's multi-worker model.
|
|
255
|
-
|
|
256
|
-
However, rip-db handles **high concurrency** through two mechanisms:
|
|
151
|
+
## Files
|
|
257
152
|
|
|
258
153
|
```
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
│
|
|
263
|
-
|
|
264
|
-
│
|
|
265
|
-
│
|
|
266
|
-
│
|
|
267
|
-
|
|
268
|
-
│ rip-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
└─────────────────────────────────────────────────────────┘
|
|
154
|
+
packages/db/
|
|
155
|
+
├── build.zig # Zig build configuration
|
|
156
|
+
├── src/
|
|
157
|
+
│ └── duckdb.zig # Native Zig bindings
|
|
158
|
+
├── lib/
|
|
159
|
+
│ ├── duckdb.mjs # Bun FFI wrapper
|
|
160
|
+
│ └── darwin-arm64/
|
|
161
|
+
│ └── duckdb.node # Compiled library
|
|
162
|
+
├── bin/
|
|
163
|
+
│ └── rip-db # CLI entry point
|
|
164
|
+
├── db.rip # Server implementation
|
|
165
|
+
├── README.md # This file
|
|
166
|
+
└── INTERNALS.md # Protocol & architecture details
|
|
273
167
|
```
|
|
274
168
|
|
|
275
|
-
**Layer 1: Bun's Async I/O**
|
|
276
|
-
- Single JavaScript thread with event loop
|
|
277
|
-
- Handles thousands of concurrent HTTP connections
|
|
278
|
-
- Non-blocking I/O — while one request waits on DuckDB, others are processed
|
|
279
|
-
- No thread-per-request overhead
|
|
280
|
-
|
|
281
|
-
**Layer 2: DuckDB's Multi-Threading**
|
|
282
|
-
- Queries are parallelized across all CPU cores internally
|
|
283
|
-
- MVCC for concurrent reads
|
|
284
|
-
- Writes serialized automatically by DuckDB
|
|
285
|
-
|
|
286
|
-
### Why Not Multi-Process?
|
|
287
|
-
|
|
288
|
-
| Approach | Works with DuckDB? | Why |
|
|
289
|
-
|----------|-------------------|-----|
|
|
290
|
-
| Multi-process (rip-server) | ❌ No | DuckDB only allows one process with write access |
|
|
291
|
-
| Multi-threaded | ✅ Yes | DuckDB handles this internally |
|
|
292
|
-
| Async I/O | ✅ Yes | Bun's event loop handles concurrent connections |
|
|
293
|
-
|
|
294
|
-
### The Result
|
|
295
|
-
|
|
296
|
-
Even as a single process, rip-db can handle:
|
|
297
|
-
- **Thousands of concurrent connections** (Bun async I/O)
|
|
298
|
-
- **Parallel query execution** (DuckDB multi-threading)
|
|
299
|
-
- **High throughput** (11,000+ queries/sec on typical hardware)
|
|
300
|
-
|
|
301
|
-
This is the correct architecture for DuckDB — single process, high concurrency.
|
|
302
|
-
|
|
303
169
|
## Requirements
|
|
304
170
|
|
|
305
171
|
- Bun 1.0+
|
|
306
172
|
- rip-lang 2.0+
|
|
307
173
|
- @rip-lang/api 0.5+
|
|
308
174
|
|
|
309
|
-
## Building from Source
|
|
310
|
-
|
|
311
|
-
To rebuild the native DuckDB bindings (requires Zig 0.15+ and DuckDB):
|
|
312
|
-
|
|
313
|
-
```bash
|
|
314
|
-
./src/build.sh
|
|
315
|
-
```
|
|
316
|
-
|
|
317
|
-
This creates `lib/{platform}-{arch}/duckdb.node` for your platform.
|
|
318
|
-
|
|
319
175
|
## License
|
|
320
176
|
|
|
321
177
|
MIT
|
package/bin/rip-db
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { execFileSync } from 'child_process';
|
|
4
4
|
import { fileURLToPath } from 'url';
|
|
5
5
|
import { dirname, join } from 'path';
|
|
6
6
|
|
|
@@ -8,10 +8,10 @@ const __filename = fileURLToPath(import.meta.url);
|
|
|
8
8
|
const __dirname = dirname(__filename);
|
|
9
9
|
|
|
10
10
|
const dbRip = join(__dirname, '..', 'db.rip');
|
|
11
|
-
const args = process.argv.slice(2)
|
|
11
|
+
const args = process.argv.slice(2);
|
|
12
12
|
|
|
13
13
|
try {
|
|
14
|
-
|
|
14
|
+
execFileSync('rip', [dbRip, ...args], { stdio: 'inherit' });
|
|
15
15
|
} catch (error) {
|
|
16
16
|
process.exit(error.status || 1);
|
|
17
17
|
}
|
package/build.zig
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
const std = @import("std");
|
|
2
|
+
|
|
3
|
+
pub fn build(b: *std.Build) void {
|
|
4
|
+
// Use native target by default
|
|
5
|
+
const target = b.standardTargetOptions(.{});
|
|
6
|
+
// Default to ReleaseFast for plain `zig build`, but allow overrides:
|
|
7
|
+
// - `-Doptimize=...`
|
|
8
|
+
// - `--release=fast|safe|small`
|
|
9
|
+
const optimize = b.option(
|
|
10
|
+
std.builtin.OptimizeMode,
|
|
11
|
+
"optimize",
|
|
12
|
+
"Prioritize performance, safety, or binary size",
|
|
13
|
+
) orelse switch (b.release_mode) {
|
|
14
|
+
.off, .fast => std.builtin.OptimizeMode.ReleaseFast,
|
|
15
|
+
.safe => std.builtin.OptimizeMode.ReleaseSafe,
|
|
16
|
+
.small => std.builtin.OptimizeMode.ReleaseSmall,
|
|
17
|
+
.any => std.builtin.OptimizeMode.ReleaseFast,
|
|
18
|
+
};
|
|
19
|
+
// Note: Recommended explicit build for packaging: zig build -Doptimize=ReleaseFast --prefix .
|
|
20
|
+
|
|
21
|
+
// Get DuckDB directory (defaults to /opt/homebrew)
|
|
22
|
+
const duckdb_dir = std.process.getEnvVarOwned(b.allocator, "DUCKDB_DIR") catch "/opt/homebrew";
|
|
23
|
+
|
|
24
|
+
// Create the module for the library
|
|
25
|
+
const module = b.createModule(.{
|
|
26
|
+
.root_source_file = b.path("src/duckdb.zig"),
|
|
27
|
+
.target = target,
|
|
28
|
+
.optimize = optimize,
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
// Add DuckDB include path
|
|
32
|
+
module.addIncludePath(.{ .cwd_relative = b.fmt("{s}/include", .{duckdb_dir}) });
|
|
33
|
+
|
|
34
|
+
// Build the shared library
|
|
35
|
+
const lib = b.addLibrary(.{
|
|
36
|
+
.linkage = .dynamic,
|
|
37
|
+
.name = "duckdb",
|
|
38
|
+
.root_module = module,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// Link against DuckDB
|
|
42
|
+
lib.addLibraryPath(.{ .cwd_relative = b.fmt("{s}/lib", .{duckdb_dir}) });
|
|
43
|
+
lib.linkSystemLibrary("duckdb");
|
|
44
|
+
|
|
45
|
+
// Determine output directory based on target
|
|
46
|
+
const os_tag = target.result.os.tag;
|
|
47
|
+
const arch = target.result.cpu.arch;
|
|
48
|
+
|
|
49
|
+
const os_name: []const u8 = switch (os_tag) {
|
|
50
|
+
.macos => "darwin",
|
|
51
|
+
.linux => "linux",
|
|
52
|
+
.windows => "windows",
|
|
53
|
+
else => "unknown",
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const arch_name: []const u8 = switch (arch) {
|
|
57
|
+
.aarch64 => "arm64",
|
|
58
|
+
.x86_64 => "x64",
|
|
59
|
+
else => "unknown",
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
// Install to lib/{os}-{arch}/duckdb.node
|
|
63
|
+
const install_dir = b.fmt("lib/{s}-{s}", .{ os_name, arch_name });
|
|
64
|
+
const install_file = b.addInstallFileWithDir(
|
|
65
|
+
lib.getEmittedBin(),
|
|
66
|
+
.{ .custom = install_dir },
|
|
67
|
+
"duckdb.node",
|
|
68
|
+
);
|
|
69
|
+
b.getInstallStep().dependOn(&install_file.step);
|
|
70
|
+
|
|
71
|
+
// Tests
|
|
72
|
+
const test_module = b.createModule(.{
|
|
73
|
+
.root_source_file = b.path("src/duckdb.zig"),
|
|
74
|
+
.target = target,
|
|
75
|
+
.optimize = optimize,
|
|
76
|
+
});
|
|
77
|
+
test_module.addIncludePath(.{ .cwd_relative = b.fmt("{s}/include", .{duckdb_dir}) });
|
|
78
|
+
|
|
79
|
+
const tests = b.addTest(.{
|
|
80
|
+
.root_module = test_module,
|
|
81
|
+
});
|
|
82
|
+
tests.addLibraryPath(.{ .cwd_relative = b.fmt("{s}/lib", .{duckdb_dir}) });
|
|
83
|
+
tests.linkSystemLibrary("duckdb");
|
|
84
|
+
|
|
85
|
+
const run_tests = b.addRunArtifact(tests);
|
|
86
|
+
const test_step = b.step("test", "Run unit tests");
|
|
87
|
+
test_step.dependOn(&run_tests.step);
|
|
88
|
+
}
|