Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add numInsertedOrUpdatedRows to InsertResult. #188

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions src/dialect/mysql/mysql-driver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,17 +121,21 @@ class MysqlConnection implements DatabaseConnection {
if (isOkPacket(result)) {
const { insertId, affectedRows } = result

const numAffectedRows =
affectedRows !== undefined && affectedRows !== null
? BigInt(affectedRows)
: undefined

return {
insertId:
insertId !== undefined &&
insertId !== null &&
insertId.toString() !== '0'
? BigInt(insertId)
: undefined,
numUpdatedOrDeletedRows:
affectedRows !== undefined && insertId !== null
igalklebanov marked this conversation as resolved.
Show resolved Hide resolved
? BigInt(affectedRows)
: undefined,
// TODO: remove.
numUpdatedOrDeletedRows: numAffectedRows,
numAffectedRows,
rows: [],
}
} else if (Array.isArray(result)) {
Expand Down
12 changes: 10 additions & 2 deletions src/dialect/postgres/postgres-driver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,17 @@ class PostgresConnection implements DatabaseConnection {
...compiledQuery.parameters,
])

if (result.command === 'UPDATE' || result.command === 'DELETE') {
if (
result.command === 'INSERT' ||
result.command === 'UPDATE' ||
result.command === 'DELETE'
) {
const numAffectedRows = BigInt(result.rowCount)

return {
numUpdatedOrDeletedRows: BigInt(result.rowCount),
// TODO: remove.
numUpdatedOrDeletedRows: numAffectedRows,
numAffectedRows,
rows: result.rows ?? [],
}
}
Expand Down
10 changes: 6 additions & 4 deletions src/dialect/sqlite/sqlite-driver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,13 @@ class SqliteConnection implements DatabaseConnection {
} else {
const { changes, lastInsertRowid } = stmt.run(parameters)

const numAffectedRows =
changes !== undefined && changes !== null ? BigInt(changes) : undefined

return Promise.resolve({
numUpdatedOrDeletedRows:
changes !== undefined && changes !== null
? BigInt(changes)
: undefined,
// TODO: remove.
numUpdatedOrDeletedRows: numAffectedRows,
numAffectedRows,
insertId:
lastInsertRowid !== undefined && lastInsertRowid !== null
? BigInt(lastInsertRowid)
Expand Down
10 changes: 8 additions & 2 deletions src/driver/database-connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,17 @@ export interface DatabaseConnection {

export interface QueryResult<O> {
/**
* This is defined for update and delete queries and contains
* the number of rows the query updated/deleted.
* @deprecated use {@link QueryResult.numAffectedRows} instead.
*/
// TODO: remove.
readonly numUpdatedOrDeletedRows?: bigint

/**
* This is defined for insert, update and delete queries and contains
* the number of rows the query inserted/updated/deleted.
*/
readonly numAffectedRows?: bigint

/**
* This is defined for insert queries on dialects that return
* the auto incrementing primary key from an insert.
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ export {
UnknownRow,
} from './util/type-utils.js'
export * from './util/infer-result.js'
export { logOnce } from './util/log-once.js'

export {
SelectExpression,
Expand Down
9 changes: 7 additions & 2 deletions src/query-builder/delete-query-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -608,9 +608,14 @@ export class DeleteQueryBuilder<DB, TB extends keyof DB, O>

if (this.#props.executor.adapter.supportsReturning && query.returning) {
return result.rows
} else {
return [new DeleteResult(result.numUpdatedOrDeletedRows!) as unknown as O]
}

return [
new DeleteResult(
// TODO: remove numUpdatedOrDeletedRows.
(result.numAffectedRows ?? result.numUpdatedOrDeletedRows)!
) as any,
]
}

/**
Expand Down
10 changes: 8 additions & 2 deletions src/query-builder/insert-query-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -652,9 +652,15 @@ export class InsertQueryBuilder<DB, TB extends keyof DB, O>

if (this.#props.executor.adapter.supportsReturning && query.returning) {
return result.rows
} else {
return [new InsertResult(result.insertId) as unknown as O]
}

return [
new InsertResult(
result.insertId,
// TODO: remove numUpdatedOrDeletedRows.
result.numAffectedRows ?? result.numUpdatedOrDeletedRows
) as any,
]
}

/**
Expand Down
17 changes: 16 additions & 1 deletion src/query-builder/insert-result.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
* need to use {@link ReturningInterface.returning} or {@link ReturningInterface.returningAll}
* to get out the inserted id.
*
* {@link numInsertedOrUpdatedRows} holds the number of (actually) inserted rows.
* On MySQL, updated rows are counted twice when using `on duplicate key update`.
*
* ### Examples
*
* ```ts
Expand All @@ -20,9 +23,14 @@
*/
export class InsertResult {
readonly #insertId: bigint | undefined
readonly #numInsertedOrUpdatedRows: bigint | undefined

constructor(insertId: bigint | undefined) {
constructor(
insertId: bigint | undefined,
numInsertedOrUpdatedRows: bigint | undefined
) {
this.#insertId = insertId
this.#numInsertedOrUpdatedRows = numInsertedOrUpdatedRows
}

/**
Expand All @@ -31,4 +39,11 @@ export class InsertResult {
get insertId(): bigint | undefined {
return this.#insertId
}

/**
* Affected rows count.
*/
get numInsertedOrUpdatedRows(): bigint | undefined {
return this.#numInsertedOrUpdatedRows
}
}
9 changes: 7 additions & 2 deletions src/query-builder/update-query-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -704,9 +704,14 @@ export class UpdateQueryBuilder<DB, UT extends keyof DB, TB extends keyof DB, O>

if (this.#props.executor.adapter.supportsReturning && query.returning) {
return result.rows
} else {
return [new UpdateResult(result.numUpdatedOrDeletedRows!) as unknown as O]
}

return [
new UpdateResult(
// TODO: remove numUpdatedOrDeletedRows.
(result.numAffectedRows ?? result.numUpdatedOrDeletedRows)!
) as any,
]
}

/**
Expand Down
30 changes: 29 additions & 1 deletion src/query-executor/query-executor-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { QueryId } from '../util/query-id.js'
import { DialectAdapter } from '../dialect/dialect-adapter.js'
import { QueryExecutor } from './query-executor.js'
import { Deferred } from '../util/deferred.js'
import { logOnce } from '../util/log-once.js'

const NO_PLUGINS: ReadonlyArray<KyselyPlugin> = freeze([])

Expand Down Expand Up @@ -65,7 +66,13 @@ export abstract class QueryExecutorBase implements QueryExecutor {
): Promise<QueryResult<R>> {
return await this.provideConnection(async (connection) => {
const result = await connection.executeQuery(compiledQuery)
return this.#transformResult(result, queryId)

const transformedResult = await this.#transformResult(result, queryId)

// TODO: remove.
warnOfOutdatedDriverOrPlugins(result, transformedResult)

return transformedResult as any
})
}

Expand Down Expand Up @@ -118,3 +125,24 @@ export abstract class QueryExecutorBase implements QueryExecutor {
return result
}
}

// TODO: remove.
function warnOfOutdatedDriverOrPlugins(
result: QueryResult<unknown>,
transformedResult: QueryResult<unknown>
): void {
const { numAffectedRows } = result

if (
(numAffectedRows === undefined &&
result.numUpdatedOrDeletedRows === undefined) ||
(numAffectedRows !== undefined &&
transformedResult.numAffectedRows !== undefined)
) {
return
}

logOnce(
'kysely:warning: outdated driver/plugin detected! QueryResult.numUpdatedOrDeletedRows is deprecated and will be removed in a future release.'
)
}
14 changes: 14 additions & 0 deletions src/util/log-once.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const LOGGED_MESSAGES: Set<string> = new Set()

/**
* Use for system-level logging, such as deprecation messages.
* Logs a message and ensures it won't be logged again.
*/
export function logOnce(message: string): void {
if (LOGGED_MESSAGES.has(message)) {
return
}

LOGGED_MESSAGES.add(message)
console.log(message)
}
5 changes: 4 additions & 1 deletion test/node/src/delete.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,10 @@ for (const dialect of BUILT_IN_DIALECTS) {
sqlite: NOT_SUPPORTED,
})

await query.execute()
const result = await query.executeTakeFirst()

expect(result).to.be.instanceOf(DeleteResult)
expect(result.numDeletedRows).to.equal(2n)
})
}

Expand Down
Loading