Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: create a different cacheId if present for count query in getManyAndCount #8283

Merged
merged 1 commit into from
Oct 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/query-builder/SelectQueryBuilder.ts
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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);
})));

});