Skip to content

Commit

Permalink
Merge pull request #1927 from alcaeus/deprecation-layer-part-2
Browse files Browse the repository at this point in the history
Deprecate more features in preparation for 2.0
  • Loading branch information
alcaeus authored Jan 14, 2019
2 parents 058e09a + 55d5f33 commit 30f3c96
Show file tree
Hide file tree
Showing 22 changed files with 309 additions and 61 deletions.
45 changes: 45 additions & 0 deletions UPGRADE-1.3.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,54 @@ The `Doctrine\ODM\MongoDB\Mapping\ClassMetadataInfo` class has been deprecated
in favor of `Doctrine\ODM\MongoDB\Mapping\ClassMetadata` and will be dropped in
2.0.

### Annotation mappings

* The `@NotSaved` annotation was deprecated and will be dropped in 2.0. Use the
`notSaved` option on the `@Field`, `@ReferenceOne`, `@ReferenceMany`,
`@EmbedOne` or `@EmbedMany` annotations instead.
* Using more than one class-level document annotation (e.g. `@Document`,
`@MappedSuperclass`) is deprecated and will throw an exception in 2.0.
Classes should only be annotated with a single document annotation.
* The `dropDups` option on the `@Index` annotation was deprecated and will be
dropped without replacement in 2.0. This functionality is no longer
available.

### XML mappings

* The `writeConcern` attribute in document mappings has been deprecated and
will be dropped in 2.0. Use `write-concern` instead.
* The `fieldName` attribute in field mappings has been deprecated and will be
dropped in 2.0. Use `field-name` instead.
* The `drop-dups` attribute in the `index` element was deprecated and will be
dropped without replacement in 2.0. This functionality is no longer
available.

### Full discriminator maps required

When using a discriminator map on a reference or embedded relationship,
persisting or loading a class that is not in the map is deprecated and will
cause an exception in 2.0. The discriminator map must contain all possible
classes that can be referenced or be omitted completely.

### Duplicate field names in mappings

Mapping two fields with the same name in the database is deprecated and will
cause an exception in 2.0. It is possible to have multiple fields with the same
name in the database as long as all but one of them have the `notSaved` option
set.

## Queries

* The `eagerCursor` method in `Doctrine\ODM\MongoDB\Query\Builder` was
deprecated and will be dropped in 2.0. This functionality is no longer
available.
* The `eager` option in `Doctrine\ODM\MongoDB\Query\Query` was deprecated and
will be dropped in 2.0. This functionality is no longer available.

## Schema manager

* The `timeout` option in the `odm:schema:create` and `odm:schema:update`
commands was deprecated and will be dropped in 2.0. Use the `maxTimeMs`
option instead.
* The `indexOptions` argument in the `ensureSharding` and
`ensureDocumentSharding` methods was deprecated and will be dropped in 2.0.
47 changes: 38 additions & 9 deletions docs/en/reference/annotations-reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,9 @@ Optional attributes:
-
collectionClass - A |FQCN| of class that implements ``Collection`` interface
and is used to hold documents. Doctrine's ``ArrayCollection`` is used by default.
-
``notSaved`` - The property is loaded if it exists in the database; however,
ODM will not save the property value back to the database.

.. code-block:: php
Expand Down Expand Up @@ -507,6 +510,9 @@ Optional attributes:
-
defaultDiscriminatorValue - A default value for discriminatorField if no value
has been set in the embedded document.
-
``notSaved`` - The property is loaded if it exists in the database; however,
ODM will not save the property value back to the database.

.. code-block:: php
Expand Down Expand Up @@ -600,6 +606,9 @@ Optional attributes:
nullable - By default, ODM will ``$unset`` fields in MongoDB if the PHP value
is null. Specify true for this option to force ODM to store a null value in
the database instead of unsetting the field.
-
``notSaved`` - The property is loaded if it exists in the database; however,
ODM will not save the property value back to the database.

Examples:

Expand Down Expand Up @@ -642,11 +651,11 @@ persisted, ODM will convert it to GridFSFile object automatically.
private $file;
Additional fields can be mapped in GridFS documents like any other, but metadata
fields set by the driver (e.g. ``length``) should be mapped with `@NotSaved`_ so
as not to inadvertently overwrite them. Some metadata fields, such as
``filename`` may be modified and do not require `@NotSaved`_. In the following
example, we also add a custom field to refer to the corresponding User document
that created the file.
fields set by the driver (e.g. ``length``) should be mapped with the
``NotSaved`` option so as not to inadvertently overwrite them. Some metadata
fields, such as ``filename`` may be modified and do not require ``NotSaved``. In
the following example, we also add a custom field to refer to the corresponding
User document that created the file.

.. code-block:: php
Expand All @@ -655,13 +664,13 @@ that created the file.
/** @Field(type="string") */
private $filename;
/** @NotSaved(type="int") */
/** @Field(type="int", notSaved=true) */
private $length;
/** @NotSaved(type="string") */
/** @Field(type="string", notSaved=true) */
private $md5;
/** @NotSaved(type="date") */
/** @Field(type="date", notSaved=true) */
private $uploadDate;
/** @ReferenceOne(targetDocument="Documents\User") */
Expand Down Expand Up @@ -977,9 +986,23 @@ MongoDB; however, ODM will not save the property value back to the database.
<?php
/** @NotSaved */
/**
* Legacy notation
* @NotSaved
*/
public $legacyField;
/**
* ODM 2.0 compatible notation
* @Field(notSaved=true)
*/
public $field;
.. note::

This annotation is deprecated. Use the `@Field`_ annotation with the
``notSaved`` option instead.

@PostLoad
---------

Expand Down Expand Up @@ -1292,6 +1315,9 @@ Optional attributes:
prime - A list of references contained in the target document that will be
initialized when the collection is loaded. Only allowed for inverse
references.
-
``notSaved`` - The property is loaded if it exists in the database; however,
ODM will not save the property value back to the database.

.. code-block:: php
Expand Down Expand Up @@ -1357,6 +1383,9 @@ Optional attributes:
limit - Limit for the query that loads the reference.
-
skip - Skip for the query that loads the reference.
-
``notSaved`` - The property is loaded if it exists in the database; however,
ODM will not save the property value back to the database.

.. code-block:: php
Expand Down
3 changes: 2 additions & 1 deletion docs/en/reference/indexes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ You can customize the index with some additional options:
too long.
-
**dropDups** - If a unique index is being created and duplicate
values exist, drop all but one duplicate value.
values exist, drop all but one duplicate value. This option is deprecated and
will be dropped without replacement in 2.0.
-
**background** - Create indexes in the background while other
operations are taking place. By default, index creation happens
Expand Down
6 changes: 3 additions & 3 deletions docs/en/reference/migrating-schemas.rst
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ Migrating your schema can be a difficult task, but Doctrine provides a few
different methods for dealing with it:

- **@AlsoLoad** - load values from old fields or transform data through methods
- **@NotSaved** - load values into fields without saving them again
- **@Field(notSaved=true)** - load values into fields without saving them again
- **@PostLoad** - execute code after all fields have been loaded
- **@PrePersist** - execute code before your document gets saved

Expand Down Expand Up @@ -166,10 +166,10 @@ Later on, you may want to migrate this data into an embedded Address document:
/** @Field(type="string") */
public $name;
/** @NotSaved */
/** @Field(notSaved=true) */
public $street;
/** @NotSaved */
/** @Field(notSaved=true) */
public $city;
/** @EmbedOne(targetDocument="Address") */
Expand Down
2 changes: 1 addition & 1 deletion docs/en/reference/query-builder-api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -642,7 +642,7 @@ document with a text index:
/** @Field(type="string") */
public $description;
/** @Field(type="float") @NotSaved */
/** @Field(type="float", notSaved=true) */
public $score;
}
Expand Down
1 change: 1 addition & 0 deletions doctrine-mongo-mapping.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,7 @@
<xs:element name="partial-filter-expression" type="odm:partial-filter-expression" minOccurs="0" maxOccurs="1"/>
</xs:choice>
<xs:attribute name="name" type="xs:NMTOKEN"/>
<!-- deprecated -->
<xs:attribute name="drop-dups" type="xs:boolean"/>
<xs:attribute name="background" type="xs:boolean"/>
<xs:attribute name="safe" type="xs:boolean"/>
Expand Down
84 changes: 59 additions & 25 deletions lib/Doctrine/ODM/MongoDB/DocumentManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
use Doctrine\ODM\MongoDB\Proxy\ProxyFactory;
use Doctrine\ODM\MongoDB\Query\FilterCollection;
use Doctrine\ODM\MongoDB\Repository\RepositoryFactory;
use const E_USER_DEPRECATED;
use function sprintf;
use function trigger_error;

/**
* The DocumentManager class is the central access point for managing the
Expand Down Expand Up @@ -729,39 +732,70 @@ public function createReference($document, array $referenceMapping)
throw new \InvalidArgumentException("Reference type {$storeAs} is invalid.");
}

/* If the class has a discriminator (field and value), use it. A child
* class that is not defined in the discriminator map may only have a
* discriminator field and no value, so default to the full class name.
*/
if (isset($class->discriminatorField)) {
$reference[$class->discriminatorField] = isset($class->discriminatorValue)
? $class->discriminatorValue
: $class->name;
return $reference + $this->getDiscriminatorData($referenceMapping, $class);
}

/**
* Build discriminator portion of reference for specified reference mapping and class metadata.
*
* @param array $referenceMapping Mappings of reference for which discriminator data is created.
* @param ClassMetadata $class Metadata of reference document class.
*
* @return array with next structure [{discriminator field} => {discriminator value}]
*
* @throws MappingException When discriminator map is present and reference class in not registered in it.
*/
private function getDiscriminatorData(array $referenceMapping, ClassMetadata $class)
{
$discriminatorField = null;
$discriminatorValue = null;
$discriminatorData = [];

if (isset($referenceMapping['discriminatorField'])) {
$discriminatorField = $referenceMapping['discriminatorField'];
if (isset($referenceMapping['discriminatorMap'])) {
$pos = array_search($class->name, $referenceMapping['discriminatorMap']);
if ($pos !== false) {
$discriminatorValue = $pos;
}
} else {
$discriminatorValue = $class->name;
}
} else {
$discriminatorField = $class->discriminatorField;
$discriminatorValue = isset($class->discriminatorValue) ? $class->discriminatorValue : $class->name;
}

/* Add a discriminator value if the referenced document is not mapped
* explicitly to a targetDocument class.
*/
if (! isset($referenceMapping['targetDocument'])) {
if ($discriminatorField !== null) {
if ($discriminatorValue === null) {
@trigger_error(sprintf('Document class "%s" is unlisted in the discriminator map for reference "%s". This is deprecated and will throw an exception in 2.0.', $class->name, $referenceMapping['name']), E_USER_DEPRECATED);
$discriminatorValue = $class->name;
}

$discriminatorData = [$discriminatorField => $discriminatorValue];
} elseif (! isset($referenceMapping['targetDocument'])) {
$discriminatorField = $referenceMapping['discriminatorField'];
$discriminatorValue = isset($referenceMapping['discriminatorMap'])
? array_search($class->name, $referenceMapping['discriminatorMap'])
: $class->name;

/* If the discriminator value was not found in the map, use the full
* class name. In the future, it may be preferable to throw an
* exception here (perhaps based on some strictness option).
*
* @see PersistenceBuilder::prepareEmbeddedDocumentValue()
*/
if ($discriminatorValue === false) {

$discriminatorMap = null;
if (isset($referenceMapping['discriminatorMap'])) {
$discriminatorMap = $referenceMapping['discriminatorMap'];
}

if ($discriminatorMap === null) {
$discriminatorValue = $class->name;
} else {
$discriminatorValue = array_search($class->name, $discriminatorMap);

if ($discriminatorValue === false) {
@trigger_error(sprintf('Document class "%s" is unlisted in the discriminator map for reference "%s". This is deprecated and will throw an exception in 2.0.', $class->name, $referenceMapping['name']), E_USER_DEPRECATED);
$discriminatorValue = $class->name;
}
}

$reference[$discriminatorField] = $discriminatorValue;
$discriminatorData = [$discriminatorField => $discriminatorValue];
}

return $reference;
return $discriminatorData;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ abstract class AbstractField extends Annotation
public $options = array();
public $strategy;

/** @var bool */
public $notSaved = false;

/**
* Gets deprecation message. The method *WILL* be removed in 2.0.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ abstract class AbstractIndex extends Annotation
{
public $keys = array();
public $name;
/** @deprecated */
public $dropDups;
public $background;
public $safe;
Expand Down
11 changes: 11 additions & 0 deletions lib/Doctrine/ODM/MongoDB/Mapping/Annotations/NotSaved.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,19 @@
* Specifies that a field will not be written to the database
*
* @Annotation
* @deprecated This class will be removed in ODM 2.0. Use `@ODM\Field(notSaved=true)` instead.
*/
final class NotSaved extends AbstractField
{
public $notSaved = true;

public function isDeprecated()
{
return true;
}

public function getDeprecationMessage()
{
return sprintf('%s will be removed in ODM 2.0. Use `@ODM\Field(notSaved="true")` instead.', get_class($this));
}
}
Loading

0 comments on commit 30f3c96

Please sign in to comment.