Skip to content
This repository has been archived by the owner on Nov 11, 2020. It is now read-only.

Commit

Permalink
Improve find/update events and use MutableEventArgs for post listeners
Browse files Browse the repository at this point in the history
With the addition of FindEventArgs, find events will not receive the field projection in addition to the query. UpdateEventArgs now has options.

A new MutableEventArgs class was created to allow Collection query/command results to be modified by the post event listeners (as requested in #94).

Finally, CollectionEventsTest was created to test all pre/post events dispatched by Collection methods.
  • Loading branch information
jmikola committed May 30, 2013
1 parent 41236a7 commit 161be2d
Show file tree
Hide file tree
Showing 10 changed files with 630 additions and 87 deletions.
76 changes: 52 additions & 24 deletions lib/Doctrine/MongoDB/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@
use Doctrine\MongoDB\Event\AggregateEventArgs;
use Doctrine\MongoDB\Event\DistinctEventArgs;
use Doctrine\MongoDB\Event\EventArgs;
use Doctrine\MongoDB\Event\FindEventArgs;
use Doctrine\MongoDB\Event\GroupEventArgs;
use Doctrine\MongoDB\Event\MapReduceEventArgs;
use Doctrine\MongoDB\Event\MutableEventArgs;
use Doctrine\MongoDB\Event\NearEventArgs;
use Doctrine\MongoDB\Event\UpdateEventArgs;
use Doctrine\MongoDB\Util\ReadPreference;
Expand Down Expand Up @@ -178,7 +180,9 @@ public function aggregate(array $pipeline /* , array $op, ... */)
$result = $this->doAggregate($pipeline);

if ($this->eventManager->hasListeners(Events::postAggregate)) {
$this->eventManager->dispatchEvent(Events::postAggregate, new EventArgs($this, $result));
$eventArgs = new MutableEventArgs($this, $result);
$this->eventManager->dispatchEvent(Events::postAggregate, $eventArgs);
$result = $eventArgs->getData();
}

return $result;
Expand Down Expand Up @@ -206,13 +210,15 @@ protected function doAggregate(array $pipeline)
public function batchInsert(array &$a, array $options = array())
{
if ($this->eventManager->hasListeners(Events::preBatchInsert)) {
$this->eventManager->dispatchEvent(Events::preBatchInsert, new EventArgs($this, $a));
$this->eventManager->dispatchEvent(Events::preBatchInsert, new EventArgs($this, $a, $options));
}

$result = $this->doBatchInsert($a, $options);

if ($this->eventManager->hasListeners(Events::postBatchInsert)) {
$this->eventManager->dispatchEvent(Events::postBatchInsert, new EventArgs($this, $result));
$eventArgs = new MutableEventArgs($this, $result);
$this->eventManager->dispatchEvent(Events::postBatchInsert, $eventArgs);
$result = $eventArgs->getData();
}

return $result;
Expand Down Expand Up @@ -257,13 +263,15 @@ public function upsert($query, array $newObj, array $options = array())
public function find(array $query = array(), array $fields = array())
{
if ($this->eventManager->hasListeners(Events::preFind)) {
$this->eventManager->dispatchEvent(Events::preFind, new EventArgs($this, $query));
$this->eventManager->dispatchEvent(Events::preFind, new FindEventArgs($this, $query, $fields));
}

$result = $this->doFind($query, $fields);

if ($this->eventManager->hasListeners(Events::postFind)) {
$this->eventManager->dispatchEvent(Events::postFind, new EventArgs($this, $result));
$eventArgs = new MutableEventArgs($this, $result);
$this->eventManager->dispatchEvent(Events::postFind, $eventArgs);
$result = $eventArgs->getData();
}

return $result;
Expand All @@ -287,13 +295,15 @@ protected function wrapCursor(\MongoCursor $cursor, $query, $fields)
public function findOne(array $query = array(), array $fields = array())
{
if ($this->eventManager->hasListeners(Events::preFindOne)) {
$this->eventManager->dispatchEvent(Events::preFindOne, new EventArgs($this, $query));
$this->eventManager->dispatchEvent(Events::preFindOne, new FindEventArgs($this, $query, $fields));
}

$result = $this->doFindOne($query, $fields);

if ($this->eventManager->hasListeners(Events::postFindOne)) {
$this->eventManager->dispatchEvent(Events::postFindOne, new EventArgs($this, $result));
$eventArgs = new MutableEventArgs($this, $result);
$this->eventManager->dispatchEvent(Events::postFindOne, $eventArgs);
$result = $eventArgs->getData();
}

return $result;
Expand All @@ -310,16 +320,18 @@ protected function doFindOne(array $query, array $fields)
public function findAndRemove(array $query, array $options = array())
{
if ($this->eventManager->hasListeners(Events::preFindAndRemove)) {
$this->eventManager->dispatchEvent(Events::preFindAndRemove, new EventArgs($this, $query));
$this->eventManager->dispatchEvent(Events::preFindAndRemove, new EventArgs($this, $query, $options));
}

$document = $this->doFindAndRemove($query, $options);
$result = $this->doFindAndRemove($query, $options);

if ($this->eventManager->hasListeners(Events::postFindAndRemove)) {
$this->eventManager->dispatchEvent(Events::postFindAndRemove, new EventArgs($this, $document));
$eventArgs = new MutableEventArgs($this, $result);
$this->eventManager->dispatchEvent(Events::postFindAndRemove, $eventArgs);
$result = $eventArgs->getData();
}

return $document;
return $result;
}

protected function doFindAndRemove(array $query, array $options = array())
Expand All @@ -341,13 +353,15 @@ public function findAndUpdate(array $query, array $newObj, array $options = arra
$this->eventManager->dispatchEvent(Events::preFindAndUpdate, new UpdateEventArgs($this, $query, $newObj, $options));
}

$document = $this->doFindAndUpdate($query, $newObj, $options);
$result = $this->doFindAndUpdate($query, $newObj, $options);

if ($this->eventManager->hasListeners(Events::postFindAndUpdate)) {
$this->eventManager->dispatchEvent(Events::postFindAndUpdate, new EventArgs($this, $document));
$eventArgs = new MutableEventArgs($this, $result);
$this->eventManager->dispatchEvent(Events::postFindAndUpdate, $eventArgs);
$result = $eventArgs->getData();
}

return $document;
return $result;
}

protected function doFindAndUpdate(array $query, array $newObj, array $options)
Expand All @@ -371,7 +385,9 @@ public function near(array $near, array $query = array(), array $options = array
$result = $this->doNear($near, $query, $options);

if ($this->eventManager->hasListeners(Events::postNear)) {
$this->eventManager->dispatchEvent(Events::postNear, new EventArgs($this, $result));
$eventArgs = new MutableEventArgs($this, $result);
$this->eventManager->dispatchEvent(Events::postNear, $eventArgs);
$result = $eventArgs->getData();
}

return $result;
Expand Down Expand Up @@ -404,7 +420,9 @@ public function distinct($field, array $query = array(), array $options = array(
$result = $this->doDistinct($field, $query, $options);

if ($this->eventManager->hasListeners(Events::postDistinct)) {
$this->eventManager->dispatchEvent(Events::postDistinct, new EventArgs($this, $result));
$eventArgs = new MutableEventArgs($this, $result);
$this->eventManager->dispatchEvent(Events::postDistinct, $eventArgs);
$result = $eventArgs->getData();
}

return $result;
Expand Down Expand Up @@ -434,7 +452,9 @@ public function mapReduce($map, $reduce, array $out = array('inline' => true), a
$result = $this->doMapReduce($map, $reduce, $out, $query, $options);

if ($this->eventManager->hasListeners(Events::postMapReduce)) {
$this->eventManager->dispatchEvent(Events::postMapReduce, new EventArgs($this, $result));
$eventArgs = new MutableEventArgs($this, $result);
$this->eventManager->dispatchEvent(Events::postMapReduce, $eventArgs);
$result = $eventArgs->getData();
}

return $result;
Expand Down Expand Up @@ -546,7 +566,9 @@ public function getDBRef(array $reference)
$result = $this->doGetDBRef($reference);

if ($this->eventManager->hasListeners(Events::postGetDBRef)) {
$this->eventManager->dispatchEvent(Events::postGetDBRef, new EventArgs($this, $result));
$eventArgs = new MutableEventArgs($this, $result);
$this->eventManager->dispatchEvent(Events::postGetDBRef, $eventArgs);
$result = $eventArgs->getData();
}

return $result;
Expand All @@ -569,7 +591,9 @@ public function group($keys, array $initial, $reduce, array $options = array())
$result = $this->doGroup($keys, $initial, $reduce, $options);

if ($this->eventManager->hasListeners(Events::postGroup)) {
$this->eventManager->dispatchEvent(Events::postGroup, new EventArgs($this, $result));
$eventArgs = new MutableEventArgs($this, $result);
$this->eventManager->dispatchEvent(Events::postGroup, $eventArgs);
$result = $eventArgs->getData();
}

return $result;
Expand Down Expand Up @@ -602,13 +626,15 @@ protected function doGroup($keys, array $initial, $reduce, array $options)
public function insert(array &$a, array $options = array())
{
if ($this->eventManager->hasListeners(Events::preInsert)) {
$this->eventManager->dispatchEvent(Events::preInsert, new EventArgs($this, $a));
$this->eventManager->dispatchEvent(Events::preInsert, new EventArgs($this, $a, $options));
}

$result = $this->doInsert($a, $options);

if ($this->eventManager->hasListeners(Events::postInsert)) {
$this->eventManager->dispatchEvent(Events::postInsert, new EventArgs($this, $result));
$eventArgs = new MutableEventArgs($this, $result);
$this->eventManager->dispatchEvent(Events::postInsert, $eventArgs);
$result = $eventArgs->getData();
}
return $result;
}
Expand All @@ -626,7 +652,7 @@ protected function doInsert(array &$a, array $options)
public function remove(array $query, array $options = array())
{
if ($this->eventManager->hasListeners(Events::preRemove)) {
$this->eventManager->dispatchEvent(Events::preRemove, new EventArgs($this, $query));
$this->eventManager->dispatchEvent(Events::preRemove, new EventArgs($this, $query, $options));
}

$result = $this->doRemove($query, $options);
Expand All @@ -646,13 +672,15 @@ protected function doRemove(array $query, array $options)
public function save(array &$a, array $options = array())
{
if ($this->eventManager->hasListeners(Events::preSave)) {
$this->eventManager->dispatchEvent(Events::preSave, new EventArgs($this, $a));
$this->eventManager->dispatchEvent(Events::preSave, new EventArgs($this, $a, $options));
}

$result = $this->doSave($a, $options);

if ($this->eventManager->hasListeners(Events::postSave)) {
$this->eventManager->dispatchEvent(Events::postSave, new EventArgs($this, $result));
$eventArgs = new MutableEventArgs($this, $result);
$this->eventManager->dispatchEvent(Events::postSave, $eventArgs);
$result = $eventArgs->getData();
}

return $result;
Expand Down
11 changes: 9 additions & 2 deletions lib/Doctrine/MongoDB/Event/EventArgs.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
use Doctrine\Common\EventArgs as BaseEventArgs;

/**
* Event args.
* Event args for generic queries.
*
* @license http://www.opensource.org/licenses/mit-license.php MIT
* @link www.doctrine-project.com
Expand All @@ -33,11 +33,13 @@ class EventArgs extends BaseEventArgs
{
private $invoker;
private $data;
private $options;

public function __construct($invoker, $data = null)
public function __construct($invoker, $data = null, array $options = array())
{
$this->invoker = $invoker;
$this->data = $data;
$this->options = $options;
}

public function getInvoker()
Expand All @@ -49,4 +51,9 @@ public function getData()
{
return $this->data;
}

public function getOptions()
{
return $this->options;
}
}
59 changes: 59 additions & 0 deletions lib/Doctrine/MongoDB/Event/FindEventArgs.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/

namespace Doctrine\MongoDB\Event;

use Doctrine\Common\EventArgs as BaseEventArgs;

/**
* Event args for find queries.
*
* @license http://www.opensource.org/licenses/mit-license.php MIT
* @link www.doctrine-project.com
* @since 1.1
* @author Jeremy Mikola <[email protected]>
*/
class FindEventArgs extends BaseEventArgs
{
private $invoker;
private $query;
private $fields;

public function __construct($invoker, array $query, array $fields)
{
$this->invoker = $invoker;
$this->query = $query;
$this->fields = $fields;
}

public function getInvoker()
{
return $this->invoker;
}

public function getQuery()
{
return $this->query;
}

public function getFields()
{
return $this->fields;
}
}
50 changes: 50 additions & 0 deletions lib/Doctrine/MongoDB/Event/MutableEventArgs.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/

namespace Doctrine\MongoDB\Event;

/**
* Mutable event args for query and command results.
*
* @license http://www.opensource.org/licenses/mit-license.php MIT
* @link www.doctrine-project.com
* @since 1.1
* @author Jeremy Mikola <[email protected]>
*/
class MutableEventArgs extends EventArgs
{
private $changedData;
private $isDataChanged = false;

public function getData()
{
return $this->isDataChanged ? $this->changedData : parent::getData();
}

public function setData($data)
{
$this->isDataChanged = parent::getData() !== $data;
$this->changedData = $this->isDataChanged ? $data : null;
}

public function isDataChanged()
{
return $this->isDataChanged;
}
}
2 changes: 1 addition & 1 deletion lib/Doctrine/MongoDB/Event/UpdateEventArgs.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
use Doctrine\Common\EventArgs as BaseEventArgs;

/**
* Update event args.
* Event args for update queries.
*
* @license http://www.opensource.org/licenses/mit-license.php MIT
* @link www.doctrine-project.com
Expand Down
Loading

0 comments on commit 161be2d

Please sign in to comment.