@mikro-orm/mongodb 7.0.0-dev.29 → 7.0.0-dev.291
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 +144 -83
- package/MongoDriver.d.ts +21 -12
- package/MongoDriver.js +123 -28
- package/MongoEntityManager.d.ts +11 -3
- package/MongoEntityManager.js +19 -5
- package/MongoExceptionConverter.d.ts +1 -1
- package/MongoExceptionConverter.js +2 -3
- package/MongoMikroORM.d.ts +10 -7
- package/MongoMikroORM.js +12 -8
- package/MongoPlatform.d.ts +2 -4
- package/MongoPlatform.js +7 -10
- package/MongoSchemaGenerator.d.ts +8 -5
- package/MongoSchemaGenerator.js +56 -28
- package/README.md +2 -0
- package/index.d.ts +1 -1
- package/package.json +6 -6
- 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,49 +1,54 @@
|
|
|
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
54
|
return this.connected = false;
|
|
@@ -51,8 +56,8 @@ export class MongoConnection extends Connection {
|
|
|
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) {
|
|
@@ -232,22 +276,22 @@ export class MongoConnection extends Connection {
|
|
|
232
276
|
case 'insertOne':
|
|
233
277
|
Object.keys(data).filter(k => typeof data[k] === 'undefined').forEach(k => delete data[k]);
|
|
234
278
|
query = log(() => `db.getCollection('${collection}').insertOne(${this.logObject(data)}, ${this.logObject(options)});`);
|
|
235
|
-
res = await this.rethrow(this.getCollection(
|
|
279
|
+
res = await this.rethrow(this.getCollection(entityName).insertOne(data, options), query);
|
|
236
280
|
break;
|
|
237
281
|
case 'insertMany':
|
|
238
282
|
data.forEach(data => Object.keys(data).filter(k => typeof data[k] === 'undefined').forEach(k => delete data[k]));
|
|
239
283
|
query = log(() => `db.getCollection('${collection}').insertMany(${this.logObject(data)}, ${this.logObject(options)});`);
|
|
240
|
-
res = await this.rethrow(this.getCollection(
|
|
284
|
+
res = await this.rethrow(this.getCollection(entityName).insertMany(data, options), query);
|
|
241
285
|
break;
|
|
242
286
|
case 'updateMany': {
|
|
243
|
-
const payload = Object.keys(data).
|
|
287
|
+
const payload = Object.keys(data).every(k => k.startsWith('$')) ? data : this.createUpdatePayload(data, upsertOptions);
|
|
244
288
|
query = log(() => `db.getCollection('${collection}').updateMany(${this.logObject(where)}, ${this.logObject(payload)}, ${this.logObject(options)});`);
|
|
245
|
-
res = await this.rethrow(this.getCollection(
|
|
289
|
+
res = await this.rethrow(this.getCollection(entityName).updateMany(where, payload, options), query);
|
|
246
290
|
break;
|
|
247
291
|
}
|
|
248
292
|
case 'bulkUpdateMany': {
|
|
249
293
|
query = log(() => `bulk = db.getCollection('${collection}').initializeUnorderedBulkOp(${this.logObject(options)});\n`);
|
|
250
|
-
const bulk = this.getCollection(
|
|
294
|
+
const bulk = this.getCollection(entityName).initializeUnorderedBulkOp(options);
|
|
251
295
|
data.forEach((row, idx) => {
|
|
252
296
|
const id = where[idx];
|
|
253
297
|
const cond = Utils.isPlainObject(id) ? id : { _id: id };
|
|
@@ -272,8 +316,19 @@ export class MongoConnection extends Connection {
|
|
|
272
316
|
}
|
|
273
317
|
case 'deleteMany':
|
|
274
318
|
case 'countDocuments':
|
|
319
|
+
if (method === 'countDocuments') {
|
|
320
|
+
if (collation) {
|
|
321
|
+
options.collation = collation;
|
|
322
|
+
}
|
|
323
|
+
if (indexHint != null) {
|
|
324
|
+
options.hint = indexHint;
|
|
325
|
+
}
|
|
326
|
+
if (maxTimeMS != null) {
|
|
327
|
+
options.maxTimeMS = maxTimeMS;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
275
330
|
query = log(() => `db.getCollection('${collection}').${method}(${this.logObject(where)}, ${this.logObject(options)});`);
|
|
276
|
-
res = await this.rethrow(this.getCollection(
|
|
331
|
+
res = await this.rethrow(this.getCollection(entityName)[method](where, options), query);
|
|
277
332
|
break;
|
|
278
333
|
}
|
|
279
334
|
this.logQuery(query, { took: Date.now() - now, ...loggerContext });
|
|
@@ -290,7 +345,14 @@ export class MongoConnection extends Connection {
|
|
|
290
345
|
});
|
|
291
346
|
}
|
|
292
347
|
createUpdatePayload(row, upsertOptions) {
|
|
348
|
+
row = { ...row };
|
|
293
349
|
const doc = { $set: row };
|
|
350
|
+
Utils.keys(row).forEach(k => {
|
|
351
|
+
if (k.toString().startsWith('$')) {
|
|
352
|
+
doc[k] = row[k];
|
|
353
|
+
delete row[k];
|
|
354
|
+
}
|
|
355
|
+
});
|
|
294
356
|
const $unset = {};
|
|
295
357
|
const $inc = {};
|
|
296
358
|
for (const k of Utils.keys(row)) {
|
|
@@ -346,13 +408,12 @@ export class MongoConnection extends Connection {
|
|
|
346
408
|
insertedIds: res.insertedIds ? Object.values(res.insertedIds) : undefined,
|
|
347
409
|
};
|
|
348
410
|
}
|
|
349
|
-
getCollectionName(
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
return meta ? meta.collection : name;
|
|
411
|
+
getCollectionName(entityName) {
|
|
412
|
+
const meta = this.metadata.find(entityName);
|
|
413
|
+
return meta ? meta.collection : Utils.className(entityName);
|
|
353
414
|
}
|
|
354
415
|
logObject(o) {
|
|
355
|
-
if (o
|
|
416
|
+
if (o?.session) {
|
|
356
417
|
o = { ...o, session: `[ClientSession]` };
|
|
357
418
|
}
|
|
358
419
|
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
|
}
|