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

Commit f2c65c0

Browse files
committed
PHPORM-49 Implement whereNot by encapsulating into $not
1 parent 78319d4 commit f2c65c0

File tree

2 files changed

+165
-0
lines changed

2 files changed

+165
-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: 152 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,147 @@ 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::testBasicOrWhereNot() */
93+
yield 'orWhereNot' => [
94+
['find' => [
95+
['$or' => [
96+
['$not' => ['name' => 'foo']],
97+
['$not' => ['name' => ['$ne' => 'bar']]],
98+
]],
99+
[], // options
100+
]],
101+
fn (Builder $builder) => $builder
102+
->orWhereNot('name', 'foo')
103+
->orWhereNot('name', '<>', 'bar')
104+
];
105+
106+
/** @see DatabaseQueryBuilderTest::testWhereNot() */
107+
yield 'whereNot callable' => [
108+
['find' => [
109+
['$not' => ['name' => 'foo']],
110+
[], // options
111+
]],
112+
fn (Builder $builder) => $builder
113+
->whereNot(fn (Builder $q) => $q->where('name', 'foo'))
114+
];
115+
116+
yield 'where and whereNot' => [
117+
['find' => [
118+
['$and' => [
119+
['name' => 'bar'],
120+
['$not' => ['email' => 'foo']],
121+
]],
122+
[], // options
123+
]],
124+
fn (Builder $builder) => $builder
125+
->where('name', '=', 'bar')
126+
->whereNot(function (Builder $q) {
127+
$q->where('email', '=', 'foo');
128+
})
129+
];
130+
131+
yield 'nested whereNot' => [
132+
['find' => [
133+
['$not' => [
134+
'$and' => [
135+
['name' => 'foo'],
136+
['$not' => ['email' => ['$ne' => 'bar']]],
137+
],
138+
]],
139+
[], // options
140+
]],
141+
fn (Builder $builder) => $builder
142+
->whereNot(function (Builder $q) {
143+
$q->where('name', '=', 'foo')
144+
->whereNot('email', '<>', 'bar');
145+
})
146+
];
147+
148+
yield 'orWhere orWhereNot' => [
149+
['find' => [
150+
['$or' => [
151+
['name' => 'bar'],
152+
['$not' => ['email' => 'foo']],
153+
]],
154+
[], // options
155+
]],
156+
fn (Builder $builder) => $builder
157+
->orWhere('name', '=', 'bar')
158+
->orWhereNot(function (Builder $q) {
159+
$q->where('email', '=', 'foo');
160+
})
161+
];
162+
163+
yield 'where or whereNot' => [
164+
['find' => [
165+
[
166+
'$and' => [['name' => 'bar']],
167+
'$or' => [['$not' => ['email' => 'foo']]]
168+
],
169+
[], // options
170+
]],
171+
fn (Builder $builder) => $builder
172+
->where('name', '=', 'bar')
173+
->orWhereNot('email', '=', 'foo')
174+
];
175+
176+
/** @see DatabaseQueryBuilderTest::testWhereNotWithArrayConditions() */
177+
yield 'whereNot with arrays of single condition' => [
178+
['find' => [
179+
['$not' => [
180+
'$and' => [
181+
['foo' => 1],
182+
['bar' => 2],
183+
],
184+
]],
185+
[], // options
186+
]],
187+
fn (Builder $builder) => $builder
188+
->whereNot([['foo', 1], ['bar', 2]])
189+
];
190+
191+
yield 'whereNot with single array of conditions' => [
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 arrays of single condition with operator' => [
206+
['find' => [
207+
['$not' => [
208+
'$and' => [
209+
['foo' => 1],
210+
['bar' => ['$lt' => 2]],
211+
],
212+
]],
213+
[], // options
214+
]],
215+
fn (Builder $builder) => $builder
216+
->whereNot([['foo', 1], ['bar', '<', 2]])
217+
];
218+
67219
/** @see DatabaseQueryBuilderTest::testOrderBys() */
68220
yield 'orderBy multiple columns' => [
69221
['find' => [[], ['sort' => ['email' => 1, 'age' => -1]]]],

0 commit comments

Comments
 (0)