/**
* Ensure index of correct specification and a unique name whether the specification or name already exist or not.
* Will not create index if $index is a prefix of an existing index
*
* @param array $index index to create in same format as \MongoCollection::ensureIndex()
*
* @return void
*
* @throws \Exception couldnt create index after 5 attempts
*/
private function _ensureIndex(array $index)
{
//if $index is a prefix of any existing index we are good
foreach ($this->_collection->getIndexInfo() as $existingIndex) {
$slice = array_slice($existingIndex['key'], 0, count($index), true);
if ($slice === $index) {
return;
}
}
for ($i = 0; $i < 5; ++$i) {
for ($name = uniqid(); strlen($name) > 0; $name = substr($name, 0, -1)) {
//creating an index with same name and different spec does nothing.
//creating an index with same spec and different name does nothing.
//so we use any generated name, and then find the right spec after we have called, and just go with that name.
try {
$this->_collection->ensureIndex($index, array('name' => $name, 'background' => true));
} catch (\MongoException $e) {
//this happens when the name was too long, let continue
}
foreach ($this->_collection->getIndexInfo() as $existingIndex) {
if ($existingIndex['key'] === $index) {
return;
}
}
}
}
throw new \Exception('couldnt create index after 5 attempts');
}