Skip to content
This repository was archived by the owner on Mar 18, 2022. It is now read-only.

Commit 7808bba

Browse files
j6limpleerock
authored andcommitted
feat: UpdateResult returns affected rows in postgresql (typeorm#4432)
* Added 'affected' field in UpdateResult as well as in DeleteResult. * PostgresQueryRunner returns the number of affected rows properly * UpdateQueryBuilder retrieves the affected rows returned by PostgresQueryRunner and sets the added 'affected' field of UpdateResult properly. Closes: typeorm#1308
1 parent 7a0beed commit 7808bba

File tree

6 files changed

+137
-3
lines changed

6 files changed

+137
-3
lines changed

src/driver/postgres/PostgresQueryRunner.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,8 @@ export class PostgresQueryRunner extends BaseQueryRunner implements QueryRunner
179179
} else {
180180
switch (result.command) {
181181
case "DELETE":
182-
// for DELETE query additionally return number of affected rows
182+
case "UPDATE":
183+
// for UPDATE and DELETE query additionally return number of affected rows
183184
ok([result.rows, result.rowCount]);
184185
break;
185186
default:

src/query-builder/UpdateQueryBuilder.ts

+10-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,16 @@ export class UpdateQueryBuilder<Entity> extends QueryBuilder<Entity> implements
8383
// execute update query
8484
const [sql, parameters] = this.getQueryAndParameters();
8585
const updateResult = new UpdateResult();
86-
updateResult.raw = await queryRunner.query(sql, parameters);
86+
const result = await queryRunner.query(sql, parameters);
87+
88+
const driver = queryRunner.connection.driver;
89+
if (driver instanceof PostgresDriver) {
90+
updateResult.raw = result[0];
91+
updateResult.affected = result[1];
92+
}
93+
else {
94+
updateResult.raw = result;
95+
}
8796

8897
// if we are updating entities and entity updation is enabled we must update some of entity columns (like version, update date, etc.)
8998
if (this.expressionMap.updateEntity === true &&

src/query-builder/result/UpdateResult.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ export class UpdateResult {
1010
*/
1111
raw: any;
1212

13+
/**
14+
* Number of affected rows/documents
15+
* Not all drivers support this
16+
*/
17+
affected?: number;
18+
1319
/**
1420
* Contains inserted entity id.
1521
* Has entity-like structure (not just column database name and values).
@@ -22,4 +28,4 @@ export class UpdateResult {
2228
*/
2329
generatedMaps: ObjectLiteral[] = [];
2430

25-
}
31+
}
+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import {EntitySchemaOptions} from "../../../../src/entity-schema/EntitySchemaOptions";
2+
import {Post} from "./Post";
3+
4+
export class Author {
5+
id: number;
6+
7+
name: string;
8+
9+
posts: Post[];
10+
}
11+
12+
export const AuthorSchema: EntitySchemaOptions<Author> = {
13+
name: "Author",
14+
15+
target: Author,
16+
17+
columns: {
18+
id: {
19+
primary: true,
20+
type: Number
21+
},
22+
23+
name: {
24+
type: "varchar"
25+
}
26+
},
27+
28+
relations: {
29+
posts: {
30+
target: () => Post,
31+
type: "one-to-many"
32+
}
33+
}
34+
};
+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import {EntitySchemaOptions} from "../../../../src/entity-schema/EntitySchemaOptions";
2+
import {Author} from "./Author";
3+
4+
export class Post {
5+
id: number;
6+
7+
title: string;
8+
9+
author: Author;
10+
}
11+
12+
export const PostSchema: EntitySchemaOptions<Post> = {
13+
name: "Post",
14+
15+
target: Post,
16+
17+
columns: {
18+
id: {
19+
primary: true,
20+
type: Number
21+
},
22+
23+
title: {
24+
type: "varchar"
25+
}
26+
},
27+
28+
relations: {
29+
author: {
30+
target: () => Author,
31+
type: "many-to-one",
32+
eager: true
33+
}
34+
}
35+
};

test/github-issues/1308/issue-1308.ts

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { closeTestingConnections, createTestingConnections, reloadTestingDatabases } from "../../utils/test-utils";
2+
import { Connection } from "../../../src/connection/Connection";
3+
import { EntitySchema } from "../../../src";
4+
import { Author, AuthorSchema } from "./entity/Author";
5+
import { Post, PostSchema } from "./entity/Post";
6+
7+
describe("github issues > #1308 Raw Postgresql Update query result is always an empty array", () => {
8+
let connections: Connection[];
9+
before(
10+
async () =>
11+
(connections = await createTestingConnections({
12+
entities: [new EntitySchema<Author>(AuthorSchema), new EntitySchema<Post>(PostSchema)],
13+
dropSchema: true,
14+
enabledDrivers: ["postgres"],
15+
}))
16+
);
17+
beforeEach(() => reloadTestingDatabases(connections));
18+
after(() => closeTestingConnections(connections));
19+
20+
async function prepareData(connection: Connection) {
21+
const author = new Author();
22+
author.id = 1;
23+
author.name = "Jane Doe";
24+
await connection.manager.save(author);
25+
}
26+
27+
it("Update query returns the number of affected rows", () =>
28+
Promise.all(
29+
connections.map(async connection => {
30+
await prepareData(connection);
31+
32+
const result1 = await connection.createQueryBuilder()
33+
.update(Author)
34+
.set({ name: "John Doe" })
35+
.where("name = :name", { name: "Jonas Doe" })
36+
.execute();
37+
38+
result1.affected!.should.be.eql(0);
39+
40+
const result2 = await connection.createQueryBuilder()
41+
.update(Author)
42+
.set({ name: "John Doe" })
43+
.where("name = :name", { name: "Jane Doe" })
44+
.execute();
45+
46+
result2.affected!.should.be.eql(1);
47+
})
48+
));
49+
});

0 commit comments

Comments
 (0)