diff --git a/api/pkgs/@duckdb/node-api/README.md b/api/pkgs/@duckdb/node-api/README.md index 923d3b4..a0058d1 100644 --- a/api/pkgs/@duckdb/node-api/README.md +++ b/api/pkgs/@duckdb/node-api/README.md @@ -126,6 +126,20 @@ prepared.bind({ const result = await prepared.run(); ``` +or even: + +```ts +const result = await connection.run('select $a, $b, $c', { + 'a': 'duck', + 'b': 42, + 'c': listValue([10, 11, 12]), +}, { + 'a': VARCHAR, + 'b': INTEGER, + 'c': LIST(INTEGER), +}); +``` + ### Stream Results Streaming results evaluate lazily when rows are read. diff --git a/api/src/DuckDBConnection.ts b/api/src/DuckDBConnection.ts index 27aeb9e..226325a 100644 --- a/api/src/DuckDBConnection.ts +++ b/api/src/DuckDBConnection.ts @@ -3,10 +3,12 @@ import { DuckDBAppender } from './DuckDBAppender'; import { DuckDBExtractedStatements } from './DuckDBExtractedStatements'; import { DuckDBInstance } from './DuckDBInstance'; import { DuckDBMaterializedResult } from './DuckDBMaterializedResult'; +import { DuckDBPendingResult } from './DuckDBPendingResult'; import { DuckDBPreparedStatement } from './DuckDBPreparedStatement'; import { DuckDBResult } from './DuckDBResult'; import { DuckDBResultReader } from './DuckDBResultReader'; -import { DuckDBPendingResult } from './DuckDBPendingResult'; +import { DuckDBType } from './DuckDBType'; +import { DuckDBValue } from './values'; export class DuckDBConnection { private readonly connection: duckdb.Connection; @@ -31,45 +33,108 @@ export class DuckDBConnection { public get progress(): duckdb.QueryProgress { return duckdb.query_progress(this.connection); } - public async run(sql: string): Promise { - return new DuckDBMaterializedResult(await duckdb.query(this.connection, sql)); - } - public async runAndRead(sql: string): Promise { - return new DuckDBResultReader(await this.run(sql)); + public async run( + sql: string, + values?: DuckDBValue[] | Record, + types?: DuckDBType[] | Record + ): Promise { + if (values) { + const prepared = await this.prepare(sql); + prepared.bind(values, types); + return prepared.run(); + } else { + return new DuckDBMaterializedResult( + await duckdb.query(this.connection, sql) + ); + } } - public async runAndReadAll(sql: string): Promise { - const reader = new DuckDBResultReader(await this.run(sql)); + public async runAndRead( + sql: string, + values?: DuckDBValue[] | Record, + types?: DuckDBType[] | Record + ): Promise { + return new DuckDBResultReader(await this.run(sql, values, types)); + } + public async runAndReadAll( + sql: string, + values?: DuckDBValue[] | Record, + types?: DuckDBType[] | Record + ): Promise { + const reader = new DuckDBResultReader(await this.run(sql, values, types)); await reader.readAll(); return reader; } - public async runAndReadUntil(sql: string, targetRowCount: number): Promise { - const reader = new DuckDBResultReader(await this.run(sql)); + public async runAndReadUntil( + sql: string, + targetRowCount: number, + values?: DuckDBValue[] | Record, + types?: DuckDBType[] | Record + ): Promise { + const reader = new DuckDBResultReader(await this.run(sql, values, types)); await reader.readUntil(targetRowCount); return reader; } - public async stream(sql: string): Promise { + public async stream( + sql: string, + values?: DuckDBValue[] | Record, + types?: DuckDBType[] | Record + ): Promise { const prepared = await this.prepare(sql); + if (values) { + prepared.bind(values, types); + } return prepared.stream(); } - public async streamAndRead(sql: string): Promise { - return new DuckDBResultReader(await this.stream(sql)); - } - public async streamAndReadAll(sql: string): Promise { - const reader = new DuckDBResultReader(await this.stream(sql)); + public async streamAndRead( + sql: string, + values?: DuckDBValue[] | Record, + types?: DuckDBType[] | Record + ): Promise { + return new DuckDBResultReader(await this.stream(sql, values, types)); + } + public async streamAndReadAll( + sql: string, + values?: DuckDBValue[] | Record, + types?: DuckDBType[] | Record + ): Promise { + const reader = new DuckDBResultReader( + await this.stream(sql, values, types) + ); await reader.readAll(); return reader; } - public async streamAndReadUntil(sql: string, targetRowCount: number): Promise { - const reader = new DuckDBResultReader(await this.stream(sql)); + public async streamAndReadUntil( + sql: string, + targetRowCount: number, + values?: DuckDBValue[] | Record, + types?: DuckDBType[] | Record + ): Promise { + const reader = new DuckDBResultReader( + await this.stream(sql, values, types) + ); await reader.readUntil(targetRowCount); return reader; } - public async start(sql: string): Promise { + public async start( + sql: string, + values?: DuckDBValue[] | Record, + types?: DuckDBType[] | Record + ): Promise { const prepared = await this.prepare(sql); + if (values) { + prepared.bind(values, types); + } return prepared.start(); } - public async startStream(sql: string): Promise { + public async startStream( + sql: string, + values?: DuckDBValue[] | Record, + types?: DuckDBType[] | Record + ): Promise { const prepared = await this.prepare(sql); + if (values) { + prepared.bind(values, types); + } return prepared.startStream(); } public async prepare(sql: string): Promise {