Skip to content
This repository was archived by the owner on Aug 22, 2023. It is now read-only.

Commit 15e7da6

Browse files
committed
PHPORM-49 Implement whereNot by encapsulating into $not
1 parent bd86f85 commit 15e7da6

File tree

2 files changed

+179
-0
lines changed

2 files changed

+179
-0
lines changed

src/Query/Builder.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1002,6 +1002,15 @@ protected function compileWheres(): array
10021002
});
10031003
}
10041004

1005+
$not = false;
1006+
if ($where['boolean'] === 'and not') {
1007+
$where['boolean'] = 'and';
1008+
$not = true;
1009+
} elseif ($where['boolean'] === 'or not') {
1010+
$where['boolean'] = 'or';
1011+
$not = true;
1012+
}
1013+
10051014
// The next item in a "chain" of wheres devices the boolean of the
10061015
// first item. So if we see that there are multiple wheres, we will
10071016
// use the operator of the next where.
@@ -1013,6 +1022,10 @@ protected function compileWheres(): array
10131022
$method = "compileWhere{$where['type']}";
10141023
$result = $this->{$method}($where);
10151024

1025+
if ($not) {
1026+
$result = ['$not' => $result];
1027+
}
1028+
10161029
// Wrap the where with an $or operator.
10171030
if ($where['boolean'] == 'or') {
10181031
$result = ['$or' => [$result]];

tests/Query/BuilderTest.php

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,17 @@ public static function provideQueryBuilderToMql(): iterable
4949
fn (Builder $builder) => $builder->where('foo', 'bar'),
5050
];
5151

52+
yield 'where with single array of conditions' => [
53+
['find' => [
54+
['$and' => [
55+
['foo' => 1],
56+
['bar' => 2],
57+
]],
58+
[], // options
59+
]],
60+
fn (Builder $builder) => $builder->where(['foo' => 1, 'bar' => 2]),
61+
];
62+
5263
yield 'find > date' => [
5364
['find' => [['foo' => ['$gt' => new UTCDateTime($date)]], []]],
5465
fn (Builder $builder) => $builder->where('foo', '>', $date),
@@ -64,6 +75,161 @@ public static function provideQueryBuilderToMql(): iterable
6475
fn (Builder $builder) => $builder->limit(10)->offset(5)->select('foo', 'bar'),
6576
];
6677

78+
/** @see DatabaseQueryBuilderTest::testBasicWhereNot() */
79+
yield 'whereNot' => [
80+
['find' => [
81+
['$and' => [
82+
['$not' => ['name' => 'foo']],
83+
['$not' => ['name' => ['$ne' => 'bar']]],
84+
]],
85+
[], // options
86+
]],
87+
fn (Builder $builder) => $builder
88+
->whereNot('name', 'foo')
89+
->whereNot('name', '<>', 'bar'),
90+
];
91+
92+
/** @see DatabaseQueryBuilderTest::testBasicOrWheres() */
93+
yield 'where orWhere' => [
94+
['find' => [
95+
['$or' => [
96+
['id' => 1],
97+
['email' => 'foo'],
98+
]],
99+
[], // options
100+
]],
101+
fn (Builder $builder) => $builder
102+
->where('id', '=', 1)
103+
->orWhere('email', '=', 'foo'),
104+
];
105+
106+
/** @see DatabaseQueryBuilderTest::testBasicOrWhereNot() */
107+
yield 'orWhereNot' => [
108+
['find' => [
109+
['$or' => [
110+
['$not' => ['name' => 'foo']],
111+
['$not' => ['name' => ['$ne' => 'bar']]],
112+
]],
113+
[], // options
114+
]],
115+
fn (Builder $builder) => $builder
116+
->orWhereNot('name', 'foo')
117+
->orWhereNot('name', '<>', 'bar'),
118+
];
119+
120+
/** @see DatabaseQueryBuilderTest::testWhereNot() */
121+
yield 'whereNot callable' => [
122+
['find' => [
123+
['$not' => ['name' => 'foo']],
124+
[], // options
125+
]],
126+
fn (Builder $builder) => $builder
127+
->whereNot(fn (Builder $q) => $q->where('name', 'foo')),
128+
];
129+
130+
yield 'where and whereNot' => [
131+
['find' => [
132+
['$and' => [
133+
['name' => 'bar'],
134+
['$not' => ['email' => 'foo']],
135+
]],
136+
[], // options
137+
]],
138+
fn (Builder $builder) => $builder
139+
->where('name', '=', 'bar')
140+
->whereNot(function (Builder $q) {
141+
$q->where('email', '=', 'foo');
142+
}),
143+
];
144+
145+
yield 'nested whereNot' => [
146+
['find' => [
147+
['$not' => [
148+
'$and' => [
149+
['name' => 'foo'],
150+
['$not' => ['email' => ['$ne' => 'bar']]],
151+
],
152+
]],
153+
[], // options
154+
]],
155+
fn (Builder $builder) => $builder
156+
->whereNot(function (Builder $q) {
157+
$q->where('name', '=', 'foo')
158+
->whereNot('email', '<>', 'bar');
159+
}),
160+
];
161+
162+
yield 'orWhere orWhereNot' => [
163+
['find' => [
164+
['$or' => [
165+
['name' => 'bar'],
166+
['$not' => ['email' => 'foo']],
167+
]],
168+
[], // options
169+
]],
170+
fn (Builder $builder) => $builder
171+
->orWhere('name', '=', 'bar')
172+
->orWhereNot(function (Builder $q) {
173+
$q->where('email', '=', 'foo');
174+
}),
175+
];
176+
177+
yield 'where or whereNot' => [
178+
['find' => [
179+
[
180+
'$and' => [['name' => 'bar']],
181+
'$or' => [['$not' => ['email' => 'foo']]],
182+
],
183+
[], // options
184+
]],
185+
fn (Builder $builder) => $builder
186+
->where('name', '=', 'bar')
187+
->orWhereNot('email', '=', 'foo'),
188+
];
189+
190+
/** @see DatabaseQueryBuilderTest::testWhereNotWithArrayConditions() */
191+
yield 'whereNot with arrays of single condition' => [
192+
['find' => [
193+
['$not' => [
194+
'$and' => [
195+
['foo' => 1],
196+
['bar' => 2],
197+
],
198+
]],
199+
[], // options
200+
]],
201+
fn (Builder $builder) => $builder
202+
->whereNot([['foo', 1], ['bar', 2]]),
203+
];
204+
205+
yield 'whereNot with single array of conditions' => [
206+
['find' => [
207+
['$not' => [
208+
'$and' => [
209+
['foo' => 1],
210+
['bar' => 2],
211+
],
212+
]],
213+
[], // options
214+
]],
215+
fn (Builder $builder) => $builder
216+
->whereNot(['foo' => 1, 'bar' => 2]),
217+
];
218+
219+
yield 'whereNot with arrays of single condition with operator' => [
220+
['find' => [
221+
['$not' => [
222+
'$and' => [
223+
['foo' => 1],
224+
['bar' => ['$lt' => 2]],
225+
],
226+
]],
227+
[], // options
228+
]],
229+
fn (Builder $builder) => $builder
230+
->whereNot([['foo', 1], ['bar', '<', 2]]),
231+
];
232+
67233
/** @see DatabaseQueryBuilderTest::testOrderBys() */
68234
yield 'orderBy multiple columns' => [
69235
['find' => [[], ['sort' => ['email' => 1, 'age' => -1]]]],

0 commit comments

Comments
 (0)