Skip to content

Commit

Permalink
feat(core): do not cache metadata for other than ts-morph provider (#569
Browse files Browse the repository at this point in the history
)

Now only `TsMorphMetadataProvider` will cache metadata. The value in ORM configuration will be respected,
so if you explicitly enable caching, it will be used regardless of what metadata provider is used.
  • Loading branch information
B4nan committed Aug 9, 2020
1 parent 952fd2f commit 49fb4eb
Show file tree
Hide file tree
Showing 46 changed files with 34 additions and 353 deletions.
20 changes: 10 additions & 10 deletions packages/core/src/entity/EntityRepository.ts
Expand Up @@ -26,32 +26,32 @@ export class EntityRepository<T extends AnyEntity<T>> {
}

async findOne(where: FilterQuery<T>, populate?: string[] | boolean, orderBy?: QueryOrderMap): Promise<T | null>;
async findOne(where: FilterQuery<T>, populate?: FindOneOptions, orderBy?: QueryOrderMap): Promise<T | null>;
async findOne(where: FilterQuery<T>, populate: string[] | boolean | FindOneOptions = [], orderBy?: QueryOrderMap): Promise<T | null> {
async findOne(where: FilterQuery<T>, populate?: FindOneOptions<T>, orderBy?: QueryOrderMap): Promise<T | null>;
async findOne(where: FilterQuery<T>, populate: string[] | boolean | FindOneOptions<T> = [], orderBy?: QueryOrderMap): Promise<T | null> {
return this.em.findOne<T>(this.entityName, where, populate as string[], orderBy);
}

async findOneOrFail(where: FilterQuery<T>, populate?: string[] | boolean, orderBy?: QueryOrderMap): Promise<T>;
async findOneOrFail(where: FilterQuery<T>, populate?: FindOneOrFailOptions, orderBy?: QueryOrderMap): Promise<T>;
async findOneOrFail(where: FilterQuery<T>, populate: string[] | boolean | FindOneOrFailOptions = [], orderBy?: QueryOrderMap): Promise<T> {
async findOneOrFail(where: FilterQuery<T>, populate?: FindOneOrFailOptions<T>, orderBy?: QueryOrderMap): Promise<T>;
async findOneOrFail(where: FilterQuery<T>, populate: string[] | boolean | FindOneOrFailOptions<T> = [], orderBy?: QueryOrderMap): Promise<T> {
return this.em.findOneOrFail<T>(this.entityName, where, populate as string[], orderBy);
}

async find(where: FilterQuery<T>, options?: FindOptions): Promise<T[]>;
async find(where: FilterQuery<T>, options?: FindOptions<T>): Promise<T[]>;
async find(where: FilterQuery<T>, populate?: string[] | boolean, orderBy?: QueryOrderMap, limit?: number, offset?: number): Promise<T[]>;
async find(where: FilterQuery<T>, populate: string[] | boolean | FindOptions = [], orderBy: QueryOrderMap = {}, limit?: number, offset?: number): Promise<T[]> {
async find(where: FilterQuery<T>, populate: string[] | boolean | FindOptions<T> = [], orderBy: QueryOrderMap = {}, limit?: number, offset?: number): Promise<T[]> {
return this.em.find<T>(this.entityName, where as FilterQuery<T>, populate as string[], orderBy, limit, offset);
}

async findAndCount(where: FilterQuery<T>, options?: FindOptions): Promise<[T[], number]>;
async findAndCount(where: FilterQuery<T>, options?: FindOptions<T>): Promise<[T[], number]>;
async findAndCount(where: FilterQuery<T>, populate?: string[] | boolean, orderBy?: QueryOrderMap, limit?: number, offset?: number): Promise<[T[], number]>;
async findAndCount(where: FilterQuery<T>, populate: string[] | boolean | FindOptions = [], orderBy: QueryOrderMap = {}, limit?: number, offset?: number): Promise<[T[], number]> {
async findAndCount(where: FilterQuery<T>, populate: string[] | boolean | FindOptions<T> = [], orderBy: QueryOrderMap = {}, limit?: number, offset?: number): Promise<[T[], number]> {
return this.em.findAndCount<T>(this.entityName, where as FilterQuery<T>, populate as string[], orderBy, limit, offset);
}

async findAll(options?: FindOptions): Promise<T[]>;
async findAll(options?: FindOptions<T>): Promise<T[]>;
async findAll(populate?: string[] | boolean | true, orderBy?: QueryOrderMap, limit?: number, offset?: number): Promise<T[]>;
async findAll(populate: string[] | boolean | true | FindOptions = [], orderBy?: QueryOrderMap, limit?: number, offset?: number): Promise<T[]> {
async findAll(populate: string[] | boolean | true | FindOptions<T> = [], orderBy?: QueryOrderMap, limit?: number, offset?: number): Promise<T[]> {
return this.em.find<T>(this.entityName, {}, populate as string[], orderBy, limit, offset);
}

Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/metadata/MetadataDiscovery.ts
Expand Up @@ -142,7 +142,7 @@ export class MetadataDiscovery {

const schema = EntitySchema.fromMetadata<T>(this.metadata.get<T>(entity.name, true));
schema.setClass(entity);
schema.meta.useCache = true;
schema.meta.useCache = this.metadataProvider.useCache();

return schema;
}
Expand Down
4 changes: 4 additions & 0 deletions packages/core/src/metadata/MetadataProvider.ts
Expand Up @@ -11,6 +11,10 @@ export abstract class MetadataProvider {
Utils.merge(meta, cache);
}

useCache(): boolean {
return this.config.get('cache').enabled ?? false;
}

protected async initProperties(meta: EntityMetadata, fallback: (prop: EntityProperty) => void | Promise<void>): Promise<void> {
// load types and column names
for (const prop of Object.values(meta.properties)) {
Expand Down
3 changes: 2 additions & 1 deletion packages/core/src/types/Type.ts
Expand Up @@ -31,7 +31,8 @@ export abstract class Type<JSType = string, DBType = JSType> {
* Gets the SQL declaration snippet for a field of this type.
*/
getColumnType(prop: EntityProperty, platform: Platform): string {
return prop.columnTypes[0];
/* istanbul ignore next */
return prop.columnTypes?.[0];
}

static getType<JSType, DBType>(cls: Constructor<Type<JSType, DBType>>): Type<JSType, DBType> {
Expand Down
3 changes: 1 addition & 2 deletions packages/core/src/utils/Configuration.ts
Expand Up @@ -51,7 +51,6 @@ export class Configuration<D extends IDatabaseDriver = IDatabaseDriver> {
emit: 'ts',
},
cache: {
enabled: true,
pretty: false,
adapter: FileCacheAdapter,
options: { cacheDir: process.cwd() + '/temp' },
Expand Down Expand Up @@ -187,7 +186,7 @@ export class Configuration<D extends IDatabaseDriver = IDatabaseDriver> {
}

private init(): void {
if (!this.options.cache.enabled) {
if (!this.getMetadataProvider().useCache()) {
this.options.cache.adapter = NullCacheAdapter;
}

Expand Down
4 changes: 4 additions & 0 deletions packages/reflection/src/TsMorphMetadataProvider.ts
Expand Up @@ -7,6 +7,10 @@ export class TsMorphMetadataProvider extends MetadataProvider {
private readonly project = new Project();
private sources!: SourceFile[];

useCache(): boolean {
return this.config.get('cache').enabled ?? true;
}

async loadEntityMetadata(meta: EntityMetadata, name: string): Promise<void> {
if (!meta.path) {
return;
Expand Down
2 changes: 1 addition & 1 deletion tests/MetadataValidator.test.ts
Expand Up @@ -113,7 +113,7 @@ describe('MetadataValidator', () => {
entities: [FooBar2, FooBaz2],
dbName: `mikro_orm_test`,
port: 3307,
metadataProvider: ReflectMetadataProvider,
cache: { enabled: true },
discovery: { tsConfigPath: BASE_DIR + '/tsconfig.test.json' },
type: 'mysql',
baseDir: BASE_DIR,
Expand Down
14 changes: 5 additions & 9 deletions tests/MikroORM.test.ts
Expand Up @@ -2,7 +2,7 @@

import fs from 'fs-extra';
import { TsMorphMetadataProvider } from '@mikro-orm/reflection';
import { MikroORM, EntityManager, Configuration, ReflectMetadataProvider } from '@mikro-orm/core';
import { MikroORM, EntityManager, Configuration } from '@mikro-orm/core';
import { Author, Test } from './entities';
import { BASE_DIR } from './bootstrap';
import { Author2, Car2, CarOwner2, FooBaz2, User2 } from './entities-sql';
Expand Down Expand Up @@ -46,8 +46,6 @@ describe('MikroORM', () => {
await MikroORM.init({
dbName: 'not-found',
baseDir: BASE_DIR,
cache: { enabled: false },
metadataProvider: ReflectMetadataProvider,
type: 'mysql',
entities: [Car2, CarOwner2, User2],
debug: ['info'],
Expand All @@ -58,32 +56,30 @@ describe('MikroORM', () => {

test('should throw when multiple entities with same class name discovered', async () => {
const err = `Entity 'BadName' not found in ./entities-3/bad-name.model.ts`;
await expect(MikroORM.init({ type: 'mongo', dbName: 'test', baseDir: BASE_DIR, cache: { enabled: false }, entitiesDirs: ['entities-3'] })).rejects.toThrowError(err);
await expect(MikroORM.init({ type: 'mongo', dbName: 'test', baseDir: BASE_DIR, entitiesDirs: ['entities-3'] })).rejects.toThrowError(err);
});

test('should throw when only abstract entities were discovered', async () => {
const err = 'Only abstract entities were discovered, maybe you forgot to use @Entity() decorator?';
await expect(MikroORM.init({ type: 'mongo', dbName: 'test', baseDir: BASE_DIR, cache: { enabled: false }, entities: [BaseEntity2], entitiesDirsTs: ['entities-sql'] })).rejects.toThrowError(err);
await expect(MikroORM.init({ type: 'mongo', dbName: 'test', baseDir: BASE_DIR, entities: [BaseEntity2], entitiesDirsTs: ['entities-sql'] })).rejects.toThrowError(err);
});

test('should throw when a relation is pointing to not discovered entity', async () => {
const err = 'Entity \'Book2\' was not discovered, please make sure to provide it in \'entities\' array when initializing the ORM';
await expect(MikroORM.init({ type: 'mongo', dbName: 'test', cache: { enabled: false }, entities: [Author2, BaseEntity2], metadataProvider: ReflectMetadataProvider })).rejects.toThrowError(err);
await expect(MikroORM.init({ type: 'mongo', dbName: 'test', entities: [Author2, BaseEntity2] })).rejects.toThrowError(err);
});

test('should throw when only multiple property decorators are used', async () => {
const err = `Multiple property decorators used on 'MultiDecorator.name' property`;
await expect(MikroORM.init({ type: 'mongo', dbName: 'test', baseDir: BASE_DIR, cache: { enabled: false }, entitiesDirs: ['entities-4'] })).rejects.toThrowError(err);
await expect(MikroORM.init({ type: 'mongo', dbName: 'test', baseDir: BASE_DIR, entitiesDirs: ['entities-4'] })).rejects.toThrowError(err);
});

test('should use CLI config', async () => {
const options = {
entities: [Test],
type: 'mongo',
dbName: 'mikro-orm-test',
metadataProvider: ReflectMetadataProvider,
discovery: { tsConfigPath: BASE_DIR + '/tsconfig.test.json', alwaysAnalyseProperties: false },
cache: { enabled: false },
};
const pathExistsMock = jest.spyOn(fs as any, 'pathExists');
pathExistsMock.mockResolvedValue(true);
Expand Down
8 changes: 2 additions & 6 deletions tests/bootstrap.ts
Expand Up @@ -42,7 +42,6 @@ export async function initORMMongo() {
type: 'mongo',
ensureIndexes: true,
implicitTransactions: true,
cache: { enabled: false },
});

// create collections first so we can use transactions
Expand Down Expand Up @@ -70,8 +69,6 @@ export async function initORMMySql<D extends MySqlDriver | MariaDbDriver = MySql
multipleStatements: true,
entityRepository: SqlEntityRepository,
type,
metadataProvider: ReflectMetadataProvider,
cache: { enabled: false },
replicas: [{ name: 'read-1' }, { name: 'read-2' }], // create two read replicas with same configuration, just for testing purposes
migrations: { path: BASE_DIR + '/../temp/migrations' },
});
Expand Down Expand Up @@ -104,8 +101,7 @@ export async function initORMPostgreSql() {
forceUtcTimezone: true,
autoJoinOneToOneOwner: false,
logger: i => i,
metadataProvider: ReflectMetadataProvider,
cache: { enabled: false },
cache: { enabled: true },
});

const schemaGenerator = new SchemaGenerator(orm.em);
Expand All @@ -127,7 +123,7 @@ export async function initORMSqlite() {
forceUtcTimezone: true,
logger: i => i,
metadataProvider: JavaScriptMetadataProvider,
cache: { pretty: true },
cache: { enabled: true, pretty: true },
});

const connection = orm.em.getConnection();
Expand Down
1 change: 0 additions & 1 deletion tests/embedded-entities.mongo.test.ts
Expand Up @@ -78,7 +78,6 @@ describe('embedded entities in mongo', () => {
entities: [Address1, Address2, User],
clientUrl: 'mongodb://localhost:27017,localhost:27018,localhost:27019/mikro-orm-test-embeddables?replicaSet=rs0',
type: 'mongo',
cache: { enabled: false },
});
});

Expand Down
1 change: 0 additions & 1 deletion tests/embedded-entities.mysql.test.ts
Expand Up @@ -76,7 +76,6 @@ describe('embedded entities in mysql', () => {
dbName: `mikro_orm_test_embeddables`,
type: 'mysql',
port: 3307,
cache: { enabled: false },
});
await orm.getSchemaGenerator().ensureDatabase();
await orm.getSchemaGenerator().createSchema();
Expand Down
2 changes: 0 additions & 2 deletions tests/issues/GH222.test.ts
Expand Up @@ -60,8 +60,6 @@ describe('GH issue 222', () => {
dbName: BASE_DIR + '/../temp/mikro_orm_test_gh222.db',
debug: false,
type: 'sqlite',
metadataProvider: ReflectMetadataProvider,
cache: { enabled: false },
});
await new SchemaGenerator(orm.em).dropSchema();
await new SchemaGenerator(orm.em).createSchema();
Expand Down
2 changes: 0 additions & 2 deletions tests/issues/GH228.test.ts
Expand Up @@ -39,8 +39,6 @@ describe('GH issue 228', () => {
debug: false,
highlight: false,
type: 'sqlite',
metadataProvider: ReflectMetadataProvider,
cache: { enabled: false },
});
await new SchemaGenerator(orm.em).dropSchema();
await new SchemaGenerator(orm.em).createSchema();
Expand Down
2 changes: 0 additions & 2 deletions tests/issues/GH234.test.ts
Expand Up @@ -43,8 +43,6 @@ describe('GH issue 234', () => {
debug: false,
highlight: false,
type: 'sqlite',
metadataProvider: ReflectMetadataProvider,
cache: { enabled: false },
});
await new SchemaGenerator(orm.em).dropSchema();
await new SchemaGenerator(orm.em).createSchema();
Expand Down
2 changes: 0 additions & 2 deletions tests/issues/GH268.test.ts
Expand Up @@ -44,8 +44,6 @@ describe('GH issue 268', () => {
debug: false,
highlight: false,
type: 'sqlite',
metadataProvider: ReflectMetadataProvider,
cache: { enabled: false },
});
await new SchemaGenerator(orm.em).dropSchema();
await new SchemaGenerator(orm.em).createSchema();
Expand Down
2 changes: 0 additions & 2 deletions tests/issues/GH269.test.ts
Expand Up @@ -42,9 +42,7 @@ describe('GH issue 269', () => {
dbName: BASE_DIR + '/../temp/mikro_orm_test_gh269.db',
debug: false,
type: 'sqlite',
metadataProvider: ReflectMetadataProvider,
autoJoinOneToOneOwner: false,
cache: { enabled: false },
});
await new SchemaGenerator(orm.em).dropSchema();
await new SchemaGenerator(orm.em).createSchema();
Expand Down
2 changes: 0 additions & 2 deletions tests/issues/GH302.test.ts
Expand Up @@ -47,8 +47,6 @@ describe('GH issue 302', () => {
dbName: BASE_DIR + '/../temp/mikro_orm_test_gh302.db',
debug: false,
type: 'sqlite',
metadataProvider: ReflectMetadataProvider,
cache: { enabled: false },
});
await new SchemaGenerator(orm.em).dropSchema();
await new SchemaGenerator(orm.em).createSchema();
Expand Down
2 changes: 0 additions & 2 deletions tests/issues/GH369.test.ts
Expand Up @@ -39,8 +39,6 @@ describe('GH issue 369', () => {
debug: false,
highlight: false,
type: 'sqlite',
metadataProvider: ReflectMetadataProvider,
cache: { enabled: false },
});
await new SchemaGenerator(orm.em).dropSchema();
await new SchemaGenerator(orm.em).createSchema();
Expand Down
2 changes: 0 additions & 2 deletions tests/issues/GH372.test.ts
Expand Up @@ -48,8 +48,6 @@ describe('GH issue 372', () => {
entities: [A],
dbName: `mikro_orm_test_gh_372`,
type: 'postgresql',
metadataProvider: ReflectMetadataProvider,
cache: { enabled: false },
});
await new SchemaGenerator(orm.em).ensureDatabase();
await new SchemaGenerator(orm.em).dropSchema();
Expand Down
2 changes: 0 additions & 2 deletions tests/issues/GH380.test.ts
Expand Up @@ -28,8 +28,6 @@ describe('GH issue 380', () => {
debug: false,
highlight: false,
type: 'postgresql',
metadataProvider: ReflectMetadataProvider,
cache: { enabled: false },
});
await new SchemaGenerator(orm.em).ensureDatabase();
await new SchemaGenerator(orm.em).dropSchema();
Expand Down
2 changes: 0 additions & 2 deletions tests/issues/GH401.test.ts
Expand Up @@ -29,8 +29,6 @@ describe('GH issue 401', () => {
entities: [Entity401],
clientUrl: 'mongodb://localhost:27017,localhost:27018,localhost:27019/mikro-orm-test?replicaSet=rs0',
type: 'mongo',
metadataProvider: ReflectMetadataProvider,
cache: { enabled: false },
});
await orm.em.remove(Entity401, {});
});
Expand Down
2 changes: 0 additions & 2 deletions tests/issues/GH435.test.ts
Expand Up @@ -41,8 +41,6 @@ describe('GH issue 435', () => {
debug: false,
highlight: false,
type: 'sqlite',
metadataProvider: ReflectMetadataProvider,
cache: { enabled: false },
});
await new SchemaGenerator(orm.em).ensureDatabase();
await new SchemaGenerator(orm.em).dropSchema();
Expand Down
2 changes: 0 additions & 2 deletions tests/issues/GH446.test.ts
Expand Up @@ -40,8 +40,6 @@ describe('GH issue 446', () => {
debug: false,
highlight: false,
type: 'postgresql',
metadataProvider: ReflectMetadataProvider,
cache: { enabled: false },
});
await new SchemaGenerator(orm.em).ensureDatabase();
await new SchemaGenerator(orm.em).dropSchema();
Expand Down
2 changes: 0 additions & 2 deletions tests/issues/GH459.test.ts
Expand Up @@ -43,8 +43,6 @@ describe('GH issue 459', () => {
debug: false,
highlight: false,
type: 'sqlite',
metadataProvider: ReflectMetadataProvider,
cache: { enabled: false },
});
await new SchemaGenerator(orm.em).dropSchema();
await new SchemaGenerator(orm.em).createSchema();
Expand Down
2 changes: 0 additions & 2 deletions tests/issues/GH463.test.ts
Expand Up @@ -37,8 +37,6 @@ describe('GH issue 463', () => {
debug: false,
highlight: false,
type: 'sqlite',
metadataProvider: ReflectMetadataProvider,
cache: { enabled: false },
});
await new SchemaGenerator(orm.em).dropSchema();
await new SchemaGenerator(orm.em).createSchema();
Expand Down
2 changes: 0 additions & 2 deletions tests/issues/GH472.test.ts
Expand Up @@ -21,9 +21,7 @@ describe('GH issue 472', () => {
entities: [A],
dbName: 'mikro_orm_test_gh472',
type: 'postgresql',
metadataProvider: ReflectMetadataProvider,
namingStrategy: EntityCaseNamingStrategy,
cache: { enabled: false },
});
await orm.getSchemaGenerator().ensureDatabase();
await orm.getSchemaGenerator().dropSchema();
Expand Down
2 changes: 0 additions & 2 deletions tests/issues/GH482.test.ts
Expand Up @@ -41,8 +41,6 @@ describe('GH issue 482', () => {
entities: [Job, Level],
dbName: 'mikro_orm_test_gh482',
type: 'postgresql',
metadataProvider: ReflectMetadataProvider,
cache: { enabled: false },
});
await orm.getSchemaGenerator().ensureDatabase();
await orm.getSchemaGenerator().dropSchema();
Expand Down
2 changes: 0 additions & 2 deletions tests/issues/GH486.test.ts
Expand Up @@ -35,8 +35,6 @@ describe('GH issue 486', () => {
entities: [A, B],
dbName: `mikro_orm_test_gh_486`,
type: 'postgresql',
metadataProvider: ReflectMetadataProvider,
cache: { enabled: false },
});
await orm.getSchemaGenerator().ensureDatabase();
await orm.getSchemaGenerator().dropSchema();
Expand Down
2 changes: 0 additions & 2 deletions tests/issues/GH491.test.ts
Expand Up @@ -37,8 +37,6 @@ describe('GH issue 491', () => {
dbName: `mikro_orm_test_gh_491`,
type: 'mariadb',
port: 3309,
metadataProvider: ReflectMetadataProvider,
cache: { enabled: false },
});
await orm.getSchemaGenerator().ensureDatabase();
await orm.getSchemaGenerator().dropSchema();
Expand Down
2 changes: 0 additions & 2 deletions tests/issues/GH519.test.ts
Expand Up @@ -48,8 +48,6 @@ describe('GH issue 519', () => {
entities: [Competition, User, Registration],
dbName: `mikro_orm_test_gh_519`,
type: 'postgresql',
metadataProvider: ReflectMetadataProvider,
cache: { enabled: false },
});
await orm.getSchemaGenerator().ensureDatabase();
await orm.getSchemaGenerator().dropSchema();
Expand Down
2 changes: 0 additions & 2 deletions tests/issues/GH529.test.ts
Expand Up @@ -90,8 +90,6 @@ describe('GH issue 529', () => {
entities: [Customer, Order, OrderItem, Product],
dbName: `mikro_orm_test_gh_529`,
type: 'postgresql',
metadataProvider: ReflectMetadataProvider,
cache: { enabled: false },
});
await orm.getSchemaGenerator().ensureDatabase();
await orm.getSchemaGenerator().dropSchema();
Expand Down

0 comments on commit 49fb4eb

Please sign in to comment.