Skip to content

Commit

Permalink
feat: UpdateResult returns affected rows in postgresql (#4432)
Browse files Browse the repository at this point in the history
* 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: #1308
  • Loading branch information
j6lim authored and pleerock committed Sep 5, 2019
1 parent 7a0beed commit 7808bba
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 3 deletions.
3 changes: 2 additions & 1 deletion src/driver/postgres/PostgresQueryRunner.ts
Expand Up @@ -179,7 +179,8 @@ export class PostgresQueryRunner extends BaseQueryRunner implements QueryRunner
} else {
switch (result.command) {
case "DELETE":
// for DELETE query additionally return number of affected rows
case "UPDATE":
// for UPDATE and DELETE query additionally return number of affected rows
ok([result.rows, result.rowCount]);
break;
default:
Expand Down
11 changes: 10 additions & 1 deletion src/query-builder/UpdateQueryBuilder.ts
Expand Up @@ -83,7 +83,16 @@ export class UpdateQueryBuilder<Entity> extends QueryBuilder<Entity> implements
// execute update query
const [sql, parameters] = this.getQueryAndParameters();
const updateResult = new UpdateResult();
updateResult.raw = await queryRunner.query(sql, parameters);
const result = await queryRunner.query(sql, parameters);

const driver = queryRunner.connection.driver;
if (driver instanceof PostgresDriver) {
updateResult.raw = result[0];
updateResult.affected = result[1];
}
else {
updateResult.raw = result;
}

// if we are updating entities and entity updation is enabled we must update some of entity columns (like version, update date, etc.)
if (this.expressionMap.updateEntity === true &&
Expand Down
8 changes: 7 additions & 1 deletion src/query-builder/result/UpdateResult.ts
Expand Up @@ -10,6 +10,12 @@ export class UpdateResult {
*/
raw: any;

/**
* Number of affected rows/documents
* Not all drivers support this
*/
affected?: number;

/**
* Contains inserted entity id.
* Has entity-like structure (not just column database name and values).
Expand All @@ -22,4 +28,4 @@ export class UpdateResult {
*/
generatedMaps: ObjectLiteral[] = [];

}
}
34 changes: 34 additions & 0 deletions test/github-issues/1308/entity/Author.ts
@@ -0,0 +1,34 @@
import {EntitySchemaOptions} from "../../../../src/entity-schema/EntitySchemaOptions";
import {Post} from "./Post";

export class Author {
id: number;

name: string;

posts: Post[];
}

export const AuthorSchema: EntitySchemaOptions<Author> = {
name: "Author",

target: Author,

columns: {
id: {
primary: true,
type: Number
},

name: {
type: "varchar"
}
},

relations: {
posts: {
target: () => Post,
type: "one-to-many"
}
}
};
35 changes: 35 additions & 0 deletions test/github-issues/1308/entity/Post.ts
@@ -0,0 +1,35 @@
import {EntitySchemaOptions} from "../../../../src/entity-schema/EntitySchemaOptions";
import {Author} from "./Author";

export class Post {
id: number;

title: string;

author: Author;
}

export const PostSchema: EntitySchemaOptions<Post> = {
name: "Post",

target: Post,

columns: {
id: {
primary: true,
type: Number
},

title: {
type: "varchar"
}
},

relations: {
author: {
target: () => Author,
type: "many-to-one",
eager: true
}
}
};
49 changes: 49 additions & 0 deletions test/github-issues/1308/issue-1308.ts
@@ -0,0 +1,49 @@
import { closeTestingConnections, createTestingConnections, reloadTestingDatabases } from "../../utils/test-utils";
import { Connection } from "../../../src/connection/Connection";
import { EntitySchema } from "../../../src";
import { Author, AuthorSchema } from "./entity/Author";
import { Post, PostSchema } from "./entity/Post";

describe("github issues > #1308 Raw Postgresql Update query result is always an empty array", () => {
let connections: Connection[];
before(
async () =>
(connections = await createTestingConnections({
entities: [new EntitySchema<Author>(AuthorSchema), new EntitySchema<Post>(PostSchema)],
dropSchema: true,
enabledDrivers: ["postgres"],
}))
);
beforeEach(() => reloadTestingDatabases(connections));
after(() => closeTestingConnections(connections));

async function prepareData(connection: Connection) {
const author = new Author();
author.id = 1;
author.name = "Jane Doe";
await connection.manager.save(author);
}

it("Update query returns the number of affected rows", () =>
Promise.all(
connections.map(async connection => {
await prepareData(connection);

const result1 = await connection.createQueryBuilder()
.update(Author)
.set({ name: "John Doe" })
.where("name = :name", { name: "Jonas Doe" })
.execute();

result1.affected!.should.be.eql(0);

const result2 = await connection.createQueryBuilder()
.update(Author)
.set({ name: "John Doe" })
.where("name = :name", { name: "Jane Doe" })
.execute();

result2.affected!.should.be.eql(1);
})
));
});

0 comments on commit 7808bba

Please sign in to comment.