新建react项目,添加依赖:
"@duckdb/duckdb-wasm": "^1.14.1",
app.tsx
:
import * as duckdb from "@duckdb/duckdb-wasm";
export function App() {
async function test() {
console.log('hello')
const JSDELIVR_BUNDLES = duckdb.getJsDelivrBundles();
// Select a bundle based on browser checks
const bundle = await duckdb.selectBundle(JSDELIVR_BUNDLES);
const worker_url = URL.createObjectURL(
new Blob([`importScripts("${bundle.mainWorker!}");`], { type: 'text/javascript' })
);
// Instantiate the asynchronus version of DuckDB-wasm
const worker = new Worker(worker_url);
const logger = new duckdb.ConsoleLogger();
const db = new duckdb.AsyncDuckDB(logger, worker);
await db.instantiate(bundle.mainModule, bundle.pthreadWorker);
const conn = await db.connect(); // Connect to db
let q = await conn.query(`SELECT * FROM 'https://shell.duckdb.org/data/tpch/0_01/parquet/orders.parquet' LIMIT 10;`); // Returns v = 101
console.log("Query result (Arrow Table):", q);
console.log('Query result copy (JSON):', JSON.parse(JSON.stringify(q.toArray())));
console.log('');
URL.revokeObjectURL(worker_url);
await conn.close();
await db.terminate();
await worker.terminate();
}
test()
// const element = document.getElementById("root");
// ReactDOM.render(
// <React.StrictMode>
// <Shell />
// </React.StrictMode>,
// element
// );
return (
<div>
<h1>hello from localhost</h1>
</div>
)
}
export default App
list组件 www.zhihu.com/tardis/bd/a…
import * as duckdb from '@duckdb/duckdb-wasm'
import { Input, Card, Table, Spin, Button, Space, Alert } from 'antd'
import { useState } from 'react'
import Highlight from 'react-highlight'
import hljs from 'highlight.js'
import sql from 'highlight.js/lib/languages/sql'
import 'highlight.js/styles/vs.css'
const { TextArea } = Input
hljs.registerLanguage('javascript', sql)
export function App() {
const [loading, setLoading] = useState(false)
const [dataSource, setDataSource] = useState([])
const [columns, setColumns] = useState([])
const [inputValue, setInputValue] = useState(
"SELECT * FROM 'https://shell.duckdb.org/data/tpch/0_01/parquet/orders.parquet' LIMIT 10",
)
const myHtmlContent = '<h1>Hello, World!</h1><p>This is some HTML content.</p>';
const [errorText, setErrorText] = useState('')
const highlightCode = hljs.highlight(inputValue, { language: 'sql' }).value
async function duckdbSearch() {
const sql = inputValue
try {
// 基于浏览器选择bundle
const JSDELIVR_BUNDLES = duckdb.getJsDelivrBundles()
const bundle = await duckdb.selectBundle(JSDELIVR_BUNDLES)
const worker_url = URL.createObjectURL(
new Blob([`importScripts("${bundle.mainWorker}");`], {
type: 'text/javascript',
}),
)
// 实例化异步DuckDB-wasm
const worker = new Worker(worker_url)
const logger = new duckdb.ConsoleLogger()
const db = new duckdb.AsyncDuckDB(logger, worker)
await db.instantiate(bundle.mainModule, bundle.pthreadWorker)
// 连接,查询
const conn = await db.connect()
let res = await conn.query(sql)
// 处理返回数据格式
if (res.numCols && res.numRows) {
const items = JSON.parse(JSON.stringify(res.toArray()))
console.log('items', items)
const col = Object.keys(items[0]).map((key) => {
return {
title: key,
dataIndex: key,
key: key,
width: `${100 / res.numCols}%`,
}
})
const data = items.map((item, index) => {
return {
...item,
key: index,
}
})
setColumns(col)
setDataSource(data)
console.log('---------col', col)
}
setLoading(false)
// 关闭连接
URL.revokeObjectURL(worker_url)
await conn.close()
await db.terminate()
await worker.terminate()
} catch (error) {
setLoading(false)
setErrorText(error.toString())
}
}
return (
<div>
<Card title="Card" size="small">
<Space
direction="vertical"
size="middle"
style={{
display: 'flex',
}}
>
<span>{highlightCode}</span>
<pre><code className="language-sql">{inputValue}</code></pre>
<pre dangerouslySetInnerHTML={{__html: highlightCode}}></pre>
{/* <Highlight languageName="sql" style={{whiteSpace:'pre-wrap'}}>{inputValue} </Highlight> */}
<TextArea
size='large'
defaultValue="default"
placeholder="在此处键入sql语句"
autoSize
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
>
</TextArea>
{/* <textarea value={inputValue}></textarea> */}
<Button
type="primary"
loading={loading}
onClick={() => {
setLoading(true)
duckdbSearch()
}}
>
{'> '}Execute
</Button>
<Spin spinning={loading}>
{!errorText && (
<Table
dataSource={dataSource}
columns={columns}
bordered
pagination={false}
scroll={{
y: 300,
}}
/>
)}
{errorText && (
<Alert
message="Error"
description={errorText}
type="error"
showIcon
/>
)}
</Spin>
</Space>
</Card>
</div>
)
}
export default App