Skip to content

Commit 21b2a1b

Browse files
committed
...
1 parent 4a30094 commit 21b2a1b

File tree

3 files changed

+59
-13
lines changed

3 files changed

+59
-13
lines changed

src/dialect/mysql/mysql-dialect-config.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@ import { DatabaseConnection } from '../../driver/database-connection.js'
66
* https://github.com/sidorares/node-mysql2#using-connection-pools
77
*/
88
export interface MysqlDialectConfig {
9+
/**
10+
* The `mysql2` `createConnection` function or similar.
11+
*
12+
* TODO: ...
13+
*/
14+
createConnection?: (opts: any) => MysqlConnection | Promise<MysqlConnection>
15+
916
/**
1017
* A mysql2 Pool instance or a function that returns one.
1118
*
@@ -41,7 +48,9 @@ export interface MysqlPool {
4148
end(callback: (error: unknown) => void): void
4249
}
4350

44-
export interface MysqlPoolConnection {
51+
export interface MysqlConnection {
52+
config: unknown
53+
connect(callback?: (error: unknown) => void): void
4554
destroy(): void
4655
query(
4756
sql: string,
@@ -52,10 +61,15 @@ export interface MysqlPoolConnection {
5261
parameters: ReadonlyArray<unknown>,
5362
callback: (error: unknown, result: MysqlQueryResult) => void,
5463
): void
55-
release(): void
5664
threadId: number
5765
}
5866

67+
export type MysqlConectionConstructor = new (opts?: object) => MysqlConnection
68+
69+
export interface MysqlPoolConnection extends MysqlConnection {
70+
release(): void
71+
}
72+
5973
export interface MysqlStreamOptions {
6074
highWaterMark?: number
6175
objectMode?: boolean

src/dialect/mysql/mysql-driver.ts

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,10 @@ export class MysqlDriver implements Driver {
4242
let connection = this.#connections.get(rawConnection)
4343

4444
if (!connection) {
45-
connection = new MysqlConnection(rawConnection)
45+
connection = new MysqlConnection(
46+
rawConnection,
47+
this.#config.createConnection,
48+
)
4649
this.#connections.set(rawConnection, connection)
4750

4851
// The driver must take care of calling `onCreateConnection` when a new
@@ -165,9 +168,14 @@ function isOkPacket(obj: unknown): obj is MysqlOkPacket {
165168
}
166169

167170
class MysqlConnection implements DatabaseConnection {
171+
readonly #createConnection: MysqlDialectConfig['createConnection']
168172
readonly #rawConnection: MysqlPoolConnection
169173

170-
constructor(rawConnection: MysqlPoolConnection) {
174+
constructor(
175+
rawConnection: MysqlPoolConnection,
176+
createConnection: MysqlDialectConfig['createConnection'],
177+
) {
178+
this.#createConnection = createConnection
171179
this.#rawConnection = rawConnection
172180
}
173181

@@ -183,14 +191,38 @@ class MysqlConnection implements DatabaseConnection {
183191
// noop
184192
}
185193

194+
const { config, threadId } = this.#rawConnection
195+
196+
// this kills the query and the connection database-side.
197+
// we're not using `kill query <connection_id>` here because it doesn't
198+
// guarantee that the query is killed immediately. we saw that in tests,
199+
// the query can still run for a while after - including registering writes.
200+
const cancelQuery = `kill connection ${threadId}`
201+
202+
if (this.#createConnection && config) {
203+
const controlConnection = await this.#createConnection({ ...config })
204+
205+
return await new Promise((resolve, reject) => {
206+
controlConnection.connect((connectError) => {
207+
if (connectError) {
208+
return reject(connectError)
209+
}
210+
211+
controlConnection.query(cancelQuery, [], (error) => {
212+
controlConnection.destroy()
213+
214+
if (error) {
215+
return reject(error)
216+
}
217+
218+
resolve()
219+
})
220+
})
221+
})
222+
}
223+
186224
await controlConnectionProvider(async (controlConnection) => {
187-
// this kills the query and the connection database-side.
188-
// we're not using `kill query <connection_id>` here because it doesn't
189-
// guarantee that the query is killed immediately. we saw that in tests,
190-
// the query can still run for a while after - including registering writes.
191-
await controlConnection.executeQuery(
192-
CompiledQuery.raw('kill connection ?', [this.#rawConnection.threadId]),
193-
)
225+
await controlConnection.executeQuery(CompiledQuery.raw(cancelQuery, []))
194226
})
195227
}
196228

@@ -231,7 +263,6 @@ class MysqlConnection implements DatabaseConnection {
231263
async *streamQuery<O>(
232264
compiledQuery: CompiledQuery,
233265
_chunkSize: number,
234-
options?: QueryOptions,
235266
): AsyncIterableIterator<QueryResult<O>> {
236267
const stream = this.#rawConnection
237268
.query(compiledQuery.sql, compiledQuery.parameters)

test/node/src/test-setup.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import chaiAsPromised from 'chai-as-promised'
33
import * as chaiSubset from 'chai-subset'
44
import * as Cursor from 'pg-cursor'
55
import { Pool, PoolConfig } from 'pg'
6-
import { createPool } from 'mysql2'
6+
import { createConnection, createPool } from 'mysql2'
77
import * as Database from 'better-sqlite3'
88
import * as Tarn from 'tarn'
99
import * as Tedious from 'tedious'
@@ -182,6 +182,7 @@ export const DB_CONFIGS: PerDialect<KyselyConfig> = {
182182

183183
mysql: {
184184
dialect: new MysqlDialect({
185+
createConnection,
185186
pool: async () => createPool(DIALECT_CONFIGS.mysql),
186187
}),
187188
plugins: PLUGINS,

0 commit comments

Comments
 (0)