Skip to content

Commit aee5a0c

Browse files
committed
PHPLIB-123: Do not throw when listing indexes on nonexistent collection
1 parent 3961ce2 commit aee5a0c

File tree

2 files changed

+63
-1
lines changed

2 files changed

+63
-1
lines changed

src/Operation/ListIndexes.php

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
use MongoDB\Driver\Command;
66
use MongoDB\Driver\Query;
77
use MongoDB\Driver\Server;
8+
use MongoDB\Driver\Exception\RuntimeException;
89
use MongoDB\Model\IndexInfoIterator;
910
use MongoDB\Model\IndexInfoIteratorIterator;
11+
use EmptyIterator;
1012

1113
/**
1214
* Operation for the listIndexes command.
@@ -17,6 +19,8 @@
1719
*/
1820
class ListIndexes implements Executable
1921
{
22+
private static $errorCodeDatabaseNotFound = 60;
23+
private static $errorCodeNamespaceNotFound = 26;
2024
private static $wireVersionForCommand = 3;
2125

2226
private $databaseName;
@@ -75,7 +79,20 @@ private function executeCommand(Server $server)
7579
$cmd['maxTimeMS'] = $this->options['maxTimeMS'];
7680
}
7781

78-
$cursor = $server->executeCommand($this->databaseName, new Command($cmd));
82+
try {
83+
$cursor = $server->executeCommand($this->databaseName, new Command($cmd));
84+
} catch (RuntimeException $e) {
85+
/* The server may return an error if the collection does not exist.
86+
* Check for possible error codes (see: SERVER-20463) and return an
87+
* empty iterator instead of throwing.
88+
*/
89+
if ($e->getCode() === self::$errorCodeNamespaceNotFound || $e->getCode() === self::$errorCodeDatabaseNotFound) {
90+
return new IndexInfoIteratorIterator(new EmptyIterator);
91+
}
92+
93+
throw $e;
94+
}
95+
7996
$cursor->setTypeMap(array('root' => 'array', 'document' => 'array'));
8097

8198
return new IndexInfoIteratorIterator($cursor);
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
namespace MongoDB\Tests\Operation;
4+
5+
use MongoDB\Driver\Server;
6+
use MongoDB\Operation\DropCollection;
7+
use MongoDB\Operation\ListIndexes;
8+
9+
class ListIndexesFunctionalTest extends FunctionalTestCase
10+
{
11+
public function testListIndexesForNewlyCreatedCollection()
12+
{
13+
$server = $this->getPrimaryServer();
14+
15+
$operation = new DropCollection($this->getDatabaseName(), $this->getCollectionName());
16+
$operation->execute($server);
17+
18+
$writeResult = $this->manager->executeInsert($this->getNamespace(), ['x' => 1]);
19+
$this->assertEquals(1, $writeResult->getInsertedCount());
20+
21+
$operation = new ListIndexes($this->getDatabaseName(), $this->getCollectionName());
22+
// Convert the CursorInfoIterator to an array since we cannot rewind its cursor
23+
$indexes = iterator_to_array($operation->execute($server));
24+
25+
$this->assertCount(1, $indexes);
26+
27+
foreach ($indexes as $index) {
28+
$this->assertInstanceOf('MongoDB\Model\IndexInfo', $index);
29+
$this->assertEquals(['_id' => 1], $index->getKey());
30+
}
31+
}
32+
33+
public function testListIndexesForNonexistentCollection()
34+
{
35+
$server = $this->getPrimaryServer();
36+
37+
$operation = new DropCollection($this->getDatabaseName(), $this->getCollectionName());
38+
$operation->execute($server);
39+
40+
$operation = new ListIndexes($this->getDatabaseName(), $this->getCollectionName());
41+
$indexes = $operation->execute($server);
42+
43+
$this->assertCount(0, $indexes);
44+
}
45+
}

0 commit comments

Comments
 (0)