Skip to content

Commit 4edad3c

Browse files
committed
Review
1 parent 0c31932 commit 4edad3c

File tree

10 files changed

+78
-45
lines changed

10 files changed

+78
-45
lines changed

psalm-baseline.xml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -324,10 +324,10 @@
324324
</file>
325325
<file src="src/Operation/CreateSearchIndexes.php">
326326
<MixedArgumentTypeCoercion>
327-
<code>(array) $index</code>
327+
<code>$index</code>
328328
</MixedArgumentTypeCoercion>
329329
<MixedAssignment>
330-
<code>$cmd[$option]</code>
330+
<code><![CDATA[$cmd['comment']]]></code>
331331
</MixedAssignment>
332332
</file>
333333
<file src="src/Operation/DatabaseCommand.php">
@@ -412,7 +412,7 @@
412412
</file>
413413
<file src="src/Operation/DropSearchIndex.php">
414414
<MixedAssignment>
415-
<code>$cmd[$option]</code>
415+
<code><![CDATA[$cmd['comment']]]></code>
416416
</MixedAssignment>
417417
</file>
418418
<file src="src/Operation/Explain.php">
@@ -596,7 +596,7 @@
596596
</file>
597597
<file src="src/Operation/UpdateSearchIndex.php">
598598
<MixedAssignment>
599-
<code>$cmd[$option]</code>
599+
<code><![CDATA[$cmd['comment']]]></code>
600600
</MixedAssignment>
601601
</file>
602602
<file src="src/Operation/Watch.php">

src/Collection.php

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
use MongoDB\BSON\JavascriptInterface;
2323
use MongoDB\Codec\DocumentCodec;
2424
use MongoDB\Driver\CursorInterface;
25-
use MongoDB\Driver\Exception\CommandException;
2625
use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
2726
use MongoDB\Driver\Manager;
2827
use MongoDB\Driver\ReadConcern;
@@ -580,14 +579,7 @@ public function dropSearchIndex(string $name, array $options = []): void
580579
$operation = new DropSearchIndex($this->databaseName, $this->collectionName, $name);
581580
$server = select_server($this->manager, $options);
582581

583-
try {
584-
$operation->execute($server);
585-
} catch (CommandException $e) {
586-
// Suppress namespace not found errors for idempotency
587-
if ($e->getCode() !== 26) {
588-
throw $e;
589-
}
590-
}
582+
$operation->execute($server);
591583
}
592584

593585
/**

src/Operation/CreateSearchIndexes.php

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22
/*
3-
* Copyright 2015-present MongoDB, Inc.
3+
* Copyright 2023-present MongoDB, Inc.
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
66
* you may not use this file except in compliance with the License.
@@ -27,7 +27,7 @@
2727
use function array_column;
2828
use function array_is_list;
2929
use function current;
30-
use function MongoDB\is_document;
30+
use function is_array;
3131
use function sprintf;
3232

3333
/**
@@ -49,7 +49,7 @@ class CreateSearchIndexes implements Executable
4949
*
5050
* @param string $databaseName Database name
5151
* @param string $collectionName Collection name
52-
* @param list<array|object> $indexes List of search index specifications
52+
* @param array[] $indexes List of search index specifications
5353
* @param array{comment?: mixed} $options Command options
5454
* @throws InvalidArgumentException for parameter parsing errors
5555
*/
@@ -60,11 +60,11 @@ public function __construct(string $databaseName, string $collectionName, array
6060
}
6161

6262
foreach ($indexes as $i => $index) {
63-
if (! is_document($index)) {
64-
throw InvalidArgumentException::expectedDocumentType(sprintf('$indexes[%d]', $i), $index);
63+
if (! is_array($index)) {
64+
throw InvalidArgumentException::invalidType(sprintf('$indexes[%d]', $i), $index, 'array');
6565
}
6666

67-
$this->indexes[] = new SearchIndexInput((array) $index);
67+
$this->indexes[] = new SearchIndexInput($index);
6868
}
6969

7070
$this->databaseName = $databaseName;
@@ -87,10 +87,8 @@ public function execute(Server $server): array
8787
'indexes' => $this->indexes,
8888
];
8989

90-
foreach (['comment'] as $option) {
91-
if (isset($this->options[$option])) {
92-
$cmd[$option] = $this->options[$option];
93-
}
90+
if (isset($this->options['comment'])) {
91+
$cmd['comment'] = $this->options['comment'];
9492
}
9593

9694
$cursor = $server->executeCommand($this->databaseName, new Command($cmd));

src/Operation/DropSearchIndex.php

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22
/*
3-
* Copyright 2015-present MongoDB, Inc.
3+
* Copyright 2023-present MongoDB, Inc.
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
66
* you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@
1818
namespace MongoDB\Operation;
1919

2020
use MongoDB\Driver\Command;
21+
use MongoDB\Driver\Exception\CommandException;
2122
use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
2223
use MongoDB\Driver\Server;
2324
use MongoDB\Exception\InvalidArgumentException;
@@ -31,6 +32,8 @@
3132
*/
3233
class DropSearchIndex implements Executable
3334
{
35+
private const ERROR_CODE_NAMESPACE_NOT_FOUND = 26;
36+
3437
private string $databaseName;
3538
private string $collectionName;
3639
private string $name;
@@ -71,12 +74,17 @@ public function execute(Server $server): void
7174
'name' => $this->name,
7275
];
7376

74-
foreach (['comment'] as $option) {
75-
if (isset($this->options[$option])) {
76-
$cmd[$option] = $this->options[$option];
77-
}
77+
if (isset($this->options['comment'])) {
78+
$cmd['comment'] = $this->options['comment'];
7879
}
7980

80-
$server->executeCommand($this->databaseName, new Command($cmd));
81+
try {
82+
$server->executeCommand($this->databaseName, new Command($cmd));
83+
} catch (CommandException $e) {
84+
// Drop operations is idempotent. The server may return an error if the collection does not exist.
85+
if ($e->getCode() !== self::ERROR_CODE_NAMESPACE_NOT_FOUND) {
86+
throw $e;
87+
}
88+
}
8189
}
8290
}

src/Operation/ListSearchIndexes.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22
/*
3-
* Copyright 2015-present MongoDB, Inc.
3+
* Copyright 2023-present MongoDB, Inc.
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
66
* you may not use this file except in compliance with the License.

src/Operation/UpdateSearchIndex.php

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22
/*
3-
* Copyright 2015-present MongoDB, Inc.
3+
* Copyright 2023-present MongoDB, Inc.
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
66
* you may not use this file except in compliance with the License.
@@ -81,10 +81,8 @@ public function execute(Server $server): void
8181
'definition' => $this->definition,
8282
];
8383

84-
foreach (['comment'] as $option) {
85-
if (isset($this->options[$option])) {
86-
$cmd[$option] = $this->options[$option];
87-
}
84+
if (isset($this->options['comment'])) {
85+
$cmd['comment'] = $this->options['comment'];
8886
}
8987

9088
$server->executeCommand($this->databaseName, new Command($cmd));

tests/Operation/CreateSearchIndexesTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public function testConstructorIndexesArgumentMustBeAList(): void
1818
public function testConstructorIndexDefinitionMustBeADocument($index): void
1919
{
2020
$this->expectException(InvalidArgumentException::class);
21-
$this->expectExceptionMessage('Expected $indexes[0] to have type "document"');
21+
$this->expectExceptionMessage('Expected $indexes[0] to have type "array"');
2222
new CreateSearchIndexes($this->getDatabaseName(), $this->getCollectionName(), [$index], []);
2323
}
2424

tests/SpecTests/SearchIndexSpecTest.php

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,22 +21,29 @@
2121
/**
2222
* Functional tests for the Atlas Search index management.
2323
*
24-
* @see https://github.com/mongodb/specifications/blob/master/source/index-management/index-management.rst
24+
* @see https://github.com/mongodb/specifications/blob/master/source/index-management/tests/README.rst#search-index-management-helpers
2525
* @group atlas
2626
*/
2727
class SearchIndexSpecTest extends FunctionalTestCase
2828
{
29-
private const WAIT_TIMEOUT = 300; // 5 minutes
29+
private const WAIT_TIMEOUT_SEC = 300;
3030

3131
public function setUp(): void
3232
{
3333
if (! self::isAtlas()) {
34-
self::markTestSkipped('Search Indexes are only supported on MongoDB Atlas');
34+
self::markTestSkipped('Search Indexes are only supported on MongoDB Atlas 7.0+');
3535
}
3636

3737
parent::setUp();
38+
39+
$this->skipIfServerVersion('<', '7.0', 'Search Indexes are only supported on MongoDB Atlas 7.0+');
3840
}
3941

42+
/**
43+
* Case 1: Driver can successfully create and list search indexes
44+
*
45+
* @see https://github.com/mongodb/specifications/blob/master/source/index-management/tests/README.rst#case-1-driver-can-successfully-create-and-list-search-indexes
46+
*/
4047
public function testCreateAndListSearchIndexes(): void
4148
{
4249
$collection = $this->createCollection($this->getDatabaseName(), $this->getCollectionName());
@@ -60,6 +67,11 @@ public function testCreateAndListSearchIndexes(): void
6067
);
6168
}
6269

70+
/**
71+
* Case 2: Driver can successfully create multiple indexes in batch
72+
*
73+
* @see https://github.com/mongodb/specifications/blob/master/source/index-management/tests/README.rst#case-2-driver-can-successfully-create-multiple-indexes-in-batch
74+
*/
6375
public function testCreateMultipleIndexesInBatch(): void
6476
{
6577
$collection = $this->createCollection($this->getDatabaseName(), $this->getCollectionName());
@@ -86,6 +98,11 @@ public function testCreateMultipleIndexesInBatch(): void
8698
}
8799
}
88100

101+
/**
102+
* Case 3: Driver can successfully drop search indexes
103+
*
104+
* @see https://github.com/mongodb/specifications/blob/master/source/index-management/tests/README.rst#case-3-driver-can-successfully-drop-search-indexes
105+
*/
89106
public function testDropSearchIndexes(): void
90107
{
91108
$collection = $this->createCollection($this->getDatabaseName(), $this->getCollectionName());
@@ -98,15 +115,20 @@ public function testDropSearchIndexes(): void
98115
);
99116
$this->assertSame($name, $createdName);
100117

101-
$this->waitForIndexes($collection, fn ($indexes) => $this->allIndexesAreQueryable($indexes));
118+
$indexes = $this->waitForIndexes($collection, fn ($indexes) => $this->allIndexesAreQueryable($indexes));
119+
$this->assertCount(1, $indexes);
102120

103121
$collection->dropSearchIndex($name);
104122

105123
$indexes = $this->waitForIndexes($collection, fn (array $indexes): bool => count($indexes) === 0);
106-
107124
$this->assertCount(0, $indexes);
108125
}
109126

127+
/**
128+
* Case 4: Driver can update a search index
129+
*
130+
* @see https://github.com/mongodb/specifications/blob/master/source/index-management/tests/README.rst#case-4-driver-can-update-a-search-index
131+
*/
110132
public function testUpdateSearchIndex(): void
111133
{
112134
$collection = $this->createCollection($this->getDatabaseName(), $this->getCollectionName());
@@ -119,7 +141,8 @@ public function testUpdateSearchIndex(): void
119141
);
120142
$this->assertSame($name, $createdName);
121143

122-
$this->waitForIndexes($collection, fn ($indexes) => $this->allIndexesAreQueryable($indexes));
144+
$indexes = $this->waitForIndexes($collection, fn ($indexes) => $this->allIndexesAreQueryable($indexes));
145+
$this->assertCount(1, $indexes);
123146

124147
$mapping = ['mappings' => ['dynamic' => true]];
125148
$collection->updateSearchIndex($name, $mapping);
@@ -135,6 +158,11 @@ public function testUpdateSearchIndex(): void
135158
);
136159
}
137160

161+
/**
162+
* Case 5: dropSearchIndex suppresses namespace not found errors
163+
*
164+
* @see https://github.com/mongodb/specifications/blob/master/source/index-management/tests/README.rst#case-5-dropsearchindex-suppresses-namespace-not-found-errors
165+
*/
138166
public function testDropSearchIndexSuppressNamespaceNotFoundError(): void
139167
{
140168
$collection = $this->dropCollection($this->getDatabaseName(), $this->getCollectionName());
@@ -155,7 +183,7 @@ protected function getCollectionName(): string
155183

156184
private function waitForIndexes(Collection $collection, Closure $callback): array
157185
{
158-
$timeout = hrtime()[0] + self::WAIT_TIMEOUT;
186+
$timeout = hrtime()[0] + self::WAIT_TIMEOUT_SEC;
159187
while (hrtime()[0] < $timeout) {
160188
sleep(5);
161189
$result = $collection->listSearchIndexes();

tests/UnifiedSpecTests/Operation.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -548,10 +548,19 @@ private function executeForCollection(Collection $collection)
548548
$options['name'] = $args['model']->name;
549549
}
550550

551+
assertInstanceOf(stdClass::class, $args['model']->definition);
552+
551553
return $collection->createSearchIndex($args['model']->definition, $options);
552554

553555
case 'createSearchIndexes':
554-
return $collection->createSearchIndexes($args['models']);
556+
$indexes = array_map(function ($index) {
557+
$index = (array) $index;
558+
assertInstanceOf(stdClass::class, $index['definition']);
559+
560+
return $index;
561+
}, $args['models']);
562+
563+
return $collection->createSearchIndexes($indexes);
555564

556565
case 'dropSearchIndex':
557566
assertArrayHasKey('name', $args);

tests/UnifiedSpecTests/UnifiedSpecTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ public function provideFailingTests()
277277
public function testIndexManagement(UnifiedTestCase $test): void
278278
{
279279
if (self::isAtlas()) {
280-
self::markTestSkipped('Search Indexes tests must run on a non-atlas cluster');
280+
self::markTestSkipped('Search Indexes tests must run on a non-Atlas cluster');
281281
}
282282

283283
if (! self::isEnterprise()) {

0 commit comments

Comments
 (0)