Skip to content

Commit fbed3dc

Browse files
Merge 4.8 into 5.0 (#3115)
2 parents bd9ef30 + 59e16b9 commit fbed3dc

File tree

3 files changed

+180
-112
lines changed

3 files changed

+180
-112
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file.
88
## [4.8.0] - next
99

1010
* Add `Query\Builder::incrementEach()` and `decrementEach()` methods by @SmallRuralDog in [#2550](https://github.com/mongodb/laravel-mongodb/pull/2550)
11+
* Add `Query\Builder::whereLike()` and `whereNotLike()` methods by @GromNaN in [#3108](https://github.com/mongodb/laravel-mongodb/pull/3108)
1112
* Deprecate `Connection::collection()` and `Schema\Builder::collection()` methods by @GromNaN in [#3062](https://github.com/mongodb/laravel-mongodb/pull/3062)
1213
* Deprecate `Model::$collection` property to customize collection name. Use `$table` instead by @GromNaN in [#3064](https://github.com/mongodb/laravel-mongodb/pull/3064)
1314

src/Query/Builder.php

+9-1
Original file line numberDiff line numberDiff line change
@@ -1255,7 +1255,8 @@ protected function compileWhereBasic(array $where): array
12551255
// All backslashes are converted to \\, which are needed in matching regexes.
12561256
preg_quote($value),
12571257
);
1258-
$value = new Regex('^' . $regex . '$', 'i');
1258+
$flags = $where['caseSensitive'] ?? false ? '' : 'i';
1259+
$value = new Regex('^' . $regex . '$', $flags);
12591260

12601261
// For inverse like operations, we can just use the $not operator with the Regex
12611262
$operator = $operator === 'like' ? '=' : 'not';
@@ -1313,6 +1314,13 @@ protected function compileWhereNotIn(array $where): array
13131314
return [$where['column'] => ['$nin' => array_values($where['values'])]];
13141315
}
13151316

1317+
protected function compileWhereLike(array $where): array
1318+
{
1319+
$where['operator'] = $where['not'] ? 'not like' : 'like';
1320+
1321+
return $this->compileWhereBasic($where);
1322+
}
1323+
13161324
protected function compileWhereNull(array $where): array
13171325
{
13181326
$where['operator'] = '=';

tests/Query/BuilderTest.php

+170-111
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,18 @@
2626
use function collect;
2727
use function method_exists;
2828
use function now;
29+
use function sprintf;
2930
use function var_export;
3031

3132
class BuilderTest extends TestCase
3233
{
3334
#[DataProvider('provideQueryBuilderToMql')]
34-
public function testMql(array $expected, Closure $build): void
35+
public function testMql(array $expected, Closure $build, ?string $requiredMethod = null): void
3536
{
37+
if ($requiredMethod && ! method_exists(Builder::class, $requiredMethod)) {
38+
$this->markTestSkipped(sprintf('Method "%s::%s()" does not exist.', Builder::class, $requiredMethod));
39+
}
40+
3641
$builder = $build(self::getBuilder());
3742
$this->assertInstanceOf(Builder::class, $builder);
3843
$mql = $builder->toMql();
@@ -758,6 +763,48 @@ function (Builder $builder) {
758763
fn (Builder $builder) => $builder->where('name', 'like', '_ac__me_'),
759764
];
760765

766+
yield 'whereLike' => [
767+
['find' => [['name' => new Regex('^1$', 'i')], []]],
768+
fn
769+
(Builder $builder) => $builder->whereLike('name', '1'),
770+
'whereLike',
771+
];
772+
773+
yield 'whereLike case not sensitive' => [
774+
['find' => [['name' => new Regex('^1$', 'i')], []]],
775+
fn
776+
(Builder $builder) => $builder->whereLike('name', '1', false),
777+
'whereLike',
778+
];
779+
780+
yield 'whereLike case sensitive' => [
781+
['find' => [['name' => new Regex('^1$', '')], []]],
782+
fn
783+
(Builder $builder) => $builder->whereLike('name', '1', true),
784+
'whereLike',
785+
];
786+
787+
yield 'whereNotLike' => [
788+
['find' => [['name' => ['$not' => new Regex('^1$', 'i')]], []]],
789+
fn
790+
(Builder $builder) => $builder->whereNotLike('name', '1'),
791+
'whereNotLike',
792+
];
793+
794+
yield 'whereNotLike case not sensitive' => [
795+
['find' => [['name' => ['$not' => new Regex('^1$', 'i')]], []]],
796+
fn
797+
(Builder $builder) => $builder->whereNotLike('name', '1', false),
798+
'whereNotLike',
799+
];
800+
801+
yield 'whereNotLike case sensitive' => [
802+
['find' => [['name' => ['$not' => new Regex('^1$', '')]], []]],
803+
fn
804+
(Builder $builder) => $builder->whereNotLike('name', '1', true),
805+
'whereNotLike',
806+
];
807+
761808
$regex = new Regex('^acme$', 'si');
762809
yield 'where BSON\Regex' => [
763810
['find' => [['name' => $regex], []]],
@@ -1186,142 +1233,154 @@ function (Builder $elemMatchQuery): void {
11861233
];
11871234

11881235
// Method added in Laravel v10.47.0
1189-
if (method_exists(Builder::class, 'whereAll')) {
1190-
/** @see DatabaseQueryBuilderTest::testWhereAll */
1191-
yield 'whereAll' => [
1192-
[
1193-
'find' => [
1194-
['$and' => [['last_name' => 'Doe'], ['email' => 'Doe']]],
1195-
[], // options
1196-
],
1236+
/** @see DatabaseQueryBuilderTest::testWhereAll */
1237+
yield 'whereAll' => [
1238+
[
1239+
'find' => [
1240+
['$and' => [['last_name' => 'Doe'], ['email' => 'Doe']]],
1241+
[], // options
11971242
],
1198-
fn(Builder $builder) => $builder->whereAll(['last_name', 'email'], 'Doe'),
1199-
];
1200-
1201-
yield 'whereAll operator' => [
1202-
[
1203-
'find' => [
1204-
[
1205-
'$and' => [
1206-
['last_name' => ['$not' => new Regex('^.*Doe.*$', 'i')]],
1207-
['email' => ['$not' => new Regex('^.*Doe.*$', 'i')]],
1208-
],
1243+
],
1244+
fn
1245+
(Builder $builder) => $builder->whereAll(['last_name', 'email'], 'Doe'),
1246+
'whereAll',
1247+
];
1248+
1249+
yield 'whereAll operator' => [
1250+
[
1251+
'find' => [
1252+
[
1253+
'$and' => [
1254+
['last_name' => ['$not' => new Regex('^.*Doe.*$', 'i')]],
1255+
['email' => ['$not' => new Regex('^.*Doe.*$', 'i')]],
12091256
],
1210-
[], // options
12111257
],
1258+
[], // options
12121259
],
1213-
fn(Builder $builder) => $builder->whereAll(['last_name', 'email'], 'not like', '%Doe%'),
1214-
];
1215-
1216-
/** @see DatabaseQueryBuilderTest::testOrWhereAll */
1217-
yield 'orWhereAll' => [
1218-
[
1219-
'find' => [
1220-
[
1221-
'$or' => [
1222-
['first_name' => 'John'],
1223-
['$and' => [['last_name' => 'Doe'], ['email' => 'Doe']]],
1224-
],
1260+
],
1261+
fn
1262+
(Builder $builder) => $builder->whereAll(['last_name', 'email'], 'not like', '%Doe%'),
1263+
'whereAll',
1264+
];
1265+
1266+
/** @see DatabaseQueryBuilderTest::testOrWhereAll */
1267+
yield 'orWhereAll' => [
1268+
[
1269+
'find' => [
1270+
[
1271+
'$or' => [
1272+
['first_name' => 'John'],
1273+
['$and' => [['last_name' => 'Doe'], ['email' => 'Doe']]],
12251274
],
1226-
[], // options
12271275
],
1276+
[], // options
12281277
],
1229-
fn(Builder $builder) => $builder
1230-
->where('first_name', 'John')
1231-
->orWhereAll(['last_name', 'email'], 'Doe'),
1232-
];
1233-
1234-
yield 'orWhereAll operator' => [
1235-
[
1236-
'find' => [
1237-
[
1238-
'$or' => [
1239-
['first_name' => new Regex('^.*John.*$', 'i')],
1240-
[
1241-
'$and' => [
1242-
['last_name' => ['$not' => new Regex('^.*Doe.*$', 'i')]],
1243-
['email' => ['$not' => new Regex('^.*Doe.*$', 'i')]],
1244-
],
1278+
],
1279+
fn
1280+
(Builder $builder) => $builder
1281+
->where('first_name', 'John')
1282+
->orWhereAll(['last_name', 'email'], 'Doe'),
1283+
'orWhereAll',
1284+
];
1285+
1286+
yield 'orWhereAll operator' => [
1287+
[
1288+
'find' => [
1289+
[
1290+
'$or' => [
1291+
['first_name' => new Regex('^.*John.*$', 'i')],
1292+
[
1293+
'$and' => [
1294+
['last_name' => ['$not' => new Regex('^.*Doe.*$', 'i')]],
1295+
['email' => ['$not' => new Regex('^.*Doe.*$', 'i')]],
12451296
],
12461297
],
12471298
],
1248-
[], // options
12491299
],
1300+
[], // options
12501301
],
1251-
fn(Builder $builder) => $builder
1252-
->where('first_name', 'like', '%John%')
1253-
->orWhereAll(['last_name', 'email'], 'not like', '%Doe%'),
1254-
];
1255-
}
1302+
],
1303+
fn
1304+
(Builder $builder) => $builder
1305+
->where('first_name', 'like', '%John%')
1306+
->orWhereAll(['last_name', 'email'], 'not like', '%Doe%'),
1307+
'orWhereAll',
1308+
];
12561309

12571310
// Method added in Laravel v10.47.0
1258-
if (method_exists(Builder::class, 'whereAny')) {
1259-
/** @see DatabaseQueryBuilderTest::testWhereAny */
1260-
yield 'whereAny' => [
1261-
[
1262-
'find' => [
1263-
['$or' => [['last_name' => 'Doe'], ['email' => 'Doe']]],
1264-
[], // options
1265-
],
1311+
/** @see DatabaseQueryBuilderTest::testWhereAny */
1312+
yield 'whereAny' => [
1313+
[
1314+
'find' => [
1315+
['$or' => [['last_name' => 'Doe'], ['email' => 'Doe']]],
1316+
[], // options
12661317
],
1267-
fn(Builder $builder) => $builder->whereAny(['last_name', 'email'], 'Doe'),
1268-
];
1269-
1270-
yield 'whereAny operator' => [
1271-
[
1272-
'find' => [
1273-
[
1274-
'$or' => [
1275-
['last_name' => ['$not' => new Regex('^.*Doe.*$', 'i')]],
1276-
['email' => ['$not' => new Regex('^.*Doe.*$', 'i')]],
1277-
],
1318+
],
1319+
fn
1320+
(Builder $builder) => $builder->whereAny(['last_name', 'email'], 'Doe'),
1321+
'whereAny',
1322+
];
1323+
1324+
yield 'whereAny operator' => [
1325+
[
1326+
'find' => [
1327+
[
1328+
'$or' => [
1329+
['last_name' => ['$not' => new Regex('^.*Doe.*$', 'i')]],
1330+
['email' => ['$not' => new Regex('^.*Doe.*$', 'i')]],
12781331
],
1279-
[], // options
12801332
],
1333+
[], // options
12811334
],
1282-
fn(Builder $builder) => $builder->whereAny(['last_name', 'email'], 'not like', '%Doe%'),
1283-
];
1284-
1285-
/** @see DatabaseQueryBuilderTest::testOrWhereAny */
1286-
yield 'orWhereAny' => [
1287-
[
1288-
'find' => [
1289-
[
1290-
'$or' => [
1291-
['first_name' => 'John'],
1292-
['$or' => [['last_name' => 'Doe'], ['email' => 'Doe']]],
1293-
],
1335+
],
1336+
fn
1337+
(Builder $builder) => $builder->whereAny(['last_name', 'email'], 'not like', '%Doe%'),
1338+
'whereAny',
1339+
];
1340+
1341+
/** @see DatabaseQueryBuilderTest::testOrWhereAny */
1342+
yield 'orWhereAny' => [
1343+
[
1344+
'find' => [
1345+
[
1346+
'$or' => [
1347+
['first_name' => 'John'],
1348+
['$or' => [['last_name' => 'Doe'], ['email' => 'Doe']]],
12941349
],
1295-
[], // options
12961350
],
1351+
[], // options
12971352
],
1298-
fn(Builder $builder) => $builder
1299-
->where('first_name', 'John')
1300-
->orWhereAny(['last_name', 'email'], 'Doe'),
1301-
];
1302-
1303-
yield 'orWhereAny operator' => [
1304-
[
1305-
'find' => [
1306-
[
1307-
'$or' => [
1308-
['first_name' => new Regex('^.*John.*$', 'i')],
1309-
[
1310-
'$or' => [
1311-
['last_name' => ['$not' => new Regex('^.*Doe.*$', 'i')]],
1312-
['email' => ['$not' => new Regex('^.*Doe.*$', 'i')]],
1313-
],
1353+
],
1354+
fn
1355+
(Builder $builder) => $builder
1356+
->where('first_name', 'John')
1357+
->orWhereAny(['last_name', 'email'], 'Doe'),
1358+
'whereAny',
1359+
];
1360+
1361+
yield 'orWhereAny operator' => [
1362+
[
1363+
'find' => [
1364+
[
1365+
'$or' => [
1366+
['first_name' => new Regex('^.*John.*$', 'i')],
1367+
[
1368+
'$or' => [
1369+
['last_name' => ['$not' => new Regex('^.*Doe.*$', 'i')]],
1370+
['email' => ['$not' => new Regex('^.*Doe.*$', 'i')]],
13141371
],
13151372
],
13161373
],
1317-
[], // options
13181374
],
1375+
[], // options
13191376
],
1320-
fn(Builder $builder) => $builder
1321-
->where('first_name', 'like', '%John%')
1322-
->orWhereAny(['last_name', 'email'], 'not like', '%Doe%'),
1323-
];
1324-
}
1377+
],
1378+
fn
1379+
(Builder $builder) => $builder
1380+
->where('first_name', 'like', '%John%')
1381+
->orWhereAny(['last_name', 'email'], 'not like', '%Doe%'),
1382+
'orWhereAny',
1383+
];
13251384
}
13261385

13271386
#[DataProvider('provideExceptions')]

0 commit comments

Comments
 (0)