Skip to content

Commit

Permalink
fix(query-builder): fix caching of raw query fragments when `qb.getQu…
Browse files Browse the repository at this point in the history
…ery()` is called

Closes #5247
  • Loading branch information
B4nan committed Feb 16, 2024
1 parent 46cb6a1 commit f79a752
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 3 deletions.
4 changes: 2 additions & 2 deletions packages/knex/src/query/QueryBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -684,7 +684,7 @@ export class QueryBuilder<T extends object = AnyEntity> {
* Returns raw interpolated query string with all the parameters inlined.
*/
getFormattedQuery(): string {
const query = this.getKnexQuery().toSQL();
const query = this.toQuery()._sql;
return this.platform.formatQuery(query.sql, query.bindings);
}

Expand Down Expand Up @@ -771,7 +771,7 @@ export class QueryBuilder<T extends object = AnyEntity> {
this.connectionType = 'write';
}

const query = this.getKnexQuery().toSQL();
const query = this.toQuery()._sql;
const cached = await this.em?.tryCache<T, U>(this.mainAlias.entityName, this._cache, ['qb.execute', query.sql, query.bindings, method]);

if (cached?.data) {
Expand Down
2 changes: 2 additions & 0 deletions tests/EntityManager.sqlite2.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import { initORMSqlite2, mockLogger } from './bootstrap';
import type { IAuthor4, IPublisher4, ITest4 } from './entities-schema';
import { Author4, Book4, BookTag4, FooBar4, Publisher4, PublisherType, Test4 } from './entities-schema';

jest.retryTimes(3);

describe.each(['sqlite', 'better-sqlite'] as const)('EntityManager (%s)', driver => {

let orm: MikroORM;
Expand Down
75 changes: 75 additions & 0 deletions tests/issues/GH5247.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { Entity, JsonType, MikroORM, PrimaryKey, Property, QBFilterQuery, RawQueryFragment } from '@mikro-orm/sqlite';

@Entity()
class Test {

@PrimaryKey()
id!: number;

@Property({ type: JsonType, nullable: true })
a!: any;

constructor(a: any) {
this.a = a;
}

}

let orm: MikroORM;

beforeAll(async () => {
orm = await MikroORM.init({
dbName: ':memory:',
entities: [Test],
});
await orm.schema.createSchema();
orm.em.create(Test, { a: {
value: 1,
} });
orm.em.create(Test, { a: {
complex: {
bool: true,
},
} });
await orm.em.flush();
orm.em.clear();
});

afterAll(async () => {
await orm.close(true);
});

test('simple - no getQuery', async () => {
const query: QBFilterQuery<Test> = { a: { value: 1 } };
const qb = orm.em.qb(Test).where(query);
const res = await qb.execute(); // proper sql query is generated
expect(res.length).toBe(1); // result as expected
expect(RawQueryFragment.checkCacheSize()).toBe(0);
});

test('simple - with getQuery', async () => {
const query: QBFilterQuery<Test> = { a: { value: 1 } };
const qb = orm.em.qb(Test).where(query);
qb.getQuery();
const res = await qb.execute(); // proper sql query is generated
expect(res.length).toBe(1); // result as expected
expect(RawQueryFragment.checkCacheSize()).toBe(0);
});

test('complex working', async () => {
const query = { $and: [{ $or: [{ a: { value: 1 } }, { a: { complex: { bool: true } } }] }] };
const qb = orm.em.qb(Test).where(query);
const res = await qb.execute(); // proper sql query is generated
expect(res.length).toBe(2); // result as expected
expect(RawQueryFragment.checkCacheSize()).toBe(0);
});

test('complex not working', async () => {
const query = { $and: [{ $or: [{ a: { value: 1 } }, { a: { complex: { bool: true } } }] }] };
const qb = orm.em.qb(Test).where(query);
expect(qb.getFormattedQuery()).toBe("select `t0`.* from `test` as `t0` where (json_extract(`t0`.`a`, '$.value') = 1 or json_extract(`t0`.`a`, '$.complex.bool') = true)");
expect(qb.getQuery()).toBe("select `t0`.* from `test` as `t0` where (json_extract(`t0`.`a`, '$.value') = ? or json_extract(`t0`.`a`, '$.complex.bool') = ?)");
const res = await qb.execute(); // faulty sql query is generated
expect(res.length).toBe(2);
expect(RawQueryFragment.checkCacheSize()).toBe(0);
});
2 changes: 1 addition & 1 deletion tests/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ process.env.MIKRO_ORM_ALLOW_GLOBAL_CLI = '1';
process.env.MIKRO_ORM_ALLOW_VERSION_MISMATCH = '1';

jest.restoreAllMocks();
jest.retryTimes(3, { logErrorsBeforeRetry: false });
jest.retryTimes(1);
MetadataStorage.clear();

0 comments on commit f79a752

Please sign in to comment.