docs(duckdb-wasm|drizzle-duckdb-wasm): added documentations and descriptions

This commit is contained in:
Neko Ayaka
2025-02-18 13:16:06 +08:00
parent 0acbe49836
commit 31b1710e34
6 changed files with 91 additions and 81 deletions
+31 -27
View File
@@ -41,42 +41,42 @@ export const users = pgTable('users', () => ({
drizzle-kit generate
```
```vue
```html
<!-- ./src/App.vue -->
<script setup lang="ts">
import type { DuckDBWasmDrizzleDatabase } from '@proj-airi/drizzle-duckdb-wasm'
import type { DuckDBWasmDrizzleDatabase } from '@proj-airi/drizzle-duckdb-wasm'
import { drizzle } from '@proj-airi/drizzle-duckdb-wasm'
import { getImportUrlBundles } from '@proj-airi/drizzle-duckdb-wasm/bundles/import-url-browser'
import { useDebounceFn } from '@vueuse/core'
import { serialize } from 'superjson'
import { onMounted, onUnmounted, ref, watch } from 'vue'
import { drizzle } from '@proj-airi/drizzle-duckdb-wasm'
import { getImportUrlBundles } from '@proj-airi/drizzle-duckdb-wasm/bundles/import-url-browser'
import { useDebounceFn } from '@vueuse/core'
import { serialize } from 'superjson'
import { onMounted, onUnmounted, ref, watch } from 'vue'
import * as schema from './db/schema'
import { users } from './db/schema'
import migration1 from './drizzle/0000_cute_kulan_gath.sql?raw'
import * as schema from './db/schema'
import { users } from './db/schema'
import migration1 from './drizzle/0000_cute_kulan_gath.sql?raw'
const results = ref<any[]>([])
const results = ref<any[]>([])
onMounted(async () => {
// db.value = drizzle('duckdb-wasm://?bundles=import-url', { schema })
// db.value = drizzle({ connection: { bundles: getImportUrlBundles() } }, { schema })
onMounted(async () => {
// db.value = drizzle('duckdb-wasm://?bundles=import-url', { schema })
// db.value = drizzle({ connection: { bundles: getImportUrlBundles() } }, { schema })
await db.value?.execute(migration1)
results.value = await db.value?.execute('SELECT count(*)::INTEGER as v FROM generate_series(0, 100) t(v)')
console.log(results.value) // Output [{ v: 101 }]
await db.value?.execute(migration1)
results.value = await db.value?.execute('SELECT count(*)::INTEGER as v FROM generate_series(0, 100) t(v)')
console.log(results.value) // Output [{ v: 101 }]
await db.value.insert(users).values({ id: '00000000-0000-0000-0000-000000000000' })
const foundUsers = await db.value.select().from(users)
console.log(foundUsers) // Output [{ id: '00000000-0000-0000-0000-000000000000' }]
})
await db.value.insert(users).values({ id: '00000000-0000-0000-0000-000000000000' })
const foundUsers = await db.value.select().from(users)
console.log(foundUsers) // Output [{ id: '00000000-0000-0000-0000-000000000000' }]
})
onUnmounted(async () => {
if (db.value) {
const client = await db.value.$client
await client.close()
}
})
onUnmounted(async () => {
if (db.value) {
const client = await db.value.$client
await client.close()
}
})
</script>
```
@@ -133,3 +133,7 @@ async function main() {
await client.close()
}
```
## Footnotes
Check out [the package](https://github.com/moeru-ai/airi/tree/main/packages/duckdb-wasm/README.md) we made for easier call to `@duckdb/duckdb-wasm` as well!
+12 -37
View File
@@ -1,9 +1,8 @@
import type { DuckDBWasmClient } from '@proj-airi/duckdb-wasm'
import type { Schema, StructRow } from 'apache-arrow'
import type { Assume, Logger, Query, RelationalSchemaConfig, TablesRelationalConfig } from 'drizzle-orm'
import type { PgDialect, PgQueryResultHKT, PgTransactionConfig, PreparedQueryConfig, SelectedFieldsOrdered } from 'drizzle-orm/pg-core'
import { beginTransaction, mapColumnData, withSavepoint } from '@proj-airi/duckdb-wasm'
import { beginTransaction, withSavepoint } from '@proj-airi/duckdb-wasm'
import { entityKind, fillPlaceholders, NoopLogger } from 'drizzle-orm'
import { PgPreparedQuery, PgSession, PgTransaction } from 'drizzle-orm/pg-core'
@@ -11,36 +10,6 @@ export type Row = Record<string, any>
export type RowList<T extends Row[]> = T
function toJSRepresentedRows<T extends { toArray: () => StructRow[], schema: Schema }>(results: T) {
const rows = (results.toArray() as StructRow[] || []).map(item => item.toJSON()) || []
const jsRepresentedRows = rows.map((row) => {
results.schema.fields.forEach((field) => {
return row[field.name] = mapColumnData(row[field.name], field)
})
return row
})
return jsRepresentedRows
}
async function callQuery(client: Promise<DuckDBWasmClient>, query: string, params: unknown[]) {
const c = await client
if (!params || params.length === 0) {
const results = await c.conn.query(query)
return toJSRepresentedRows(results)
}
const stmt = await c.conn.prepare(query)
const results = await stmt.query(...params)
const rows = toJSRepresentedRows(results)
stmt.close()
return rows
}
export class DuckDBWASMPreparedQuery<T extends PreparedQueryConfig> extends PgPreparedQuery<T> {
static override readonly [entityKind]: string = 'DuckDBWasmPreparedQuery'
@@ -60,17 +29,21 @@ export class DuckDBWASMPreparedQuery<T extends PreparedQueryConfig> extends PgPr
this.logger.logQuery(this.queryString, params)
const { fields, queryString: query, client, customResultMapper } = this
const c = await client
if (!fields && !customResultMapper) {
return callQuery(client, query, params)
return c.query(query, params)
}
return callQuery(client, query, params)
return c.query(query, params)
}
async all(placeholderValues: Record<string, unknown> | undefined = {}): Promise<T['all']> {
const params = fillPlaceholders(this.params, placeholderValues)
this.logger.logQuery(this.queryString, params)
return callQuery(this.client, this.queryString, params)
const c = await this.client
return c.query(this.queryString, params)
}
}
@@ -116,7 +89,8 @@ export class DuckDBWasmSession<
async query(query: string, params: unknown[]): Promise<RowList<Row[]>> {
this.logger.logQuery(query, params)
return callQuery(this.client, query, params)
const c = await this.client
return c.query(query, params)
}
async queryObjects<T extends Row>(
@@ -124,7 +98,8 @@ export class DuckDBWasmSession<
params: unknown[],
): Promise<RowList<T[]>> {
this.logger.logQuery(query, params)
return callQuery(this.client, query, params) as Promise<RowList<T[]>>
const c = await this.client
return c.query(query, params) as Promise<RowList<T[]>>
}
override transaction<T>(
+18 -14
View File
@@ -17,25 +17,25 @@ npm i @proj-airi/duckdb-wasm -D
### Browser
```vue
```html
<script setup lang="ts">
import type { DuckDBWasmClient } from '@proj-airi/duckdb-wasm'
import type { DuckDBWasmClient } from '@proj-airi/duckdb-wasm'
import { connect, getEnvironment } from '@proj-airi/duckdb-wasm'
import { getImportUrlBundles } from '@proj-airi/duckdb-wasm/bundles/import-url-browser'
import { onMounted, onUnmounted, ref } from 'vue'
import { connect, getEnvironment } from '@proj-airi/duckdb-wasm'
import { getImportUrlBundles } from '@proj-airi/duckdb-wasm/bundles/import-url-browser'
import { onMounted, onUnmounted, ref } from 'vue'
const db = ref<DuckDBWasmClient>()
const db = ref<DuckDBWasmClient>()
onMounted(async () => {
db.value = await connect({ bundles: getImportUrlBundles })
const result = await db.value.conn.query('SELECT 1 + 1 AS res')
console.log(result) // Output: [{ res: 2 }]
})
onMounted(async () => {
db.value = await connect({ bundles: getImportUrlBundles })
const result = await db.value.conn.query('SELECT 1 + 1 AS res')
console.log(result) // Output: [{ res: 2 }]
})
onUnmounted(() => {
db.value?.close()
})
onUnmounted(() => {
db.value?.close()
})
</script>
```
@@ -62,3 +62,7 @@ async function main() {
await close()
}
```
## Footnotes
Check out the [Drizzle ORM driver](https://github.com/moeru-ai/airi/blob/main/packages/drizzle-duckdb-wasm/README.md) we made for `@duckdb/duckdb-wasm` as welL!
-2
View File
@@ -36,6 +36,4 @@ export async function getEnvironment() {
catch {
return 'unknown'
}
return 'unknown'
}
+15
View File
@@ -4,6 +4,7 @@ import { AsyncDuckDB, ConsoleLogger, selectBundle, VoidLogger } from '@duckdb/du
import { defu } from 'defu'
import { getEnvironment } from './common'
import { mapStructRowData } from './format'
export type ConnectOptions = ConnectRequiredOptions & ConnectOptionalOptions
@@ -21,6 +22,7 @@ export interface DuckDBWasmClient {
db: AsyncDuckDB
conn: AsyncDuckDBConnection
close: () => Promise<void>
query: (string, params?: unknown[]) => Promise<Record<string, unknown>[]>
}
export async function connect(options: ConnectOptions): Promise<DuckDBWasmClient> {
@@ -79,6 +81,19 @@ export async function connect(options: ConnectOptions): Promise<DuckDBWasmClient
worker,
db,
conn,
query: async (query: string, params: unknown[] = []) => {
if (!params || params.length === 0) {
const results = await conn.query(query)
return mapStructRowData(results)
}
const stmt = await conn.prepare(query)
const results = await stmt.query(...params)
const rows = mapStructRowData(results)
stmt.close()
return rows
},
close: async () => {
await conn.close()
await db.terminate()
+15 -1
View File
@@ -1,5 +1,5 @@
import type { TZDate } from '@date-fns/tz'
import type { Field, StructRow } from 'apache-arrow'
import type { Field, Schema, StructRow } from 'apache-arrow'
import type { DataType } from './types'
import { TZDateMini } from '@date-fns/tz'
@@ -605,3 +605,17 @@ export function mapColumnData<T = unknown>(x: DataType, field?: Field): T {
return String(x) as T
}
export function mapStructRowData<T extends { toArray: () => StructRow[], schema: Schema }>(results: T) {
const rows = (results.toArray() as StructRow[] || []).map(item => item.toJSON()) || []
const jsRepresentedRows = rows.map((row) => {
results.schema.fields.forEach((field) => {
return row[field.name] = mapColumnData(row[field.name], field)
})
return row
})
return jsRepresentedRows
}