Repository: typeorm/typeorm
File: src/entity-manager/EntityManager.ts (TypeScript)

Code before:
    }

    /**
     * Return the MAX of a column
     */
    maximum<Entity extends ObjectLiteral>(
        entityClass: EntityTarget<Entity>,
        field: PickKeysByType<Entity, number>,
        where?: FindOptionsWhere<Entity> | FindOptionsWhere<Entity>[],
    ): Promise<number | null> {
        return this.callAggregateFun(entityClass, "MAX", field, where)
    }

    private async callAggregateFun<Entity extends ObjectLiteral>(
        entityClass: EntityTarget<Entity>,
        fnName: "SUM" | "AVG" | "MIN" | "MAX",
        field: PickKeysByType<Entity, number>,
        where: FindOptionsWhere<Entity> | FindOptionsWhere<Entity>[] = {},
    ): Promise<number | null> {
        const metadata = this.connection.getMetadata(entityClass)
        const { [fnName]: result } = await this.createQueryBuilder(
            entityClass,
            metadata.name,
        )
            .setFindOptions({ where })
            .select(`${fnName}(${field.toString()})`, fnName)
            .getRawOne()
        return result === null ? null : parseFloat(result)
    }

    /**
     * Finds entities that match given find options.
     */
    async find<Entity extends ObjectLiteral>(
        entityClass: EntityTarget<Entity>,
        options?: FindManyOptions<Entity>,
    ): Promise<Entity[]> {
        const metadata = this.connection.getMetadata(entityClass)
        return this.createQueryBuilder<Entity>(
            entityClass as any,
            FindOptionsUtils.extractFindManyOptionsAlias(options) ||
                metadata.name,
        )
            .setFindOptions(options || {})
            .getMany()
    }

    /**
     * Finds entities that match given find options.
     */
    async findBy<Entity extends ObjectLiteral>(

Review comment (bug):
`field.toString()` must be properly escaped. Oracle test currently failing with `QueryFailedError: ORA-00904: "COUNTER": invalid identifier`.

Code after:
    }

    /**
     * Return the MAX of a column
     */
    maximum<Entity extends ObjectLiteral>(
        entityClass: EntityTarget<Entity>,
        columnName: PickKeysByType<Entity, number>,
        where?: FindOptionsWhere<Entity> | FindOptionsWhere<Entity>[],
    ): Promise<number | null> {
        return this.callAggregateFun(entityClass, "MAX", columnName, where)
    }

    private async callAggregateFun<Entity extends ObjectLiteral>(
        entityClass: EntityTarget<Entity>,
        fnName: "SUM" | "AVG" | "MIN" | "MAX",
        columnName: PickKeysByType<Entity, number>,
        where: FindOptionsWhere<Entity> | FindOptionsWhere<Entity>[] = {},
    ): Promise<number | null> {
        const metadata = this.connection.getMetadata(entityClass)
        const result = await this.createQueryBuilder(entityClass, metadata.name)
            .setFindOptions({ where })
            .select(
                `${fnName}(${this.connection.driver.escape(
                    String(columnName),
                )})`,
                fnName,
            )
            .getRawOne()
        return result[fnName] === null ? null : parseFloat(result[fnName])
    }

    /**
     * Finds entities that match given find options.
     */
    async find<Entity extends ObjectLiteral>(
        entityClass: EntityTarget<Entity>,
        options?: FindManyOptions<Entity>,
    ): Promise<Entity[]> {
        const metadata = this.connection.getMetadata(entityClass)
        return this.createQueryBuilder<Entity>(
            entityClass as any,
            FindOptionsUtils.extractFindManyOptionsAlias(options) ||
                metadata.name,
        )
            .setFindOptions(options || {})
            .getMany()
    }

    /**
     * Finds entities that match given find options.