Skip to content

Commit

Permalink
fix: create a different cacheId if present for count query in getMany…
Browse files Browse the repository at this point in the history
…AndCount (#8283)

Closes #4277
  • Loading branch information
eugenio165 committed Oct 21, 2021
1 parent 503d1dc commit 9f14e48
Show file tree
Hide file tree
Showing 3 changed files with 146 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/query-builder/SelectQueryBuilder.ts
Expand Up @@ -1199,6 +1199,10 @@ export class SelectQueryBuilder<Entity> extends QueryBuilder<Entity> implements
this.expressionMap.queryEntity = true;
const entitiesAndRaw = await this.executeEntitiesAndRawResults(queryRunner);
this.expressionMap.queryEntity = false;
const cacheId = this.expressionMap.cacheId;
// Creates a new cacheId for the count query, or it will retreive the above query results
// and count will return 0.
this.expressionMap.cacheId = (cacheId) ? `${cacheId}-count` : cacheId;
const count = await this.executeCountQuery(queryRunner);
const results: [Entity[], number] = [entitiesAndRaw.entities, count];

Expand Down
10 changes: 10 additions & 0 deletions test/github-issues/4277/entity/User.ts
@@ -0,0 +1,10 @@
import {Entity, PrimaryGeneratedColumn, Column} from "../../../../src";

@Entity()
export class User {
@PrimaryGeneratedColumn({ type: "integer" })
id: number;

@Column()
name: string;
}
132 changes: 132 additions & 0 deletions test/github-issues/4277/issue-4277.ts
@@ -0,0 +1,132 @@
import "reflect-metadata";
import {createTestingConnections, closeTestingConnections, reloadTestingDatabases} from "../../utils/test-utils";
import {Connection} from "../../../src/connection/Connection";
import {expect} from "chai";
import {User} from "./entity/User";

describe("github issues > #4277 Using cache in findAndCount and getManyAndCount returns 0 as count", () => {

let connections: Connection[];
before(async () => {
connections = await createTestingConnections({
entities: [__dirname + "/entity/*{.js,.ts}"],
schemaCreate: true,
dropSchema: true,
cache: {
type: "database",
},
});
});
beforeEach(async () => {
await reloadTestingDatabases(connections);
await Promise.all(connections.map((conn) => {
const repo = conn.getRepository(User);

const usersToInsert = [...Array(10)].map((e) => {
const user = new User();
user.name = "Jeremy Clarkson";
return user;
});

return repo.save(usersToInsert);
}));
});
after(() => closeTestingConnections(connections));

it("getManyAndCount and findAndCount should count correctly when using cacheId", () => Promise.all(connections.map(async connection => {
const repo = connection.getRepository(User);

const getManyAndCount = () => repo.createQueryBuilder()
.cache("cache-id-1", 60000)
.getManyAndCount();

const findAndCount = () => repo.findAndCount({
cache: {
id: "cache-id-2",
milliseconds: 60000,
},
});


const [users, count] = await getManyAndCount();
expect(users.length).equal(10);
expect(count).equal(10);

const [users2, count2] = await findAndCount();
expect(users2.length).equal(10);
expect(count2).equal(10);

await repo.save({ name: "Jeremy Clarkson" });

// After caching, both queries should be cached correctly. Save above should not affect results
const [_users, _count] = await getManyAndCount();
expect(_users.length).equal(10);
expect(_count).equal(10);

const [_users2, _count2] = await findAndCount();
expect(_users2.length).equal(10);
expect(_count2).equal(10);
})));

it("getManyAndCount and findAndCount should count correctly when NOT using cacheId", () => Promise.all(connections.map(async connection => {
const repo = connection.getRepository(User);

const getManyAndCount = () => repo.createQueryBuilder()
.cache(60000)
.getManyAndCount();

const findAndCount = () => repo.findAndCount({
cache: 60000,
});


const [users, count] = await getManyAndCount();
expect(users.length).equal(10);
expect(count).equal(10);

const [users2, count2] = await findAndCount();
expect(users2.length).equal(10);
expect(count2).equal(10);

await repo.save({ name: "Jeremy Clarkson" });

// After caching, both queries should be cached correctly. Save above should not affect results
const [_users, _count] = await getManyAndCount();
expect(_users.length).equal(10);
expect(_count).equal(10);

const [_users2, _count2] = await findAndCount();
expect(_users2.length).equal(10);
expect(_count2).equal(10);
})));

it("getManyAndCount and findAndCount should count correctly when NOT using cache", () => Promise.all(connections.map(async connection => {
const repo = connection.getRepository(User);

const getManyAndCount = () => repo.createQueryBuilder()
.getManyAndCount();

const findAndCount = () => repo.findAndCount();


const [users, count] = await getManyAndCount();
expect(users.length).equal(10);
expect(count).equal(10);

const [users2, count2] = await findAndCount();
expect(users2.length).equal(10);
expect(count2).equal(10);

await repo.save({ name: "Jeremy Clarkson" });

// After queries, both should NOT be cached. Save above SHOULD affect results
const [_users, _count] = await getManyAndCount();
expect(_users.length).equal(11);
expect(_count).equal(11);

const [_users2, _count2] = await findAndCount();
expect(_users2.length).equal(11);
expect(_count2).equal(11);
})));

});

0 comments on commit 9f14e48

Please sign in to comment.