@mikro-orm/core 7.0.0-rc.3 → 7.0.1-dev.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/EntityManager.d.ts +2 -15
- package/EntityManager.js +155 -152
- package/MikroORM.d.ts +4 -6
- package/MikroORM.js +20 -20
- package/README.md +5 -4
- package/cache/FileCacheAdapter.d.ts +1 -5
- package/cache/FileCacheAdapter.js +22 -22
- package/cache/GeneratedCacheAdapter.d.ts +1 -1
- package/cache/GeneratedCacheAdapter.js +6 -6
- package/cache/MemoryCacheAdapter.d.ts +1 -2
- package/cache/MemoryCacheAdapter.js +8 -8
- package/cache/index.d.ts +1 -1
- package/cache/index.js +0 -1
- package/connections/Connection.d.ts +1 -0
- package/connections/Connection.js +27 -11
- package/drivers/DatabaseDriver.d.ts +0 -2
- package/drivers/DatabaseDriver.js +2 -4
- package/entity/Collection.d.ts +1 -9
- package/entity/Collection.js +95 -105
- package/entity/EntityFactory.d.ts +1 -8
- package/entity/EntityFactory.js +48 -48
- package/entity/EntityLoader.d.ts +1 -3
- package/entity/EntityLoader.js +36 -39
- package/entity/Reference.d.ts +1 -2
- package/entity/Reference.js +11 -11
- package/entity/WrappedEntity.d.ts +4 -2
- package/entity/defineEntity.d.ts +18 -73
- package/enums.d.ts +2 -1
- package/enums.js +1 -0
- package/errors.d.ts +11 -11
- package/errors.js +3 -13
- package/events/EventManager.d.ts +1 -4
- package/events/EventManager.js +25 -22
- package/events/index.d.ts +1 -1
- package/events/index.js +0 -1
- package/exceptions.js +8 -6
- package/hydration/ObjectHydrator.d.ts +1 -2
- package/hydration/ObjectHydrator.js +16 -16
- package/logging/DefaultLogger.js +3 -2
- package/logging/Logger.d.ts +2 -1
- package/logging/colors.js +1 -1
- package/logging/index.d.ts +1 -1
- package/logging/index.js +0 -1
- package/metadata/EntitySchema.d.ts +1 -1
- package/metadata/MetadataDiscovery.d.ts +1 -9
- package/metadata/MetadataDiscovery.js +162 -149
- package/metadata/MetadataStorage.d.ts +1 -5
- package/metadata/MetadataStorage.js +36 -36
- package/metadata/discover-entities.js +1 -1
- package/metadata/index.d.ts +1 -1
- package/metadata/index.js +0 -1
- package/naming-strategy/AbstractNamingStrategy.js +1 -1
- package/naming-strategy/EntityCaseNamingStrategy.js +1 -1
- package/naming-strategy/index.d.ts +1 -1
- package/naming-strategy/index.js +0 -1
- package/package.json +1 -1
- package/platforms/Platform.d.ts +23 -1
- package/platforms/Platform.js +57 -4
- package/serialization/EntitySerializer.js +1 -1
- package/serialization/EntityTransformer.js +4 -1
- package/serialization/SerializationContext.d.ts +4 -8
- package/serialization/SerializationContext.js +20 -15
- package/types/UuidType.d.ts +2 -0
- package/types/UuidType.js +14 -2
- package/types/index.d.ts +2 -1
- package/typings.d.ts +12 -1
- package/unit-of-work/ChangeSetComputer.d.ts +1 -6
- package/unit-of-work/ChangeSetComputer.js +21 -21
- package/unit-of-work/ChangeSetPersister.d.ts +1 -9
- package/unit-of-work/ChangeSetPersister.js +52 -52
- package/unit-of-work/CommitOrderCalculator.d.ts +1 -4
- package/unit-of-work/CommitOrderCalculator.js +13 -13
- package/unit-of-work/IdentityMap.d.ts +2 -5
- package/unit-of-work/IdentityMap.js +18 -18
- package/unit-of-work/UnitOfWork.d.ts +5 -19
- package/unit-of-work/UnitOfWork.js +182 -174
- package/utils/AbstractMigrator.d.ts +1 -1
- package/utils/AbstractMigrator.js +7 -7
- package/utils/Configuration.d.ts +90 -189
- package/utils/Configuration.js +94 -78
- package/utils/Cursor.d.ts +3 -3
- package/utils/Cursor.js +4 -4
- package/utils/EntityComparator.d.ts +8 -15
- package/utils/EntityComparator.js +49 -49
- package/utils/QueryHelper.d.ts +16 -1
- package/utils/QueryHelper.js +70 -24
- package/utils/RawQueryFragment.d.ts +4 -4
- package/utils/TransactionManager.js +1 -2
- package/utils/Utils.d.ts +1 -1
- package/utils/Utils.js +5 -4
- package/utils/clone.js +5 -0
- package/utils/fs-utils.d.ts +3 -17
- package/utils/fs-utils.js +1 -1
- package/utils/upsert-utils.js +1 -1
package/MikroORM.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { Configuration, type Options } from './utils/Configuration.js';
|
|
|
5
5
|
import type { EntityManager } from './EntityManager.js';
|
|
6
6
|
import type { AnyEntity, Constructor, EntityClass, EntityMetadata, EntityName, IEntityGenerator, IMigrator, ISeedManager } from './typings.js';
|
|
7
7
|
/** @internal */
|
|
8
|
-
export declare function loadOptionalDependencies(options: Options): Promise<void>;
|
|
8
|
+
export declare function loadOptionalDependencies(options: Partial<Options>): Promise<void>;
|
|
9
9
|
/**
|
|
10
10
|
* The main class used to configure and bootstrap the ORM.
|
|
11
11
|
*
|
|
@@ -35,27 +35,25 @@ export declare function loadOptionalDependencies(options: Options): Promise<void
|
|
|
35
35
|
* ```
|
|
36
36
|
*/
|
|
37
37
|
export declare class MikroORM<Driver extends IDatabaseDriver = IDatabaseDriver, EM extends Driver[typeof EntityManagerType] & EntityManager<Driver> = Driver[typeof EntityManagerType] & EntityManager<Driver>, Entities extends (string | EntityClass<AnyEntity> | EntitySchema)[] = (string | EntityClass<AnyEntity> | EntitySchema)[]> {
|
|
38
|
+
#private;
|
|
38
39
|
/** The global EntityManager instance. If you are using `RequestContext` helper, it will automatically pick the request specific context under the hood */
|
|
39
40
|
em: EM & {
|
|
40
41
|
'~entities'?: Entities;
|
|
41
42
|
};
|
|
42
43
|
readonly driver: Driver;
|
|
43
44
|
readonly config: Configuration<Driver>;
|
|
44
|
-
private metadata;
|
|
45
|
-
private readonly logger;
|
|
46
|
-
private readonly discovery;
|
|
47
45
|
/**
|
|
48
46
|
* Initialize the ORM, load entity metadata, create EntityManager and connect to the database.
|
|
49
47
|
* If you omit the `options` parameter, your CLI config will be used.
|
|
50
48
|
*/
|
|
51
|
-
static init<D extends IDatabaseDriver = IDatabaseDriver, EM extends D[typeof EntityManagerType] & EntityManager<D> = D[typeof EntityManagerType] & EntityManager<D>, Entities extends (string | EntityClass<AnyEntity> | EntitySchema)[] = (string | EntityClass<AnyEntity> | EntitySchema)[]>(options: Options<D, EM, Entities
|
|
49
|
+
static init<D extends IDatabaseDriver = IDatabaseDriver, EM extends D[typeof EntityManagerType] & EntityManager<D> = D[typeof EntityManagerType] & EntityManager<D>, Entities extends (string | EntityClass<AnyEntity> | EntitySchema)[] = (string | EntityClass<AnyEntity> | EntitySchema)[]>(options: Partial<Options<D, EM, Entities>>): Promise<MikroORM<D, EM, Entities>>;
|
|
52
50
|
/**
|
|
53
51
|
* Synchronous variant of the `init` method with some limitations:
|
|
54
52
|
* - folder-based discovery not supported
|
|
55
53
|
* - ORM extensions are not autoloaded
|
|
56
54
|
* - when metadata cache is enabled, `FileCacheAdapter` needs to be explicitly set in the config
|
|
57
55
|
*/
|
|
58
|
-
constructor(options: Options<Driver, EM, Entities
|
|
56
|
+
constructor(options: Partial<Options<Driver, EM, Entities>>);
|
|
59
57
|
/**
|
|
60
58
|
* Connects to the database.
|
|
61
59
|
*/
|
package/MikroORM.js
CHANGED
|
@@ -74,9 +74,9 @@ export class MikroORM {
|
|
|
74
74
|
em;
|
|
75
75
|
driver;
|
|
76
76
|
config;
|
|
77
|
-
metadata;
|
|
78
|
-
logger;
|
|
79
|
-
discovery;
|
|
77
|
+
#metadata;
|
|
78
|
+
#logger;
|
|
79
|
+
#discovery;
|
|
80
80
|
/**
|
|
81
81
|
* Initialize the ORM, load entity metadata, create EntityManager and connect to the database.
|
|
82
82
|
* If you omit the `options` parameter, your CLI config will be used.
|
|
@@ -92,7 +92,7 @@ export class MikroORM {
|
|
|
92
92
|
await loadOptionalDependencies(options);
|
|
93
93
|
const orm = new this(options);
|
|
94
94
|
const preferTs = orm.config.get('preferTs', Utils.detectTypeScriptSupport());
|
|
95
|
-
orm
|
|
95
|
+
orm.#metadata = await orm.#discovery.discover(preferTs);
|
|
96
96
|
orm.createEntityManager();
|
|
97
97
|
return orm;
|
|
98
98
|
}
|
|
@@ -108,15 +108,15 @@ export class MikroORM {
|
|
|
108
108
|
this.config = new Configuration(options);
|
|
109
109
|
const discovery = this.config.get('discovery');
|
|
110
110
|
this.driver = this.config.getDriver();
|
|
111
|
-
this
|
|
112
|
-
this
|
|
113
|
-
this
|
|
111
|
+
this.#logger = this.config.getLogger();
|
|
112
|
+
this.#logger.log('info', `MikroORM version: ${colors.green(Utils.getORMVersion())}`);
|
|
113
|
+
this.#discovery = new MetadataDiscovery(new MetadataStorage(), this.driver.getPlatform(), this.config);
|
|
114
114
|
this.driver.getPlatform().init(this);
|
|
115
115
|
for (const extension of this.config.get('extensions')) {
|
|
116
116
|
extension.register(this);
|
|
117
117
|
}
|
|
118
118
|
if (!discovery.skipSyncDiscovery) {
|
|
119
|
-
this
|
|
119
|
+
this.#metadata = this.#discovery.discoverSync();
|
|
120
120
|
this.createEntityManager();
|
|
121
121
|
}
|
|
122
122
|
}
|
|
@@ -162,32 +162,32 @@ export class MikroORM {
|
|
|
162
162
|
*/
|
|
163
163
|
getMetadata(entityName) {
|
|
164
164
|
if (entityName) {
|
|
165
|
-
return this
|
|
165
|
+
return this.#metadata.get(entityName);
|
|
166
166
|
}
|
|
167
|
-
return this
|
|
167
|
+
return this.#metadata;
|
|
168
168
|
}
|
|
169
169
|
createEntityManager() {
|
|
170
|
-
this.driver.setMetadata(this
|
|
170
|
+
this.driver.setMetadata(this.#metadata);
|
|
171
171
|
this.em = this.driver.createEntityManager();
|
|
172
172
|
this.em.global = true;
|
|
173
|
-
this
|
|
174
|
-
this.driver.setMetadata(this
|
|
173
|
+
this.#metadata.decorate(this.em);
|
|
174
|
+
this.driver.setMetadata(this.#metadata);
|
|
175
175
|
}
|
|
176
176
|
/**
|
|
177
177
|
* Allows dynamically discovering new entity by reference, handy for testing schema diffing.
|
|
178
178
|
*/
|
|
179
179
|
discoverEntity(entities, reset) {
|
|
180
180
|
for (const className of Utils.asArray(reset)) {
|
|
181
|
-
this
|
|
182
|
-
this
|
|
181
|
+
this.#metadata.reset(className);
|
|
182
|
+
this.#discovery.reset(className);
|
|
183
183
|
}
|
|
184
|
-
const tmp = this
|
|
185
|
-
const metadata = this
|
|
184
|
+
const tmp = this.#discovery.discoverReferences(Utils.asArray(entities));
|
|
185
|
+
const metadata = this.#discovery.processDiscoveredEntities(tmp);
|
|
186
186
|
for (const meta of metadata) {
|
|
187
|
-
this
|
|
188
|
-
meta.root = this
|
|
187
|
+
this.#metadata.set(meta.class, meta);
|
|
188
|
+
meta.root = this.#metadata.get(meta.root.class);
|
|
189
189
|
}
|
|
190
|
-
this
|
|
190
|
+
this.#metadata.decorate(this.em);
|
|
191
191
|
}
|
|
192
192
|
/**
|
|
193
193
|
* Gets the SchemaGenerator.
|
package/README.md
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
<a href="https://mikro-orm.io"><img src="https://raw.githubusercontent.com/mikro-orm/mikro-orm/master/docs/static/img/logo-readme.svg?sanitize=true" alt="MikroORM" /></a>
|
|
3
3
|
</h1>
|
|
4
4
|
|
|
5
|
-
TypeScript ORM for Node.js based on Data Mapper, [Unit of Work](https://mikro-orm.io/docs/unit-of-work/) and [Identity Map](https://mikro-orm.io/docs/identity-map/) patterns. Supports MongoDB, MySQL, MariaDB, PostgreSQL
|
|
5
|
+
TypeScript ORM for Node.js based on Data Mapper, [Unit of Work](https://mikro-orm.io/docs/unit-of-work/) and [Identity Map](https://mikro-orm.io/docs/identity-map/) patterns. Supports MongoDB, MySQL, MariaDB, PostgreSQL, SQLite (including libSQL), MSSQL and Oracle databases.
|
|
6
6
|
|
|
7
7
|
> Heavily inspired by [Doctrine](https://www.doctrine-project.org/) and [Hibernate](https://hibernate.org/).
|
|
8
8
|
|
|
9
|
-
[](https://
|
|
10
|
-
[](https://
|
|
9
|
+
[](https://npmx.dev/package/@mikro-orm/core)
|
|
10
|
+
[](https://npmx.dev/package/@mikro-orm/core)
|
|
11
11
|
[](https://discord.gg/w8bjxFHS7X)
|
|
12
|
-
[](https://
|
|
12
|
+
[](https://npmx.dev/package/@mikro-orm/core)
|
|
13
13
|
[](https://coveralls.io/r/mikro-orm/mikro-orm?branch=master)
|
|
14
14
|
[](https://github.com/mikro-orm/mikro-orm/actions?workflow=tests)
|
|
15
15
|
|
|
@@ -181,6 +181,7 @@ yarn add @mikro-orm/core @mikro-orm/mysql # for mysql/mariadb
|
|
|
181
181
|
yarn add @mikro-orm/core @mikro-orm/mariadb # for mysql/mariadb
|
|
182
182
|
yarn add @mikro-orm/core @mikro-orm/postgresql # for postgresql
|
|
183
183
|
yarn add @mikro-orm/core @mikro-orm/mssql # for mssql
|
|
184
|
+
yarn add @mikro-orm/core @mikro-orm/oracledb # for oracle
|
|
184
185
|
yarn add @mikro-orm/core @mikro-orm/sqlite # for sqlite
|
|
185
186
|
yarn add @mikro-orm/core @mikro-orm/libsql # for libsql
|
|
186
187
|
```
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
import type { SyncCacheAdapter } from './CacheAdapter.js';
|
|
2
2
|
export declare class FileCacheAdapter implements SyncCacheAdapter {
|
|
3
|
-
private
|
|
4
|
-
private readonly baseDir;
|
|
5
|
-
private readonly pretty;
|
|
6
|
-
private readonly VERSION;
|
|
7
|
-
private cache;
|
|
3
|
+
#private;
|
|
8
4
|
constructor(options: {
|
|
9
5
|
cacheDir: string;
|
|
10
6
|
combined?: boolean | string;
|
|
@@ -2,16 +2,16 @@ import { existsSync, readFileSync, writeFileSync, unlinkSync } from 'node:fs';
|
|
|
2
2
|
import { fs } from '../utils/fs-utils.js';
|
|
3
3
|
import { Utils } from '../utils/Utils.js';
|
|
4
4
|
export class FileCacheAdapter {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
#VERSION = Utils.getORMVersion();
|
|
6
|
+
#cache = {};
|
|
7
|
+
#options;
|
|
8
|
+
#baseDir;
|
|
9
|
+
#pretty;
|
|
10
10
|
constructor(options = {}, baseDir, pretty = false) {
|
|
11
|
-
this
|
|
12
|
-
this
|
|
13
|
-
this
|
|
14
|
-
this
|
|
11
|
+
this.#options = options;
|
|
12
|
+
this.#baseDir = baseDir;
|
|
13
|
+
this.#pretty = pretty;
|
|
14
|
+
this.#options.cacheDir ??= process.cwd() + '/temp';
|
|
15
15
|
}
|
|
16
16
|
/**
|
|
17
17
|
* @inheritDoc
|
|
@@ -32,13 +32,13 @@ export class FileCacheAdapter {
|
|
|
32
32
|
* @inheritDoc
|
|
33
33
|
*/
|
|
34
34
|
set(name, data, origin) {
|
|
35
|
-
if (this
|
|
36
|
-
this
|
|
35
|
+
if (this.#options.combined) {
|
|
36
|
+
this.#cache[name.replace(/\.[jt]s$/, '')] = data;
|
|
37
37
|
return;
|
|
38
38
|
}
|
|
39
39
|
const path = this.path(name);
|
|
40
40
|
const hash = this.getHash(origin);
|
|
41
|
-
writeFileSync(path, JSON.stringify({ data, origin, hash, version: this
|
|
41
|
+
writeFileSync(path, JSON.stringify({ data, origin, hash, version: this.#VERSION }, null, this.#pretty ? 2 : undefined));
|
|
42
42
|
}
|
|
43
43
|
/**
|
|
44
44
|
* @inheritDoc
|
|
@@ -62,28 +62,28 @@ export class FileCacheAdapter {
|
|
|
62
62
|
// ignore if file is already gone
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
|
-
this
|
|
65
|
+
this.#cache = {};
|
|
66
66
|
}
|
|
67
67
|
combine() {
|
|
68
|
-
if (!this
|
|
68
|
+
if (!this.#options.combined) {
|
|
69
69
|
return;
|
|
70
70
|
}
|
|
71
|
-
let path = typeof this
|
|
72
|
-
path = fs.normalizePath(this
|
|
73
|
-
this
|
|
74
|
-
writeFileSync(path, JSON.stringify(this
|
|
71
|
+
let path = typeof this.#options.combined === 'string' ? this.#options.combined : './metadata.json';
|
|
72
|
+
path = fs.normalizePath(this.#options.cacheDir, path);
|
|
73
|
+
this.#options.combined = path; // override in the options, so we can log it from the CLI in `cache:generate` command
|
|
74
|
+
writeFileSync(path, JSON.stringify(this.#cache, null, this.#pretty ? 2 : undefined));
|
|
75
75
|
return path;
|
|
76
76
|
}
|
|
77
77
|
path(name) {
|
|
78
|
-
fs.ensureDir(this
|
|
79
|
-
return `${this
|
|
78
|
+
fs.ensureDir(this.#options.cacheDir);
|
|
79
|
+
return `${this.#options.cacheDir}/${name}.json`;
|
|
80
80
|
}
|
|
81
81
|
getHash(origin) {
|
|
82
|
-
origin = fs.absolutePath(origin, this
|
|
82
|
+
origin = fs.absolutePath(origin, this.#baseDir);
|
|
83
83
|
if (!existsSync(origin)) {
|
|
84
84
|
return null;
|
|
85
85
|
}
|
|
86
86
|
const contents = readFileSync(origin);
|
|
87
|
-
return Utils.hash(contents.toString() + this
|
|
87
|
+
return Utils.hash(contents.toString() + this.#VERSION);
|
|
88
88
|
}
|
|
89
89
|
}
|
|
@@ -1,32 +1,32 @@
|
|
|
1
1
|
export class GeneratedCacheAdapter {
|
|
2
|
-
data
|
|
2
|
+
#data;
|
|
3
3
|
constructor(options) {
|
|
4
|
-
this
|
|
4
|
+
this.#data = new Map(Object.entries(options.data));
|
|
5
5
|
}
|
|
6
6
|
/**
|
|
7
7
|
* @inheritDoc
|
|
8
8
|
*/
|
|
9
9
|
get(name) {
|
|
10
10
|
const key = name.replace(/\.[jt]s$/, '');
|
|
11
|
-
const data = this
|
|
11
|
+
const data = this.#data.get(key);
|
|
12
12
|
return data;
|
|
13
13
|
}
|
|
14
14
|
/**
|
|
15
15
|
* @inheritDoc
|
|
16
16
|
*/
|
|
17
17
|
set(name, data, origin) {
|
|
18
|
-
this
|
|
18
|
+
this.#data.set(name, { data });
|
|
19
19
|
}
|
|
20
20
|
/**
|
|
21
21
|
* @inheritDoc
|
|
22
22
|
*/
|
|
23
23
|
remove(name) {
|
|
24
|
-
this
|
|
24
|
+
this.#data.delete(name);
|
|
25
25
|
}
|
|
26
26
|
/**
|
|
27
27
|
* @inheritDoc
|
|
28
28
|
*/
|
|
29
29
|
clear() {
|
|
30
|
-
this
|
|
30
|
+
this.#data.clear();
|
|
31
31
|
}
|
|
32
32
|
}
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
export class MemoryCacheAdapter {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
#data = new Map();
|
|
3
|
+
#options;
|
|
4
4
|
constructor(options) {
|
|
5
|
-
this
|
|
5
|
+
this.#options = options;
|
|
6
6
|
}
|
|
7
7
|
/**
|
|
8
8
|
* @inheritDoc
|
|
9
9
|
*/
|
|
10
10
|
get(name) {
|
|
11
|
-
const data = this
|
|
11
|
+
const data = this.#data.get(name);
|
|
12
12
|
if (data) {
|
|
13
13
|
if (data.expiration < Date.now()) {
|
|
14
|
-
this
|
|
14
|
+
this.#data.delete(name);
|
|
15
15
|
}
|
|
16
16
|
else {
|
|
17
17
|
return data.data;
|
|
@@ -23,18 +23,18 @@ export class MemoryCacheAdapter {
|
|
|
23
23
|
* @inheritDoc
|
|
24
24
|
*/
|
|
25
25
|
set(name, data, origin, expiration) {
|
|
26
|
-
this
|
|
26
|
+
this.#data.set(name, { data, expiration: Date.now() + (expiration ?? this.#options.expiration) });
|
|
27
27
|
}
|
|
28
28
|
/**
|
|
29
29
|
* @inheritDoc
|
|
30
30
|
*/
|
|
31
31
|
remove(name) {
|
|
32
|
-
this
|
|
32
|
+
this.#data.delete(name);
|
|
33
33
|
}
|
|
34
34
|
/**
|
|
35
35
|
* @inheritDoc
|
|
36
36
|
*/
|
|
37
37
|
clear() {
|
|
38
|
-
this
|
|
38
|
+
this.#data.clear();
|
|
39
39
|
}
|
|
40
40
|
}
|
package/cache/index.d.ts
CHANGED
package/cache/index.js
CHANGED
|
@@ -6,6 +6,7 @@ import type { Platform } from '../platforms/Platform.js';
|
|
|
6
6
|
import type { TransactionEventBroadcaster } from '../events/TransactionEventBroadcaster.js';
|
|
7
7
|
import type { IsolationLevel } from '../enums.js';
|
|
8
8
|
export declare abstract class Connection {
|
|
9
|
+
#private;
|
|
9
10
|
protected readonly config: Configuration;
|
|
10
11
|
protected readonly type: ConnectionType;
|
|
11
12
|
protected metadata: MetadataStorage;
|
|
@@ -7,6 +7,12 @@ export class Connection {
|
|
|
7
7
|
options;
|
|
8
8
|
logger;
|
|
9
9
|
connected = false;
|
|
10
|
+
get #connectionLabel() {
|
|
11
|
+
return {
|
|
12
|
+
type: this.type,
|
|
13
|
+
name: this.options.name || this.config.get('name') || this.options.host || this.options.dbName,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
10
16
|
constructor(config, options, type = 'write') {
|
|
11
17
|
this.config = config;
|
|
12
18
|
this.type = type;
|
|
@@ -120,28 +126,38 @@ export class Connection {
|
|
|
120
126
|
const now = Date.now();
|
|
121
127
|
try {
|
|
122
128
|
const res = await cb();
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
affected: Utils.isPlainObject(res) ? res.affectedRows : undefined,
|
|
128
|
-
});
|
|
129
|
+
const took = Date.now() - now;
|
|
130
|
+
const results = Array.isArray(res) ? res.length : undefined;
|
|
131
|
+
const affected = Utils.isPlainObject(res) ? res.affectedRows : undefined;
|
|
132
|
+
this.logQuery(query, { ...context, took, results, affected });
|
|
129
133
|
return res;
|
|
130
134
|
}
|
|
131
135
|
catch (e) {
|
|
132
|
-
|
|
136
|
+
const took = Date.now() - now;
|
|
137
|
+
this.logQuery(query, { ...context, took, level: 'error' });
|
|
133
138
|
throw e;
|
|
134
139
|
}
|
|
135
140
|
}
|
|
136
141
|
logQuery(query, context = {}) {
|
|
142
|
+
const connection = this.#connectionLabel;
|
|
137
143
|
this.logger.logQuery({
|
|
138
144
|
level: 'info',
|
|
139
|
-
connection
|
|
140
|
-
type: this.type,
|
|
141
|
-
name: this.options.name || this.config.get('name') || this.options.host,
|
|
142
|
-
},
|
|
145
|
+
connection,
|
|
143
146
|
...context,
|
|
144
147
|
query,
|
|
145
148
|
});
|
|
149
|
+
const threshold = this.config.get('slowQueryThreshold');
|
|
150
|
+
if (threshold != null && (context.took ?? 0) >= threshold) {
|
|
151
|
+
this.config.getSlowQueryLogger().logQuery({
|
|
152
|
+
...context,
|
|
153
|
+
// `enabled: true` bypasses the debug-mode check in isEnabled(),
|
|
154
|
+
// ensuring slow query logs are always emitted regardless of the `debug` setting.
|
|
155
|
+
enabled: true,
|
|
156
|
+
level: context.level ?? 'warning',
|
|
157
|
+
namespace: 'slow-query',
|
|
158
|
+
connection,
|
|
159
|
+
query,
|
|
160
|
+
});
|
|
161
|
+
}
|
|
146
162
|
}
|
|
147
163
|
}
|
|
@@ -9,7 +9,6 @@ import type { Platform } from '../platforms/Platform.js';
|
|
|
9
9
|
import type { Collection } from '../entity/Collection.js';
|
|
10
10
|
import { EntityManager } from '../EntityManager.js';
|
|
11
11
|
import { DriverException } from '../exceptions.js';
|
|
12
|
-
import type { Logger } from '../logging/Logger.js';
|
|
13
12
|
import { MikroORM } from '../MikroORM.js';
|
|
14
13
|
export declare abstract class DatabaseDriver<C extends Connection> implements IDatabaseDriver<C> {
|
|
15
14
|
readonly config: Configuration;
|
|
@@ -18,7 +17,6 @@ export declare abstract class DatabaseDriver<C extends Connection> implements ID
|
|
|
18
17
|
protected readonly connection: C;
|
|
19
18
|
protected readonly replicas: C[];
|
|
20
19
|
protected readonly platform: Platform;
|
|
21
|
-
protected readonly logger: Logger;
|
|
22
20
|
protected comparator: EntityComparator;
|
|
23
21
|
protected metadata: MetadataStorage;
|
|
24
22
|
protected constructor(config: Configuration, dependencies: string[]);
|
|
@@ -18,13 +18,11 @@ export class DatabaseDriver {
|
|
|
18
18
|
connection;
|
|
19
19
|
replicas = [];
|
|
20
20
|
platform;
|
|
21
|
-
logger;
|
|
22
21
|
comparator;
|
|
23
22
|
metadata;
|
|
24
23
|
constructor(config, dependencies) {
|
|
25
24
|
this.config = config;
|
|
26
25
|
this.dependencies = dependencies;
|
|
27
|
-
this.logger = this.config.getLogger();
|
|
28
26
|
}
|
|
29
27
|
async nativeUpdateMany(entityName, where, data, options) {
|
|
30
28
|
throw new Error(`Batch updates are not supported by ${this.constructor.name} driver`);
|
|
@@ -348,8 +346,8 @@ export class DatabaseDriver {
|
|
|
348
346
|
const props = prop.embeddedProps;
|
|
349
347
|
let unknownProp = false;
|
|
350
348
|
Object.keys(data[prop.name]).forEach(kk => {
|
|
351
|
-
// explicitly allow `$exists`, `$eq` and `$
|
|
352
|
-
const operator = Object.keys(data[prop.name]).some(f => Utils.isOperator(f) && !['$exists', '$ne', '$eq'].includes(f));
|
|
349
|
+
// explicitly allow `$exists`, `$eq`, `$ne` and `$elemMatch` operators here as they can't be misused this way
|
|
350
|
+
const operator = Object.keys(data[prop.name]).some(f => Utils.isOperator(f) && !['$exists', '$ne', '$eq', '$elemMatch'].includes(f));
|
|
353
351
|
if (operator) {
|
|
354
352
|
throw ValidationError.cannotUseOperatorsInsideEmbeddables(meta.class, prop.name, data);
|
|
355
353
|
}
|
package/entity/Collection.d.ts
CHANGED
|
@@ -9,17 +9,9 @@ export interface MatchingOptions<T extends object, P extends string = never> ext
|
|
|
9
9
|
ctx?: Transaction;
|
|
10
10
|
}
|
|
11
11
|
export declare class Collection<T extends object, O extends object = object> {
|
|
12
|
+
#private;
|
|
12
13
|
readonly owner: O;
|
|
13
14
|
[k: number]: T;
|
|
14
|
-
protected readonly items: Set<T>;
|
|
15
|
-
protected initialized: boolean;
|
|
16
|
-
protected dirty: boolean;
|
|
17
|
-
protected partial: boolean;
|
|
18
|
-
protected snapshot: T[] | undefined;
|
|
19
|
-
private readonly?;
|
|
20
|
-
protected _count?: number;
|
|
21
|
-
private _property?;
|
|
22
|
-
private _populated?;
|
|
23
15
|
constructor(owner: O, items?: T[], initialized?: boolean);
|
|
24
16
|
/**
|
|
25
17
|
* Creates new Collection instance, assigns it to the owning entity and sets the items to it (propagating them to their inverse sides)
|