@mikro-orm/mongodb 7.0.0-dev.32 → 7.0.0-dev.321
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/MongoConnection.d.ts +37 -15
- package/MongoConnection.js +154 -87
- package/MongoDriver.d.ts +21 -12
- package/MongoDriver.js +140 -28
- package/MongoEntityManager.d.ts +11 -3
- package/MongoEntityManager.js +19 -5
- package/MongoExceptionConverter.d.ts +1 -1
- package/MongoExceptionConverter.js +3 -4
- package/MongoMikroORM.d.ts +10 -7
- package/MongoMikroORM.js +14 -8
- package/MongoPlatform.d.ts +2 -4
- package/MongoPlatform.js +7 -10
- package/MongoSchemaGenerator.d.ts +8 -5
- package/MongoSchemaGenerator.js +81 -35
- package/README.md +7 -4
- package/index.d.ts +1 -1
- package/package.json +32 -32
- package/tsconfig.build.tsbuildinfo +1 -0
package/MongoConnection.d.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { type ClientSession, type Collection, type Db, MongoClient, type MongoClientOptions, type TransactionOptions } from 'mongodb';
|
|
2
|
+
import { type AnyEntity, type CollationOptions, type Configuration, Connection, type ConnectionOptions, type ConnectionType, type Dictionary, type EntityData, type EntityName, type FilterQuery, type IsolationLevel, type LoggingOptions, type QueryOrderMap, type QueryResult, type Transaction, type TransactionEventBroadcaster, type UpsertManyOptions, type UpsertOptions } from '@mikro-orm/core';
|
|
3
3
|
export declare class MongoConnection extends Connection {
|
|
4
|
-
|
|
5
|
-
protected db: Db;
|
|
4
|
+
#private;
|
|
6
5
|
constructor(config: Configuration, options?: ConnectionOptions, type?: ConnectionType);
|
|
7
|
-
connect(
|
|
6
|
+
connect(options?: {
|
|
7
|
+
skipOnConnect?: boolean;
|
|
8
|
+
}): Promise<void>;
|
|
9
|
+
createClient(): void;
|
|
8
10
|
close(force?: boolean): Promise<void>;
|
|
9
11
|
isConnected(): Promise<boolean>;
|
|
10
12
|
checkConnection(): Promise<{
|
|
@@ -15,22 +17,24 @@ export declare class MongoConnection extends Connection {
|
|
|
15
17
|
error?: Error;
|
|
16
18
|
}>;
|
|
17
19
|
getClient(): MongoClient;
|
|
18
|
-
getCollection<T extends object>(name: EntityName<T>): Collection<T>;
|
|
20
|
+
getCollection<T extends object>(name: EntityName<T> | string): Collection<T>;
|
|
19
21
|
createCollection<T extends object>(name: EntityName<T>): Promise<Collection<T>>;
|
|
20
22
|
listCollections(): Promise<string[]>;
|
|
21
23
|
dropCollection(name: EntityName<AnyEntity>): Promise<boolean>;
|
|
22
24
|
mapOptions(overrides: MongoClientOptions): MongoClientOptions;
|
|
23
|
-
getClientUrl(): string;
|
|
24
25
|
getDb(): Db;
|
|
25
26
|
execute(query: string): Promise<any>;
|
|
26
|
-
find<T extends object>(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
27
|
+
find<T extends object>(entityName: EntityName<T>, where: FilterQuery<T>, opts?: MongoFindOptions<T>): Promise<EntityData<T>[]>;
|
|
28
|
+
stream<T extends object>(entityName: EntityName<T>, where: FilterQuery<T>, opts?: MongoFindOptions<T>): AsyncIterableIterator<T>;
|
|
29
|
+
private _find;
|
|
30
|
+
insertOne<T extends object>(entityName: EntityName<T>, data: Partial<T>, ctx?: Transaction<ClientSession>): Promise<QueryResult<T>>;
|
|
31
|
+
insertMany<T extends object>(entityName: EntityName<T>, data: Partial<T>[], ctx?: Transaction<ClientSession>): Promise<QueryResult<T>>;
|
|
32
|
+
updateMany<T extends object>(entityName: EntityName<T>, where: FilterQuery<T>, data: Partial<T>, ctx?: Transaction<ClientSession>, upsert?: boolean, upsertOptions?: UpsertOptions<T>): Promise<QueryResult<T>>;
|
|
33
|
+
bulkUpdateMany<T extends object>(entityName: EntityName<T>, where: FilterQuery<T>[], data: Partial<T>[], ctx?: Transaction<ClientSession>, upsert?: boolean, upsertOptions?: UpsertManyOptions<T>): Promise<QueryResult<T>>;
|
|
34
|
+
deleteMany<T extends object>(entityName: EntityName<T>, where: FilterQuery<T>, ctx?: Transaction<ClientSession>): Promise<QueryResult<T>>;
|
|
35
|
+
aggregate<T extends object = any>(entityName: EntityName<T>, pipeline: any[], ctx?: Transaction<ClientSession>, loggerContext?: LoggingOptions): Promise<T[]>;
|
|
36
|
+
streamAggregate<T extends object>(entityName: EntityName<T>, pipeline: any[], ctx?: Transaction<ClientSession>, loggerContext?: LoggingOptions, stream?: boolean): AsyncIterableIterator<T>;
|
|
37
|
+
countDocuments<T extends object>(entityName: EntityName<T>, where: FilterQuery<T>, opts?: MongoCountOptions): Promise<number>;
|
|
34
38
|
transactional<T>(cb: (trx: Transaction<ClientSession>) => Promise<T>, options?: {
|
|
35
39
|
isolationLevel?: IsolationLevel;
|
|
36
40
|
ctx?: Transaction<ClientSession>;
|
|
@@ -50,3 +54,21 @@ export declare class MongoConnection extends Connection {
|
|
|
50
54
|
private getCollectionName;
|
|
51
55
|
private logObject;
|
|
52
56
|
}
|
|
57
|
+
export interface MongoQueryOptions {
|
|
58
|
+
collation?: CollationOptions;
|
|
59
|
+
indexHint?: string | Dictionary;
|
|
60
|
+
maxTimeMS?: number;
|
|
61
|
+
allowDiskUse?: boolean;
|
|
62
|
+
}
|
|
63
|
+
export interface MongoFindOptions<T extends object> extends MongoQueryOptions {
|
|
64
|
+
orderBy?: QueryOrderMap<T> | QueryOrderMap<T>[];
|
|
65
|
+
limit?: number;
|
|
66
|
+
offset?: number;
|
|
67
|
+
fields?: string[];
|
|
68
|
+
ctx?: Transaction<ClientSession>;
|
|
69
|
+
loggerContext?: LoggingOptions;
|
|
70
|
+
}
|
|
71
|
+
export interface MongoCountOptions extends Omit<MongoQueryOptions, 'allowDiskUse'> {
|
|
72
|
+
ctx?: Transaction<ClientSession>;
|
|
73
|
+
loggerContext?: LoggingOptions;
|
|
74
|
+
}
|
package/MongoConnection.js
CHANGED
|
@@ -1,58 +1,63 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { inspect } from '
|
|
3
|
-
import { Connection, EventType, QueryOrder, Utils, ValidationError, } from '@mikro-orm/core';
|
|
1
|
+
import { MongoClient, ObjectId, } from 'mongodb';
|
|
2
|
+
import { Connection, EventType, inspect, QueryOrder, Utils, ValidationError, } from '@mikro-orm/core';
|
|
4
3
|
export class MongoConnection extends Connection {
|
|
5
|
-
client;
|
|
6
|
-
db;
|
|
4
|
+
#client;
|
|
5
|
+
#db;
|
|
7
6
|
constructor(config, options, type = 'write') {
|
|
8
7
|
super(config, options, type);
|
|
9
8
|
// @ts-ignore
|
|
10
|
-
ObjectId.prototype[inspect.custom] = function () {
|
|
9
|
+
ObjectId.prototype[Symbol.for('nodejs.util.inspect.custom')] = function () {
|
|
11
10
|
return `ObjectId('${this.toHexString()}')`;
|
|
12
11
|
};
|
|
13
12
|
// @ts-ignore
|
|
14
|
-
Date.prototype[inspect.custom] = function () {
|
|
13
|
+
Date.prototype[Symbol.for('nodejs.util.inspect.custom')] = function () {
|
|
15
14
|
return `ISODate('${this.toISOString()}')`;
|
|
16
15
|
};
|
|
17
16
|
}
|
|
18
|
-
async connect() {
|
|
17
|
+
async connect(options) {
|
|
18
|
+
this.getClient();
|
|
19
|
+
this.connected = true;
|
|
20
|
+
if (options?.skipOnConnect !== true) {
|
|
21
|
+
await this.onConnect();
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
createClient() {
|
|
19
25
|
let driverOptions = this.options.driverOptions ?? this.config.get('driverOptions');
|
|
20
26
|
if (typeof driverOptions === 'function') {
|
|
21
|
-
driverOptions =
|
|
27
|
+
driverOptions = driverOptions();
|
|
22
28
|
}
|
|
23
29
|
if (driverOptions instanceof MongoClient) {
|
|
24
30
|
this.logger.log('info', 'Reusing MongoClient provided via `driverOptions`');
|
|
25
|
-
this
|
|
31
|
+
this.#client = driverOptions;
|
|
26
32
|
}
|
|
27
33
|
else {
|
|
28
|
-
this
|
|
29
|
-
await this.client.connect();
|
|
34
|
+
this.#client = new MongoClient(this.config.get('clientUrl'), this.mapOptions(driverOptions));
|
|
30
35
|
const onCreateConnection = this.options.onCreateConnection ?? this.config.get('onCreateConnection');
|
|
31
|
-
/* v8 ignore next
|
|
32
|
-
this
|
|
33
|
-
void onCreateConnection?.(this
|
|
36
|
+
/* v8 ignore next */
|
|
37
|
+
this.#client.on('connectionCreated', () => {
|
|
38
|
+
void onCreateConnection?.(this.#client);
|
|
34
39
|
});
|
|
35
40
|
}
|
|
36
|
-
this
|
|
37
|
-
this.connected = true;
|
|
41
|
+
this.#db = this.#client.db(this.config.get('dbName'));
|
|
38
42
|
}
|
|
39
43
|
async close(force) {
|
|
40
|
-
await this
|
|
44
|
+
await this.#client?.close(force);
|
|
41
45
|
this.connected = false;
|
|
46
|
+
this.#client = undefined;
|
|
42
47
|
}
|
|
43
48
|
async isConnected() {
|
|
44
49
|
try {
|
|
45
|
-
const res = await this
|
|
46
|
-
return this.connected = !!res
|
|
50
|
+
const res = await this.#db?.command({ ping: 1 });
|
|
51
|
+
return (this.connected = !!res?.ok);
|
|
47
52
|
}
|
|
48
53
|
catch (error) {
|
|
49
|
-
return this.connected = false;
|
|
54
|
+
return (this.connected = false);
|
|
50
55
|
}
|
|
51
56
|
}
|
|
52
57
|
async checkConnection() {
|
|
53
58
|
try {
|
|
54
|
-
const res = await this
|
|
55
|
-
return res
|
|
59
|
+
const res = await this.#db?.command({ ping: 1 });
|
|
60
|
+
return res?.ok
|
|
56
61
|
? { ok: true }
|
|
57
62
|
: { ok: false, reason: 'Ping reply does not feature "ok" property, or it evaluates to "false"' };
|
|
58
63
|
}
|
|
@@ -61,20 +66,23 @@ export class MongoConnection extends Connection {
|
|
|
61
66
|
}
|
|
62
67
|
}
|
|
63
68
|
getClient() {
|
|
64
|
-
|
|
69
|
+
if (!this.#client) {
|
|
70
|
+
this.createClient();
|
|
71
|
+
}
|
|
72
|
+
return this.#client;
|
|
65
73
|
}
|
|
66
74
|
getCollection(name) {
|
|
67
|
-
return this.
|
|
75
|
+
return this.getDb().collection(this.getCollectionName(name));
|
|
68
76
|
}
|
|
69
77
|
async createCollection(name) {
|
|
70
|
-
return this.
|
|
78
|
+
return this.getDb().createCollection(this.getCollectionName(name));
|
|
71
79
|
}
|
|
72
80
|
async listCollections() {
|
|
73
|
-
const collections = await this.
|
|
81
|
+
const collections = await this.getDb().listCollections({}, { nameOnly: true }).toArray();
|
|
74
82
|
return collections.map(c => c.name);
|
|
75
83
|
}
|
|
76
84
|
async dropCollection(name) {
|
|
77
|
-
return this.
|
|
85
|
+
return this.getDb().dropCollection(this.getCollectionName(name));
|
|
78
86
|
}
|
|
79
87
|
mapOptions(overrides) {
|
|
80
88
|
const ret = {};
|
|
@@ -96,83 +104,118 @@ export class MongoConnection extends Connection {
|
|
|
96
104
|
};
|
|
97
105
|
return Utils.mergeConfig(ret, overrides);
|
|
98
106
|
}
|
|
99
|
-
getClientUrl() {
|
|
100
|
-
const options = this.mapOptions(this.options.driverOptions ?? {});
|
|
101
|
-
const clientUrl = this.config.getClientUrl(true);
|
|
102
|
-
const match = clientUrl.match(/^(\w+):\/\/((.*@.+)|.+)$/);
|
|
103
|
-
return match ? `${match[1]}://${options.auth ? options.auth.username + ':*****@' : ''}${match[2]}` : clientUrl;
|
|
104
|
-
}
|
|
105
107
|
getDb() {
|
|
106
|
-
|
|
108
|
+
this.#db ??= this.getClient().db(this.config.get('dbName'));
|
|
109
|
+
return this.#db;
|
|
107
110
|
}
|
|
108
111
|
async execute(query) {
|
|
109
112
|
throw new Error(`${this.constructor.name} does not support generic execute method`);
|
|
110
113
|
}
|
|
111
|
-
async find(
|
|
114
|
+
async find(entityName, where, opts = {}) {
|
|
115
|
+
const { cursor, query } = await this._find(entityName, where, opts);
|
|
116
|
+
const now = Date.now();
|
|
117
|
+
const res = await cursor.toArray();
|
|
118
|
+
this.logQuery(`${query}.toArray();`, { took: Date.now() - now, results: res.length, ...opts.loggerContext });
|
|
119
|
+
return res;
|
|
120
|
+
}
|
|
121
|
+
async *stream(entityName, where, opts = {}) {
|
|
122
|
+
const { cursor, query } = await this._find(entityName, where, opts);
|
|
123
|
+
this.logQuery(`${query}.toArray();`, opts.loggerContext);
|
|
124
|
+
yield* cursor;
|
|
125
|
+
}
|
|
126
|
+
async _find(entityName, where, opts = {}) {
|
|
112
127
|
await this.ensureConnection();
|
|
113
|
-
collection = this.getCollectionName(
|
|
114
|
-
const options = ctx ? { session: ctx } : {};
|
|
115
|
-
if (fields) {
|
|
116
|
-
options.projection = fields.reduce((o, k) => Object.assign(o, { [k]: 1 }), {});
|
|
128
|
+
const collection = this.getCollectionName(entityName);
|
|
129
|
+
const options = opts.ctx ? { session: opts.ctx } : {};
|
|
130
|
+
if (opts.fields) {
|
|
131
|
+
options.projection = opts.fields.reduce((o, k) => Object.assign(o, { [k]: 1 }), {});
|
|
132
|
+
}
|
|
133
|
+
if (opts.collation) {
|
|
134
|
+
options.collation = opts.collation;
|
|
135
|
+
}
|
|
136
|
+
if (opts.indexHint != null) {
|
|
137
|
+
options.hint = opts.indexHint;
|
|
138
|
+
}
|
|
139
|
+
if (opts.maxTimeMS != null) {
|
|
140
|
+
options.maxTimeMS = opts.maxTimeMS;
|
|
141
|
+
}
|
|
142
|
+
if (opts.allowDiskUse != null) {
|
|
143
|
+
options.allowDiskUse = opts.allowDiskUse;
|
|
117
144
|
}
|
|
118
|
-
const resultSet = this.getCollection(
|
|
145
|
+
const resultSet = this.getCollection(entityName).find(where, options);
|
|
119
146
|
let query = `db.getCollection('${collection}').find(${this.logObject(where)}, ${this.logObject(options)})`;
|
|
120
|
-
orderBy = Utils.asArray(orderBy);
|
|
121
|
-
if (
|
|
147
|
+
const orderBy = Utils.asArray(opts.orderBy);
|
|
148
|
+
if (orderBy.length > 0) {
|
|
122
149
|
const orderByTuples = [];
|
|
123
150
|
orderBy.forEach(o => {
|
|
124
151
|
Utils.keys(o).forEach(k => {
|
|
125
152
|
const direction = o[k];
|
|
126
|
-
|
|
153
|
+
if (typeof direction === 'string') {
|
|
154
|
+
orderByTuples.push([k.toString(), direction.toUpperCase() === QueryOrder.ASC ? 1 : -1]);
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
orderByTuples.push([k.toString(), direction]);
|
|
158
|
+
}
|
|
127
159
|
});
|
|
128
160
|
});
|
|
129
161
|
if (orderByTuples.length > 0) {
|
|
130
162
|
query += `.sort(${this.logObject(orderByTuples)})`;
|
|
131
|
-
// @ts-expect-error ??
|
|
132
163
|
resultSet.sort(orderByTuples);
|
|
133
164
|
}
|
|
134
165
|
}
|
|
135
|
-
if (limit !== undefined) {
|
|
136
|
-
query += `.limit(${limit})`;
|
|
137
|
-
resultSet.limit(limit);
|
|
166
|
+
if (opts.limit !== undefined) {
|
|
167
|
+
query += `.limit(${opts.limit})`;
|
|
168
|
+
resultSet.limit(opts.limit);
|
|
138
169
|
}
|
|
139
|
-
if (offset !== undefined) {
|
|
140
|
-
query += `.skip(${offset})`;
|
|
141
|
-
resultSet.skip(offset);
|
|
170
|
+
if (opts.offset !== undefined) {
|
|
171
|
+
query += `.skip(${opts.offset})`;
|
|
172
|
+
resultSet.skip(opts.offset);
|
|
142
173
|
}
|
|
143
|
-
|
|
144
|
-
const res = await resultSet.toArray();
|
|
145
|
-
this.logQuery(`${query}.toArray();`, { took: Date.now() - now, results: res.length, ...loggerContext });
|
|
146
|
-
return res;
|
|
174
|
+
return { cursor: resultSet, query };
|
|
147
175
|
}
|
|
148
|
-
async insertOne(
|
|
149
|
-
return this.runQuery('insertOne',
|
|
176
|
+
async insertOne(entityName, data, ctx) {
|
|
177
|
+
return this.runQuery('insertOne', entityName, data, undefined, ctx);
|
|
150
178
|
}
|
|
151
|
-
async insertMany(
|
|
152
|
-
return this.runQuery('insertMany',
|
|
179
|
+
async insertMany(entityName, data, ctx) {
|
|
180
|
+
return this.runQuery('insertMany', entityName, data, undefined, ctx);
|
|
153
181
|
}
|
|
154
|
-
async updateMany(
|
|
155
|
-
return this.runQuery('updateMany',
|
|
182
|
+
async updateMany(entityName, where, data, ctx, upsert, upsertOptions) {
|
|
183
|
+
return this.runQuery('updateMany', entityName, data, where, ctx, { upsert, upsertOptions });
|
|
156
184
|
}
|
|
157
|
-
async bulkUpdateMany(
|
|
158
|
-
return this.runQuery('bulkUpdateMany',
|
|
185
|
+
async bulkUpdateMany(entityName, where, data, ctx, upsert, upsertOptions) {
|
|
186
|
+
return this.runQuery('bulkUpdateMany', entityName, data, where, ctx, { upsert, upsertOptions });
|
|
159
187
|
}
|
|
160
|
-
async deleteMany(
|
|
161
|
-
return this.runQuery('deleteMany',
|
|
188
|
+
async deleteMany(entityName, where, ctx) {
|
|
189
|
+
return this.runQuery('deleteMany', entityName, undefined, where, ctx);
|
|
162
190
|
}
|
|
163
|
-
async aggregate(
|
|
191
|
+
async aggregate(entityName, pipeline, ctx, loggerContext) {
|
|
164
192
|
await this.ensureConnection();
|
|
165
|
-
collection = this.getCollectionName(
|
|
193
|
+
const collection = this.getCollectionName(entityName);
|
|
166
194
|
/* v8 ignore next */
|
|
167
195
|
const options = ctx ? { session: ctx } : {};
|
|
168
196
|
const query = `db.getCollection('${collection}').aggregate(${this.logObject(pipeline)}, ${this.logObject(options)}).toArray();`;
|
|
169
197
|
const now = Date.now();
|
|
170
|
-
const res = await this.getCollection(
|
|
198
|
+
const res = await this.getCollection(entityName).aggregate(pipeline, options).toArray();
|
|
171
199
|
this.logQuery(query, { took: Date.now() - now, results: res.length, ...loggerContext });
|
|
172
200
|
return res;
|
|
173
201
|
}
|
|
174
|
-
async
|
|
175
|
-
|
|
202
|
+
async *streamAggregate(entityName, pipeline, ctx, loggerContext, stream = false) {
|
|
203
|
+
await this.ensureConnection();
|
|
204
|
+
const collection = this.getCollectionName(entityName);
|
|
205
|
+
/* v8 ignore next */
|
|
206
|
+
const options = ctx ? { session: ctx } : {};
|
|
207
|
+
const query = `db.getCollection('${collection}').aggregate(${this.logObject(pipeline)}, ${this.logObject(options)})};`;
|
|
208
|
+
const cursor = this.getCollection(entityName).aggregate(pipeline, options);
|
|
209
|
+
this.logQuery(query, { ...loggerContext });
|
|
210
|
+
yield* cursor;
|
|
211
|
+
}
|
|
212
|
+
async countDocuments(entityName, where, opts = {}) {
|
|
213
|
+
return this.runQuery('countDocuments', entityName, undefined, where, opts.ctx, {
|
|
214
|
+
loggerContext: opts.loggerContext,
|
|
215
|
+
collation: opts.collation,
|
|
216
|
+
indexHint: opts.indexHint,
|
|
217
|
+
maxTimeMS: opts.maxTimeMS,
|
|
218
|
+
});
|
|
176
219
|
}
|
|
177
220
|
async transactional(cb, options = {}) {
|
|
178
221
|
await this.ensureConnection();
|
|
@@ -196,7 +239,7 @@ export class MongoConnection extends Connection {
|
|
|
196
239
|
if (!ctx) {
|
|
197
240
|
await eventBroadcaster?.dispatchEvent(EventType.beforeTransactionStart);
|
|
198
241
|
}
|
|
199
|
-
const session = ctx || this.
|
|
242
|
+
const session = ctx || this.getClient().startSession();
|
|
200
243
|
session.startTransaction(txOptions);
|
|
201
244
|
this.logQuery('db.begin();');
|
|
202
245
|
await eventBroadcaster?.dispatchEvent(EventType.afterTransactionStart, session);
|
|
@@ -216,9 +259,10 @@ export class MongoConnection extends Connection {
|
|
|
216
259
|
this.logQuery('db.rollback();');
|
|
217
260
|
await eventBroadcaster?.dispatchEvent(EventType.afterTransactionRollback, ctx);
|
|
218
261
|
}
|
|
219
|
-
async runQuery(method,
|
|
262
|
+
async runQuery(method, entityName, data, where, ctx, opts) {
|
|
220
263
|
await this.ensureConnection();
|
|
221
|
-
|
|
264
|
+
const { upsert, upsertOptions, loggerContext, collation, indexHint, maxTimeMS } = opts ?? {};
|
|
265
|
+
const collection = this.getCollectionName(entityName);
|
|
222
266
|
const logger = this.config.getLogger();
|
|
223
267
|
const options = ctx ? { session: ctx, upsert } : { upsert };
|
|
224
268
|
if (options.upsert === undefined) {
|
|
@@ -227,27 +271,33 @@ export class MongoConnection extends Connection {
|
|
|
227
271
|
const now = Date.now();
|
|
228
272
|
let res;
|
|
229
273
|
let query;
|
|
230
|
-
const log = (msg) => logger.isEnabled('query') ? msg() : '';
|
|
274
|
+
const log = (msg) => (logger.isEnabled('query') ? msg() : '');
|
|
231
275
|
switch (method) {
|
|
232
276
|
case 'insertOne':
|
|
233
|
-
Object.keys(data)
|
|
277
|
+
Object.keys(data)
|
|
278
|
+
.filter(k => typeof data[k] === 'undefined')
|
|
279
|
+
.forEach(k => delete data[k]);
|
|
234
280
|
query = log(() => `db.getCollection('${collection}').insertOne(${this.logObject(data)}, ${this.logObject(options)});`);
|
|
235
|
-
res = await this.rethrow(this.getCollection(
|
|
281
|
+
res = await this.rethrow(this.getCollection(entityName).insertOne(data, options), query);
|
|
236
282
|
break;
|
|
237
283
|
case 'insertMany':
|
|
238
|
-
data.forEach(data => Object.keys(data)
|
|
284
|
+
data.forEach(data => Object.keys(data)
|
|
285
|
+
.filter(k => typeof data[k] === 'undefined')
|
|
286
|
+
.forEach(k => delete data[k]));
|
|
239
287
|
query = log(() => `db.getCollection('${collection}').insertMany(${this.logObject(data)}, ${this.logObject(options)});`);
|
|
240
|
-
res = await this.rethrow(this.getCollection(
|
|
288
|
+
res = await this.rethrow(this.getCollection(entityName).insertMany(data, options), query);
|
|
241
289
|
break;
|
|
242
290
|
case 'updateMany': {
|
|
243
|
-
const payload = Object.keys(data).
|
|
291
|
+
const payload = Object.keys(data).every(k => k.startsWith('$'))
|
|
292
|
+
? data
|
|
293
|
+
: this.createUpdatePayload(data, upsertOptions);
|
|
244
294
|
query = log(() => `db.getCollection('${collection}').updateMany(${this.logObject(where)}, ${this.logObject(payload)}, ${this.logObject(options)});`);
|
|
245
|
-
res = await this.rethrow(this.getCollection(
|
|
295
|
+
res = (await this.rethrow(this.getCollection(entityName).updateMany(where, payload, options), query));
|
|
246
296
|
break;
|
|
247
297
|
}
|
|
248
298
|
case 'bulkUpdateMany': {
|
|
249
299
|
query = log(() => `bulk = db.getCollection('${collection}').initializeUnorderedBulkOp(${this.logObject(options)});\n`);
|
|
250
|
-
const bulk = this.getCollection(
|
|
300
|
+
const bulk = this.getCollection(entityName).initializeUnorderedBulkOp(options);
|
|
251
301
|
data.forEach((row, idx) => {
|
|
252
302
|
const id = where[idx];
|
|
253
303
|
const cond = Utils.isPlainObject(id) ? id : { _id: id };
|
|
@@ -272,8 +322,19 @@ export class MongoConnection extends Connection {
|
|
|
272
322
|
}
|
|
273
323
|
case 'deleteMany':
|
|
274
324
|
case 'countDocuments':
|
|
325
|
+
if (method === 'countDocuments') {
|
|
326
|
+
if (collation) {
|
|
327
|
+
options.collation = collation;
|
|
328
|
+
}
|
|
329
|
+
if (indexHint != null) {
|
|
330
|
+
options.hint = indexHint;
|
|
331
|
+
}
|
|
332
|
+
if (maxTimeMS != null) {
|
|
333
|
+
options.maxTimeMS = maxTimeMS;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
275
336
|
query = log(() => `db.getCollection('${collection}').${method}(${this.logObject(where)}, ${this.logObject(options)});`);
|
|
276
|
-
res = await this.rethrow(this.getCollection(
|
|
337
|
+
res = await this.rethrow(this.getCollection(entityName)[method](where, options), query);
|
|
277
338
|
break;
|
|
278
339
|
}
|
|
279
340
|
this.logQuery(query, { took: Date.now() - now, ...loggerContext });
|
|
@@ -290,7 +351,14 @@ export class MongoConnection extends Connection {
|
|
|
290
351
|
});
|
|
291
352
|
}
|
|
292
353
|
createUpdatePayload(row, upsertOptions) {
|
|
354
|
+
row = { ...row };
|
|
293
355
|
const doc = { $set: row };
|
|
356
|
+
Utils.keys(row).forEach(k => {
|
|
357
|
+
if (k.toString().startsWith('$')) {
|
|
358
|
+
doc[k] = row[k];
|
|
359
|
+
delete row[k];
|
|
360
|
+
}
|
|
361
|
+
});
|
|
294
362
|
const $unset = {};
|
|
295
363
|
const $inc = {};
|
|
296
364
|
for (const k of Utils.keys(row)) {
|
|
@@ -346,13 +414,12 @@ export class MongoConnection extends Connection {
|
|
|
346
414
|
insertedIds: res.insertedIds ? Object.values(res.insertedIds) : undefined,
|
|
347
415
|
};
|
|
348
416
|
}
|
|
349
|
-
getCollectionName(
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
return meta ? meta.collection : name;
|
|
417
|
+
getCollectionName(entityName) {
|
|
418
|
+
const meta = this.metadata.find(entityName);
|
|
419
|
+
return meta ? meta.collection : Utils.className(entityName);
|
|
353
420
|
}
|
|
354
421
|
logObject(o) {
|
|
355
|
-
if (o
|
|
422
|
+
if (o?.session) {
|
|
356
423
|
o = { ...o, session: `[ClientSession]` };
|
|
357
424
|
}
|
|
358
425
|
return inspect(o, { depth: 5, compact: true, breakLength: 300 });
|
package/MongoDriver.d.ts
CHANGED
|
@@ -1,30 +1,39 @@
|
|
|
1
1
|
import { type ClientSession } from 'mongodb';
|
|
2
|
-
import { type Configuration, type CountOptions, DatabaseDriver, type EntityData, type EntityDictionary, type EntityField, EntityManagerType, type FilterQuery, type FindOneOptions, type FindOptions, type NativeInsertUpdateManyOptions, type NativeInsertUpdateOptions, type PopulateOptions, type PopulatePath, type QueryResult, type Transaction, type UpsertManyOptions, type UpsertOptions } from '@mikro-orm/core';
|
|
2
|
+
import { type Configuration, type Constructor, type CountOptions, DatabaseDriver, type EntityData, type EntityDictionary, type EntityField, EntityManagerType, type EntityName, type FilterQuery, type FindOneOptions, type FindOptions, type NativeInsertUpdateManyOptions, type NativeInsertUpdateOptions, type PopulateOptions, type PopulatePath, type QueryResult, type StreamOptions, type Transaction, type UpsertManyOptions, type UpsertOptions } from '@mikro-orm/core';
|
|
3
3
|
import { MongoConnection } from './MongoConnection.js';
|
|
4
4
|
import { MongoPlatform } from './MongoPlatform.js';
|
|
5
5
|
import { MongoEntityManager } from './MongoEntityManager.js';
|
|
6
|
+
import { MongoMikroORM } from './MongoMikroORM.js';
|
|
6
7
|
export declare class MongoDriver extends DatabaseDriver<MongoConnection> {
|
|
7
8
|
[EntityManagerType]: MongoEntityManager<this>;
|
|
8
9
|
protected readonly connection: MongoConnection;
|
|
9
10
|
protected readonly platform: MongoPlatform;
|
|
10
11
|
constructor(config: Configuration);
|
|
11
12
|
createEntityManager(useContext?: boolean): this[typeof EntityManagerType];
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
13
|
+
stream<T extends object>(entityName: EntityName<T>, where: FilterQuery<T>, options: StreamOptions<T, any, any, any> & {
|
|
14
|
+
rawResults?: boolean;
|
|
15
|
+
}): AsyncIterableIterator<T>;
|
|
16
|
+
find<T extends object, P extends string = never, F extends string = '*', E extends string = never>(entityName: EntityName<T>, where: FilterQuery<T>, options?: FindOptions<T, P, F, E>): Promise<EntityData<T>[]>;
|
|
17
|
+
findOne<T extends object, P extends string = never, F extends string = PopulatePath.ALL, E extends string = never>(entityName: EntityName<T>, where: FilterQuery<T>, options?: FindOneOptions<T, P, F, E>): Promise<EntityData<T> | null>;
|
|
18
|
+
findVirtual<T extends object>(entityName: EntityName<T>, where: FilterQuery<T>, options: FindOptions<T, any, any, any>): Promise<EntityData<T>[]>;
|
|
19
|
+
streamVirtual<T extends object>(entityName: EntityName<T>, where: FilterQuery<T>, options: FindOptions<T, any, any, any>): AsyncIterableIterator<EntityData<T>>;
|
|
20
|
+
count<T extends object>(entityName: EntityName<T>, where: FilterQuery<T>, options?: CountOptions<T>): Promise<number>;
|
|
21
|
+
nativeInsert<T extends object>(entityName: EntityName<T>, data: EntityDictionary<T>, options?: NativeInsertUpdateOptions<T>): Promise<QueryResult<T>>;
|
|
22
|
+
nativeInsertMany<T extends object>(entityName: EntityName<T>, data: EntityDictionary<T>[], options?: NativeInsertUpdateManyOptions<T>): Promise<QueryResult<T>>;
|
|
23
|
+
nativeUpdate<T extends object>(entityName: EntityName<T>, where: FilterQuery<T>, data: EntityDictionary<T>, options?: NativeInsertUpdateOptions<T> & UpsertOptions<T>): Promise<QueryResult<T>>;
|
|
24
|
+
nativeUpdateMany<T extends object>(entityName: EntityName<T>, where: FilterQuery<T>[], data: EntityDictionary<T>[], options?: NativeInsertUpdateOptions<T> & UpsertManyOptions<T>): Promise<QueryResult<T>>;
|
|
25
|
+
nativeDelete<T extends object>(entityName: EntityName<T>, where: FilterQuery<T>, options?: {
|
|
21
26
|
ctx?: Transaction<ClientSession>;
|
|
22
27
|
}): Promise<QueryResult<T>>;
|
|
23
|
-
aggregate(entityName:
|
|
28
|
+
aggregate(entityName: EntityName, pipeline: any[], ctx?: Transaction<ClientSession>): Promise<any[]>;
|
|
29
|
+
streamAggregate<T extends object>(entityName: EntityName<T>, pipeline: any[], ctx?: Transaction<ClientSession>): AsyncIterableIterator<T>;
|
|
24
30
|
getPlatform(): MongoPlatform;
|
|
31
|
+
private buildQueryOptions;
|
|
25
32
|
private renameFields;
|
|
26
33
|
private convertObjectIds;
|
|
27
34
|
private buildFilterById;
|
|
28
|
-
protected buildFields<T extends object, P extends string = never>(entityName:
|
|
35
|
+
protected buildFields<T extends object, P extends string = never>(entityName: EntityName<T>, populate: PopulateOptions<T>[], fields?: readonly EntityField<T, P>[], exclude?: string[]): string[] | undefined;
|
|
29
36
|
private handleVersionProperty;
|
|
37
|
+
/** @inheritDoc */
|
|
38
|
+
getORMClass(): Constructor<MongoMikroORM>;
|
|
30
39
|
}
|