Skip to content

Commit

Permalink
fix: don't process delete PKs if norows were affected (#621)
Browse files Browse the repository at this point in the history
  • Loading branch information
fergusean authored Jan 26, 2025
1 parent 52fb570 commit f2f6ed0
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 3 deletions.
9 changes: 6 additions & 3 deletions packages/mysql/src/mysql-adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -427,9 +427,12 @@ export class MySQLQueryResolver<T extends OrmEntity> extends SQLQueryResolver<T>
`;

const rows = await connection.execAndReturnAll(sql, select.params);
const returning = rows[1];
const pk = returning[0]['@_pk'];
if (pk) deleteResult.primaryKeys = JSON.parse(pk).map(primaryKeyConverted);
const affectedRows = rows[0].affectedRows;
if (affectedRows) {
const returning = rows[1];
const pk = returning[0]['@_pk'];
deleteResult.primaryKeys = JSON.parse(pk).map(primaryKeyConverted);
}
deleteResult.modified = deleteResult.primaryKeys.length;
} catch (error: any) {
error = new DatabaseDeleteError(this.classSchema, 'Could not delete in database', { cause: error });
Expand Down
40 changes: 40 additions & 0 deletions packages/mysql/tests/mysql.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -344,3 +344,43 @@ test('non-object null unions should not render as JSON', async () => {
{name: 'Thomas', nickName: 'Tom', birthdate: new Date('1960-02-10T00:00:00Z')},
]);
});

test('updates & deletes should ignore previous @_pk session variable if no rows were affected', async () => {
@entity.name('model7')
class Model {
id: number & PrimaryKey & AutoIncrement = 0;

constructor(public name: string) {}
}

const database = await databaseFactory([Model]);
const model = new Model('Peter');
await database.persist(model);
expect(model.id).toEqual(expect.any(Number));

// perform update & delete in single database connection to ensure @_pk session variable is shared
// between multiple queries. outside a transaction, this is luck of the draw based on connection pooling.
await database.transaction(async txn => {
{
const result = await txn.query(Model).filter({id: model.id}).patchMany({name: 'Paul'});
expect(result.primaryKeys[0]).toEqual({ id: model.id });
}

{
const result = await txn.query(Model).filter({id: model.id}).deleteMany();
expect(result.primaryKeys[0]).toEqual({ id: model.id });
}

// there should be no ID returned if we try to update a non-existent record
{
const result = await txn.query(Model).filter({id: model.id}).patchMany({name: 'Simon'});
expect(result.primaryKeys[0]).toBeUndefined();
}

// there should be no ID returned if we try to delete a non-existent record
{
const result = await txn.query(Model).filter({id: model.id}).deleteMany();
expect(result.primaryKeys[0]).toBeUndefined();
}
});
});

0 comments on commit f2f6ed0

Please sign in to comment.