Skip to content

Commit

Permalink
add numInsertedOrUpdatedRows to InsertResult. (#188)
Browse files Browse the repository at this point in the history
* add numAffectedRows to InsertResult.

* update numUpdatedOrDeletedRows ts doc.

* update InsertQueryBuilder's execute().

* fix MysqlDriver not passing affected rows in result.

* make PostgresDriver pass row count in result of insert command.

* rename numAffectedRows to numInsertedOrUpdatedRows to align with others.

* add some result expectations @ node insert test.

* more node test stuff.

* add ts doc paragraph for numInsertedOrUpdatedRows.

* remove silly length assertion.

* add numUpdatedOrDeletedRows deprecation warning @ QueryExecutorBase.

* add numAffectedRows to QueryResult.

* add numAffectedRows (/w backwards compat) handling at builders.

* add numAffectedRows (/w backwards compat) handling @ dialect drivers.

* add logOnce helper fn.

* add logOnce unit test.

* nullish coalescing assignment not supported in node.js 14.
  • Loading branch information
igalklebanov authored Dec 10, 2022
1 parent 458b3c0 commit 606b001
Show file tree
Hide file tree
Showing 15 changed files with 301 additions and 43 deletions.
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
? 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

0 comments on commit 606b001

Please sign in to comment.