Skip to content

Commit 98dd794

Browse files
committed
executable.
apply executable @ select. test suite prep. ?? best bench results. ... update qb. merge qb. insert qb. delete qb. kysely. raw builder. fix regression in takeFirst. more core. abort. ... ... ...
1 parent 22aa3f7 commit 98dd794

17 files changed

Lines changed: 442 additions & 218 deletions

src/driver/database-connection.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,21 @@
11
import { CompiledQuery } from '../query-compiler/compiled-query.js'
2+
import { ExecuteQueryOptions } from '../query-executor/query-executor.js'
23

34
/**
45
* A single connection to the database engine.
56
*
67
* These are created by an instance of {@link Driver}.
78
*/
89
export interface DatabaseConnection {
9-
executeQuery<R>(compiledQuery: CompiledQuery): Promise<QueryResult<R>>
10+
executeQuery<R>(
11+
compiledQuery: CompiledQuery,
12+
options?: ExecuteQueryOptions,
13+
): Promise<QueryResult<R>>
14+
1015
streamQuery<R>(
1116
compiledQuery: CompiledQuery,
12-
chunkSize?: number,
17+
chunkSize: number,
18+
options?: ExecuteQueryOptions,
1319
): AsyncIterableIterator<QueryResult<R>>
1420
}
1521

src/driver/runtime-driver.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,12 +167,13 @@ export class RuntimeDriver implements Driver {
167167

168168
connection.executeQuery = async (
169169
compiledQuery,
170+
options,
170171
): Promise<QueryResult<any>> => {
171172
let caughtError: unknown
172173
const startTime = performanceNow()
173174

174175
try {
175-
return await executeQuery.call(connection, compiledQuery)
176+
return await executeQuery.call(connection, compiledQuery, options)
176177
} catch (error) {
177178
caughtError = error
178179
await dis.#logError(error, compiledQuery, startTime)
@@ -187,6 +188,7 @@ export class RuntimeDriver implements Driver {
187188
connection.streamQuery = async function* (
188189
compiledQuery,
189190
chunkSize,
191+
options,
190192
): AsyncIterableIterator<QueryResult<any>> {
191193
let caughtError: unknown
192194
const startTime = performanceNow()
@@ -196,6 +198,7 @@ export class RuntimeDriver implements Driver {
196198
connection,
197199
compiledQuery,
198200
chunkSize,
201+
options,
199202
)) {
200203
yield result
201204
}

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ export * from './util/column-type.js'
224224
export * from './util/compilable.js'
225225
export * from './util/explainable.js'
226226
export * from './util/streamable.js'
227+
export * from './util/executable.js'
227228
export * from './util/log.js'
228229
export {
229230
AnyAliasedColumn,

src/kysely.ts

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ import { Dialect } from './dialect/dialect.js'
22
import { SchemaModule } from './schema/schema.js'
33
import { DynamicModule } from './dynamic/dynamic.js'
44
import { DefaultConnectionProvider } from './driver/default-connection-provider.js'
5-
import { QueryExecutor } from './query-executor/query-executor.js'
5+
import {
6+
ExecuteQueryOptions,
7+
QueryExecutor,
8+
} from './query-executor/query-executor.js'
69
import { QueryCreator, QueryCreatorProps } from './query-creator.js'
710
import { KyselyPlugin } from './plugin/kysely-plugin.js'
811
import { DefaultQueryExecutor } from './query-executor/default-query-executor.js'
@@ -48,7 +51,7 @@ import {
4851
provideControlledConnection,
4952
} from './util/provide-controlled-connection.js'
5053
import { ConnectionProvider } from './driver/connection-provider.js'
51-
import { logOnce } from './util/log-once.js'
54+
import { ExecuteOptions } from './util/executable.js'
5255

5356
// @ts-ignore
5457
Symbol.asyncDispose ??= Symbol('Symbol.asyncDispose')
@@ -538,20 +541,13 @@ export class Kysely<DB>
538541
*
539542
* See {@link https://github.com/kysely-org/kysely/blob/master/site/docs/recipes/0004-splitting-query-building-and-execution.md#execute-compiled-queries splitting build, compile and execute code recipe} for more information.
540543
*/
541-
executeQuery<R>(
544+
async executeQuery<R>(
542545
query: CompiledQuery<R> | Compilable<R>,
543-
// TODO: remove this in the future. deprecated in 0.28.x
544-
queryId?: QueryId,
546+
options?: ExecuteOptions,
545547
): Promise<QueryResult<R>> {
546-
if (queryId !== undefined) {
547-
logOnce(
548-
'Passing `queryId` in `db.executeQuery` is deprecated and will result in a compile-time error in the future.',
549-
)
550-
}
551-
552548
const compiledQuery = isCompilable(query) ? query.compile() : query
553549

554-
return this.getExecutor().executeQuery<R>(compiledQuery)
550+
return await this.getExecutor().executeQuery<R>(compiledQuery, options)
555551
}
556552

557553
async [Symbol.asyncDispose]() {
@@ -1177,17 +1173,21 @@ class NotCommittedOrRolledBackAssertingExecutor implements QueryExecutor {
11771173
return this.#executor.provideConnection(consumer)
11781174
}
11791175

1180-
executeQuery<R>(compiledQuery: CompiledQuery<R>): Promise<QueryResult<R>> {
1176+
executeQuery<R>(
1177+
compiledQuery: CompiledQuery<R>,
1178+
options?: ExecuteQueryOptions,
1179+
): Promise<QueryResult<R>> {
11811180
assertNotCommittedOrRolledBack(this.#state)
1182-
return this.#executor.executeQuery(compiledQuery)
1181+
return this.#executor.executeQuery(compiledQuery, options)
11831182
}
11841183

11851184
stream<R>(
11861185
compiledQuery: CompiledQuery<R>,
11871186
chunkSize: number,
1187+
options?: ExecuteQueryOptions,
11881188
): AsyncIterableIterator<QueryResult<R>> {
11891189
assertNotCommittedOrRolledBack(this.#state)
1190-
return this.#executor.stream(compiledQuery, chunkSize)
1190+
return this.#executor.stream(compiledQuery, chunkSize, options)
11911191
}
11921192

11931193
withConnectionProvider(

src/query-builder/delete-query-builder.ts

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,7 @@ import { freeze } from '../util/object-utils.js'
4242
import { KyselyPlugin } from '../plugin/kysely-plugin.js'
4343
import { WhereInterface } from './where-interface.js'
4444
import { MultiTableReturningInterface } from './returning-interface.js'
45-
import {
46-
isNoResultErrorConstructor,
47-
NoResultError,
48-
NoResultErrorConstructor,
49-
} from './no-result-error.js'
45+
import { isNoResultErrorConstructor, NoResultError } from './no-result-error.js'
5046
import { DeleteResult } from './delete-result.js'
5147
import { DeleteQueryNode } from '../operation-node/delete-query-node.js'
5248
import { LimitNode } from '../operation-node/limit-node.js'
@@ -81,6 +77,11 @@ import {
8177
} from './output-interface.js'
8278
import { JoinType } from '../operation-node/join-node.js'
8379
import { OrderByInterface } from './order-by-interface.js'
80+
import {
81+
Executable,
82+
ExecuteOptions,
83+
ExecuteOrThrowOptions,
84+
} from '../util/executable.js'
8485

8586
export class DeleteQueryBuilder<DB, TB extends keyof DB, O>
8687
implements
@@ -90,6 +91,7 @@ export class DeleteQueryBuilder<DB, TB extends keyof DB, O>
9091
OrderByInterface<DB, TB, {}>,
9192
OperationNodeSource,
9293
Compilable<O>,
94+
Executable<O>,
9395
Explainable,
9496
Streamable<O>
9597
{
@@ -1051,15 +1053,13 @@ export class DeleteQueryBuilder<DB, TB extends keyof DB, O>
10511053
)
10521054
}
10531055

1054-
/**
1055-
* Executes the query and returns an array of rows.
1056-
*
1057-
* Also see the {@link executeTakeFirst} and {@link executeTakeFirstOrThrow} methods.
1058-
*/
1059-
async execute(): Promise<SimplifyResult<O>[]> {
1056+
async execute(options?: ExecuteOptions): Promise<SimplifyResult<O>[]> {
10601057
const compiledQuery = this.compile()
10611058

1062-
const result = await this.#props.executor.executeQuery<O>(compiledQuery)
1059+
const result = await this.#props.executor.executeQuery<O>(
1060+
compiledQuery,
1061+
options,
1062+
)
10631063

10641064
const { adapter } = this.#props.executor
10651065
const query = compiledQuery.query as DeleteQueryNode
@@ -1068,45 +1068,45 @@ export class DeleteQueryBuilder<DB, TB extends keyof DB, O>
10681068
(query.returning && adapter.supportsReturning) ||
10691069
(query.output && adapter.supportsOutput)
10701070
) {
1071-
return result.rows as any
1071+
return result.rows as never
10721072
}
10731073

1074-
return [new DeleteResult(result.numAffectedRows ?? BigInt(0)) as any]
1074+
return [new DeleteResult(result.numAffectedRows ?? BigInt(0)) as never]
10751075
}
10761076

1077-
/**
1078-
* Executes the query and returns the first result or undefined if
1079-
* the query returned no result.
1080-
*/
1081-
async executeTakeFirst(): Promise<SimplifySingleResult<O>> {
1082-
const [result] = await this.execute()
1083-
return result as SimplifySingleResult<O>
1077+
async executeTakeFirst(
1078+
options?: ExecuteOptions,
1079+
): Promise<SimplifySingleResult<O>> {
1080+
const [result] = await this.execute(options)
1081+
1082+
return result
10841083
}
10851084

1086-
/**
1087-
* Executes the query and returns the first result or throws if
1088-
* the query returned no result.
1089-
*
1090-
* By default an instance of {@link NoResultError} is thrown, but you can
1091-
* provide a custom error class, or callback as the only argument to throw a different
1092-
* error.
1093-
*/
10941085
async executeTakeFirstOrThrow(
1095-
errorConstructor:
1096-
| NoResultErrorConstructor
1097-
| ((node: QueryNode) => Error) = NoResultError,
1086+
errorConstructorOrOptions?:
1087+
| ExecuteOrThrowOptions
1088+
| ExecuteOrThrowOptions['errorConstructor'],
10981089
): Promise<SimplifyResult<O>> {
1099-
const result = await this.executeTakeFirst()
1090+
if (typeof errorConstructorOrOptions === 'function') {
1091+
errorConstructorOrOptions = {
1092+
errorConstructor: errorConstructorOrOptions,
1093+
}
1094+
}
1095+
1096+
const result = await this.executeTakeFirst(errorConstructorOrOptions)
11001097

11011098
if (result === undefined) {
1099+
const errorConstructor =
1100+
errorConstructorOrOptions?.errorConstructor ?? NoResultError
1101+
11021102
const error = isNoResultErrorConstructor(errorConstructor)
11031103
? new errorConstructor(this.toOperationNode())
11041104
: errorConstructor(this.toOperationNode())
11051105

11061106
throw error
11071107
}
11081108

1109-
return result as SimplifyResult<O>
1109+
return result as never
11101110
}
11111111

11121112
async *stream(chunkSize: number = 100): AsyncIterableIterator<O> {

src/query-builder/insert-query-builder.ts

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,7 @@ import {
3434
ReturningCallbackRow,
3535
ReturningRow,
3636
} from '../parser/returning-parser.js'
37-
import {
38-
isNoResultErrorConstructor,
39-
NoResultError,
40-
NoResultErrorConstructor,
41-
} from './no-result-error.js'
37+
import { isNoResultErrorConstructor, NoResultError } from './no-result-error.js'
4238
import {
4339
ExpressionOrFactory,
4440
parseExpression,
@@ -67,13 +63,19 @@ import {
6763
SelectExpressionFromOutputExpression,
6864
} from './output-interface.js'
6965
import { OrActionNode } from '../operation-node/or-action-node.js'
66+
import {
67+
Executable,
68+
ExecuteOptions,
69+
ExecuteOrThrowOptions,
70+
} from '../util/executable.js'
7071

7172
export class InsertQueryBuilder<DB, TB extends keyof DB, O>
7273
implements
7374
ReturningInterface<DB, TB, O>,
7475
OutputInterface<DB, TB, O, 'inserted'>,
7576
OperationNodeSource,
7677
Compilable<O>,
78+
Executable<O>,
7779
Explainable,
7880
Streamable<O>
7981
{
@@ -1284,15 +1286,13 @@ export class InsertQueryBuilder<DB, TB extends keyof DB, O>
12841286
)
12851287
}
12861288

1287-
/**
1288-
* Executes the query and returns an array of rows.
1289-
*
1290-
* Also see the {@link executeTakeFirst} and {@link executeTakeFirstOrThrow} methods.
1291-
*/
1292-
async execute(): Promise<SimplifyResult<O>[]> {
1289+
async execute(options?: ExecuteOptions): Promise<SimplifyResult<O>[]> {
12931290
const compiledQuery = this.compile()
12941291

1295-
const result = await this.#props.executor.executeQuery<O>(compiledQuery)
1292+
const result = await this.#props.executor.executeQuery<O>(
1293+
compiledQuery,
1294+
options,
1295+
)
12961296

12971297
const { adapter } = this.#props.executor
12981298
const query = compiledQuery.query as InsertQueryNode
@@ -1301,50 +1301,50 @@ export class InsertQueryBuilder<DB, TB extends keyof DB, O>
13011301
(query.returning && adapter.supportsReturning) ||
13021302
(query.output && adapter.supportsOutput)
13031303
) {
1304-
return result.rows as any
1304+
return result.rows as never
13051305
}
13061306

13071307
return [
13081308
new InsertResult(
13091309
result.insertId,
13101310
result.numAffectedRows ?? BigInt(0),
1311-
) as any,
1311+
) as never,
13121312
]
13131313
}
13141314

1315-
/**
1316-
* Executes the query and returns the first result or undefined if
1317-
* the query returned no result.
1318-
*/
1319-
async executeTakeFirst(): Promise<SimplifySingleResult<O>> {
1320-
const [result] = await this.execute()
1321-
return result as SimplifySingleResult<O>
1315+
async executeTakeFirst(
1316+
options?: ExecuteOptions,
1317+
): Promise<SimplifySingleResult<O>> {
1318+
const [result] = await this.execute(options)
1319+
1320+
return result
13221321
}
13231322

1324-
/**
1325-
* Executes the query and returns the first result or throws if
1326-
* the query returned no result.
1327-
*
1328-
* By default an instance of {@link NoResultError} is thrown, but you can
1329-
* provide a custom error class, or callback as the only argument to throw a different
1330-
* error.
1331-
*/
13321323
async executeTakeFirstOrThrow(
1333-
errorConstructor:
1334-
| NoResultErrorConstructor
1335-
| ((node: QueryNode) => Error) = NoResultError,
1324+
errorConstructorOrOptions?:
1325+
| ExecuteOrThrowOptions
1326+
| ExecuteOrThrowOptions['errorConstructor'],
13361327
): Promise<SimplifyResult<O>> {
1337-
const result = await this.executeTakeFirst()
1328+
if (typeof errorConstructorOrOptions === 'function') {
1329+
errorConstructorOrOptions = {
1330+
errorConstructor: errorConstructorOrOptions,
1331+
}
1332+
}
1333+
1334+
const result = await this.executeTakeFirst(errorConstructorOrOptions)
13381335

13391336
if (result === undefined) {
1337+
const errorConstructor =
1338+
errorConstructorOrOptions?.errorConstructor ?? NoResultError
1339+
13401340
const error = isNoResultErrorConstructor(errorConstructor)
13411341
? new errorConstructor(this.toOperationNode())
13421342
: errorConstructor(this.toOperationNode())
13431343

13441344
throw error
13451345
}
13461346

1347-
return result as SimplifyResult<O>
1347+
return result as never
13481348
}
13491349

13501350
async *stream(chunkSize: number = 100): AsyncIterableIterator<O> {

0 commit comments

Comments
 (0)