feat: support for the latest mongodb v5 (#9925)

* fix: add support for mongodb driver v5

This new fix allow support to mongodb driver v5

Closes: #7907

* refactor: remove callback from MongoDriver connect

* fix: check for propertyName in transform

* fix: add support for mongodb driver v5

This new fix allow support to mongodb driver v5

Closes: #7907

* feat: mongodb 5.2.0 typings

* fix: instanceof ObjectId check

Instanceof check now no longer references to just the
type but the loaded class ref instead.

* test: fix test name to mongodb v5

---------

Co-authored-by: Matheus Melo Antiquera <matheusantiquera@finchsolucoes.com.br>
Co-authored-by: tgrassl <grassl.timon@gmail.com>
Co-authored-by: Matheus Melo Antiquera <matheus.melo.a@hotmail.com>
This commit is contained in:
mptr 2023-04-15 10:30:01 +02:00 committed by GitHub
parent 3a72e35081
commit f6a3ce732d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
97 changed files with 14740 additions and 9397 deletions

View File

@ -250,7 +250,7 @@ await timber.remove()
- for **MongoDB** (experimental)
`npm install mongodb@^3.6.0 --save`
`npm install mongodb@^5.2.0 --save`
- for **NativeScript**, **react-native** and **Cordova**

View File

@ -184,7 +184,7 @@ await timber.remove();
- **MongoDB** (experimental)의 경우
`npm install mongodb@^3.6.0 --save`
`npm install mongodb@^5.2.0 --save`
- **NativeScript**, **react-native**, **Cordova**의 경우

View File

@ -287,16 +287,16 @@ Learn more about [entity columns](entities.md#entity-columns).
#### `@ObjectIdColumn`
Marks a property in your entity as ObjectID.
Marks a property in your entity as ObjectId.
This decorator is only used in MongoDB.
Every entity in MongoDB must have a ObjectID column.
Every entity in MongoDB must have a ObjectId column.
Example:
```typescript
@Entity()
export class User {
@ObjectIdColumn()
id: ObjectID
id: ObjectId
}
```

View File

@ -20,12 +20,12 @@ instead of `@PrimaryColumn` or `@PrimaryGeneratedColumn`.
Simple entity example:
```typescript
import { Entity, ObjectID, ObjectIdColumn, Column } from "typeorm"
import { Entity, ObjectId, ObjectIdColumn, Column } from "typeorm"
@Entity()
export class User {
@ObjectIdColumn()
id: ObjectID
id: ObjectId
@Column()
firstName: string
@ -54,7 +54,7 @@ Since MongoDB stores objects and objects inside objects (or documents inside doc
you can do the same in TypeORM:
```typescript
import { Entity, ObjectID, ObjectIdColumn, Column } from "typeorm"
import { Entity, ObjectId, ObjectIdColumn, Column } from "typeorm"
export class Profile {
@Column()
@ -69,7 +69,7 @@ export class Profile {
```
```typescript
import { Entity, ObjectID, ObjectIdColumn, Column } from "typeorm"
import { Entity, ObjectId, ObjectIdColumn, Column } from "typeorm"
export class Photo {
@Column()
@ -90,12 +90,12 @@ export class Photo {
```
```typescript
import { Entity, ObjectID, ObjectIdColumn, Column } from "typeorm"
import { Entity, ObjectId, ObjectIdColumn, Column } from "typeorm"
@Entity()
export class User {
@ObjectIdColumn()
id: ObjectID
id: ObjectId
@Column()
firstName: string
@ -373,10 +373,6 @@ Returns if the collection is a capped collection.
Get the list of all indexes information for the collection.
#### `mapReduce`
Run Map Reduce across a collection. Be aware that the inline option for out will return an array of results not a collection.
#### `parallelCollectionScan`
Return N number of parallel cursors for a collection allowing parallel reading of entire collection. There are no ordering guarantees for returned results

View File

@ -18,12 +18,12 @@ TypeORM 大多数功能都是特定于 RDBMS 的,
简单实体示例:
```typescript
import { Entity, ObjectID, ObjectIdColumn, Column } from "typeorm";
import { Entity, ObjectId, ObjectIdColumn, Column } from "typeorm";
@Entity()
export class User {
@ObjectIdColumn()
id: ObjectID;
id: ObjectId;
@Column()
firstName: string;
@ -51,7 +51,7 @@ const connection: Connection = await createConnection({
由于 MongoDB 存储对象和对象内的对象(或文档内的文档),因此你可以在 TypeORM 中执行相同的操作:
```typescript
import { Entity, ObjectID, ObjectIdColumn, Column } from "typeorm";
import { Entity, ObjectId, ObjectIdColumn, Column } from "typeorm";
export class Profile {
@Column()
@ -66,7 +66,7 @@ export class Profile {
```
```typescript
import { Entity, ObjectID, ObjectIdColumn, Column } from "typeorm";
import { Entity, ObjectId, ObjectIdColumn, Column } from "typeorm";
export class Photo {
@Column()
@ -87,12 +87,12 @@ export class Photo {
```
```typescript
import { Entity, ObjectID, ObjectIdColumn, Column } from "typeorm";
import { Entity, ObjectId, ObjectIdColumn, Column } from "typeorm";
@Entity()
export class User {
@ObjectIdColumn()
id: ObjectID;
id: ObjectId;
@Column()
firstName: string;
@ -297,10 +297,6 @@ distinct 命令返回集合中给定键的不同值列表。
获取集合的所有索引信息的列表。
#### `mapReduce`
在集合中运行 Map Reduce。 请注意out 的内联选项将返回结果数组而不是集合。
#### `parallelCollectionScan`
为集合返回 N 个并行游标,允许并行读取整个集合。 返回的结果没有顺序保证。

7538
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -121,7 +121,7 @@
"gulpclass": "^0.2.0",
"husky": "^8.0.3",
"mocha": "^10.2.0",
"mongodb": "^3.7.3",
"mongodb": "^5.2.0",
"mssql": "^9.1.1",
"mysql": "^2.18.1",
"mysql2": "^3.1.1",
@ -146,7 +146,7 @@
"better-sqlite3": "^7.1.2 || ^8.0.0",
"hdb-pool": "^0.1.6",
"ioredis": "^5.0.4",
"mongodb": "^3.6.0",
"mongodb": "^5.2.0",
"mssql": "^9.1.1",
"mysql2": "^2.2.5 || ^3.0.1",
"oracledb": "^5.1.0",
@ -229,14 +229,14 @@
"yargs": "^17.6.2"
},
"scripts": {
"test": "rimraf ./build && tsc && mocha --file ./build/compiled/test/utils/test-setup.js --bail --recursive --timeout 60000 ./build/compiled/test",
"test-fast": "mocha --file ./build/compiled/test/utils/test-setup.js --bail --recursive --timeout 60000 ./build/compiled/test",
"test": "rimraf ./build && tsc && mocha --file ./build/compiled/test/utils/test-setup.js --bail --recursive --timeout 90000 ./build/compiled/test",
"test-fast": "mocha --file ./build/compiled/test/utils/test-setup.js --bail --recursive --timeout 90000 ./build/compiled/test",
"compile": "rimraf ./build && tsc",
"watch": "./node_modules/.bin/tsc -w",
"package": "gulp package",
"pack": "gulp pack",
"lint": "prettier --check \"./src/**/*.ts\" \"./test/**/*.ts\" \"./sample/**/*.ts\"",
"format": "prettier --write \"./src/**/*.ts\" \"./test/**/*.ts\" \"./sample/**/*.ts\"",
"format": "prettier --write --end-of-line auto \"./src/**/*.ts\" \"./test/**/*.ts\" \"./sample/**/*.ts\"",
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 2"
},
"bin": {
@ -265,4 +265,4 @@
],
"reporter": "json"
}
}
}

View File

@ -1,11 +1,11 @@
import { Column, Entity } from "../../../src/index"
import { ObjectIdColumn } from "../../../src/decorator/columns/ObjectIdColumn"
import { ObjectID } from "../../../src/driver/mongodb/typings"
import { ObjectId } from "../../../src/driver/mongodb/typings"
@Entity("sample34_post")
export class Post {
@ObjectIdColumn()
id: ObjectID
id: ObjectId
@Column()
title: string

View File

@ -315,7 +315,7 @@ temp/`
protected static getUserEntityTemplate(database: string): string {
return `import { Entity, ${
database === "mongodb"
? "ObjectIdColumn, ObjectID"
? "ObjectIdColumn, ObjectId"
: "PrimaryGeneratedColumn"
}, Column } from "typeorm"
@ -327,7 +327,7 @@ export class User {
? "@ObjectIdColumn()"
: "@PrimaryGeneratedColumn()"
}
id: ${database === "mongodb" ? "ObjectID" : "number"}
id: ${database === "mongodb" ? "ObjectId" : "number"}
@Column()
firstName: string
@ -724,7 +724,7 @@ Steps to run this project:
packageJson.dependencies["mssql"] = "^9.1.1"
break
case "mongodb":
packageJson.dependencies["mongodb"] = "^3.0.8"
packageJson.dependencies["mongodb"] = "^5.2.0"
break
case "spanner":
packageJson.dependencies["@google-cloud/spanner"] = "^5.18.0"

View File

@ -10,6 +10,7 @@ import {
CannotExecuteNotConnectedError,
EntityMetadataNotFoundError,
QueryRunnerProviderAlreadyReleasedError,
TypeORMError,
} from "../error"
import { TreeRepository } from "../repository/TreeRepository"
import { NamingStrategyInterface } from "../naming-strategy/NamingStrategyInterface"
@ -35,7 +36,6 @@ import { RelationLoader } from "../query-builder/RelationLoader"
import { ObjectUtils } from "../util/ObjectUtils"
import { IsolationLevel } from "../driver/types/IsolationLevel"
import { ReplicationMode } from "../driver/types/ReplicationMode"
import { TypeORMError } from "../error"
import { RelationIdLoader } from "../query-builder/RelationIdLoader"
import { DriverUtils } from "../driver/DriverUtils"
import { InstanceChecker } from "../util/InstanceChecker"

View File

@ -248,26 +248,17 @@ export class MongoDriver implements Driver {
/**
* Performs connection to the database.
*/
connect(): Promise<void> {
return new Promise<void>((ok, fail) => {
const options = DriverUtils.buildMongoDBDriverOptions(this.options)
async connect(): Promise<void> {
const options = DriverUtils.buildMongoDBDriverOptions(this.options)
this.mongodb.MongoClient.connect(
this.buildConnectionUrl(options),
this.buildConnectionOptions(options),
(err: any, client: any) => {
if (err) return fail(err)
const client = await this.mongodb.MongoClient.connect(
this.buildConnectionUrl(options),
this.buildConnectionOptions(options),
)
this.queryRunner = new MongoQueryRunner(
this.connection,
client,
)
ObjectUtils.assign(this.queryRunner, {
manager: this.connection.manager,
})
ok()
},
)
this.queryRunner = new MongoQueryRunner(this.connection, client)
ObjectUtils.assign(this.queryRunner, {
manager: this.connection.manager,
})
}
@ -279,14 +270,11 @@ export class MongoDriver implements Driver {
* Closes connection with the database.
*/
async disconnect(): Promise<void> {
return new Promise<void>((ok, fail) => {
if (!this.queryRunner)
return fail(new ConnectionIsNotSetError("mongodb"))
const handler = (err: any) => (err ? fail(err) : ok())
this.queryRunner.databaseConnection.close(handler)
this.queryRunner = undefined
})
if (!this.queryRunner) throw new ConnectionIsNotSetError("mongodb")
// const handler = (err: any) => (err ? fail(err) : ok())
this.queryRunner.databaseConnection.close()
this.queryRunner = undefined
// return ok()
}
/**

View File

@ -1,44 +1,10 @@
import { QueryRunner } from "../../query-runner/QueryRunner"
import { ObjectLiteral } from "../../common/ObjectLiteral"
import { TableColumn } from "../../schema-builder/table/TableColumn"
import { Table } from "../../schema-builder/table/Table"
import { TableForeignKey } from "../../schema-builder/table/TableForeignKey"
import { TableIndex } from "../../schema-builder/table/TableIndex"
import { View } from "../../schema-builder/view/View"
import {
AggregationCursor,
BulkWriteOpResultObject,
ChangeStream,
ChangeStreamOptions,
Code,
Collection,
CollectionAggregationOptions,
CollectionBulkWriteOptions,
CollectionInsertManyOptions,
CollectionInsertOneOptions,
CollectionOptions,
CollStats,
CommandCursor,
Cursor,
DeleteWriteOpResultObject,
FindAndModifyWriteOpResultObject,
FindOneAndReplaceOption,
GeoHaystackSearchOptions,
GeoNearOptions,
InsertOneWriteOpResult,
InsertWriteOpResult,
MapReduceOptions,
MongoClient,
MongoCountPreferences,
MongodbIndexOptions,
OrderedBulkOperation,
ParallelCollectionScanOptions,
ReadPreference,
ReplaceOneOptions,
UnorderedBulkOperation,
UpdateWriteOpResult,
} from "./typings"
import { DataSource } from "../../data-source/DataSource"
// import {Connection} from "../../connection/Connection";
import { ReadStream } from "../../platform/PlatformTools"
import { MongoEntityManager } from "../../entity-manager/MongoEntityManager"
import { SqlInMemory } from "../SqlInMemory"
@ -47,6 +13,49 @@ import { Broadcaster } from "../../subscriber/Broadcaster"
import { TableCheck } from "../../schema-builder/table/TableCheck"
import { TableExclusion } from "../../schema-builder/table/TableExclusion"
import { TypeORMError } from "../../error"
import {
BulkWriteResult,
AggregationCursor,
MongoClient,
Collection,
FindCursor,
Document,
AggregateOptions,
AnyBulkWriteOperation,
BulkWriteOptions,
Filter,
CountOptions,
CountDocumentsOptions,
IndexSpecification,
CreateIndexesOptions,
IndexDescription,
DeleteResult,
DeleteOptions,
CommandOperationOptions,
FindOneAndDeleteOptions,
FindOneAndReplaceOptions,
UpdateFilter,
FindOneAndUpdateOptions,
RenameOptions,
ReplaceOptions,
UpdateResult,
CollStats,
CollStatsOptions,
ChangeStreamOptions,
ChangeStream,
UpdateOptions,
ListIndexesOptions,
ListIndexesCursor,
OptionalId,
InsertOneOptions,
InsertOneResult,
InsertManyResult,
UnorderedBulkOperation,
OrderedBulkOperation,
IndexInformationOptions,
} from "../../driver/mongodb/typings"
import { DataSource } from "../../data-source/DataSource"
import { ReplicationMode } from "../types/ReplicationMode"
/**
@ -137,8 +146,8 @@ export class MongoQueryRunner implements QueryRunner {
/**
* Creates a cursor for a query that can be used to iterate over results from MongoDB.
*/
cursor(collectionName: string, query?: ObjectLiteral): Cursor<any> {
return this.getCollection(collectionName).find(query || {})
cursor(collectionName: string, filter: Filter<Document>): FindCursor<any> {
return this.getCollection(collectionName).find(filter || {})
}
/**
@ -146,10 +155,13 @@ export class MongoQueryRunner implements QueryRunner {
*/
aggregate(
collectionName: string,
pipeline: ObjectLiteral[],
options?: CollectionAggregationOptions,
pipeline: Document[],
options?: AggregateOptions,
): AggregationCursor<any> {
return this.getCollection(collectionName).aggregate(pipeline, options)
return this.getCollection(collectionName).aggregate(
pipeline,
options || {},
)
}
/**
@ -157,12 +169,12 @@ export class MongoQueryRunner implements QueryRunner {
*/
async bulkWrite(
collectionName: string,
operations: ObjectLiteral[],
options?: CollectionBulkWriteOptions,
): Promise<BulkWriteOpResultObject> {
operations: AnyBulkWriteOperation<Document>[],
options?: BulkWriteOptions,
): Promise<BulkWriteResult> {
return await this.getCollection(collectionName).bulkWrite(
operations,
options,
options || {},
)
}
@ -171,12 +183,26 @@ export class MongoQueryRunner implements QueryRunner {
*/
async count(
collectionName: string,
query?: ObjectLiteral,
options?: MongoCountPreferences,
filter: Filter<Document>,
options?: CountOptions,
): Promise<number> {
return this.getCollection(collectionName).count(
filter || {},
options || {},
)
}
/**
* Count number of matching documents in the db to a query.
*/
async countDocuments(
collectionName: string,
filter: Filter<Document>,
options?: CountDocumentsOptions,
): Promise<any> {
return await this.getCollection(collectionName).countDocuments(
query || {},
options,
return this.getCollection(collectionName).countDocuments(
filter || {},
options || {},
)
}
@ -185,12 +211,12 @@ export class MongoQueryRunner implements QueryRunner {
*/
async createCollectionIndex(
collectionName: string,
fieldOrSpec: string | any,
options?: MongodbIndexOptions,
indexSpec: IndexSpecification,
options?: CreateIndexesOptions,
): Promise<string> {
return await this.getCollection(collectionName).createIndex(
fieldOrSpec,
options,
return this.getCollection(collectionName).createIndex(
indexSpec,
options || {},
)
}
@ -200,11 +226,9 @@ export class MongoQueryRunner implements QueryRunner {
*/
async createCollectionIndexes(
collectionName: string,
indexSpecs: ObjectLiteral[],
): Promise<void> {
return await this.getCollection(collectionName).createIndexes(
indexSpecs,
)
indexSpecs: IndexDescription[],
): Promise<string[]> {
return this.getCollection(collectionName).createIndexes(indexSpecs)
}
/**
@ -212,12 +236,12 @@ export class MongoQueryRunner implements QueryRunner {
*/
async deleteMany(
collectionName: string,
query: ObjectLiteral,
options?: CollectionOptions,
): Promise<DeleteWriteOpResultObject> {
return await this.getCollection(collectionName).deleteMany(
query,
options,
filter: Filter<Document>,
options: DeleteOptions,
): Promise<DeleteResult> {
return this.getCollection(collectionName).deleteMany(
filter,
options || {},
)
}
@ -226,12 +250,12 @@ export class MongoQueryRunner implements QueryRunner {
*/
async deleteOne(
collectionName: string,
query: ObjectLiteral,
options?: CollectionOptions,
): Promise<DeleteWriteOpResultObject> {
return await this.getCollection(collectionName).deleteOne(
query,
options,
filter: Filter<Document>,
options?: DeleteOptions,
): Promise<DeleteResult> {
return this.getCollection(collectionName).deleteOne(
filter,
options || {},
)
}
@ -240,14 +264,14 @@ export class MongoQueryRunner implements QueryRunner {
*/
async distinct(
collectionName: string,
key: string,
query: ObjectLiteral,
options?: { readPreference?: ReadPreference | string },
key: any,
filter: Filter<Document>,
options?: CommandOperationOptions,
): Promise<any> {
return await this.getCollection(collectionName).distinct(
return this.getCollection(collectionName).distinct(
key,
query,
options,
filter,
options || {},
)
}
@ -257,19 +281,19 @@ export class MongoQueryRunner implements QueryRunner {
async dropCollectionIndex(
collectionName: string,
indexName: string,
options?: CollectionOptions,
): Promise<any> {
return await this.getCollection(collectionName).dropIndex(
options?: CommandOperationOptions,
): Promise<Document> {
return this.getCollection(collectionName).dropIndex(
indexName,
options,
options || {},
)
}
/**
* Drops all indexes from the collection.
*/
async dropCollectionIndexes(collectionName: string): Promise<any> {
return await this.getCollection(collectionName).dropIndexes()
async dropCollectionIndexes(collectionName: string): Promise<Document> {
return this.getCollection(collectionName).dropIndexes()
}
/**
@ -277,12 +301,12 @@ export class MongoQueryRunner implements QueryRunner {
*/
async findOneAndDelete(
collectionName: string,
query: ObjectLiteral,
options?: { projection?: Object; sort?: Object; maxTimeMS?: number },
): Promise<FindAndModifyWriteOpResultObject> {
return await this.getCollection(collectionName).findOneAndDelete(
query,
options,
filter: Filter<Document>,
options?: FindOneAndDeleteOptions,
): Promise<Document> {
return this.getCollection(collectionName).findOneAndDelete(
filter,
options || {},
)
}
@ -291,14 +315,14 @@ export class MongoQueryRunner implements QueryRunner {
*/
async findOneAndReplace(
collectionName: string,
query: ObjectLiteral,
replacement: Object,
options?: FindOneAndReplaceOption,
): Promise<FindAndModifyWriteOpResultObject> {
return await this.getCollection(collectionName).findOneAndReplace(
query,
filter: Filter<Document>,
replacement: Document,
options?: FindOneAndReplaceOptions,
): Promise<Document> {
return this.getCollection(collectionName).findOneAndReplace(
filter,
replacement,
options,
options || {},
)
}
@ -307,74 +331,22 @@ export class MongoQueryRunner implements QueryRunner {
*/
async findOneAndUpdate(
collectionName: string,
query: ObjectLiteral,
update: Object,
options?: FindOneAndReplaceOption,
): Promise<FindAndModifyWriteOpResultObject> {
return await this.getCollection(collectionName).findOneAndUpdate(
query,
filter: Filter<Document>,
update: UpdateFilter<Document>,
options?: FindOneAndUpdateOptions,
): Promise<Document> {
return this.getCollection(collectionName).findOneAndUpdate(
filter,
update,
options,
)
}
/**
* Execute a geo search using a geo haystack index on a collection.
*/
async geoHaystackSearch(
collectionName: string,
x: number,
y: number,
options?: GeoHaystackSearchOptions,
): Promise<any> {
return await this.getCollection(collectionName).geoHaystackSearch(
x,
y,
options,
)
}
/**
* Execute the geoNear command to search for items in the collection.
*/
async geoNear(
collectionName: string,
x: number,
y: number,
options?: GeoNearOptions,
): Promise<any> {
return await this.getCollection(collectionName).geoNear(x, y, options)
}
/**
* Run a group command across a collection.
*/
async group(
collectionName: string,
keys: Object | Array<any> | Function | Code,
condition: Object,
initial: Object,
reduce: Function | Code,
finalize: Function | Code,
command: boolean,
options?: { readPreference?: ReadPreference | string },
): Promise<any> {
return await this.getCollection(collectionName).group(
keys,
condition,
initial,
reduce,
finalize,
command,
options,
options || {},
)
}
/**
* Retrieve all the indexes on the collection.
*/
async collectionIndexes(collectionName: string): Promise<any> {
return await this.getCollection(collectionName).indexes()
async collectionIndexes(collectionName: string): Promise<Document> {
return this.getCollection(collectionName).indexes()
}
/**
@ -384,7 +356,7 @@ export class MongoQueryRunner implements QueryRunner {
collectionName: string,
indexes: string | string[],
): Promise<boolean> {
return await this.getCollection(collectionName).indexExists(indexes)
return this.getCollection(collectionName).indexExists(indexes)
}
/**
@ -392,10 +364,10 @@ export class MongoQueryRunner implements QueryRunner {
*/
async collectionIndexInformation(
collectionName: string,
options?: { full: boolean },
options?: IndexInformationOptions,
): Promise<any> {
return await this.getCollection(collectionName).indexInformation(
options,
return this.getCollection(collectionName).indexInformation(
options || {},
)
}
@ -404,7 +376,7 @@ export class MongoQueryRunner implements QueryRunner {
*/
initializeOrderedBulkOp(
collectionName: string,
options?: CollectionOptions,
options?: BulkWriteOptions,
): OrderedBulkOperation {
return this.getCollection(collectionName).initializeOrderedBulkOp(
options,
@ -416,7 +388,7 @@ export class MongoQueryRunner implements QueryRunner {
*/
initializeUnorderedBulkOp(
collectionName: string,
options?: CollectionOptions,
options?: BulkWriteOptions,
): UnorderedBulkOperation {
return this.getCollection(collectionName).initializeUnorderedBulkOp(
options,
@ -428,12 +400,12 @@ export class MongoQueryRunner implements QueryRunner {
*/
async insertMany(
collectionName: string,
docs: ObjectLiteral[],
options?: CollectionInsertManyOptions,
): Promise<InsertWriteOpResult> {
return await this.getCollection(collectionName).insertMany(
docs: OptionalId<Document>[],
options?: BulkWriteOptions,
): Promise<InsertManyResult> {
return this.getCollection(collectionName).insertMany(
docs,
options,
options || {},
)
}
@ -442,17 +414,17 @@ export class MongoQueryRunner implements QueryRunner {
*/
async insertOne(
collectionName: string,
doc: ObjectLiteral,
options?: CollectionInsertOneOptions,
): Promise<InsertOneWriteOpResult> {
return await this.getCollection(collectionName).insertOne(doc, options)
doc: OptionalId<Document>,
options?: InsertOneOptions,
): Promise<InsertOneResult> {
return this.getCollection(collectionName).insertOne(doc, options || {})
}
/**
* Returns if the collection is a capped collection.
*/
async isCapped(collectionName: string): Promise<any> {
return await this.getCollection(collectionName).isCapped()
async isCapped(collectionName: string): Promise<boolean> {
return this.getCollection(collectionName).isCapped()
}
/**
@ -460,59 +432,20 @@ export class MongoQueryRunner implements QueryRunner {
*/
listCollectionIndexes(
collectionName: string,
options?: {
batchSize?: number
readPreference?: ReadPreference | string
},
): CommandCursor {
options?: ListIndexesOptions,
): ListIndexesCursor {
return this.getCollection(collectionName).listIndexes(options)
}
/**
* Run Map Reduce across a collection. Be aware that the inline option for out will return an array of results not a collection.
*/
async mapReduce(
collectionName: string,
map: Function | string,
reduce: Function | string,
options?: MapReduceOptions,
): Promise<any> {
return await this.getCollection(collectionName).mapReduce(
map,
reduce,
options,
)
}
/**
* Return N number of parallel cursors for a collection allowing parallel reading of entire collection.
* There are no ordering guarantees for returned results.
*/
async parallelCollectionScan(
collectionName: string,
options?: ParallelCollectionScanOptions,
): Promise<Cursor<any>[]> {
return await this.getCollection(collectionName).parallelCollectionScan(
options,
)
}
/**
* Reindex all indexes on the collection Warning: reIndex is a blocking operation (indexes are rebuilt in the foreground) and will be slow for large collections.
*/
async reIndex(collectionName: string): Promise<any> {
return await this.getCollection(collectionName).reIndex()
}
/**
* Reindex all indexes on the collection Warning: reIndex is a blocking operation (indexes are rebuilt in the foreground) and will be slow for large collections.
*/
async rename(
collectionName: string,
newName: string,
options?: { dropTarget?: boolean },
): Promise<Collection<any>> {
return await this.getCollection(collectionName).rename(newName, options)
options?: RenameOptions,
): Promise<Collection<Document>> {
return this.getCollection(collectionName).rename(newName, options || {})
}
/**
@ -520,14 +453,14 @@ export class MongoQueryRunner implements QueryRunner {
*/
async replaceOne(
collectionName: string,
query: ObjectLiteral,
doc: ObjectLiteral,
options?: ReplaceOneOptions,
): Promise<UpdateWriteOpResult> {
return await this.getCollection(collectionName).replaceOne(
query,
doc,
options,
filter: Filter<Document>,
replacement: Document,
options?: ReplaceOptions,
): Promise<Document | UpdateResult> {
return this.getCollection(collectionName).replaceOne(
filter,
replacement,
options || {},
)
}
@ -536,9 +469,9 @@ export class MongoQueryRunner implements QueryRunner {
*/
async stats(
collectionName: string,
options?: { scale: number },
options?: CollStatsOptions,
): Promise<CollStats> {
return await this.getCollection(collectionName).stats(options)
return this.getCollection(collectionName).stats(options || {})
}
/**
@ -546,7 +479,7 @@ export class MongoQueryRunner implements QueryRunner {
*/
watch(
collectionName: string,
pipeline?: Object[],
pipeline?: Document[],
options?: ChangeStreamOptions,
): ChangeStream {
return this.getCollection(collectionName).watch(pipeline, options)
@ -557,14 +490,14 @@ export class MongoQueryRunner implements QueryRunner {
*/
async updateMany(
collectionName: string,
query: ObjectLiteral,
update: ObjectLiteral,
options?: { upsert?: boolean; w?: any; wtimeout?: number; j?: boolean },
): Promise<UpdateWriteOpResult> {
return await this.getCollection(collectionName).updateMany(
query,
filter: Filter<Document>,
update: UpdateFilter<Document>,
options?: UpdateOptions,
): Promise<Document | UpdateResult> {
return this.getCollection(collectionName).updateMany(
filter,
update,
options,
options || {},
)
}
@ -573,14 +506,14 @@ export class MongoQueryRunner implements QueryRunner {
*/
async updateOne(
collectionName: string,
query: ObjectLiteral,
update: ObjectLiteral,
options?: ReplaceOneOptions,
): Promise<UpdateWriteOpResult> {
filter: Filter<Document>,
update: UpdateFilter<Document>,
options?: UpdateOptions,
): Promise<Document | UpdateResult> {
return await this.getCollection(collectionName).updateOne(
query,
filter,
update,
options,
options || {},
)
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -26,7 +26,7 @@ import { QueryRunner } from "../query-runner/QueryRunner"
import { SelectQueryBuilder } from "../query-builder/SelectQueryBuilder"
import { QueryDeepPartialEntity } from "../query-builder/QueryPartialEntity"
import { EntityPersistExecutor } from "../persistence/EntityPersistExecutor"
import { ObjectID } from "../driver/mongodb/typings"
import { ObjectId } from "../driver/mongodb/typings"
import { InsertResult } from "../query-builder/result/InsertResult"
import { UpdateResult } from "../query-builder/result/UpdateResult"
import { DeleteResult } from "../query-builder/result/DeleteResult"
@ -753,8 +753,8 @@ export class EntityManager {
| number[]
| Date
| Date[]
| ObjectID
| ObjectID[]
| ObjectId
| ObjectId[]
| any,
partialEntity: QueryDeepPartialEntity<Entity>,
): Promise<UpdateResult> {
@ -808,8 +808,8 @@ export class EntityManager {
| number[]
| Date
| Date[]
| ObjectID
| ObjectID[]
| ObjectId
| ObjectId[]
| any,
): Promise<DeleteResult> {
// if user passed empty criteria or empty list of criterias, then throw an error
@ -862,8 +862,8 @@ export class EntityManager {
| number[]
| Date
| Date[]
| ObjectID
| ObjectID[]
| ObjectId
| ObjectId[]
| any,
): Promise<UpdateResult> {
// if user passed empty criteria or empty list of criterias, then throw an error
@ -916,8 +916,8 @@ export class EntityManager {
| number[]
| Date
| Date[]
| ObjectID
| ObjectID[]
| ObjectId
| ObjectId[]
| any,
): Promise<UpdateResult> {
// if user passed empty criteria or empty list of criterias, then throw an error
@ -1224,7 +1224,7 @@ export class EntityManager {
*/
async findOneById<Entity extends ObjectLiteral>(
entityClass: EntityTarget<Entity>,
id: number | string | Date | ObjectID,
id: number | string | Date | ObjectId,
): Promise<Entity | null> {
const metadata = this.connection.getMetadata(entityClass)

View File

@ -1,46 +1,11 @@
import { DataSource } from "../data-source/DataSource"
import { EntityManager } from "./EntityManager"
import { EntityTarget } from "../common/EntityTarget"
import {
AggregationCursor,
BulkWriteOpResultObject,
ChangeStream,
ChangeStreamOptions,
Code,
Collection,
CollectionAggregationOptions,
CollectionBulkWriteOptions,
CollectionInsertManyOptions,
CollectionInsertOneOptions,
CollectionOptions,
CollStats,
CommandCursor,
Cursor,
CursorResult,
DeleteWriteOpResultObject,
FindAndModifyWriteOpResultObject,
FindOneAndReplaceOption,
GeoHaystackSearchOptions,
GeoNearOptions,
InsertOneWriteOpResult,
InsertWriteOpResult,
MapReduceOptions,
MongoCallback,
MongoCountPreferences,
MongodbIndexOptions,
MongoError,
ObjectID,
OrderedBulkOperation,
ParallelCollectionScanOptions,
ReadPreference,
ReplaceOneOptions,
UnorderedBulkOperation,
UpdateWriteOpResult,
} from "../driver/mongodb/typings"
import { ObjectLiteral } from "../common/ObjectLiteral"
import { MongoQueryRunner } from "../driver/mongodb/MongoQueryRunner"
import { MongoDriver } from "../driver/mongodb/MongoDriver"
import { DocumentToEntityTransformer } from "../query-builder/transformer/DocumentToEntityTransformer"
import { FindManyOptions } from "../find-options/FindManyOptions"
import { FindOptionsUtils } from "../find-options/FindOptionsUtils"
import { PlatformTools } from "../platform/PlatformTools"
import { QueryDeepPartialEntity } from "../query-builder/QueryPartialEntity"
@ -48,15 +13,57 @@ import { InsertResult } from "../query-builder/result/InsertResult"
import { UpdateResult } from "../query-builder/result/UpdateResult"
import { DeleteResult } from "../query-builder/result/DeleteResult"
import { EntityMetadata } from "../metadata/EntityMetadata"
import { FindOptionsWhere } from "../find-options/FindOptionsWhere"
import {
BulkWriteResult,
AggregationCursor,
Collection,
FindCursor,
Document,
AggregateOptions,
AnyBulkWriteOperation,
BulkWriteOptions,
Filter,
CountOptions,
IndexSpecification,
CreateIndexesOptions,
IndexDescription,
DeleteResult as DeleteResultMongoDb,
DeleteOptions,
CommandOperationOptions,
FindOneAndDeleteOptions,
FindOneAndReplaceOptions,
UpdateFilter,
FindOneAndUpdateOptions,
RenameOptions,
ReplaceOptions,
UpdateResult as UpdateResultMongoDb,
CollStats,
CollStatsOptions,
ChangeStreamOptions,
ChangeStream,
UpdateOptions,
ListIndexesOptions,
ListIndexesCursor,
OptionalId,
InsertOneOptions,
InsertOneResult,
InsertManyResult,
UnorderedBulkOperation,
OrderedBulkOperation,
IndexInformationOptions,
ObjectId,
FilterOperators,
} from "../driver/mongodb/typings"
import { DataSource } from "../data-source/DataSource"
import { MongoFindManyOptions } from "../find-options/mongodb/MongoFindManyOptions"
import { MongoFindOneOptions } from "../find-options/mongodb/MongoFindOneOptions"
import {
FindOptionsSelect,
FindOptionsSelectByString,
} from "../find-options/FindOptionsSelect"
import { MongoFindManyOptions } from "../find-options/mongodb/MongoFindManyOptions"
import { MongoFindOneOptions } from "../find-options/mongodb/MongoFindOneOptions"
import { ColumnMetadata } from "../metadata/ColumnMetadata"
import { ObjectUtils } from "../util/ObjectUtils"
import { ColumnMetadata } from "../metadata/ColumnMetadata"
/**
* Entity manager supposed to work with any entity, automatically find its repository and call its methods,
@ -87,25 +94,54 @@ export class MongoEntityManager extends EntityManager {
/**
* Finds entities that match given find options.
*/
/**
* Finds entities that match given find options or conditions.
*/
async find<Entity>(
entityClassOrName: EntityTarget<Entity>,
options?: MongoFindManyOptions<Entity>,
optionsOrConditions?:
| FindManyOptions<Entity>
| Partial<Entity>
| FilterOperators<Entity>,
): Promise<Entity[]> {
return this.executeFind(entityClassOrName, options)
const query =
this.convertFindManyOptionsOrConditionsToMongodbQuery(
optionsOrConditions,
)
const cursor = this.createEntityCursor<Entity>(
entityClassOrName,
query as Filter<Entity>,
)
const deleteDateColumn =
this.connection.getMetadata(entityClassOrName).deleteDateColumn
if (FindOptionsUtils.isFindManyOptions(optionsOrConditions)) {
if (optionsOrConditions.select)
cursor.project(
this.convertFindOptionsSelectToProjectCriteria(
optionsOrConditions.select,
),
)
if (optionsOrConditions.skip) cursor.skip(optionsOrConditions.skip)
if (optionsOrConditions.take) cursor.limit(optionsOrConditions.take)
if (optionsOrConditions.order)
cursor.sort(
this.convertFindOptionsOrderToOrderCriteria(
optionsOrConditions.order,
),
)
if (deleteDateColumn && !optionsOrConditions.withDeleted) {
this.filterSoftDeleted(cursor, deleteDateColumn, query)
}
} else if (deleteDateColumn) {
this.filterSoftDeleted(cursor, deleteDateColumn, query)
}
return cursor.toArray()
}
/**
* Finds entities that match given conditions.
*/
async findBy<Entity>(
entityClassOrName: EntityTarget<Entity>,
where: any,
): Promise<Entity[]> {
return this.executeFind(entityClassOrName, where)
}
/**
* Finds entities that match given find options.
* Finds entities that match given find options or conditions.
* Also counts all entities that match given conditions,
* but ignores pagination settings (from and take options).
*/
async findAndCount<Entity>(
entityClassOrName: EntityTarget<Entity>,
@ -133,37 +169,38 @@ export class MongoEntityManager extends EntityManager {
async findByIds<Entity>(
entityClassOrName: EntityTarget<Entity>,
ids: any[],
optionsOrConditions?: any,
optionsOrConditions?: FindManyOptions<Entity> | Partial<Entity>,
): Promise<Entity[]> {
const metadata = this.connection.getMetadata(entityClassOrName)
const query =
this.convertFindManyOptionsOrConditionsToMongodbQuery(
optionsOrConditions,
) || {}
const objectIdInstance = PlatformTools.load("mongodb").ObjectID
const objectIdInstance = PlatformTools.load("mongodb").ObjectId
query["_id"] = {
$in: ids.map((id) => {
if (typeof id === "string") {
return new objectIdInstance(id)
}
if (ObjectUtils.isObject(id)) {
if (typeof id === "object") {
if (id instanceof objectIdInstance) {
return id
}
const propertyName = metadata.objectIdColumn!.propertyName
if ((id as any)[propertyName] instanceof objectIdInstance) {
return (id as any)[propertyName]
if (id[propertyName] instanceof objectIdInstance) {
return id[propertyName]
}
}
}),
}
const cursor = await this.createEntityCursor(entityClassOrName, query)
const deleteDateColumn =
this.connection.getMetadata(entityClassOrName).deleteDateColumn
const cursor = this.createEntityCursor<Entity>(
entityClassOrName,
query as Filter<Entity>,
)
if (FindOptionsUtils.isFindManyOptions(optionsOrConditions)) {
if (optionsOrConditions.select)
cursor.project(
@ -179,17 +216,12 @@ export class MongoEntityManager extends EntityManager {
optionsOrConditions.order,
),
)
if (deleteDateColumn && !optionsOrConditions.withDeleted) {
this.filterSoftDeleted(cursor, deleteDateColumn, query)
}
} else if (deleteDateColumn) {
this.filterSoftDeleted(cursor, deleteDateColumn, query)
}
return await cursor.toArray()
return cursor.toArray()
}
/**
* Finds first entity that matches given find options.
* Finds first entity that matches given conditions and/or find options.
*/
async findOne<Entity>(
entityClassOrName: EntityTarget<Entity>,
@ -219,15 +251,7 @@ export class MongoEntityManager extends EntityManager {
*/
async findOneById<Entity>(
entityClassOrName: EntityTarget<Entity>,
id:
| string
| string[]
| number
| number[]
| Date
| Date[]
| ObjectID
| ObjectID[],
id: string | number | Date | ObjectId,
): Promise<Entity | null> {
return this.executeFindOne(entityClassOrName, id)
}
@ -298,9 +322,9 @@ export class MongoEntityManager extends EntityManager {
| number[]
| Date
| Date[]
| ObjectID
| ObjectID[]
| FindOptionsWhere<Entity>,
| ObjectId
| ObjectId[]
| ObjectLiteral,
partialEntity: QueryDeepPartialEntity<Entity>,
): Promise<UpdateResult> {
const result = new UpdateResult()
@ -350,9 +374,9 @@ export class MongoEntityManager extends EntityManager {
| number[]
| Date
| Date[]
| ObjectID
| ObjectID[]
| FindOptionsWhere<Entity>,
| ObjectId
| ObjectId[]
| ObjectLiteral[],
): Promise<DeleteResult> {
const result = new DeleteResult()
@ -392,8 +416,8 @@ export class MongoEntityManager extends EntityManager {
*/
createCursor<Entity, T = any>(
entityClassOrName: EntityTarget<Entity>,
query?: ObjectLiteral,
): Cursor<T> {
query: ObjectLiteral = {},
): FindCursor<T> {
const metadata = this.connection.getMetadata(entityClassOrName)
return this.mongoQueryRunner.cursor(metadata.tableName, query)
}
@ -404,8 +428,8 @@ export class MongoEntityManager extends EntityManager {
*/
createEntityCursor<Entity>(
entityClassOrName: EntityTarget<Entity>,
query?: ObjectLiteral,
): Cursor<Entity> {
query: ObjectLiteral = {},
): FindCursor<Entity> {
const metadata = this.connection.getMetadata(entityClassOrName)
const cursor = this.createCursor(entityClassOrName, query)
this.applyEntityTransformationToCursor(metadata, cursor)
@ -417,8 +441,8 @@ export class MongoEntityManager extends EntityManager {
*/
aggregate<Entity, R = any>(
entityClassOrName: EntityTarget<Entity>,
pipeline: ObjectLiteral[],
options?: CollectionAggregationOptions,
pipeline: Document[],
options?: AggregateOptions,
): AggregationCursor<R> {
const metadata = this.connection.getMetadata(entityClassOrName)
return this.mongoQueryRunner.aggregate(
@ -434,8 +458,8 @@ export class MongoEntityManager extends EntityManager {
*/
aggregateEntity<Entity>(
entityClassOrName: EntityTarget<Entity>,
pipeline: ObjectLiteral[],
options?: CollectionAggregationOptions,
pipeline: Document[],
options?: AggregateOptions,
): AggregationCursor<Entity> {
const metadata = this.connection.getMetadata(entityClassOrName)
const cursor = this.mongoQueryRunner.aggregate(
@ -452,9 +476,9 @@ export class MongoEntityManager extends EntityManager {
*/
bulkWrite<Entity>(
entityClassOrName: EntityTarget<Entity>,
operations: ObjectLiteral[],
options?: CollectionBulkWriteOptions,
): Promise<BulkWriteOpResultObject> {
operations: AnyBulkWriteOperation<Document>[],
options?: BulkWriteOptions,
): Promise<BulkWriteResult> {
const metadata = this.connection.getMetadata(entityClassOrName)
return this.mongoQueryRunner.bulkWrite(
metadata.tableName,
@ -468,8 +492,8 @@ export class MongoEntityManager extends EntityManager {
*/
count<Entity>(
entityClassOrName: EntityTarget<Entity>,
query?: ObjectLiteral,
options?: MongoCountPreferences,
query: Filter<Document> = {},
options: CountOptions = {},
): Promise<number> {
const metadata = this.connection.getMetadata(entityClassOrName)
return this.mongoQueryRunner.count(metadata.tableName, query, options)
@ -481,7 +505,7 @@ export class MongoEntityManager extends EntityManager {
countBy<Entity>(
entityClassOrName: EntityTarget<Entity>,
query?: ObjectLiteral,
options?: MongoCountPreferences,
options?: CountOptions,
): Promise<number> {
return this.count(entityClassOrName, query, options)
}
@ -491,8 +515,8 @@ export class MongoEntityManager extends EntityManager {
*/
createCollectionIndex<Entity>(
entityClassOrName: EntityTarget<Entity>,
fieldOrSpec: string | any,
options?: MongodbIndexOptions,
fieldOrSpec: IndexSpecification,
options?: CreateIndexesOptions,
): Promise<string> {
const metadata = this.connection.getMetadata(entityClassOrName)
return this.mongoQueryRunner.createCollectionIndex(
@ -509,8 +533,8 @@ export class MongoEntityManager extends EntityManager {
*/
createCollectionIndexes<Entity>(
entityClassOrName: EntityTarget<Entity>,
indexSpecs: ObjectLiteral[],
): Promise<void> {
indexSpecs: IndexDescription[],
): Promise<string[]> {
const metadata = this.connection.getMetadata(entityClassOrName)
return this.mongoQueryRunner.createCollectionIndexes(
metadata.tableName,
@ -523,9 +547,9 @@ export class MongoEntityManager extends EntityManager {
*/
deleteMany<Entity>(
entityClassOrName: EntityTarget<Entity>,
query: ObjectLiteral,
options?: CollectionOptions,
): Promise<DeleteWriteOpResultObject> {
query: Filter<Document>,
options: DeleteOptions = {},
): Promise<DeleteResultMongoDb> {
const metadata = this.connection.getMetadata(entityClassOrName)
return this.mongoQueryRunner.deleteMany(
metadata.tableName,
@ -539,9 +563,9 @@ export class MongoEntityManager extends EntityManager {
*/
deleteOne<Entity>(
entityClassOrName: EntityTarget<Entity>,
query: ObjectLiteral,
options?: CollectionOptions,
): Promise<DeleteWriteOpResultObject> {
query: Filter<Document>,
options: DeleteOptions = {},
): Promise<DeleteResultMongoDb> {
const metadata = this.connection.getMetadata(entityClassOrName)
return this.mongoQueryRunner.deleteOne(
metadata.tableName,
@ -556,8 +580,8 @@ export class MongoEntityManager extends EntityManager {
distinct<Entity>(
entityClassOrName: EntityTarget<Entity>,
key: string,
query: ObjectLiteral,
options?: { readPreference?: ReadPreference | string },
query: Filter<Document>,
options?: CommandOperationOptions,
): Promise<any> {
const metadata = this.connection.getMetadata(entityClassOrName)
return this.mongoQueryRunner.distinct(
@ -574,7 +598,7 @@ export class MongoEntityManager extends EntityManager {
dropCollectionIndex<Entity>(
entityClassOrName: EntityTarget<Entity>,
indexName: string,
options?: CollectionOptions,
options?: CommandOperationOptions,
): Promise<any> {
const metadata = this.connection.getMetadata(entityClassOrName)
return this.mongoQueryRunner.dropCollectionIndex(
@ -600,8 +624,8 @@ export class MongoEntityManager extends EntityManager {
findOneAndDelete<Entity>(
entityClassOrName: EntityTarget<Entity>,
query: ObjectLiteral,
options?: { projection?: Object; sort?: Object; maxTimeMS?: number },
): Promise<FindAndModifyWriteOpResultObject> {
options?: FindOneAndDeleteOptions,
): Promise<Document> {
const metadata = this.connection.getMetadata(entityClassOrName)
return this.mongoQueryRunner.findOneAndDelete(
metadata.tableName,
@ -615,10 +639,10 @@ export class MongoEntityManager extends EntityManager {
*/
findOneAndReplace<Entity>(
entityClassOrName: EntityTarget<Entity>,
query: ObjectLiteral,
replacement: Object,
options?: FindOneAndReplaceOption,
): Promise<FindAndModifyWriteOpResultObject> {
query: Filter<Document>,
replacement: Document,
options?: FindOneAndReplaceOptions,
): Promise<Document> {
const metadata = this.connection.getMetadata(entityClassOrName)
return this.mongoQueryRunner.findOneAndReplace(
metadata.tableName,
@ -633,10 +657,10 @@ export class MongoEntityManager extends EntityManager {
*/
findOneAndUpdate<Entity>(
entityClassOrName: EntityTarget<Entity>,
query: ObjectLiteral,
update: Object,
options?: FindOneAndReplaceOption,
): Promise<FindAndModifyWriteOpResultObject> {
query: Filter<Document>,
update: UpdateFilter<Document>,
options?: FindOneAndUpdateOptions,
): Promise<Document> {
const metadata = this.connection.getMetadata(entityClassOrName)
return this.mongoQueryRunner.findOneAndUpdate(
metadata.tableName,
@ -646,69 +670,12 @@ export class MongoEntityManager extends EntityManager {
)
}
/**
* Execute a geo search using a geo haystack index on a collection.
*/
geoHaystackSearch<Entity>(
entityClassOrName: EntityTarget<Entity>,
x: number,
y: number,
options?: GeoHaystackSearchOptions,
): Promise<any> {
const metadata = this.connection.getMetadata(entityClassOrName)
return this.mongoQueryRunner.geoHaystackSearch(
metadata.tableName,
x,
y,
options,
)
}
/**
* Execute the geoNear command to search for items in the collection.
*/
geoNear<Entity>(
entityClassOrName: EntityTarget<Entity>,
x: number,
y: number,
options?: GeoNearOptions,
): Promise<any> {
const metadata = this.connection.getMetadata(entityClassOrName)
return this.mongoQueryRunner.geoNear(metadata.tableName, x, y, options)
}
/**
* Run a group command across a collection.
*/
group<Entity>(
entityClassOrName: EntityTarget<Entity>,
keys: Object | Array<any> | Function | Code,
condition: Object,
initial: Object,
reduce: Function | Code,
finalize: Function | Code,
command: boolean,
options?: { readPreference?: ReadPreference | string },
): Promise<any> {
const metadata = this.connection.getMetadata(entityClassOrName)
return this.mongoQueryRunner.group(
metadata.tableName,
keys,
condition,
initial,
reduce,
finalize,
command,
options,
)
}
/**
* Retrieve all the indexes on the collection.
*/
collectionIndexes<Entity>(
entityClassOrName: EntityTarget<Entity>,
): Promise<any> {
): Promise<Document> {
const metadata = this.connection.getMetadata(entityClassOrName)
return this.mongoQueryRunner.collectionIndexes(metadata.tableName)
}
@ -732,7 +699,7 @@ export class MongoEntityManager extends EntityManager {
*/
collectionIndexInformation<Entity>(
entityClassOrName: EntityTarget<Entity>,
options?: { full: boolean },
options?: IndexInformationOptions,
): Promise<any> {
const metadata = this.connection.getMetadata(entityClassOrName)
return this.mongoQueryRunner.collectionIndexInformation(
@ -746,7 +713,7 @@ export class MongoEntityManager extends EntityManager {
*/
initializeOrderedBulkOp<Entity>(
entityClassOrName: EntityTarget<Entity>,
options?: CollectionOptions,
options?: BulkWriteOptions,
): OrderedBulkOperation {
const metadata = this.connection.getMetadata(entityClassOrName)
return this.mongoQueryRunner.initializeOrderedBulkOp(
@ -760,7 +727,7 @@ export class MongoEntityManager extends EntityManager {
*/
initializeUnorderedBulkOp<Entity>(
entityClassOrName: EntityTarget<Entity>,
options?: CollectionOptions,
options?: BulkWriteOptions,
): UnorderedBulkOperation {
const metadata = this.connection.getMetadata(entityClassOrName)
return this.mongoQueryRunner.initializeUnorderedBulkOp(
@ -774,9 +741,9 @@ export class MongoEntityManager extends EntityManager {
*/
insertMany<Entity>(
entityClassOrName: EntityTarget<Entity>,
docs: ObjectLiteral[],
options?: CollectionInsertManyOptions,
): Promise<InsertWriteOpResult> {
docs: OptionalId<Document>[],
options?: BulkWriteOptions,
): Promise<InsertManyResult> {
const metadata = this.connection.getMetadata(entityClassOrName)
return this.mongoQueryRunner.insertMany(
metadata.tableName,
@ -790,9 +757,9 @@ export class MongoEntityManager extends EntityManager {
*/
insertOne<Entity>(
entityClassOrName: EntityTarget<Entity>,
doc: ObjectLiteral,
options?: CollectionInsertOneOptions,
): Promise<InsertOneWriteOpResult> {
doc: OptionalId<Document>,
options?: InsertOneOptions,
): Promise<InsertOneResult> {
const metadata = this.connection.getMetadata(entityClassOrName)
return this.mongoQueryRunner.insertOne(metadata.tableName, doc, options)
}
@ -810,11 +777,8 @@ export class MongoEntityManager extends EntityManager {
*/
listCollectionIndexes<Entity>(
entityClassOrName: EntityTarget<Entity>,
options?: {
batchSize?: number
readPreference?: ReadPreference | string
},
): CommandCursor {
options?: ListIndexesOptions,
): ListIndexesCursor {
const metadata = this.connection.getMetadata(entityClassOrName)
return this.mongoQueryRunner.listCollectionIndexes(
metadata.tableName,
@ -822,55 +786,14 @@ export class MongoEntityManager extends EntityManager {
)
}
/**
* Run Map Reduce across a collection. Be aware that the inline option for out will return an array of results not a collection.
*/
mapReduce<Entity>(
entityClassOrName: EntityTarget<Entity>,
map: Function | string,
reduce: Function | string,
options?: MapReduceOptions,
): Promise<any> {
const metadata = this.connection.getMetadata(entityClassOrName)
return this.mongoQueryRunner.mapReduce(
metadata.tableName,
map,
reduce,
options,
)
}
/**
* Return N number of parallel cursors for a collection allowing parallel reading of entire collection.
* There are no ordering guarantees for returned results.
*/
parallelCollectionScan<Entity>(
entityClassOrName: EntityTarget<Entity>,
options?: ParallelCollectionScanOptions,
): Promise<Cursor<Entity>[]> {
const metadata = this.connection.getMetadata(entityClassOrName)
return this.mongoQueryRunner.parallelCollectionScan(
metadata.tableName,
options,
)
}
/**
* Reindex all indexes on the collection Warning: reIndex is a blocking operation (indexes are rebuilt in the foreground) and will be slow for large collections.
*/
reIndex<Entity>(entityClassOrName: EntityTarget<Entity>): Promise<any> {
const metadata = this.connection.getMetadata(entityClassOrName)
return this.mongoQueryRunner.reIndex(metadata.tableName)
}
/**
* Reindex all indexes on the collection Warning: reIndex is a blocking operation (indexes are rebuilt in the foreground) and will be slow for large collections.
*/
rename<Entity>(
entityClassOrName: EntityTarget<Entity>,
newName: string,
options?: { dropTarget?: boolean },
): Promise<Collection<any>> {
options?: RenameOptions,
): Promise<Collection<Document>> {
const metadata = this.connection.getMetadata(entityClassOrName)
return this.mongoQueryRunner.rename(
metadata.tableName,
@ -884,10 +807,10 @@ export class MongoEntityManager extends EntityManager {
*/
replaceOne<Entity>(
entityClassOrName: EntityTarget<Entity>,
query: ObjectLiteral,
doc: ObjectLiteral,
options?: ReplaceOneOptions,
): Promise<UpdateWriteOpResult> {
query: Filter<Document>,
doc: Document,
options?: ReplaceOptions,
): Promise<Document | UpdateResultMongoDb> {
const metadata = this.connection.getMetadata(entityClassOrName)
return this.mongoQueryRunner.replaceOne(
metadata.tableName,
@ -902,7 +825,7 @@ export class MongoEntityManager extends EntityManager {
*/
stats<Entity>(
entityClassOrName: EntityTarget<Entity>,
options?: { scale: number },
options?: CollStatsOptions,
): Promise<CollStats> {
const metadata = this.connection.getMetadata(entityClassOrName)
return this.mongoQueryRunner.stats(metadata.tableName, options)
@ -910,7 +833,7 @@ export class MongoEntityManager extends EntityManager {
watch<Entity>(
entityClassOrName: EntityTarget<Entity>,
pipeline?: Object[],
pipeline?: Document[],
options?: ChangeStreamOptions,
): ChangeStream {
const metadata = this.connection.getMetadata(entityClassOrName)
@ -926,10 +849,10 @@ export class MongoEntityManager extends EntityManager {
*/
updateMany<Entity>(
entityClassOrName: EntityTarget<Entity>,
query: ObjectLiteral,
update: ObjectLiteral,
options?: { upsert?: boolean; w?: any; wtimeout?: number; j?: boolean },
): Promise<UpdateWriteOpResult> {
query: Filter<Document>,
update: UpdateFilter<Document>,
options?: UpdateOptions,
): Promise<Document | UpdateResultMongoDb> {
const metadata = this.connection.getMetadata(entityClassOrName)
return this.mongoQueryRunner.updateMany(
metadata.tableName,
@ -944,10 +867,10 @@ export class MongoEntityManager extends EntityManager {
*/
updateOne<Entity>(
entityClassOrName: EntityTarget<Entity>,
query: ObjectLiteral,
update: ObjectLiteral,
options?: ReplaceOneOptions,
): Promise<UpdateWriteOpResult> {
query: Filter<Document>,
update: UpdateFilter<Document>,
options?: UpdateOptions,
): Promise<Document | UpdateResultMongoDb> {
const metadata = this.connection.getMetadata(entityClassOrName)
return this.mongoQueryRunner.updateOne(
metadata.tableName,
@ -968,6 +891,7 @@ export class MongoEntityManager extends EntityManager {
optionsOrConditions:
| MongoFindManyOptions<Entity>
| Partial<Entity>
| FilterOperators<Entity>
| any[]
| undefined,
): ObjectLiteral | undefined {
@ -1047,7 +971,7 @@ export class MongoEntityManager extends EntityManager {
metadata: EntityMetadata,
idMap: any,
): ObjectLiteral {
const objectIdInstance = PlatformTools.load("mongodb").ObjectID
const objectIdInstance = PlatformTools.load("mongodb").ObjectId
// check first if it's ObjectId compatible:
// string, number, Buffer, ObjectId or ObjectId-like
@ -1068,7 +992,7 @@ export class MongoEntityManager extends EntityManager {
}, {} as any)
}
// last resort: try to convert it to an ObjectID anyway
// last resort: try to convert it to an ObjectId anyway
// most likely it will fail, but we want to be backwards compatible and keep the same thrown Errors.
// it can still pass with null/undefined
return {
@ -1081,92 +1005,45 @@ export class MongoEntityManager extends EntityManager {
*/
protected applyEntityTransformationToCursor<Entity extends ObjectLiteral>(
metadata: EntityMetadata,
cursor: Cursor<Entity> | AggregationCursor<Entity>,
cursor: FindCursor<Entity> | AggregationCursor<Entity>,
) {
// mongdb-3.7 exports Cursor, mongodb-4.2 exports FindCursor, provide support for both.
const ParentCursor =
PlatformTools.load("mongodb").Cursor ||
PlatformTools.load("mongodb").FindCursor
const queryRunner = this.mongoQueryRunner
cursor.toArray = function (callback?: MongoCallback<Entity[]>) {
if (callback) {
ParentCursor.prototype.toArray.call(
this,
(error: MongoError, results: Entity[]): void => {
if (error) {
callback(error, results)
return
}
cursor.toArray = () =>
cursor
.clone()
.toArray()
.then(async (results: Entity[]) => {
const transformer = new DocumentToEntityTransformer()
const entities = transformer.transformAll(results, metadata)
// broadcast "load" events
await queryRunner.broadcaster.broadcast(
"Load",
metadata,
entities,
)
return entities
})
const transformer = new DocumentToEntityTransformer()
const entities = transformer.transformAll(
results,
metadata,
)
// broadcast "load" events
queryRunner.broadcaster
.broadcast("Load", metadata, entities)
.then(() => callback(error, entities))
},
)
} else {
return ParentCursor.prototype.toArray
.call(this)
.then((results: Entity[]) => {
const transformer = new DocumentToEntityTransformer()
const entities = transformer.transformAll(
results,
metadata,
)
// broadcast "load" events
return queryRunner.broadcaster
.broadcast("Load", metadata, entities)
.then(() => entities)
})
}
}
cursor.next = function (callback?: MongoCallback<CursorResult>) {
if (callback) {
ParentCursor.prototype.next.call(
this,
(error: MongoError, result: CursorResult): void => {
if (error || !result) {
callback(error, result)
return
}
const transformer = new DocumentToEntityTransformer()
const entity = transformer.transform(result, metadata)
// broadcast "load" events
queryRunner.broadcaster
.broadcast("Load", metadata, [entity])
.then(() => callback(error, entity))
},
)
} else {
return ParentCursor.prototype.next
.call(this)
.then((result: Entity) => {
if (!result) return result
const transformer = new DocumentToEntityTransformer()
const entity = transformer.transform(result, metadata)
// broadcast "load" events
return queryRunner.broadcaster
.broadcast("Load", metadata, [entity])
.then(() => entity)
})
}
}
cursor.next = () =>
cursor
.clone()
.next()
.then(async (result: Entity) => {
if (!result) {
return result
}
const transformer = new DocumentToEntityTransformer()
const entity = transformer.transform(result, metadata)
// broadcast "load" events
await queryRunner.broadcaster.broadcast("Load", metadata, [
entity,
])
return entity
})
}
protected filterSoftDeleted<Entity>(
cursor: Cursor<Entity>,
cursor: FindCursor<Entity>,
deleteDateColumn: ColumnMetadata,
query?: ObjectLiteral,
) {
@ -1188,7 +1065,7 @@ export class MongoEntityManager extends EntityManager {
optionsOrConditions?: any,
maybeOptions?: MongoFindOneOptions<Entity>,
): Promise<Entity | null> {
const objectIdInstance = PlatformTools.load("mongodb").ObjectID
const objectIdInstance = PlatformTools.load("mongodb").ObjectId
const id =
optionsOrConditions instanceof objectIdInstance ||
typeof optionsOrConditions === "string"
@ -1203,9 +1080,9 @@ export class MongoEntityManager extends EntityManager {
) || {}
if (id) {
query["_id"] =
id instanceof objectIdInstance ? id : new objectIdInstance(id)
id instanceof objectIdInstance ? id : new ObjectId(id)
}
const cursor = await this.createEntityCursor(entityClassOrName, query)
const cursor = this.createEntityCursor<Entity>(entityClassOrName, query)
const deleteDateColumn =
this.connection.getMetadata(entityClassOrName).deleteDateColumn
if (FindOptionsUtils.isFindOneOptions(findOneOptionsOrConditions)) {
@ -1244,7 +1121,7 @@ export class MongoEntityManager extends EntityManager {
this.convertFindManyOptionsOrConditionsToMongodbQuery(
optionsOrConditions,
)
const cursor = await this.createEntityCursor(entityClassOrName, query)
const cursor = this.createEntityCursor<Entity>(entityClassOrName, query)
const deleteDateColumn =
this.connection.getMetadata(entityClassOrName).deleteDateColumn

View File

@ -9,7 +9,7 @@ export interface EntitySchemaColumnOptions extends SpatialColumnOptions {
primary?: boolean
/**
* Indicates if this column is of type ObjectID
* Indicates if this column is of type ObjectId
*/
objectId?: boolean

View File

@ -1,4 +1,4 @@
import { ObjectID } from "../driver/mongodb/typings"
import { ObjectId } from "../driver/mongodb/typings"
/**
* A single property handler for FindOptionsOrder.
@ -21,7 +21,7 @@ export type FindOptionsOrderProperty<Property> = Property extends Promise<
? FindOptionsOrderValue
: Property extends Date
? FindOptionsOrderValue
: Property extends ObjectID
: Property extends ObjectId
? FindOptionsOrderValue
: Property extends object
? FindOptionsOrder<Property> | FindOptionsOrderValue

View File

@ -1,4 +1,4 @@
import { ObjectID } from "../driver/mongodb/typings"
import { ObjectId } from "../driver/mongodb/typings"
/**
* A single property handler for FindOptionsRelations.
@ -21,7 +21,7 @@ export type FindOptionsRelationsProperty<Property> = Property extends Promise<
? never
: Property extends Date
? never
: Property extends ObjectID
: Property extends ObjectId
? never
: Property extends object
? FindOptionsRelations<Property> | boolean

View File

@ -1,4 +1,4 @@
import { ObjectID } from "../driver/mongodb/typings"
import { ObjectId } from "../driver/mongodb/typings"
/**
* A single property handler for FindOptionsSelect.
@ -21,7 +21,7 @@ export type FindOptionsSelectProperty<Property> = Property extends Promise<
? boolean
: Property extends Date
? boolean
: Property extends ObjectID
: Property extends ObjectId
? boolean
: Property extends object
? FindOptionsSelect<Property>

View File

@ -1,5 +1,5 @@
import { FindOperator } from "./FindOperator"
import { ObjectID } from "../driver/mongodb/typings"
import { ObjectId } from "../driver/mongodb/typings"
import { EqualOperator } from "./EqualOperator"
/**
@ -22,7 +22,7 @@ export type FindOptionsWhereProperty<
? Property | FindOperator<Property>
: PropertyToBeNarrowed extends Date
? Property | FindOperator<Property>
: PropertyToBeNarrowed extends ObjectID
: PropertyToBeNarrowed extends ObjectId
? Property | FindOperator<Property>
: PropertyToBeNarrowed extends string
? Property | FindOperator<Property>

View File

@ -550,10 +550,8 @@ export class MigrationExecutor {
): Promise<Migration[]> {
if (this.connection.driver.options.type === "mongodb") {
const mongoRunner = queryRunner as MongoQueryRunner
return await mongoRunner.databaseConnection
.db(this.connection.driver.database!)
.collection(this.migrationsTableName)
.find<Migration>()
return mongoRunner
.cursor(this.migrationsTableName, {})
.sort({ _id: -1 })
.toArray()
} else {

View File

@ -33,16 +33,24 @@ export class DocumentToEntityTransformer {
let hasData = false
// handle _id property the special way
if (
metadata.objectIdColumn &&
document[metadata.objectIdColumn.databaseNameWithoutPrefixes]
) {
if (metadata.objectIdColumn) {
// todo: we can't use driver in this class
// do we really need prepare hydrated value here? If no then no problem. If yes then think maybe prepareHydratedValue process should be extracted out of driver class?
// entity[metadata.objectIdColumn.propertyName] = this.driver.prepareHydratedValue(document[metadata.objectIdColumn.name"], metadata.objectIdColumn);
entity[metadata.objectIdColumn.propertyName] =
document[metadata.objectIdColumn.databaseNameWithoutPrefixes]
hasData = true
// entity[metadata.ObjectIdColumn.propertyName] = this.driver.prepareHydratedValue(document[metadata.ObjectIdColumn.name"], metadata.ObjectIdColumn);
const { databaseNameWithoutPrefixes, propertyName } =
metadata.objectIdColumn
const documentIdWithoutPrefixes =
document[databaseNameWithoutPrefixes]
const documentIdWithPropertyName = document[propertyName]
if (documentIdWithoutPrefixes) {
entity[propertyName] = documentIdWithoutPrefixes
hasData = true
} else if (documentIdWithPropertyName) {
entity[propertyName] = documentIdWithPropertyName
hasData = true
}
}
// add special columns that contains relation ids

View File

@ -10,7 +10,7 @@ import { SelectQueryBuilder } from "../query-builder/SelectQueryBuilder"
import { InsertResult } from "../query-builder/result/InsertResult"
import { UpdateResult } from "../query-builder/result/UpdateResult"
import { DeleteResult } from "../query-builder/result/DeleteResult"
import { ObjectID } from "../driver/mongodb/typings"
import { ObjectId } from "../driver/mongodb/typings"
import { ObjectUtils } from "../util/ObjectUtils"
import { QueryDeepPartialEntity } from "../query-builder/QueryPartialEntity"
import { UpsertOptions } from "./UpsertOptions"
@ -341,8 +341,8 @@ export class BaseEntity {
| number[]
| Date
| Date[]
| ObjectID
| ObjectID[]
| ObjectId
| ObjectId[]
| FindOptionsWhere<T>,
partialEntity: QueryDeepPartialEntity<T>,
): Promise<UpdateResult> {
@ -382,8 +382,8 @@ export class BaseEntity {
| number[]
| Date
| Date[]
| ObjectID
| ObjectID[]
| ObjectId
| ObjectId[]
| FindOptionsWhere<T>,
): Promise<DeleteResult> {
return this.getRepository<T>().delete(criteria)
@ -545,7 +545,7 @@ export class BaseEntity {
*/
static findOneById<T extends BaseEntity>(
this: { new (): T } & typeof BaseEntity,
id: string | number | Date | ObjectID,
id: string | number | Date | ObjectId,
): Promise<T | null> {
return this.getRepository<T>().findOneById(id)
}

View File

@ -1,3 +1,3 @@
import { ObjectID } from "../driver/mongodb/typings"
import { ObjectId } from "../driver/mongodb/typings"
export type EntityId = string | number | Date | ObjectID
export type EntityId = string | number | Date | ObjectId

View File

@ -1,37 +1,6 @@
import { ObjectLiteral } from "../common/ObjectLiteral"
import { Repository } from "./Repository"
import { MongoFindManyOptions } from "../find-options/mongodb/MongoFindManyOptions"
import {
AggregationCursor,
BulkWriteOpResultObject,
Code,
Collection,
CollectionAggregationOptions,
CollectionBulkWriteOptions,
CollectionInsertManyOptions,
CollectionInsertOneOptions,
CollectionOptions,
CollStats,
CommandCursor,
Cursor,
DeleteWriteOpResultObject,
FindAndModifyWriteOpResultObject,
FindOneAndReplaceOption,
GeoHaystackSearchOptions,
GeoNearOptions,
InsertOneWriteOpResult,
InsertWriteOpResult,
MapReduceOptions,
MongoCountPreferences,
MongodbIndexOptions,
ObjectID,
OrderedBulkOperation,
ParallelCollectionScanOptions,
ReadPreference,
ReplaceOneOptions,
UnorderedBulkOperation,
UpdateWriteOpResult,
} from "../driver/mongodb/typings"
import { MongoEntityManager } from "../entity-manager/MongoEntityManager"
import { QueryRunner } from "../query-runner/QueryRunner"
import { SelectQueryBuilder } from "../query-builder/SelectQueryBuilder"
@ -39,6 +8,44 @@ import { TypeORMError } from "../error/TypeORMError"
import { MongoFindOneOptions } from "../find-options/mongodb/MongoFindOneOptions"
import { FindOneOptions } from "../find-options/FindOneOptions"
import {
CreateIndexesOptions,
ObjectId,
ReplaceOptions,
//
AggregateOptions,
AggregationCursor,
AnyBulkWriteOperation,
BulkWriteOptions,
BulkWriteResult,
Collection,
CollStats,
CollStatsOptions,
CommandOperationOptions,
CountOptions,
DeleteOptions,
DeleteResult,
Document,
Filter,
FilterOperators,
FindCursor,
FindOneAndDeleteOptions,
FindOneAndReplaceOptions,
FindOneAndUpdateOptions,
IndexDescription,
InsertManyResult,
InsertOneOptions,
InsertOneResult,
ListIndexesCursor,
ListIndexesOptions,
OrderedBulkOperation,
UnorderedBulkOperation,
UpdateFilter,
UpdateOptions,
UpdateResult,
} from "../driver/mongodb/typings"
import { FindManyOptions } from "../find-options/FindManyOptions"
/**
* Repository used to manage mongodb documents of a single entity type.
*/
@ -80,7 +87,12 @@ export class MongoRepository<
/**
* Finds entities that match given find options or conditions.
*/
find(options?: MongoFindManyOptions<Entity>): Promise<Entity[]> {
find(
options?:
| FindManyOptions<Entity>
| Partial<Entity>
| FilterOperators<Entity>,
): Promise<Entity[]> {
return this.manager.find(this.metadata.target, options)
}
@ -151,15 +163,7 @@ export class MongoRepository<
* })
*/
async findOneById(
id:
| string
| string[]
| number
| number[]
| Date
| Date[]
| ObjectID
| ObjectID[],
id: string | number | Date | ObjectId,
): Promise<Entity | null> {
return this.manager.findOneById(this.metadata.target, id)
}
@ -183,7 +187,7 @@ export class MongoRepository<
/**
* Creates a cursor for a query that can be used to iterate over results from MongoDB.
*/
createCursor<T = any>(query?: ObjectLiteral): Cursor<T> {
createCursor<T = any>(query?: Filter<Entity>): FindCursor<T> {
return this.manager.createCursor(this.metadata.target, query)
}
@ -191,7 +195,7 @@ export class MongoRepository<
* Creates a cursor for a query that can be used to iterate over results from MongoDB.
* This returns modified version of cursor that transforms each result into Entity model.
*/
createEntityCursor(query?: ObjectLiteral): Cursor<Entity> {
createEntityCursor(query?: Filter<Entity>): FindCursor<Entity> {
return this.manager.createEntityCursor(this.metadata.target, query)
}
@ -200,8 +204,8 @@ export class MongoRepository<
*/
aggregate<R = any>(
pipeline: ObjectLiteral[],
options?: CollectionAggregationOptions,
): AggregationCursor<R> {
options?: AggregateOptions,
): AggregationCursor<Entity> {
return this.manager.aggregate<R>(
this.metadata.target,
pipeline,
@ -215,7 +219,7 @@ export class MongoRepository<
*/
aggregateEntity(
pipeline: ObjectLiteral[],
options?: CollectionAggregationOptions,
options?: AggregateOptions,
): AggregationCursor<Entity> {
return this.manager.aggregateEntity(
this.metadata.target,
@ -227,30 +231,24 @@ export class MongoRepository<
* Perform a bulkWrite operation without a fluent API.
*/
bulkWrite(
operations: ObjectLiteral[],
options?: CollectionBulkWriteOptions,
): Promise<BulkWriteOpResultObject> {
operations: AnyBulkWriteOperation[],
options?: BulkWriteOptions,
): Promise<BulkWriteResult> {
return this.manager.bulkWrite(this.metadata.target, operations, options)
}
/**
* Count number of matching documents in the db to a query.
*/
count(
query?: ObjectLiteral,
options?: MongoCountPreferences,
): Promise<number> {
count(query?: ObjectLiteral, options?: CountOptions): Promise<number> {
return this.manager.count(this.metadata.target, query || {}, options)
}
/**
* Count number of matching documents in the db to a query.
*/
countBy(
query?: ObjectLiteral,
options?: MongoCountPreferences,
): Promise<number> {
return this.manager.countBy(this.metadata.target, query || {}, options)
countBy(query?: ObjectLiteral, options?: CountOptions): Promise<number> {
return this.manager.countBy(this.metadata.target, query, options)
}
/**
@ -258,7 +256,7 @@ export class MongoRepository<
*/
createCollectionIndex(
fieldOrSpec: string | any,
options?: MongodbIndexOptions,
options?: CreateIndexesOptions,
): Promise<string> {
return this.manager.createCollectionIndex(
this.metadata.target,
@ -272,7 +270,7 @@ export class MongoRepository<
* Earlier version of MongoDB will throw a command not supported error.
* Index specifications are defined at http://docs.mongodb.org/manual/reference/command/createIndexes/.
*/
createCollectionIndexes(indexSpecs: ObjectLiteral[]): Promise<void> {
createCollectionIndexes(indexSpecs: IndexDescription[]): Promise<string[]> {
return this.manager.createCollectionIndexes(
this.metadata.target,
indexSpecs,
@ -284,8 +282,8 @@ export class MongoRepository<
*/
deleteMany(
query: ObjectLiteral,
options?: CollectionOptions,
): Promise<DeleteWriteOpResultObject> {
options?: DeleteOptions,
): Promise<DeleteResult> {
return this.manager.deleteMany(this.metadata.tableName, query, options)
}
@ -294,8 +292,8 @@ export class MongoRepository<
*/
deleteOne(
query: ObjectLiteral,
options?: CollectionOptions,
): Promise<DeleteWriteOpResultObject> {
options?: DeleteOptions,
): Promise<DeleteResult> {
return this.manager.deleteOne(this.metadata.tableName, query, options)
}
@ -305,7 +303,7 @@ export class MongoRepository<
distinct(
key: string,
query: ObjectLiteral,
options?: { readPreference?: ReadPreference | string },
options?: CommandOperationOptions,
): Promise<any> {
return this.manager.distinct(
this.metadata.tableName,
@ -320,7 +318,7 @@ export class MongoRepository<
*/
dropCollectionIndex(
indexName: string,
options?: CollectionOptions,
options?: CommandOperationOptions,
): Promise<any> {
return this.manager.dropCollectionIndex(
this.metadata.tableName,
@ -341,8 +339,8 @@ export class MongoRepository<
*/
findOneAndDelete(
query: ObjectLiteral,
options?: { projection?: Object; sort?: Object; maxTimeMS?: number },
): Promise<FindAndModifyWriteOpResultObject> {
options?: FindOneAndDeleteOptions,
): Promise<Document> {
return this.manager.findOneAndDelete(
this.metadata.tableName,
query,
@ -356,8 +354,8 @@ export class MongoRepository<
findOneAndReplace(
query: ObjectLiteral,
replacement: Object,
options?: FindOneAndReplaceOption,
): Promise<FindAndModifyWriteOpResultObject> {
options?: FindOneAndReplaceOptions,
): Promise<Document> {
return this.manager.findOneAndReplace(
this.metadata.tableName,
query,
@ -372,8 +370,8 @@ export class MongoRepository<
findOneAndUpdate(
query: ObjectLiteral,
update: Object,
options?: FindOneAndReplaceOption,
): Promise<FindAndModifyWriteOpResultObject> {
options?: FindOneAndUpdateOptions,
): Promise<Document> {
return this.manager.findOneAndUpdate(
this.metadata.tableName,
query,
@ -382,53 +380,6 @@ export class MongoRepository<
)
}
/**
* Execute a geo search using a geo haystack index on a collection.
*/
geoHaystackSearch(
x: number,
y: number,
options?: GeoHaystackSearchOptions,
): Promise<any> {
return this.manager.geoHaystackSearch(
this.metadata.tableName,
x,
y,
options,
)
}
/**
* Execute the geoNear command to search for items in the collection.
*/
geoNear(x: number, y: number, options?: GeoNearOptions): Promise<any> {
return this.manager.geoNear(this.metadata.tableName, x, y, options)
}
/**
* Run a group command across a collection.
*/
group(
keys: Object | Array<any> | Function | Code,
condition: Object,
initial: Object,
reduce: Function | Code,
finalize: Function | Code,
command: boolean,
options?: { readPreference?: ReadPreference | string },
): Promise<any> {
return this.manager.group(
this.metadata.tableName,
keys,
condition,
initial,
reduce,
finalize,
command,
options,
)
}
/**
* Retrieve all the indexes on the collection.
*/
@ -459,7 +410,7 @@ export class MongoRepository<
/**
* Initiate an In order bulk write operation, operations will be serially executed in the order they are added, creating a new operation for each switch in types.
*/
initializeOrderedBulkOp(options?: CollectionOptions): OrderedBulkOperation {
initializeOrderedBulkOp(options?: BulkWriteOptions): OrderedBulkOperation {
return this.manager.initializeOrderedBulkOp(
this.metadata.tableName,
options,
@ -470,7 +421,7 @@ export class MongoRepository<
* Initiate a Out of order batch write operation. All operations will be buffered into insert/update/remove commands executed out of order.
*/
initializeUnorderedBulkOp(
options?: CollectionOptions,
options?: BulkWriteOptions,
): UnorderedBulkOperation {
return this.manager.initializeUnorderedBulkOp(
this.metadata.tableName,
@ -483,8 +434,8 @@ export class MongoRepository<
*/
insertMany(
docs: ObjectLiteral[],
options?: CollectionInsertManyOptions,
): Promise<InsertWriteOpResult> {
options?: BulkWriteOptions,
): Promise<InsertManyResult<Document>> {
return this.manager.insertMany(this.metadata.tableName, docs, options)
}
@ -493,8 +444,8 @@ export class MongoRepository<
*/
insertOne(
doc: ObjectLiteral,
options?: CollectionInsertOneOptions,
): Promise<InsertOneWriteOpResult> {
options?: InsertOneOptions,
): Promise<InsertOneResult> {
return this.manager.insertOne(this.metadata.tableName, doc, options)
}
@ -508,59 +459,20 @@ export class MongoRepository<
/**
* Get the list of all indexes information for the collection.
*/
listCollectionIndexes(options?: {
batchSize?: number
readPreference?: ReadPreference | string
}): CommandCursor {
listCollectionIndexes(options?: ListIndexesOptions): ListIndexesCursor {
return this.manager.listCollectionIndexes(
this.metadata.tableName,
options,
)
}
/**
* Run Map Reduce across a collection. Be aware that the inline option for out will return an array of results not a collection.
*/
mapReduce(
map: Function | string,
reduce: Function | string,
options?: MapReduceOptions,
): Promise<any> {
return this.manager.mapReduce(
this.metadata.tableName,
map,
reduce,
options,
)
}
/**
* Return N number of parallel cursors for a collection allowing parallel reading of entire collection.
* There are no ordering guarantees for returned results.
*/
parallelCollectionScan(
options?: ParallelCollectionScanOptions,
): Promise<Cursor<Entity>[]> {
return this.manager.parallelCollectionScan(
this.metadata.tableName,
options,
)
}
/**
* Reindex all indexes on the collection Warning: reIndex is a blocking operation (indexes are rebuilt in the foreground) and will be slow for large collections.
*/
reIndex(): Promise<any> {
return this.manager.reIndex(this.metadata.tableName)
}
/**
* Reindex all indexes on the collection Warning: reIndex is a blocking operation (indexes are rebuilt in the foreground) and will be slow for large collections.
*/
rename(
newName: string,
options?: { dropTarget?: boolean },
): Promise<Collection<any>> {
): Promise<Collection<Document>> {
return this.manager.rename(this.metadata.tableName, newName, options)
}
@ -570,8 +482,8 @@ export class MongoRepository<
replaceOne(
query: ObjectLiteral,
doc: ObjectLiteral,
options?: ReplaceOneOptions,
): Promise<UpdateWriteOpResult> {
options?: ReplaceOptions,
): Promise<Document | UpdateResult> {
return this.manager.replaceOne(
this.metadata.tableName,
query,
@ -583,7 +495,7 @@ export class MongoRepository<
/**
* Get all the collection statistics.
*/
stats(options?: { scale: number }): Promise<CollStats> {
stats(options?: CollStatsOptions): Promise<CollStats> {
return this.manager.stats(this.metadata.tableName, options)
}
@ -592,9 +504,9 @@ export class MongoRepository<
*/
updateMany(
query: ObjectLiteral,
update: ObjectLiteral,
options?: { upsert?: boolean; w?: any; wtimeout?: number; j?: boolean },
): Promise<UpdateWriteOpResult> {
update: UpdateFilter<Document>,
options?: UpdateOptions,
): Promise<Document | UpdateResult> {
return this.manager.updateMany(
this.metadata.tableName,
query,
@ -608,9 +520,9 @@ export class MongoRepository<
*/
updateOne(
query: ObjectLiteral,
update: ObjectLiteral,
options?: ReplaceOneOptions,
): Promise<UpdateWriteOpResult> {
update: UpdateFilter<Document>,
options?: UpdateOptions,
): Promise<Document | UpdateResult> {
return this.manager.updateOne(
this.metadata.tableName,
query,

View File

@ -11,7 +11,7 @@ import { DeleteResult } from "../query-builder/result/DeleteResult"
import { UpdateResult } from "../query-builder/result/UpdateResult"
import { InsertResult } from "../query-builder/result/InsertResult"
import { QueryDeepPartialEntity } from "../query-builder/QueryPartialEntity"
import { ObjectID } from "../driver/mongodb/typings"
import { ObjectId } from "../driver/mongodb/typings"
import { FindOptionsWhere } from "../find-options/FindOptionsWhere"
import { UpsertOptions } from "./UpsertOptions"
import { EntityTarget } from "../common/EntityTarget"
@ -353,8 +353,8 @@ export class Repository<Entity extends ObjectLiteral> {
| number[]
| Date
| Date[]
| ObjectID
| ObjectID[]
| ObjectId
| ObjectId[]
| FindOptionsWhere<Entity>,
partialEntity: QueryDeepPartialEntity<Entity>,
): Promise<UpdateResult> {
@ -397,8 +397,8 @@ export class Repository<Entity extends ObjectLiteral> {
| number[]
| Date
| Date[]
| ObjectID
| ObjectID[]
| ObjectId
| ObjectId[]
| FindOptionsWhere<Entity>,
): Promise<DeleteResult> {
return this.manager.delete(this.metadata.target as any, criteria as any)
@ -418,8 +418,8 @@ export class Repository<Entity extends ObjectLiteral> {
| number[]
| Date
| Date[]
| ObjectID
| ObjectID[]
| ObjectId
| ObjectId[]
| FindOptionsWhere<Entity>,
): Promise<UpdateResult> {
return this.manager.softDelete(
@ -442,8 +442,8 @@ export class Repository<Entity extends ObjectLiteral> {
| number[]
| Date
| Date[]
| ObjectID
| ObjectID[]
| ObjectId
| ObjectId[]
| FindOptionsWhere<Entity>,
): Promise<UpdateResult> {
return this.manager.restore(
@ -598,7 +598,7 @@ export class Repository<Entity extends ObjectLiteral> {
* })
*/
async findOneById(
id: number | string | Date | ObjectID,
id: number | string | Date | ObjectId,
): Promise<Entity | null> {
return this.manager.findOneById(this.metadata.target, id)
}

View File

@ -2,7 +2,7 @@ import { DataSource } from "../data-source/DataSource"
import { SchemaBuilder } from "./SchemaBuilder"
import { MongoQueryRunner } from "../driver/mongodb/MongoQueryRunner"
import { SqlInMemory } from "../driver/SqlInMemory"
import { MongodbIndexOptions } from "../driver/mongodb/typings"
import { CreateIndexesOptions } from "../driver/mongodb/typings"
/**
* Creates complete tables schemas in the database based on the entity metadatas.
@ -38,7 +38,7 @@ export class MongoSchemaBuilder implements SchemaBuilder {
const promises: Promise<any>[] = []
this.connection.entityMetadatas.forEach((metadata) => {
metadata.indices.forEach((index) => {
const options: MongodbIndexOptions = Object.assign(
const options: CreateIndexesOptions = Object.assign(
{},
{
name: index.name,
@ -59,7 +59,7 @@ export class MongoSchemaBuilder implements SchemaBuilder {
)
})
metadata.uniques.forEach((unique) => {
const options = <MongodbIndexOptions>{
const options = <CreateIndexesOptions>{
name: unique.name,
unique: true,
}

View File

@ -24,22 +24,22 @@ describe("benchmark > QueryBuilder > wide join", () => {
it("testing query builder with join to 10 relations with 10 columns each", () => {
for (let i = 1; i <= 10_000; i++) {
connections.map((connection) =>
connections.forEach((connection) =>
connection.manager
.createQueryBuilder(One, "ones")
.setFindOptions({
where: { id: 1 },
relations: [
"two",
"three",
"four",
"five",
"six",
"seven",
"eight",
"nine",
"ten",
],
relations: {
two: true,
three: true,
four: true,
five: true,
six: true,
seven: true,
eight: true,
nine: true,
ten: true,
},
})
.getQuery(),
)

View File

@ -44,7 +44,7 @@ describe("deferrable fk constraints should be check at the end of transaction (#
// now check
const user = await connection.manager.findOne(User, {
relations: ["company"],
relations: { company: true },
where: { id: 1 },
})
@ -86,7 +86,7 @@ describe("deferrable fk constraints should be check at the end of transaction (#
// now check
const office = await connection.manager.findOne(Office, {
relations: ["company"],
relations: { company: true },
where: { id: 2 },
})

View File

@ -25,13 +25,14 @@ describe("MongoDriver", () => {
const connectPromise = driver.connect()
// There is not callback on connect method
// Take the promise parameter that we receive in the callback, call it, so the underlying promise gets resolved.
const firstMethodCall = connect.args[0]
const callback = firstMethodCall[2]
callback(undefined, {})
// const firstMethodCall = connect.args[0]
// const callback = firstMethodCall[2]
// callback(undefined, {})
await connectPromise
return firstMethodCall[0]
return url
}
describe("connection string", () => {

View File

@ -91,7 +91,7 @@ describe("find options > relations", () => {
const posts2 = await connection
.createQueryBuilder(Post, "post")
.setFindOptions({
relations: ["author"],
relations: { author: true },
order: {
id: "asc",
},

View File

@ -26,7 +26,7 @@ describe("find options > select", () => {
const posts1 = await connection
.createQueryBuilder(Post, "post")
.setFindOptions({
select: ["id"],
select: { id: true },
order: {
id: "asc",
},
@ -67,7 +67,7 @@ describe("find options > select", () => {
const posts1 = await connection
.createQueryBuilder(Post, "post")
.setFindOptions({
select: ["title"],
select: { title: true },
order: {
title: "asc",
},
@ -108,7 +108,7 @@ describe("find options > select", () => {
const posts1 = await connection
.createQueryBuilder(Post, "post")
.setFindOptions({
select: ["title", "text"],
select: { title: true, text: true },
order: {
title: "asc",
},

View File

@ -2,12 +2,12 @@ import { Entity } from "../../../../../../src/decorator/entity/Entity"
import { Column } from "../../../../../../src/decorator/columns/Column"
import { ObjectIdColumn } from "../../../../../../src/decorator/columns/ObjectIdColumn"
import { Counters } from "./Counters"
import { ObjectID } from "../../../../../../src/driver/mongodb/typings"
import { ObjectId } from "../../../../../../src/driver/mongodb/typings"
@Entity()
export class Post {
@ObjectIdColumn()
id: ObjectID
id: ObjectId
@Column()
title: string

View File

@ -2,13 +2,13 @@ import { Entity } from "../../../../../../src/decorator/entity/Entity"
import { Column } from "../../../../../../src/decorator/columns/Column"
import { ObjectIdColumn } from "../../../../../../src/decorator/columns/ObjectIdColumn"
import { Counters } from "./Counters"
import { ObjectID } from "../../../../../../src/driver/mongodb/typings"
import { ObjectId } from "../../../../../../src/driver/mongodb/typings"
import { Tags } from "./Tags"
@Entity()
export class Post {
@ObjectIdColumn()
id: ObjectID
id: ObjectId
@Column()
title: string

View File

@ -2,12 +2,12 @@ import { Entity } from "../../../../../../src/decorator/entity/Entity"
import { Column } from "../../../../../../src/decorator/columns/Column"
import { ObjectIdColumn } from "../../../../../../src/decorator/columns/ObjectIdColumn"
import { Counters } from "./Counters"
import { ObjectID } from "../../../../../../src/driver/mongodb/typings"
import { ObjectId } from "../../../../../../src/driver/mongodb/typings"
@Entity()
export class Post {
@ObjectIdColumn()
id: ObjectID
id: ObjectId
@Column()
title: string

View File

@ -2,14 +2,14 @@ import { Entity } from "../../../../../../src/decorator/entity/Entity"
import { Column } from "../../../../../../src/decorator/columns/Column"
import { ObjectIdColumn } from "../../../../../../src/decorator/columns/ObjectIdColumn"
import { Index } from "../../../../../../src/decorator/Index"
import { ObjectID } from "../../../../../../src/driver/mongodb/typings"
import { ObjectId } from "../../../../../../src/driver/mongodb/typings"
import { Information } from "./Information"
@Entity()
@Index("info_description", ["info.description"])
export class Post {
@ObjectIdColumn()
id: ObjectID
id: ObjectId
@Column()
title: string

View File

@ -2,7 +2,7 @@ import { Entity } from "../../../../../../src/decorator/entity/Entity"
import { Column } from "../../../../../../src/decorator/columns/Column"
import { ObjectIdColumn } from "../../../../../../src/decorator/columns/ObjectIdColumn"
import { Index } from "../../../../../../src/decorator/Index"
import { ObjectID } from "../../../../../../src/driver/mongodb/typings"
import { ObjectId } from "../../../../../../src/driver/mongodb/typings"
@Entity()
@Index(["title", "name"])
@ -13,7 +13,7 @@ import { ObjectID } from "../../../../../../src/driver/mongodb/typings"
@Index("count_expire", () => ({ title: -1 }), { expireAfterSeconds: 3600 })
export class Post {
@ObjectIdColumn()
id: ObjectID
id: ObjectId
@Column()
@Index()

View File

@ -1,13 +1,13 @@
import { Entity } from "../../../../../../src/decorator/entity/Entity"
import { Column } from "../../../../../../src/decorator/columns/Column"
import { ObjectIdColumn } from "../../../../../../src/decorator/columns/ObjectIdColumn"
import { ObjectID } from "../../../../../../src/driver/mongodb/typings"
import { ObjectId } from "../../../../../../src/driver/mongodb/typings"
import { DeleteDateColumn } from "../../../../../../src"
@Entity()
export class Post {
@ObjectIdColumn()
id: ObjectID
id: ObjectId
@Column()
title: string
@ -22,7 +22,7 @@ export class Post {
@Entity()
export class PostWithDeleted {
@ObjectIdColumn()
id: ObjectID
id: ObjectId
@Column()
title: string

View File

@ -104,7 +104,7 @@ describe("mongodb > MongoRepository", () => {
}),
))
it("should be able to use findByIds with both objectId and strings", () =>
it("should be able to use findByIds with both ObjectId and strings", () =>
Promise.all(
connections.map(async (connection) => {
const postRepository = connection.getMongoRepository(Post)

View File

@ -1,12 +1,11 @@
import { Entity } from "../../../../../../src/decorator/entity/Entity"
import { Column } from "../../../../../../src/decorator/columns/Column"
import { ObjectIdColumn } from "../../../../../../src/decorator/columns/ObjectIdColumn"
import { ObjectID } from "../../../../../../src/driver/mongodb/typings"
import { ObjectId } from "../../../../../../src/driver/mongodb/typings"
@Entity()
export class Post {
@ObjectIdColumn()
nonIdNameOfObjectId: ObjectID
nonIdNameOfObjectId: ObjectId
@Column()
title: string

View File

@ -1,12 +1,12 @@
import { Entity } from "../../../../../../src/decorator/entity/Entity"
import { Column } from "../../../../../../src/decorator/columns/Column"
import { ObjectIdColumn } from "../../../../../../src/decorator/columns/ObjectIdColumn"
import { ObjectID } from "../../../../../../src/driver/mongodb/typings"
import { ObjectId } from "../../../../../../src/driver/mongodb/typings"
@Entity()
export class PostWithUnderscoreId {
@ObjectIdColumn()
_id: ObjectID
_id: ObjectId
@Column()
title: string

View File

@ -34,7 +34,7 @@ describe("mongodb > object id columns", () => {
// little hack to get raw data from mongodb
const aggArr = await postMongoRepository.aggregate([]).toArray()
expect(aggArr[0]._id).to.be.not.undefined
expect((aggArr[0] as any)._id).to.be.not.undefined
expect(aggArr[0].nonIdNameOfObjectId).to.be.undefined
}),
))
@ -94,7 +94,7 @@ describe("mongodb > object id columns", () => {
// little hack to get raw data from mongodb
const aggArr = await postMongoRepository.aggregate([]).toArray()
expect(aggArr[0]._id).to.be.not.undefined
expect((aggArr[0] as any)._id).to.be.not.undefined
expect(aggArr[0].nonIdNameOfObjectId).to.be.undefined
}),
))

View File

@ -2,12 +2,12 @@ import { Entity } from "../../../../../../src/decorator/entity/Entity"
import { Counters } from "./Counters"
import { Column } from "../../../../../../src/decorator/columns/Column"
import { ObjectIdColumn } from "../../../../../../src/decorator/columns/ObjectIdColumn"
import { ObjectID } from "../../../../../../src/driver/mongodb/typings"
import { ObjectId } from "../../../../../../src/driver/mongodb/typings"
@Entity()
export class Post {
@ObjectIdColumn()
id: ObjectID
id: ObjectId
@Column()
title: string

View File

@ -1,14 +1,14 @@
import { Entity } from "../../../../../../src/decorator/entity/Entity"
import { Column } from "../../../../../../src/decorator/columns/Column"
import { ObjectIdColumn } from "../../../../../../src/decorator/columns/ObjectIdColumn"
import { ObjectID } from "../../../../../../src/driver/mongodb/typings"
import { ObjectId } from "../../../../../../src/driver/mongodb/typings"
import { CreateDateColumn } from "../../../../../../src/decorator/columns/CreateDateColumn"
import { UpdateDateColumn } from "../../../../../../src/decorator/columns/UpdateDateColumn"
@Entity()
export class Post {
@ObjectIdColumn()
id: ObjectID
id: ObjectId
@Column()
message: string

View File

@ -45,7 +45,7 @@ describe("persistence > one-to-one", function () {
const loadedUser = await userRepository.findOne({
where: { email: "mwelnick@test.com" },
relations: ["access_token"],
relations: { access_token: true },
})
expect(loadedUser).not.to.be.null

View File

@ -35,7 +35,11 @@ describe("persistence > orphanage > delete", () => {
let postRepository: Repository<Post>
let categoryId: number
beforeEach(async () => {
beforeEach(async function () {
if (connections.length === 0) {
this.skip()
}
await Promise.all(
connections.map(async (connection) => {
categoryRepository = connection.getRepository(Category)

View File

@ -35,7 +35,11 @@ describe("persistence > orphanage > disable", () => {
let settingRepo: Repository<Setting>
let userId: number
beforeEach(async () => {
beforeEach(async function () {
if (connections.length === 0) {
this.skip()
}
await Promise.all(
connections.map(async (connection) => {
userRepo = connection.getRepository(User)

View File

@ -300,7 +300,7 @@ describe("query builder > soft-delete", () => {
await userRepository.save(user2)
const users = await userRepository.find({
relations: ["picture"],
relations: { picture: true },
})
expect(users[0].picture.deletedAt).to.equal(null)
@ -312,7 +312,7 @@ describe("query builder > soft-delete", () => {
const usersWithSoftDelete = await userRepository.find({
withDeleted: true,
relations: ["picture"],
relations: { picture: true },
})
expect(usersWithSoftDelete[0].picture.deletedAt).to.not.equal(

View File

@ -58,7 +58,7 @@ describe("relations > multiple-primary-keys > one-to-many", () => {
await insertSimpleTestData(connection)
const [user] = await connection.getRepository(User).find({
relations: ["settings"],
relations: { settings: true },
// relationLoadStrategy: "join"
})
@ -86,7 +86,7 @@ describe("relations > multiple-primary-keys > one-to-many", () => {
const [user] = await connection
.getRepository(User)
.find({ relations: ["settings"] })
.find({ relations: { settings: true } })
// check the saved items have correctly updated value
expect(user!).not.to.be.undefined
@ -117,7 +117,7 @@ describe("relations > multiple-primary-keys > one-to-many", () => {
})
const [user] = await connection.getRepository(User).find({
relations: ["settings"],
relations: { settings: true },
})
// check that no relational items are found

View File

@ -595,7 +595,7 @@ describe("repository > find options > locking", () => {
.getRepository(Post)
.findOne({
where: { id: 1 },
relations: ["author"],
relations: { author: true },
lock: {
mode: "pessimistic_write",
tables: ["img"],
@ -617,7 +617,7 @@ describe("repository > find options > locking", () => {
return Promise.all([
entityManager.getRepository(Post).findOne({
where: { id: 1 },
relations: ["author"],
relations: { author: true },
lock: {
mode: "pessimistic_write",
tables: ["post"],
@ -625,7 +625,7 @@ describe("repository > find options > locking", () => {
}),
entityManager.getRepository(Post).findOne({
where: { id: 1 },
relations: ["author"],
relations: { author: true },
lock: { mode: "pessimistic_write" },
}),
])
@ -637,7 +637,7 @@ describe("repository > find options > locking", () => {
return Promise.all([
entityManager.getRepository(Post).findOne({
where: { id: 1 },
relations: ["author"],
relations: { author: true },
lock: {
mode: "pessimistic_write",
tables: ["post"],
@ -647,7 +647,7 @@ describe("repository > find options > locking", () => {
.getRepository(Post)
.findOne({
where: { id: 1 },
relations: ["author"],
relations: { author: true },
lock: { mode: "pessimistic_write" },
})
.should.be.rejectedWith(
@ -670,7 +670,7 @@ describe("repository > find options > locking", () => {
return Promise.all([
entityManager.getRepository(Post).findOne({
where: { id: 1 },
relations: ["author"],
relations: { author: true },
lock: {
mode: "pessimistic_read",
tables: ["post"],
@ -678,7 +678,7 @@ describe("repository > find options > locking", () => {
}),
entityManager.getRepository(Post).findOne({
where: { id: 1 },
relations: ["author"],
relations: { author: true },
lock: {
mode: "pessimistic_write",
tables: ["post"],
@ -686,7 +686,7 @@ describe("repository > find options > locking", () => {
}),
entityManager.getRepository(Post).findOne({
where: { id: 1 },
relations: ["author"],
relations: { author: true },
lock: {
mode: "pessimistic_partial_write",
tables: ["post"],
@ -694,7 +694,7 @@ describe("repository > find options > locking", () => {
}),
entityManager.getRepository(Post).findOne({
where: { id: 1 },
relations: ["author"],
relations: { author: true },
lock: {
mode: "pessimistic_write_or_fail",
tables: ["post"],
@ -702,7 +702,7 @@ describe("repository > find options > locking", () => {
}),
entityManager.getRepository(Post).findOne({
where: { id: 1 },
relations: ["author"],
relations: { author: true },
lock: {
mode: "for_no_key_update",
tables: ["post"],
@ -710,7 +710,7 @@ describe("repository > find options > locking", () => {
}),
entityManager.getRepository(Post).findOne({
where: { id: 1 },
relations: ["author"],
relations: { author: true },
lock: {
mode: "for_key_share",
tables: ["post"],

View File

@ -45,7 +45,7 @@ describe("repository > find options", () => {
await connection.manager.save(post)
const [loadedPost] = await connection.getRepository(Post).find({
relations: ["author", "categories"],
relations: { author: true, categories: true },
})
expect(loadedPost).to.be.eql({
id: 1,
@ -126,7 +126,7 @@ describe("repository > find options", () => {
const loadedPhoto = await connection
.getRepository(Photo)
.findOne({
select: ["name"],
select: { name: true },
where: {
id: 5,
},
@ -135,14 +135,14 @@ describe("repository > find options", () => {
const loadedPhotos1 = await connection
.getRepository(Photo)
.find({
select: ["filename", "views"],
select: { filename: true, views: true },
})
const loadedPhotos2 = await connection
.getRepository(Photo)
.find({
select: ["id", "name", "description"],
relations: ["categories"],
select: { id: true, name: true, description: true },
relations: { categories: true },
})
// const loadedPhotos3 = await connection.getRepository(Photo).createQueryBuilder("photo")

View File

@ -55,7 +55,7 @@ describe("table-inheritance > single-table > no-type-column", () => {
// -------------------------------------------------------------------------
const [postIt] = await postItRepo.find({
relations: ["owner"],
relations: { owner: true },
})
postIt.owner.should.be.an.instanceOf(Employee)
@ -63,7 +63,7 @@ describe("table-inheritance > single-table > no-type-column", () => {
postIt.owner.employeeName.should.be.equal("Alice Foo")
const [sticky] = await stickyRepo.find({
relations: ["owner"],
relations: { owner: true },
})
sticky.owner.should.be.an.instanceOf(Author)

View File

@ -45,7 +45,7 @@ describe("github issues > #1178 subqueries must work in insert statements", () =
where: {
id: 1,
},
relations: ["user"],
relations: { user: true },
})
.should.eventually.eql({
id: 1,

View File

@ -1,4 +1,4 @@
import { ObjectID } from "../../../../src/driver/mongodb/typings"
import { ObjectId } from "../../../../src/driver/mongodb/typings"
import { Entity } from "../../../../src/decorator/entity/Entity"
import { ObjectIdColumn } from "../../../../src/decorator/columns/ObjectIdColumn"
import { Column } from "../../../../src/decorator/columns/Column"
@ -6,7 +6,7 @@ import { Column } from "../../../../src/decorator/columns/Column"
@Entity()
export class Event {
@ObjectIdColumn()
id: ObjectID
id: ObjectId
@Column()
name: string

View File

@ -1,13 +1,13 @@
import { Entity } from "../../../../src/decorator/entity/Entity"
import { ObjectIdColumn } from "../../../../src/decorator/columns/ObjectIdColumn"
import { Column } from "../../../../src/decorator/columns/Column"
import { ObjectID } from "../../../../src/driver/mongodb/typings"
import { ObjectId } from "../../../../src/driver/mongodb/typings"
import { Event } from "./Event"
@Entity()
export class User {
@ObjectIdColumn()
id: ObjectID
id: ObjectId
@Column()
firstName: string

View File

@ -50,7 +50,7 @@ describe("github issue > #1416 Wrong behavior when fetching an entity that has a
where: {
name: photoAuthor.name,
},
relations: ["photos"],
relations: { photos: true },
})) as Author
expect(author).not.to.be.null
expect(author.photos[0]).not.to.be.undefined

View File

@ -26,11 +26,13 @@ describe("github issues > #1504 Cannot eagerly query Entity with relation more t
where: {
id: 1,
},
relations: [
"Entity2",
"Entity2.Entity3",
"Entity2.Entity3.Entity4",
],
relations: {
Entity2: {
Entity3: {
Entity4: true,
},
},
},
})
}),
))

View File

@ -28,11 +28,11 @@ describe("github issues > #1510 entity schema does not support mode=objectId", (
},
})
const UserWithoutObjectIDEntity = new EntitySchema<{
const UserWithoutObjectIdEntity = new EntitySchema<{
_id: number
name: string
}>({
name: "UserWithoutObjectID",
name: "UserWithoutObjectId",
tableName: "test_1510_users2",
columns: {
_id: {
@ -52,7 +52,7 @@ describe("github issues > #1510 entity schema does not support mode=objectId", (
entities: [
__dirname + "/entity/*{.js,.ts}",
UserEntity,
UserWithoutObjectIDEntity,
UserWithoutObjectIdEntity,
],
enabledDrivers: ["mongodb"],
}))
@ -63,7 +63,7 @@ describe("github issues > #1510 entity schema does not support mode=objectId", (
it("throws an error because there is no object id defined", () =>
Promise.all(
connections.map(async (connection) => {
const repo = connection.getRepository(UserWithoutObjectIDEntity)
const repo = connection.getRepository(UserWithoutObjectIdEntity)
try {
await repo.insert({

View File

@ -1,12 +1,12 @@
import { Entity } from "../../../../src/decorator/entity/Entity"
import { ObjectIdColumn } from "../../../../src/decorator/columns/ObjectIdColumn"
import { Column } from "../../../../src/decorator/columns/Column"
import { ObjectID } from "../../../../src/driver/mongodb/typings"
import { ObjectId } from "../../../../src/driver/mongodb/typings"
@Entity()
export class User {
@ObjectIdColumn()
id: ObjectID
id: ObjectId
@Column()
name: string

View File

@ -37,7 +37,7 @@ describe("github issues > #1720 Listener not invoked when relation loaded throug
await connection.manager.save(post1)
const [loadedPost] = await connection.manager.find(Post, {
relations: ["categories"],
relations: { categories: true },
})
loadedPost!.categories[0].loaded.should.be.equal(true)
loadedPost!.categories[1].loaded.should.be.equal(true)

View File

@ -41,7 +41,7 @@ describe("github issues > #1788 One to One does not load relationships.", () =>
await providerRepository.save(provider)
const dbProvider = await providerRepository.find({
relations: ["personalization"],
relations: { personalization: true },
})
expect(dbProvider[0].personalization).to.not.eql(undefined)

View File

@ -1,4 +1,4 @@
import { Column, Entity, ObjectID, ObjectIdColumn } from "../../../../src"
import { Column, Entity, ObjectId, ObjectIdColumn } from "../../../../src"
@Entity()
export class Product {
@ -9,7 +9,7 @@ export class Product {
}
@ObjectIdColumn()
id: ObjectID
id: ObjectId
@Column()
name: string

View File

@ -30,7 +30,7 @@ describe("github issues > #1929 Select attributes in Find method - mongodb", ()
product = new Product("test3", "label3", 30)
await productRepository.save(product)
await productRepository.find({
select: ["name", "label"],
select: { name: true, label: true },
order: { name: 1 },
})
}),
@ -47,7 +47,7 @@ describe("github issues > #1929 Select attributes in Find method - mongodb", ()
product = new Product("test3", "label3", 30)
await productRepository.save(product)
await productRepository.findAndCount({
select: ["name", "label"],
select: { name: true, label: true },
order: { name: 1 },
})
}),
@ -65,7 +65,7 @@ describe("github issues > #1929 Select attributes in Find method - mongodb", ()
const product3 = await productRepository.save(product)
await productRepository.find({
where: { _id: product3.id },
select: ["name", "label"],
select: { name: true, label: true },
order: { name: 1 },
})
}),
@ -82,7 +82,7 @@ describe("github issues > #1929 Select attributes in Find method - mongodb", ()
product = new Product("test3", "label3", 30)
await productRepository.findOne({
where: { name: "test2" },
select: ["name", "label"],
select: { name: true, label: true },
order: { name: 1 },
})
}),

View File

@ -37,7 +37,7 @@ describe("github issues > #2044 Should not double get embedded column value", ()
await connection.manager.save(photo)
const photos = await connection.manager.find(Photo, {
relations: ["user"],
relations: { user: true },
})
const resultPhoto = photos[0]

View File

@ -49,7 +49,7 @@ describe("github issues > #2632 createQueryBuilder relation remove works only if
let loadedPost1 = await connection.manager.findOne(Post, {
where: { id: 1 },
relations: ["categories"],
relations: { categories: true },
})
expect(loadedPost1!.categories).to.deep.include({
id: 1,
@ -64,7 +64,7 @@ describe("github issues > #2632 createQueryBuilder relation remove works only if
loadedPost1 = await connection.manager.findOne(Post, {
where: { id: 1 },
relations: ["categories"],
relations: { categories: true },
})
expect(loadedPost1!.categories).to.be.eql([])
@ -76,7 +76,7 @@ describe("github issues > #2632 createQueryBuilder relation remove works only if
let loadedPost2 = await connection.manager.findOne(Post, {
where: { id: 2 },
relations: ["categories"],
relations: { categories: true },
})
expect(loadedPost2!.categories).to.deep.include({
id: 2,
@ -91,7 +91,7 @@ describe("github issues > #2632 createQueryBuilder relation remove works only if
loadedPost1 = await connection.manager.findOne(Post, {
where: { id: 2 },
relations: ["categories"],
relations: { categories: true },
})
expect(loadedPost1!.categories).to.be.eql([])
}),

View File

@ -36,7 +36,9 @@ describe("github issues > #2965 Reuse preloaded lazy relations", () => {
await repoNote.insert({ label: "note1", owner: personA })
await repoNote.insert({ label: "note2", owner: personB })
const res1 = await repoPerson.find({ relations: ["notes"] })
const res1 = await repoPerson.find({
relations: { notes: true },
})
const originalLoad: (...args: any[]) => Promise<any[]> =
connection.relationLoader.load

View File

@ -79,11 +79,15 @@ describe("github issues > #3118 shorten alias names (for RDBMS with a limit) whe
const [loadedCategory] = await connection.manager.find(
CategoryWithVeryLongName,
{
relations: [
"postsWithVeryLongName",
relations: {
postsWithVeryLongName: {
authorWithVeryLongName: {
groupWithVeryLongName: true,
},
},
// before: used to generate a SELECT "AS" alias like `CategoryWithVeryLongName__postsWithVeryLongName__authorWithVeryLongName_firstName`
// now: `CaWiVeLoNa__poWiVeLoNa__auWiVeLoNa_firstName`, which is acceptable by Postgres (limit to 63 characters)
"postsWithVeryLongName.authorWithVeryLongName",
// "postsWithVeryLongName.authorWithVeryLongName",
// before:
// used to generate a JOIN "AS" alias like :
// `CategoryWithVeryLongName__postsWithVeryLongName__authorWithVeryLongName_firstName`
@ -95,8 +99,8 @@ describe("github issues > #3118 shorten alias names (for RDBMS with a limit) whe
// now:
// `CaWiVeLoNa__poWiVeLoNa__auWiVeLoNa_firstName`
// `CaWiVeLoNa__poWiVeLoNa__auWiVeLoNa__grWiVeLoNa_name`
"postsWithVeryLongName.authorWithVeryLongName.groupWithVeryLongName",
],
// "postsWithVeryLongName.authorWithVeryLongName.groupWithVeryLongName",
},
},
)
expect(loadedCategory).not.to.be.null
@ -119,11 +123,13 @@ describe("github issues > #3118 shorten alias names (for RDBMS with a limit) whe
const loadedCategories = await connection.manager.find(
CategoryWithVeryLongName,
{
relations: [
"postsWithVeryLongName",
"postsWithVeryLongName.authorWithVeryLongName",
"postsWithVeryLongName.authorWithVeryLongName.groupWithVeryLongName",
],
relations: {
postsWithVeryLongName: {
authorWithVeryLongName: {
groupWithVeryLongName: true,
},
},
},
},
)
expect(loadedCategories).to.be.an("array").that.is.not.empty

View File

@ -123,7 +123,11 @@ describe('github issues > #3120 Add relation option "createForeignKeyConstraints
ActionLog,
{
where: { action: "Test Log #1" },
relations: ["person", "actionDetails", "addresses"],
relations: {
person: true,
actionDetails: true,
addresses: true,
},
},
)

View File

@ -1,4 +1,4 @@
import { Entity, ObjectIdColumn, Column, ObjectID } from "../../../../src"
import { Entity, ObjectIdColumn, Column, ObjectId } from "../../../../src"
export class Page {
@Column()
@ -16,7 +16,7 @@ export class Chapter {
@Entity()
export class Book {
@ObjectIdColumn()
id: ObjectID
id: ObjectId
@Column()
title: string

View File

@ -39,7 +39,7 @@ describe("github issues > #4190 Relation decorators: allow to pass string instea
await connection.manager.save(user)
const users = await connection.manager.find(User, {
relations: ["profile"],
relations: { profile: true },
})
users.should.eql([
@ -73,10 +73,10 @@ describe("github issues > #4190 Relation decorators: allow to pass string instea
await connection.manager.save(user)
const users = await connection.manager.find(User, {
relations: ["photos"],
relations: { photos: true },
})
const photos = await connection.manager.find(Photo, {
relations: ["user"],
relations: { user: true },
})
// Check one-to-many
@ -130,7 +130,7 @@ describe("github issues > #4190 Relation decorators: allow to pass string instea
await connection.manager.save(question)
const questions = await connection.manager.find(Question, {
relations: ["categories"],
relations: { categories: true },
})
questions[0].categories.should.have.deep.members([

View File

@ -1,4 +1,4 @@
import { Entity, ObjectIdColumn, ObjectID, Column } from "../../../../src"
import { Entity, ObjectIdColumn, ObjectId, Column } from "../../../../src"
/**
* @deprecated use item config instead
@ -6,7 +6,7 @@ import { Entity, ObjectIdColumn, ObjectID, Column } from "../../../../src"
@Entity()
export class Config {
@ObjectIdColumn()
_id: ObjectID
_id: ObjectId
@Column()
itemId: string

View File

@ -1,9 +1,9 @@
import { Entity, ObjectIdColumn, ObjectID, Column } from "../../../../src"
import { Entity, ObjectIdColumn, ObjectId, Column } from "../../../../src"
@Entity()
export class Item {
@ObjectIdColumn()
public _id: ObjectID
public _id: ObjectId
/**
* @deprecated use contacts instead

View File

@ -75,31 +75,38 @@ describe("github issues > #5684 eager relation skips children relations", () =>
}
}
const relations = [
"company",
"company.admin", // <-- can't be loaded without the fix.
"company.staff", // <-- can't be loaded without the fix.
"company.staff.company", // <-- can't be loaded without the fix.
"company.staff.company.admin", // <-- can't be loaded without the fix.
]
const relations = {
company: {
admin: true,
staff: {
company: {
admin: true,
},
},
},
// "company.admin", // <-- can't be loaded without the fix.
// "company.staff", // <-- can't be loaded without the fix.
// "company.staff.company", // <-- can't be loaded without the fix.
// "company.staff.company.admin", // <-- can't be loaded without the fix.
}
const user1 = await connection.getRepository(User).findOne({
where: { id: userAdmin.id },
relations: [...relations],
relations: relations,
})
assert(user1)
const user2 = await connection
.getRepository(User)
.findOneOrFail({
where: { id: userAdmin.id },
relations: [...relations],
relations: relations,
})
assert(user2)
const users3 = await connection.getRepository(User).find({
where: {
id: userAdmin.id,
},
relations: [...relations],
relations: relations,
})
assert(users3.pop())
const [users4] = await connection
@ -108,14 +115,14 @@ describe("github issues > #5684 eager relation skips children relations", () =>
where: {
id: userAdmin.id,
},
relations: [...relations],
relations: relations,
})
assert(users4.pop())
const users5 = await connection.getRepository(User).find({
where: {
id: In([userAdmin.id]),
},
relations: [...relations],
relations: relations,
})
assert(users5.pop())
}),

View File

@ -103,27 +103,29 @@ describe("github issues > #5691 RelationId is too slow", () => {
// const test1Start = new Date().getTime();
// 54 rows for 1 root
await connection.getRepository(Root).find({
relations: [
"allChild1",
"allChild1.allShared",
"allChild2",
],
relations: {
allChild1: {
allShared: true,
},
allChild2: true,
},
})
// 21 rows 1 root
await connection.getRepository(Root).find({
relations: ["allShared"],
relations: { allShared: true },
})
// const test1End = new Date().getTime();
// const test2Start = new Date().getTime();
// 1134 rows 1 root
await connection.getRepository(Root).find({
relations: [
"allChild1",
"allChild1.allShared",
"allChild2",
"allShared",
],
relations: {
allChild1: {
allShared: true,
},
allChild2: true,
allShared: true,
},
})
// const test2End = new Date().getTime();

View File

@ -1,11 +1,11 @@
import { ObjectID, ObjectIdColumn } from "../../../../src"
import { ObjectId, ObjectIdColumn } from "../../../../src"
import { Column } from "../../../../src/decorator/columns/Column"
import { Entity } from "../../../../src/decorator/entity/Entity"
@Entity()
export class Post {
@ObjectIdColumn()
_id: ObjectID
_id: ObjectId
@Column()
title: string

View File

@ -1,11 +1,11 @@
import { ObjectID, ObjectIdColumn } from "../../../../src"
import { ObjectId, ObjectIdColumn } from "../../../../src"
import { Column } from "../../../../src/decorator/columns/Column"
import { Entity } from "../../../../src/decorator/entity/Entity"
@Entity()
export class PostV2 {
@ObjectIdColumn()
postId: ObjectID
postId: ObjectId
@Column()
title: string

View File

@ -35,9 +35,9 @@ describe("github issues > #6552 MongoRepository delete by ObjectId deletes the w
post2.title = "Post 2"
await connection.manager.save(post2)
const objectIdInstance = PlatformTools.load("mongodb").ObjectID
const objectIdInstance = PlatformTools.load("mongodb").ObjectId
// double check that post2._id is actually an ObjectID
// double check that post2._id is actually an ObjectId
expect(post2._id).to.be.not.null
expect(post2._id).to.be.not.undefined
expect(post2._id).to.be.instanceof(objectIdInstance)
@ -75,9 +75,9 @@ describe("github issues > #6552 MongoRepository delete by ObjectId deletes the w
post2.title = "Post 2"
await postV2Repository.save(post2)
const objectIdInstance = PlatformTools.load("mongodb").ObjectID
const objectIdInstance = PlatformTools.load("mongodb").ObjectId
// double check that post2.postId is actually an ObjectID
// double check that post2.postId is actually an ObjectId
expect(post2.postId).to.be.not.null
expect(post2.postId).to.be.not.undefined
expect(post2.postId).to.be.instanceof(objectIdInstance)
@ -113,9 +113,9 @@ describe("github issues > #6552 MongoRepository delete by ObjectId deletes the w
post2.title = "Post 2"
await connection.manager.save(post2)
const objectIdInstance = PlatformTools.load("mongodb").ObjectID
const objectIdInstance = PlatformTools.load("mongodb").ObjectId
// double check that post2._id is actually an ObjectID
// double check that post2._id is actually an ObjectId
expect(post2._id).to.be.not.null
expect(post2._id).to.be.not.undefined
expect(post2._id).to.be.instanceof(objectIdInstance)

View File

@ -1,9 +1,9 @@
import { Entity, ObjectID, ObjectIdColumn, Column } from "../../../../src"
import { Entity, ObjectId, ObjectIdColumn, Column } from "../../../../src"
@Entity("warnings")
export class Warn {
@ObjectIdColumn()
id!: ObjectID
id!: ObjectId
@Column()
guild!: string

View File

@ -39,7 +39,7 @@ describe("github issues > #703.findOne does not return an empty array on OneToMa
where: {
id: 1,
},
relations: ["categories"],
relations: { categories: true },
})
loadedPost!.id.should.be.equal(1)

View File

@ -32,7 +32,7 @@ describe("github issues > #7041 When requesting nested relations on foreign key
where: {
id: testUser.id,
},
relations: ["admin", "admin.organization"],
relations: { admin: { organization: true } },
})
expect(foundUser?.randomField).eq("foo")
expect(foundUser?.admin).eq(null)
@ -50,7 +50,7 @@ describe("github issues > #7041 When requesting nested relations on foreign key
where: {
id: testUser.id,
},
relations: ["membership", "membership.organization"],
relations: { membership: { organization: true } },
})
expect(foundUser?.randomField).eq("foo")
expect(foundUser?.membership).eql([])

View File

@ -50,7 +50,7 @@ describe("github issues > #7065 ChildEntity type relationship produces unexpecte
where: {
id: 1,
},
relations: ["emails", "phones"],
relations: { emails: true, phones: true },
})
expect(result!.emails.length).eq(1)

View File

@ -1,14 +1,14 @@
import {
DeleteDateColumn,
Entity,
ObjectID,
ObjectId,
ObjectIdColumn,
} from "../../../../src"
@Entity()
export class Configuration {
@ObjectIdColumn()
_id: ObjectID
_id: ObjectId
@DeleteDateColumn()
deletedAt?: Date

View File

@ -39,9 +39,9 @@ describe("github issues > #7852 saving a ManyToMany relation tries to insert (DE
await userRepository.save(userEntity)
// Save on object
const objectId = 1
const ObjectId = 1
const objectEntity = new UsersObject()
objectEntity.id = objectId
objectEntity.id = ObjectId
await usersObjectRepository.save(objectEntity)
// Updating using save method
@ -59,7 +59,7 @@ describe("github issues > #7852 saving a ManyToMany relation tries to insert (DE
expect(savedUser.objects.length).to.be.eql(1)
expect(savedUser.objects[0]).to.be.instanceOf(UsersObject)
expect(savedUser.objects[0].id).to.be.eql(objectId)
expect(savedUser.objects[0].id).to.be.eql(ObjectId)
}),
))
})

View File

@ -25,13 +25,13 @@ describe("github issues > #7882 .findOne reduces relations to an empty array",
it("should delete all documents related to search pattern", () =>
Promise.all(
connections.map(async (connection) => {
const relations = ["exampleText"]
const relations = { exampleText: true }
const repo = connection.getRepository(Example)
await repo.find({ relations })
expect(relations).to.be.eql(["exampleText"])
expect(relations).to.be.eql({ exampleText: true })
}),
))
})

View File

@ -0,0 +1,16 @@
import { Entity } from "../../../../src/decorator/entity/Entity"
import { Column } from "../../../../src/decorator/columns/Column"
import { ObjectIdColumn } from "../../../../src/decorator/columns/ObjectIdColumn"
import { ObjectId } from "../../../../src"
@Entity()
export class Post {
@ObjectIdColumn()
id: ObjectId
@Column()
title: string
@Column()
text: string
}

View File

@ -0,0 +1,44 @@
import "reflect-metadata"
import { expect } from "chai"
import { DataSource } from "../../../src"
import {
closeTestingConnections,
createTestingConnections,
reloadTestingDatabases,
} from "../../utils/test-utils"
import { Post } from "./entity/Post"
describe("github issues > #7907 add support for mongodb driver v5", () => {
let connections: DataSource[]
before(
async () =>
(connections = await createTestingConnections({
entities: [Post],
enabledDrivers: ["mongodb"],
})),
)
beforeEach(() => reloadTestingDatabases(connections))
after(() => closeTestingConnections(connections))
it("should find the Post without throw error: Cannot read property 'prototype' of undefined", () =>
Promise.all(
connections.map(async (connection) => {
const postMongoRepository = connection.getMongoRepository(Post)
// save a post
const post = new Post()
post.title = "Post"
post.text = "This is a simple post"
await postMongoRepository.save(post)
const findPosts = async () => {
return postMongoRepository.find()
}
const posts = await findPosts()
expect(findPosts).to.not.throw()
expect(posts).to.have.lengthOf(1)
expect(posts[0]).to.be.instanceOf(Post)
}),
))
})

View File

@ -40,7 +40,7 @@ describe("github issues > #8018 Non-unique relation property names causes entity
await connection.manager.save([parent, child1, child2])
const result = await connection.manager.find(Parent, {
relations: ["children"],
relations: { children: true },
})
expect(result).to.have.lengthOf(1)

View File

@ -35,7 +35,11 @@ describe("persistence > delete orphans", () => {
let postRepository: Repository<Post>
let categoryId: number
beforeEach(async () => {
beforeEach(async function () {
if (connections.length === 0) {
this.skip()
}
await Promise.all(
connections.map(async (connection) => {
categoryRepository = connection.getRepository(Category)

View File

@ -1,11 +1,11 @@
import { ObjectID } from "../../../../src/driver/mongodb/typings"
import { ObjectId } from "../../../../src/driver/mongodb/typings"
import { Comment } from "./comment"
import { Column, Entity, ObjectIdColumn } from "../../../../src"
@Entity()
export class Post {
@ObjectIdColumn()
_id?: ObjectID
_id?: ObjectId
@Column(() => Comment)
comments: Comment[]

View File

@ -1,8 +1,8 @@
import { Column, ObjectID, ObjectIdColumn } from "../../../../src"
import { Column, ObjectId, ObjectIdColumn } from "../../../../src"
export class Value {
@ObjectIdColumn()
_id?: ObjectID
_id?: ObjectId
@Column({ type: "string" })
description: string

View File

@ -1,9 +1,9 @@
import { Column, Entity, ObjectID, ObjectIdColumn } from "../../../../src"
import { Column, Entity, ObjectId, ObjectIdColumn } from "../../../../src"
@Entity()
export class Post {
@ObjectIdColumn()
id: ObjectID
id: ObjectId
@Column()
title: string

View File

@ -1,12 +1,12 @@
import { Entity } from "../../../../src/decorator/entity/Entity"
import { ObjectIdColumn } from "../../../../src/decorator/columns/ObjectIdColumn"
import { ObjectID } from "../../../../src/driver/mongodb/typings"
import { ObjectId } from "../../../../src/driver/mongodb/typings"
import { Column } from "../../../../src/decorator/columns/Column"
@Entity()
export class Post {
@ObjectIdColumn()
id: ObjectID
id: ObjectId
@Column()
title: string

View File

@ -1,12 +1,12 @@
import { Entity } from "../../../../src/decorator/entity/Entity"
import { Column } from "../../../../src/decorator/columns/Column"
import { UpdateDateColumn } from "../../../../src/decorator/columns/UpdateDateColumn"
import { ObjectID, ObjectIdColumn } from "../../../../src"
import { ObjectId, ObjectIdColumn } from "../../../../src"
@Entity()
export class Post {
@ObjectIdColumn()
id: ObjectID
id: ObjectId
@Column()
title: string

View File

@ -30,13 +30,13 @@ describe("other issues > preventing-injection", () => {
const postWithOnlyIdSelected = await connection.manager.find(
Post,
{
select: ["id"],
select: { id: true },
},
)
postWithOnlyIdSelected.should.be.eql([{ id: 1 }])
await connection.manager.find(Post, {
select: ["(WHERE LIMIT 1)" as any],
select: "(WHERE LIMIT 1)" as any,
}).should.be.rejected
}),
))

View File

@ -39,7 +39,7 @@ describe("other issues > Relation decorators: allow to pass given table name str
await connection.manager.save(user)
const users = await connection.manager.find(User, {
relations: ["profile"],
relations: { profile: true },
})
users.should.eql([
@ -73,10 +73,14 @@ describe("other issues > Relation decorators: allow to pass given table name str
await connection.manager.save(user)
const users = await connection.manager.find(User, {
relations: ["photos"],
relations: {
photos: true,
},
})
const photos = await connection.manager.find(Photo, {
relations: ["user"],
relations: {
user: true,
},
})
// Check one-to-many
@ -130,7 +134,7 @@ describe("other issues > Relation decorators: allow to pass given table name str
await connection.manager.save(question)
const questions = await connection.manager.find(Question, {
relations: ["categories"],
relations: { categories: true },
})
questions[0].categories.should.have.deep.members([

View File

@ -482,7 +482,7 @@ export function closeTestingConnections(connections: DataSource[]) {
return Promise.all(
connections.map((connection) =>
connection && connection.isInitialized
? connection.close()
? connection.destroy()
: undefined,
),
)