Skip to content

Commit

Permalink
Merge branch '1.3.x'
Browse files Browse the repository at this point in the history
* 1.3.x:
  Use constants for MongoDB error codes
  Fix failing index test
  Fix detection of sharding command return codes
  Add sharding group to sharding tests
  Add build against PHP 7.3 and MongoDB 4.0 to pipeline
  Revert "Fix wrong usage of discriminator map in complex document inheritance chains"
  Clarify deprecation of update() and multiple()
  Add test with overly long index name to confirm exception
  Document index name prefixing logic
  Fix embedding documents containing named indexes
  Fix adding discriminator map to queries
  Reset existing discriminator information when setting a discriminator map
  Add failing test case for wrong discriminator map inheritance
  • Loading branch information
alcaeus committed Mar 14, 2019
2 parents 3bf3ceb + c2c86c5 commit 9d89778
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 1 deletion.
12 changes: 11 additions & 1 deletion docs/en/reference/annotations-reference.rst
Expand Up @@ -526,7 +526,8 @@ Optional attributes:
respectively. Special index types (e.g. ``2dsphere``) should be specified as
strings. This is required when `@Index`_ is used at the class level.
-
``options`` - Options for creating the index
``options`` - Options for creating the index. Options are documented in the
:ref:`indexes chapter <indees>`.

The ``keys`` and ``options`` attributes correspond to the arguments for
`MongoCollection::createIndex() <http://php.net/manual/en/mongocollection.createindex.php>`_.
Expand Down Expand Up @@ -559,6 +560,15 @@ If you are creating a single-field index, you can simply specify an `@Index`_ or
/** @Field(type="string") @UniqueIndex */
private $username;
.. note::

If the ``name`` option is specified on an index in an embedded document, it
will be prefixed with the embedded field path before creating the index.
This is necessary to avoid index name conflict when the same document is
embedded multiple times in a single collection. Prefixing of the index name
can cause errors due to excessive index name length. In this case, try
shortening the index name or embedded field path.

@Indexes
--------

Expand Down
9 changes: 9 additions & 0 deletions docs/en/reference/indexes.rst
Expand Up @@ -284,6 +284,15 @@ Also, for your convenience you can create the indexes for your mapped documents
unless you specify a discriminator map for the :ref:`embed-one <embed_one>`
or :ref:`embed-many <embed_many>` relationship.

.. note::

If the ``name`` option is specified on an index in an embedded document, it
will be prefixed with the embedded field path before creating the index.
This is necessary to avoid index name conflict when the same document is
embedded multiple times in a single collection. Prefixing of the index name
can cause errors due to excessive index name length. In this case, try
shortening the index name or embedded field path.

Geospatial Indexing
-------------------

Expand Down
5 changes: 5 additions & 0 deletions lib/Doctrine/ODM/MongoDB/SchemaManager.php
Expand Up @@ -18,6 +18,7 @@
use function iterator_count;
use function iterator_to_array;
use function ksort;
use function sprintf;

class SchemaManager
{
Expand Down Expand Up @@ -166,6 +167,10 @@ private function doGetDocumentIndexes(string $documentName, array &$visited) : a
unset($embeddedIndex['keys'][$key]);
}

if (isset($embeddedIndex['options']['name'])) {
$embeddedIndex['options']['name'] = sprintf('%s_%s', $fieldMapping['name'], $embeddedIndex['options']['name']);
}

$indexes[] = $embeddedIndex;
}
}
Expand Down
Expand Up @@ -11,6 +11,9 @@
use Documents\Sharded\ShardedOneWithDifferentKey;
use function iterator_to_array;

/**
* @group sharding
*/
class EnsureShardingTest extends BaseTest
{
public function setUp()
Expand Down
3 changes: 3 additions & 0 deletions tests/Doctrine/ODM/MongoDB/Tests/Functional/ShardKeyTest.php
Expand Up @@ -11,6 +11,9 @@
use function end;
use function get_class;

/**
* @group sharding
*/
class ShardKeyTest extends BaseTest
{
/** @var CommandLogger */
Expand Down
90 changes: 90 additions & 0 deletions tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1344Test.php
@@ -0,0 +1,90 @@
<?php

declare(strict_types=1);

namespace Doctrine\ODM\MongoDB\Tests\Functional\Ticket;

use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;
use Doctrine\ODM\MongoDB\Tests\BaseTest;
use MongoDB\Driver\Exception\CommandException;

class GH1344Test extends BaseTest
{
public function testGeneratingIndexesDoesNotThrowException()
{
$indexes = $this->dm->getSchemaManager()->getDocumentIndexes(GH1344Main::class);
self::assertCount(4, $indexes);
self::assertSame('embedded1_embedded', $indexes[0]['options']['name']);
self::assertSame('embedded1_embedded_nested', $indexes[1]['options']['name']);
self::assertSame('embedded2_embedded', $indexes[2]['options']['name']);
self::assertSame('embedded2_embedded_nested', $indexes[3]['options']['name']);

$this->dm->getSchemaManager()->ensureDocumentIndexes(GH1344Main::class);
}

public function testGeneratingIndexesWithTooLongIndexNameThrowsException()
{
// Ensure that at least the beginning of the index name is contained in
// the exception message. This can vary between driver/server versions.
$this->expectException(CommandException::class);
$this->expectExceptionMessageRegExp('#GH1344TooLongIndexName.\$embedded1_this_is_a_really_long_name_that#');

$this->dm->getSchemaManager()->ensureDocumentIndexes(GH1344TooLongIndexName::class);
}
}

/** @ODM\Document */
class GH1344Main
{
/** @ODM\Id */
public $id;

/** @ODM\EmbedOne(targetDocument=GH1344Embedded::class) */
public $embedded1;

/** @ODM\EmbedOne(targetDocument=GH1344Embedded::class) */
public $embedded2;
}

/**
* @ODM\EmbeddedDocument
* @ODM\Index(keys={"property"="asc"}, name="embedded")
*/
class GH1344Embedded
{
/** @ODM\Field */
public $property;

/** @ODM\EmbedOne(targetDocument=GH1344EmbeddedNested::class) */
public $embedded;
}

/**
* @ODM\EmbeddedDocument
* @ODM\Index(keys={"property"="asc"}, name="nested")
*/
class GH1344EmbeddedNested
{
/** @ODM\Field */
public $property;
}

/** @ODM\Document */
class GH1344TooLongIndexName
{
/** @ODM\Id */
public $id;

/** @ODM\EmbedOne(targetDocument=GH1344TooLongIndexNameEmbedded::class) */
public $embedded1;
}

/**
* @ODM\EmbeddedDocument
* @ODM\Index(keys={"property"="asc"}, name="this_is_a_really_long_name_that_will_cause_problems_for_whoever_tries_to_use_it_whether_in_an_embedded_field_or_not")
*/
class GH1344TooLongIndexNameEmbedded
{
/** @ODM\Field */
public $property;
}

0 comments on commit 9d89778

Please sign in to comment.