mirror of
https://github.com/typeorm/typeorm.git
synced 2025-12-08 21:26:23 +00:00
feat: implement OR operator (#10086)
* feat: implement or operator This new feature enables typeorm to allow use multiple operators joining with or Closes: #10054 * feat: implement or operator Completed code formating using command. Closes: #10054 * feat: implement or operator Completed the documentation update. Closes: #10054 * feat: implement or operator Renamed Or operator file name. Closes: #10054 * feat: implement or operator Renamed Or operator file name. Closes: #10054 * feat: implement or operator Renamed Or operator file name. Closes: #10054 * feat: implement or operator Renamed Or operator. Closes: #10054
This commit is contained in:
parent
dd595242a7
commit
a00b1df68f
@ -606,7 +606,9 @@ SELECT * FROM "post" WHERE "titles" IN ('Go To Statement Considered Harmful', 'S
|
||||
|
||||
## Combining Advanced Options
|
||||
|
||||
Also you can combine these operators with `Not` operator:
|
||||
Also you can combine these operators with below:
|
||||
|
||||
- `Not`
|
||||
|
||||
```ts
|
||||
import { Not, MoreThan, Equal } from "typeorm"
|
||||
@ -622,3 +624,19 @@ will execute following query:
|
||||
```sql
|
||||
SELECT * FROM "post" WHERE NOT("likes" > 10) AND NOT("title" = 'About #2')
|
||||
```
|
||||
|
||||
- `Or`
|
||||
|
||||
```ts
|
||||
import { Not, MoreThan, ILike } from "typeorm"
|
||||
|
||||
const loadedPosts = await dataSource.getRepository(Post).findBy({
|
||||
title: Or(Equal("About #2"), ILike("About%")),
|
||||
})
|
||||
```
|
||||
|
||||
will execute following query:
|
||||
|
||||
```sql
|
||||
SELECT * FROM "post" WHERE "title" = 'About #2' OR "title" ILIKE 'About%'
|
||||
```
|
||||
@ -20,3 +20,4 @@ export type FindOperatorType =
|
||||
| "arrayOverlap"
|
||||
| "and"
|
||||
| "jsonContains"
|
||||
| "or"
|
||||
|
||||
5
src/find-options/operator/Or.ts
Normal file
5
src/find-options/operator/Or.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import { FindOperator } from "../FindOperator"
|
||||
|
||||
export function Or<T>(...values: FindOperator<T>[]): FindOperator<T> {
|
||||
return new FindOperator("or", values as any, true, true)
|
||||
}
|
||||
@ -67,6 +67,7 @@ export * from "./decorator/Exclusion"
|
||||
export * from "./decorator/Generated"
|
||||
export * from "./decorator/EntityRepository"
|
||||
export * from "./find-options/operator/And"
|
||||
export * from "./find-options/operator/Or"
|
||||
export * from "./find-options/operator/Any"
|
||||
export * from "./find-options/operator/ArrayContainedBy"
|
||||
export * from "./find-options/operator/ArrayContains"
|
||||
|
||||
@ -1127,6 +1127,8 @@ export abstract class QueryBuilder<Entity extends ObjectLiteral> {
|
||||
)}`
|
||||
case "and":
|
||||
return condition.parameters.join(" AND ")
|
||||
case "or":
|
||||
return condition.parameters.join(" OR ")
|
||||
}
|
||||
|
||||
throw new TypeError(
|
||||
@ -1542,6 +1544,20 @@ export abstract class QueryBuilder<Entity extends ObjectLiteral> {
|
||||
} else if (parameterValue.type === "and") {
|
||||
const values: FindOperator<any>[] = parameterValue.value
|
||||
|
||||
return {
|
||||
operator: parameterValue.type,
|
||||
parameters: values.map((operator) =>
|
||||
this.createWhereConditionExpression(
|
||||
this.getWherePredicateCondition(
|
||||
aliasPath,
|
||||
operator,
|
||||
),
|
||||
),
|
||||
),
|
||||
}
|
||||
} else if (parameterValue.type === "or") {
|
||||
const values: FindOperator<any>[] = parameterValue.value
|
||||
|
||||
return {
|
||||
operator: parameterValue.type,
|
||||
parameters: values.map((operator) =>
|
||||
|
||||
@ -18,6 +18,7 @@ type PredicateOperator =
|
||||
| "arrayOverlap"
|
||||
| "and"
|
||||
| "jsonContains"
|
||||
| "or"
|
||||
|
||||
export interface WherePredicateOperator {
|
||||
operator: PredicateOperator
|
||||
|
||||
13
test/github-issues/10054/entity/Person.ts
Normal file
13
test/github-issues/10054/entity/Person.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import { Entity, Column, PrimaryGeneratedColumn } from "../../../../src"
|
||||
|
||||
@Entity({ name: "person" })
|
||||
export class Person {
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number
|
||||
|
||||
@Column()
|
||||
name: string
|
||||
|
||||
@Column({ type: "int", nullable: true })
|
||||
age: number | null
|
||||
}
|
||||
65
test/github-issues/10054/issue-10054.ts
Normal file
65
test/github-issues/10054/issue-10054.ts
Normal file
@ -0,0 +1,65 @@
|
||||
import { Or, DataSource, ILike, Equal } from "../../../src"
|
||||
import {
|
||||
closeTestingConnections,
|
||||
createTestingConnections,
|
||||
reloadTestingDatabases,
|
||||
} from "../../utils/test-utils"
|
||||
import { Person } from "./entity/Person"
|
||||
import { expect } from "chai"
|
||||
|
||||
describe("github issues > #10054 Nested 'Or' Condition/Operation Support in Repository Where condition", () => {
|
||||
let dataSources: DataSource[]
|
||||
|
||||
before(async () => {
|
||||
dataSources = await createTestingConnections({
|
||||
entities: [Person],
|
||||
enabledDrivers: ["postgres", "mysql"],
|
||||
schemaCreate: true,
|
||||
dropSchema: true,
|
||||
})
|
||||
})
|
||||
|
||||
beforeEach(() => reloadTestingDatabases(dataSources))
|
||||
after(() => closeTestingConnections(dataSources))
|
||||
|
||||
it("should find person where name starts with foo or equal to jane", async () => {
|
||||
await Promise.all(
|
||||
dataSources.map(async (dataSource) => {
|
||||
debugger
|
||||
const foo = new Person()
|
||||
foo.name = "Foo"
|
||||
foo.age = null
|
||||
|
||||
const john = new Person()
|
||||
john.name = "John"
|
||||
john.age = 11
|
||||
|
||||
const dave = new Person()
|
||||
dave.name = "Jane"
|
||||
dave.age = 12
|
||||
|
||||
const foobar = new Person()
|
||||
foobar.name = "FooBar"
|
||||
foobar.age = 14
|
||||
|
||||
await dataSource.manager.save([foo, john, dave, foobar])
|
||||
const persons = await dataSource.manager.find(Person, {
|
||||
where: {
|
||||
name: Or(ILike("foo%"), Equal("Jane")),
|
||||
},
|
||||
})
|
||||
|
||||
expect(persons).to.have.length(3)
|
||||
|
||||
expect(persons.find((user) => user.name === "Foo")).to.be.not
|
||||
.undefined
|
||||
|
||||
expect(persons.find((user) => user.name === "Jane")).to.be.not
|
||||
.undefined
|
||||
|
||||
expect(persons.find((user) => user.name === "FooBar")).to.be.not
|
||||
.undefined
|
||||
}),
|
||||
)
|
||||
})
|
||||
})
|
||||
Loading…
x
Reference in New Issue
Block a user