サンプルコード
DuckDB WASMアダプターの実践的なサンプルコード集です。
基本的なクエリ
シンプルなSELECT
javascript
import { createConnection } from '@northprint/duckdb-wasm-adapter-core';
const connection = await createConnection();
// テーブル作成
await connection.execute(`
CREATE TABLE users (
id INTEGER PRIMARY KEY,
name VARCHAR,
age INTEGER
)
`);
// データ挿入
await connection.execute(
'INSERT INTO users (id, name, age) VALUES (?, ?, ?)',
[1, '田中太郎', 30]
);
// データ取得
const result = await connection.execute('SELECT * FROM users');
console.log(result.toArray());React サンプル
基本的なコンポーネント
jsx
import { DuckDBProvider, useQuery } from '@northprint/duckdb-wasm-adapter-react';
function App() {
return (
<DuckDBProvider autoConnect>
<UserList />
</DuckDBProvider>
);
}
function UserList() {
const { data, loading, error } = useQuery('SELECT * FROM users');
if (loading) return <div>読み込み中...</div>;
if (error) return <div>エラー: {error.message}</div>;
return (
<ul>
{data?.map(user => (
<li key={user.id}>{user.name} ({user.age}歳)</li>
))}
</ul>
);
}データ入力フォーム
jsx
import { useMutation } from '@northprint/duckdb-wasm-adapter-react';
function AddUserForm() {
const { mutate, loading } = useMutation();
const handleSubmit = async (e) => {
e.preventDefault();
const formData = new FormData(e.target);
await mutate(
'INSERT INTO users (name, age) VALUES (?, ?)',
[formData.get('name'), Number(formData.get('age'))]
);
e.target.reset();
};
return (
<form onSubmit={handleSubmit}>
<input name="name" placeholder="名前" required />
<input name="age" type="number" placeholder="年齢" required />
<button type="submit" disabled={loading}>
{loading ? '追加中...' : '追加'}
</button>
</form>
);
}Vue サンプル
基本的なコンポーネント
vue
<template>
<div>
<h2>ユーザーリスト</h2>
<div v-if="loading">読み込み中...</div>
<ul v-else-if="data">
<li v-for="user in data" :key="user.id">
{{ user.name }} ({{ user.age }}歳)
</li>
</ul>
</div>
</template>
<script setup>
import { useQuery } from '@northprint/duckdb-wasm-adapter-vue';
const { data, loading, error } = useQuery('SELECT * FROM users');
</script>リアクティブ検索
vue
<template>
<div>
<input v-model="searchTerm" placeholder="検索...">
<ul v-if="data">
<li v-for="user in data" :key="user.id">
{{ user.name }}
</li>
</ul>
</div>
</template>
<script setup>
import { ref, computed } from 'vue';
import { useQuery } from '@northprint/duckdb-wasm-adapter-vue';
const searchTerm = ref('');
const query = computed(() =>
searchTerm.value
? `SELECT * FROM users WHERE name LIKE '%${searchTerm.value}%'`
: 'SELECT * FROM users'
);
const { data } = useQuery(query);
</script>Svelte サンプル
基本的なコンポーネント
svelte
<script>
import { createDuckDB } from '@northprint/duckdb-wasm-adapter-svelte';
const db = createDuckDB({ autoConnect: true });
$: users = db.query('SELECT * FROM users');
</script>
<h2>ユーザーリスト</h2>
{#if $users.loading}
<p>読み込み中...</p>
{:else if $users.data}
<ul>
{#each $users.data as user}
<li>{user.name} ({user.age}歳)</li>
{/each}
</ul>
{/if}インタラクティブなフィルター
svelte
<script>
import { createDuckDB } from '@northprint/duckdb-wasm-adapter-svelte';
const db = createDuckDB({ autoConnect: true });
let minAge = 0;
let maxAge = 100;
$: query = `
SELECT * FROM users
WHERE age >= ${minAge} AND age <= ${maxAge}
ORDER BY age
`;
$: users = db.query(query);
</script>
<div>
<label>
最小年齢: <input type="number" bind:value={minAge} min="0" max="100">
</label>
<label>
最大年齢: <input type="number" bind:value={maxAge} min="0" max="100">
</label>
</div>
{#if $users.data}
<ul>
{#each $users.data as user}
<li>{user.name} ({user.age}歳)</li>
{/each}
</ul>
{/if}データインポート/エクスポート
CSVインポート
javascript
// CSVファイルのインポート
const fileInput = document.querySelector('input[type="file"]');
const file = fileInput.files[0];
await connection.importCSV(file, 'sales_data', {
header: true,
delimiter: ','
});
// インポートしたデータを確認
const result = await connection.execute('SELECT COUNT(*) FROM sales_data');
console.log('インポートした行数:', result.toArray()[0].count);JSONエクスポート
javascript
// データをJSON形式でエクスポート
const data = await connection.exportJSON('SELECT * FROM users');
// ファイルとしてダウンロード
const blob = new Blob([JSON.stringify(data, null, 2)], {
type: 'application/json'
});
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'users.json';
a.click();クエリビルダー
動的なクエリ構築
javascript
import { QueryBuilder } from '@northprint/duckdb-wasm-adapter-core';
const builder = new QueryBuilder();
// 条件を動的に追加
builder
.select('id', 'name', 'age')
.from('users');
if (filters.name) {
builder.where('name', 'LIKE', `%${filters.name}%`);
}
if (filters.minAge) {
builder.where('age', '>=', filters.minAge);
}
builder.orderBy('name', 'ASC').limit(10);
// クエリを実行
const sql = builder.build();
const result = await connection.execute(sql);パフォーマンス最適化
バッチ処理
javascript
// トランザクションでバッチ処理
await connection.execute('BEGIN TRANSACTION');
try {
const users = [
{ name: '田中', age: 30 },
{ name: '佐藤', age: 25 },
{ name: '鈴木', age: 35 }
];
for (const user of users) {
await connection.execute(
'INSERT INTO users (name, age) VALUES (?, ?)',
[user.name, user.age]
);
}
await connection.execute('COMMIT');
console.log('バッチ処理完了');
} catch (error) {
await connection.execute('ROLLBACK');
console.error('エラー:', error);
}キャッシング
javascript
// キャッシュ付きクエリ
const result = await connection.execute(
'SELECT * FROM large_table',
undefined,
{
cache: true,
cacheKey: 'large-table-all',
cacheTTL: 60000 // 1分間キャッシュ
}
);
// 2回目は高速
const cachedResult = await connection.execute(
'SELECT * FROM large_table',
undefined,
{
cache: true,
cacheKey: 'large-table-all'
}
);エラーハンドリング
javascript
import { DuckDBError, ErrorCode } from '@northprint/duckdb-wasm-adapter-core';
try {
const result = await connection.execute('SELECT * FROM non_existent_table');
} catch (error) {
if (error instanceof DuckDBError) {
switch (error.code) {
case ErrorCode.TABLE_NOT_FOUND:
console.error('テーブルが見つかりません');
break;
case ErrorCode.QUERY_FAILED:
console.error('クエリ実行エラー:', error.message);
break;
default:
console.error('不明なエラー:', error);
}
}
}次のステップ
- APIリファレンス - 詳細なAPI仕様
- フレームワークガイド - フレームワーク別の詳細ガイド
- GitHub - ソースコードとより多くのサンプル