@rip-lang/db 0.9.0 â 0.10.0
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/db.html +76 -30
- package/db.rip +127 -25
- package/lib/duckdb-binary.rip +13 -16
- package/package.json +1 -4
package/db.html
CHANGED
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
h1 { margin: 0 0 20px; font-size: 24px; color: #fff; }
|
|
10
10
|
.container { max-width: 1200px; margin: 0 auto; }
|
|
11
11
|
textarea { width: 100%; height: 120px; padding: 12px; font-family: 'Monaco', 'Menlo', monospace; font-size: 14px; background: #16213e; color: #0f0; border: 1px solid #0f4c75; border-radius: 6px; resize: vertical; }
|
|
12
|
-
|
|
12
|
+
.buttons { margin: 10px 0; }
|
|
13
|
+
button { padding: 10px 24px; font-size: 14px; background: #0f4c75; color: #fff; border: none; border-radius: 6px; cursor: pointer; margin-right: 10px; }
|
|
13
14
|
button:hover { background: #1b6ca8; }
|
|
14
15
|
.info { font-size: 12px; color: #888; margin-bottom: 10px; }
|
|
15
16
|
.results { margin-top: 20px; }
|
|
@@ -29,48 +30,93 @@
|
|
|
29
30
|
<h1>đĻ DuckDB Console</h1>
|
|
30
31
|
<div class="info">Connected to: <span id="db">loading...</span></div>
|
|
31
32
|
<textarea id="sql" placeholder="SELECT * FROM users LIMIT 10;">SELECT * FROM users;</textarea>
|
|
32
|
-
<div>
|
|
33
|
-
<button onclick="
|
|
34
|
-
<button onclick="
|
|
35
|
-
<button onclick="
|
|
33
|
+
<div class="buttons">
|
|
34
|
+
<button onclick="run()">âļ Run (Cmd+Enter)</button>
|
|
35
|
+
<button onclick="tables()">đ Tables</button>
|
|
36
|
+
<button onclick="status()">âšī¸ Status</button>
|
|
36
37
|
</div>
|
|
37
38
|
<div id="results" class="results"></div>
|
|
38
39
|
</div>
|
|
39
40
|
<script>
|
|
40
|
-
|
|
41
|
-
document.getElementById('
|
|
42
|
-
|
|
41
|
+
const sqlEl = document.getElementById('sql');
|
|
42
|
+
const resultsEl = document.getElementById('results');
|
|
43
|
+
|
|
44
|
+
// Load status on startup
|
|
45
|
+
fetch('/status').then(r => r.json()).then(d => {
|
|
46
|
+
document.getElementById('db').textContent = d.database;
|
|
43
47
|
});
|
|
44
|
-
|
|
45
|
-
|
|
48
|
+
|
|
49
|
+
// Cmd+Enter to run
|
|
50
|
+
sqlEl.addEventListener('keydown', e => {
|
|
51
|
+
if ((e.metaKey || e.ctrlKey) && e.key === 'Enter') {
|
|
52
|
+
e.preventDefault();
|
|
53
|
+
run();
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
function run() {
|
|
58
|
+
const sql = sqlEl.value.trim();
|
|
46
59
|
if (!sql) return;
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
60
|
+
fetch('/sql', {
|
|
61
|
+
method: 'POST',
|
|
62
|
+
headers: { 'Content-Type': 'application/json' },
|
|
63
|
+
body: JSON.stringify({ sql })
|
|
64
|
+
})
|
|
65
|
+
.then(r => r.json())
|
|
66
|
+
.then(renderResult)
|
|
67
|
+
.catch(e => renderError(e.message));
|
|
51
68
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
69
|
+
|
|
70
|
+
function tables() {
|
|
71
|
+
sqlEl.value = "SELECT table_name FROM information_schema.tables WHERE table_schema = 'main';";
|
|
72
|
+
run();
|
|
55
73
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
74
|
+
|
|
75
|
+
function status() {
|
|
76
|
+
fetch('/status')
|
|
77
|
+
.then(r => r.json())
|
|
78
|
+
.then(data => {
|
|
79
|
+
resultsEl.innerHTML = `
|
|
80
|
+
<div style="background:#16213e;padding:16px;border-radius:6px;">
|
|
81
|
+
<div><strong>Database:</strong> ${data.database}</div>
|
|
82
|
+
<div><strong>Tables:</strong> ${data.tables?.join(', ') || 'none'}</div>
|
|
83
|
+
<div><strong>Time:</strong> ${data.time}</div>
|
|
84
|
+
</div>`;
|
|
85
|
+
})
|
|
86
|
+
.catch(e => renderError(e.message));
|
|
61
87
|
}
|
|
88
|
+
|
|
62
89
|
function renderResult(data) {
|
|
63
|
-
if (data.error) {
|
|
64
|
-
|
|
90
|
+
if (data.error) {
|
|
91
|
+
renderError(data.error);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
if (!data.meta?.length) {
|
|
95
|
+
resultsEl.innerHTML = `<div class="meta"><span class="status ok">â OK</span> Query executed in ${data.time}s</div>`;
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
65
98
|
let html = '<table><tr>';
|
|
66
|
-
data.meta.forEach(col => {
|
|
99
|
+
data.meta.forEach(col => {
|
|
100
|
+
html += `<th>${col.name}<br><span style="font-weight:normal;font-size:11px;color:#888">${col.type}</span></th>`;
|
|
101
|
+
});
|
|
67
102
|
html += '</tr>';
|
|
68
|
-
data.data.forEach(row => {
|
|
69
|
-
|
|
70
|
-
|
|
103
|
+
data.data.forEach(row => {
|
|
104
|
+
html += '<tr>';
|
|
105
|
+
row.forEach(val => {
|
|
106
|
+
html += `<td>${val === null ? '<span style="color:#666">NULL</span>' : val}</td>`;
|
|
107
|
+
});
|
|
108
|
+
html += '</tr>';
|
|
109
|
+
});
|
|
110
|
+
html += `</table><div class="meta"><span class="status ok">â OK</span> ${data.rows} row${data.rows !== 1 ? 's' : ''} in ${data.time}s</div>`;
|
|
111
|
+
resultsEl.innerHTML = html;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function renderError(msg) {
|
|
115
|
+
resultsEl.innerHTML = `<div class="error"><span class="status err">â Error</span> ${msg}</div>`;
|
|
71
116
|
}
|
|
72
|
-
|
|
73
|
-
|
|
117
|
+
|
|
118
|
+
// Run initial query
|
|
119
|
+
run();
|
|
74
120
|
</script>
|
|
75
121
|
</body>
|
|
76
122
|
</html>
|
package/db.rip
CHANGED
|
@@ -3,20 +3,24 @@
|
|
|
3
3
|
# ==============================================================================
|
|
4
4
|
#
|
|
5
5
|
# A simple HTTP server for DuckDB queries. One server per database.
|
|
6
|
-
#
|
|
6
|
+
# Fully compatible with the official DuckDB UI!
|
|
7
7
|
#
|
|
8
8
|
# Usage:
|
|
9
9
|
# rip db.rip <database.duckdb> [--port 4000]
|
|
10
10
|
# rip db.rip :memory: --port 4000
|
|
11
11
|
#
|
|
12
|
+
# Then open http://localhost:4000/ for the official DuckDB UI!
|
|
13
|
+
# (UI assets are proxied from ui.duckdb.org)
|
|
14
|
+
#
|
|
12
15
|
# Endpoints:
|
|
13
|
-
#
|
|
16
|
+
# GET / - Official DuckDB UI (proxied from ui.duckdb.org)
|
|
17
|
+
# GET /ui - Built-in SQL console (simple, no proxy)
|
|
18
|
+
# POST /sql - Execute SQL (JSON API)
|
|
14
19
|
# POST /ddb/run - DuckDB UI binary protocol
|
|
15
|
-
# GET /health - Health check
|
|
16
|
-
# GET /status - Database info
|
|
17
|
-
# GET /tables - List
|
|
18
|
-
# GET /schema/:table -
|
|
19
|
-
# GET /ui - Built-in SQL console
|
|
20
|
+
# GET /health - Health check
|
|
21
|
+
# GET /status - Database info
|
|
22
|
+
# GET /tables - List tables
|
|
23
|
+
# GET /schema/:table - Table schema
|
|
20
24
|
#
|
|
21
25
|
# ==============================================================================
|
|
22
26
|
|
|
@@ -36,6 +40,14 @@ import {
|
|
|
36
40
|
# Enable CORS for duck-ui and other clients
|
|
37
41
|
use cors preflight: true
|
|
38
42
|
|
|
43
|
+
# Log all requests
|
|
44
|
+
use (c, next) ->
|
|
45
|
+
start = Date.now()
|
|
46
|
+
result = next!
|
|
47
|
+
ms = Date.now() - start
|
|
48
|
+
console.log "#{c.req.method} #{c.req.path} #{ms}ms"
|
|
49
|
+
result
|
|
50
|
+
|
|
39
51
|
# ==============================================================================
|
|
40
52
|
# Configuration
|
|
41
53
|
# ==============================================================================
|
|
@@ -54,7 +66,7 @@ if '--help' in args or '-h' in args
|
|
|
54
66
|
database Path to DuckDB file (default: :memory:)
|
|
55
67
|
|
|
56
68
|
Options:
|
|
57
|
-
--port=N Port to listen on (default:
|
|
69
|
+
--port=N Port to listen on (default: 4213)
|
|
58
70
|
--help Show this help
|
|
59
71
|
--version Show version
|
|
60
72
|
|
|
@@ -70,7 +82,7 @@ if '--help' in args or '-h' in args
|
|
|
70
82
|
GET /schema/:t Get schema for table t
|
|
71
83
|
|
|
72
84
|
Examples:
|
|
73
|
-
rip db.rip # In-memory database on port
|
|
85
|
+
rip db.rip # In-memory database on port 4213
|
|
74
86
|
rip db.rip mydb.duckdb # File-based database
|
|
75
87
|
rip db.rip :memory: --port=8080
|
|
76
88
|
|
|
@@ -85,7 +97,7 @@ if '--version' in args or '-v' in args
|
|
|
85
97
|
|
|
86
98
|
# Support both env vars (for rip-server) and CLI args (for rip db.rip)
|
|
87
99
|
path = process.env.DB_PATH or args.find((a) -> not a.startsWith('-')) or ':memory:'
|
|
88
|
-
port = parseInt(process.env.DB_PORT or (args.find((a) -> a.startsWith('--port=')))?.split('=')[1]) or
|
|
100
|
+
port = parseInt(process.env.DB_PORT or (args.find((a) -> a.startsWith('--port=')))?.split('=')[1]) or 4213
|
|
89
101
|
|
|
90
102
|
# Open database
|
|
91
103
|
db = open(path)
|
|
@@ -97,7 +109,8 @@ console.log "rip-db: database=#{path} (bun-native)"
|
|
|
97
109
|
|
|
98
110
|
# Extract column info from result
|
|
99
111
|
getColumnInfo = (rows) ->
|
|
100
|
-
|
|
112
|
+
if not rows?.length > 0
|
|
113
|
+
return { columns: [], types: [] }
|
|
101
114
|
first = rows[0]
|
|
102
115
|
columns = Object.keys(first)
|
|
103
116
|
types = columns.map (col) ->
|
|
@@ -157,15 +170,16 @@ executeSQL = (sql, params = []) ->
|
|
|
157
170
|
# POST / â duck-ui compatible (raw SQL in body)
|
|
158
171
|
post '/' ->
|
|
159
172
|
sql = read 'body', 'string'
|
|
160
|
-
|
|
173
|
+
if not sql
|
|
174
|
+
return { error: 'Empty query' }
|
|
161
175
|
executeSQL sql
|
|
162
176
|
|
|
163
177
|
# POST /sql â JSON body with optional params
|
|
164
|
-
post '/sql'
|
|
178
|
+
post '/sql' ->
|
|
165
179
|
{ sql, params } = read()
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
executeSQL sql, params or []
|
|
180
|
+
if not sql
|
|
181
|
+
return { error: 'Missing required field: sql' }
|
|
182
|
+
executeSQL sql, (params or [])
|
|
169
183
|
|
|
170
184
|
# GET /health â Simple health check (no DB query)
|
|
171
185
|
get '/health', ->
|
|
@@ -241,7 +255,8 @@ get '/ui', -> new Response Bun.file(import.meta.dir + '/db.html')
|
|
|
241
255
|
post '/ddb/run' ->
|
|
242
256
|
try
|
|
243
257
|
sql = read 'body', 'string'
|
|
244
|
-
|
|
258
|
+
if not sql
|
|
259
|
+
return binaryResponse serializeErrorResult 'Empty query'
|
|
245
260
|
|
|
246
261
|
# Parse row limit from DuckDB UI header
|
|
247
262
|
rowLimit = parseInt(@req.header('x-duckdb-ui-result-row-limit') or '10000')
|
|
@@ -267,35 +282,121 @@ post '/ddb/run' ->
|
|
|
267
282
|
finally
|
|
268
283
|
conn.close()
|
|
269
284
|
|
|
270
|
-
catch
|
|
271
|
-
console.error "POST /ddb/run error:", message
|
|
272
|
-
binaryResponse serializeErrorResult message or 'Unknown error'
|
|
285
|
+
catch err
|
|
286
|
+
console.error "POST /ddb/run error:", err?.message
|
|
287
|
+
binaryResponse serializeErrorResult err?.message or 'Unknown error'
|
|
273
288
|
|
|
274
289
|
# POST /ddb/interrupt â Cancel running query
|
|
275
|
-
post '/ddb/interrupt' ->
|
|
290
|
+
post '/ddb/interrupt', ->
|
|
276
291
|
# In a real implementation, this would cancel the running query
|
|
277
292
|
# For now, just return empty result
|
|
278
293
|
binaryResponse serializeEmptyResult()
|
|
279
294
|
|
|
280
295
|
# POST /ddb/tokenize â Tokenize SQL for syntax highlighting
|
|
281
296
|
post '/ddb/tokenize' ->
|
|
282
|
-
sql = read 'body', 'string'
|
|
297
|
+
sql = read 'body', 'string'
|
|
283
298
|
tokens = tokenizeSQL sql
|
|
284
299
|
binaryResponse serializeTokenizeResult tokens
|
|
285
300
|
|
|
301
|
+
# GET /version â Tell UI we're running in local/HTTP mode (not WASM)
|
|
302
|
+
get '/version' ->
|
|
303
|
+
{ origin: 'local', version: '139-944c08a214' }
|
|
304
|
+
|
|
305
|
+
# GET /localToken â Return empty token for local mode (no MotherDuck)
|
|
306
|
+
get '/localToken' ->
|
|
307
|
+
new Response '', { status: 200, headers: { 'Content-Type': 'text/plain' } }
|
|
308
|
+
|
|
286
309
|
# GET /info â Server version info (DuckDB UI checks this)
|
|
310
|
+
# The UI checks X-DuckDB-UI-Extension-Version to decide HTTP vs WASM mode
|
|
311
|
+
# Version format must match desiredDuckDBUIExtensionVersions in /config
|
|
287
312
|
get '/info' ->
|
|
288
313
|
@body '', 200,
|
|
289
314
|
'Access-Control-Allow-Origin': '*'
|
|
290
|
-
'X-DuckDB-Version': '1.
|
|
315
|
+
'X-DuckDB-Version': '1.4.1'
|
|
291
316
|
'X-DuckDB-Platform': 'rip-db'
|
|
292
|
-
'X-DuckDB-UI-Extension-Version':
|
|
317
|
+
'X-DuckDB-UI-Extension-Version': '139-944c08a214'
|
|
293
318
|
|
|
294
319
|
# Helper to create binary response
|
|
295
320
|
binaryResponse = (buffer) ->
|
|
296
321
|
new Response buffer,
|
|
297
322
|
headers: { 'Content-Type': 'application/octet-stream' }
|
|
298
323
|
|
|
324
|
+
# ==============================================================================
|
|
325
|
+
# DuckDB UI Proxy â Serve official UI assets from ui.duckdb.org
|
|
326
|
+
# ==============================================================================
|
|
327
|
+
#
|
|
328
|
+
# The official DuckDB UI is a React app hosted at https://ui.duckdb.org
|
|
329
|
+
# We proxy these assets so you can use the beautiful UI with rip-db!
|
|
330
|
+
#
|
|
331
|
+
# The UI makes API requests to relative URLs (/ddb/run, /ddb/tokenize, etc.)
|
|
332
|
+
# which we handle above. This proxy just serves the static UI assets.
|
|
333
|
+
#
|
|
334
|
+
# ==============================================================================
|
|
335
|
+
|
|
336
|
+
UI_REMOTE_URL = 'https://ui.duckdb.org'
|
|
337
|
+
|
|
338
|
+
# GET /localEvents â Server-sent events for catalog updates
|
|
339
|
+
get '/localEvents' ->
|
|
340
|
+
# Create SSE response with keep-alive
|
|
341
|
+
encoder = new TextEncoder()
|
|
342
|
+
intervalId = null
|
|
343
|
+
|
|
344
|
+
stream = new ReadableStream
|
|
345
|
+
start: (controller) ->
|
|
346
|
+
# Send initial connection event
|
|
347
|
+
controller.enqueue encoder.encode "event: connected\ndata: {}\n\n"
|
|
348
|
+
|
|
349
|
+
# Keep connection alive with periodic heartbeats
|
|
350
|
+
intervalId = setInterval ->
|
|
351
|
+
try
|
|
352
|
+
controller.enqueue encoder.encode ": heartbeat\n\n"
|
|
353
|
+
catch
|
|
354
|
+
clearInterval intervalId
|
|
355
|
+
, 30000
|
|
356
|
+
|
|
357
|
+
cancel: ->
|
|
358
|
+
clearInterval intervalId if intervalId
|
|
359
|
+
|
|
360
|
+
new Response stream,
|
|
361
|
+
headers:
|
|
362
|
+
'Content-Type': 'text/event-stream'
|
|
363
|
+
'Cache-Control': 'no-cache'
|
|
364
|
+
'Connection': 'keep-alive'
|
|
365
|
+
|
|
366
|
+
# GET /* â Proxy UI assets from ui.duckdb.org (catch-all, must be last)
|
|
367
|
+
get '/*' ->
|
|
368
|
+
path = @req.path
|
|
369
|
+
|
|
370
|
+
# Skip if this is one of our API endpoints (shouldn't reach here, but safety)
|
|
371
|
+
return { error: 'Not found' } if path in ['/health', '/status', '/tables', '/info', '/ui']
|
|
372
|
+
|
|
373
|
+
try
|
|
374
|
+
# Fetch from remote UI server
|
|
375
|
+
response = fetch! "#{UI_REMOTE_URL}#{path}",
|
|
376
|
+
headers:
|
|
377
|
+
'User-Agent': "rip-db/#{VERSION}"
|
|
378
|
+
|
|
379
|
+
# Get response body and content type
|
|
380
|
+
body = response.arrayBuffer!
|
|
381
|
+
contentType = response.headers.get('Content-Type') or 'application/octet-stream'
|
|
382
|
+
|
|
383
|
+
# Build response headers
|
|
384
|
+
headers =
|
|
385
|
+
'Content-Type': contentType
|
|
386
|
+
'Cache-Control': response.headers.get('Cache-Control') or 'public, max-age=3600'
|
|
387
|
+
|
|
388
|
+
# For /config endpoint, add DuckDB version headers (UI uses these to detect mode)
|
|
389
|
+
if path is '/config'
|
|
390
|
+
headers['X-DuckDB-Version'] = '1.4.1'
|
|
391
|
+
headers['X-DuckDB-Platform'] = 'rip-db'
|
|
392
|
+
headers['X-DuckDB-UI-Extension-Version'] = '139-944c08a214'
|
|
393
|
+
|
|
394
|
+
new Response body, { status: response.status, headers }
|
|
395
|
+
|
|
396
|
+
catch err
|
|
397
|
+
console.error "Proxy error for #{path}:", err?.message
|
|
398
|
+
new Response "Failed to fetch UI asset: #{path}", { status: 502 }
|
|
399
|
+
|
|
299
400
|
# ==============================================================================
|
|
300
401
|
# Start Server
|
|
301
402
|
# ==============================================================================
|
|
@@ -303,4 +404,5 @@ binaryResponse = (buffer) ->
|
|
|
303
404
|
start port: port
|
|
304
405
|
|
|
305
406
|
console.log "rip-db: listening on http://localhost:#{port}"
|
|
306
|
-
console.log "rip-db:
|
|
407
|
+
console.log "rip-db: Official DuckDB UI available at http://localhost:#{port}/"
|
|
408
|
+
console.log "rip-db: Built-in console at http://localhost:#{port}/ui"
|
package/lib/duckdb-binary.rip
CHANGED
|
@@ -229,28 +229,25 @@ serializeVector = (s, column, values) ->
|
|
|
229
229
|
s.writeFieldId 101
|
|
230
230
|
s.writeData createValidityBitmap values
|
|
231
231
|
|
|
232
|
-
# Type IDs: VARCHAR=25, CHAR=24, BOOLEAN=10, TINYINT=11, UTINYINT=28,
|
|
233
|
-
# SMALLINT=12, USMALLINT=29, INTEGER=13, UINTEGER=30, BIGINT=14, UBIGINT=31,
|
|
234
|
-
# FLOAT=22, DOUBLE=23, DATE=15, TIMESTAMP=19, TIMESTAMP_TZ=32
|
|
235
232
|
switch typeId
|
|
236
|
-
when
|
|
233
|
+
when LogicalTypeId.VARCHAR, LogicalTypeId.CHAR
|
|
237
234
|
s.writeList 102, values, (s, v) -> s.writeString String(v ? '')
|
|
238
235
|
|
|
239
|
-
when
|
|
236
|
+
when LogicalTypeId.BOOLEAN
|
|
240
237
|
s.writeFieldId 102
|
|
241
238
|
bytes = new Uint8Array values.length
|
|
242
239
|
for v, i in values
|
|
243
240
|
bytes[i] = if v then 1 else 0
|
|
244
241
|
s.writeData bytes
|
|
245
242
|
|
|
246
|
-
when
|
|
243
|
+
when LogicalTypeId.TINYINT, LogicalTypeId.UTINYINT
|
|
247
244
|
s.writeFieldId 102
|
|
248
245
|
bytes = new Uint8Array values.length
|
|
249
246
|
for v, i in values
|
|
250
247
|
bytes[i] = (v ? 0) & 0xFF
|
|
251
248
|
s.writeData bytes
|
|
252
249
|
|
|
253
|
-
when
|
|
250
|
+
when LogicalTypeId.SMALLINT
|
|
254
251
|
s.writeFieldId 102
|
|
255
252
|
bytes = new Uint8Array values.length * 2
|
|
256
253
|
dv = new DataView bytes.buffer
|
|
@@ -258,7 +255,7 @@ serializeVector = (s, column, values) ->
|
|
|
258
255
|
dv.setInt16 i * 2, v ? 0, true
|
|
259
256
|
s.writeData bytes
|
|
260
257
|
|
|
261
|
-
when
|
|
258
|
+
when LogicalTypeId.USMALLINT
|
|
262
259
|
s.writeFieldId 102
|
|
263
260
|
bytes = new Uint8Array values.length * 2
|
|
264
261
|
dv = new DataView bytes.buffer
|
|
@@ -266,7 +263,7 @@ serializeVector = (s, column, values) ->
|
|
|
266
263
|
dv.setUint16 i * 2, v ? 0, true
|
|
267
264
|
s.writeData bytes
|
|
268
265
|
|
|
269
|
-
when
|
|
266
|
+
when LogicalTypeId.INTEGER
|
|
270
267
|
s.writeFieldId 102
|
|
271
268
|
bytes = new Uint8Array values.length * 4
|
|
272
269
|
dv = new DataView bytes.buffer
|
|
@@ -274,7 +271,7 @@ serializeVector = (s, column, values) ->
|
|
|
274
271
|
dv.setInt32 i * 4, v ? 0, true
|
|
275
272
|
s.writeData bytes
|
|
276
273
|
|
|
277
|
-
when
|
|
274
|
+
when LogicalTypeId.UINTEGER
|
|
278
275
|
s.writeFieldId 102
|
|
279
276
|
bytes = new Uint8Array values.length * 4
|
|
280
277
|
dv = new DataView bytes.buffer
|
|
@@ -282,7 +279,7 @@ serializeVector = (s, column, values) ->
|
|
|
282
279
|
dv.setUint32 i * 4, v ? 0, true
|
|
283
280
|
s.writeData bytes
|
|
284
281
|
|
|
285
|
-
when
|
|
282
|
+
when LogicalTypeId.BIGINT
|
|
286
283
|
s.writeFieldId 102
|
|
287
284
|
bytes = new Uint8Array values.length * 8
|
|
288
285
|
dv = new DataView bytes.buffer
|
|
@@ -290,7 +287,7 @@ serializeVector = (s, column, values) ->
|
|
|
290
287
|
dv.setBigInt64 i * 8, BigInt(v ? 0), true
|
|
291
288
|
s.writeData bytes
|
|
292
289
|
|
|
293
|
-
when
|
|
290
|
+
when LogicalTypeId.UBIGINT
|
|
294
291
|
s.writeFieldId 102
|
|
295
292
|
bytes = new Uint8Array values.length * 8
|
|
296
293
|
dv = new DataView bytes.buffer
|
|
@@ -298,7 +295,7 @@ serializeVector = (s, column, values) ->
|
|
|
298
295
|
dv.setBigUint64 i * 8, BigInt(v ? 0), true
|
|
299
296
|
s.writeData bytes
|
|
300
297
|
|
|
301
|
-
when
|
|
298
|
+
when LogicalTypeId.FLOAT
|
|
302
299
|
s.writeFieldId 102
|
|
303
300
|
bytes = new Uint8Array values.length * 4
|
|
304
301
|
dv = new DataView bytes.buffer
|
|
@@ -306,7 +303,7 @@ serializeVector = (s, column, values) ->
|
|
|
306
303
|
dv.setFloat32 i * 4, v ? 0, true
|
|
307
304
|
s.writeData bytes
|
|
308
305
|
|
|
309
|
-
when
|
|
306
|
+
when LogicalTypeId.DOUBLE
|
|
310
307
|
s.writeFieldId 102
|
|
311
308
|
bytes = new Uint8Array values.length * 8
|
|
312
309
|
dv = new DataView bytes.buffer
|
|
@@ -314,7 +311,7 @@ serializeVector = (s, column, values) ->
|
|
|
314
311
|
dv.setFloat64 i * 8, v ? 0, true
|
|
315
312
|
s.writeData bytes
|
|
316
313
|
|
|
317
|
-
when
|
|
314
|
+
when LogicalTypeId.DATE
|
|
318
315
|
s.writeFieldId 102
|
|
319
316
|
bytes = new Uint8Array values.length * 4
|
|
320
317
|
dv = new DataView bytes.buffer
|
|
@@ -323,7 +320,7 @@ serializeVector = (s, column, values) ->
|
|
|
323
320
|
dv.setInt32 i * 4, days, true
|
|
324
321
|
s.writeData bytes
|
|
325
322
|
|
|
326
|
-
when
|
|
323
|
+
when LogicalTypeId.TIMESTAMP, LogicalTypeId.TIMESTAMP_TZ
|
|
327
324
|
s.writeFieldId 102
|
|
328
325
|
bytes = new Uint8Array values.length * 8
|
|
329
326
|
dv = new DataView bytes.buffer
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rip-lang/db",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "DuckDB Server â Simple HTTP API for DuckDB queries",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "db.rip",
|
|
@@ -12,9 +12,6 @@
|
|
|
12
12
|
"dev": "rip db.rip :memory:",
|
|
13
13
|
"test": "bun test"
|
|
14
14
|
},
|
|
15
|
-
"dependencies": {
|
|
16
|
-
"@rip-lang/api": "^0.5.0"
|
|
17
|
-
},
|
|
18
15
|
"keywords": [
|
|
19
16
|
"db",
|
|
20
17
|
"database",
|