merged branch jmikola/2.1-mongoclient (PR #6338)

This PR was merged into the 2.1 branch.

Commits
-------

f24e3d7 [HttpKernel] Revise MongoDbProfilerStorage::write() return value
78c5273 [Session] Document Mongo|MongoClient argument type instead of "object"
de19a81 [HttpKernel] Support MongoClient and Mongo connection classes
b28af77 [Session] Support MongoClient and Mongo connection classes
20e93bf [Session] Utilize MongoDB::selectCollection()

Discussion
----------

[2.1] Support PHP MongoDB driver 1.3.0+ in profiler/session classes

> Bug fix: yes
> Feature addition: yes
> Backwards compatibility break: no
> Symfony2 tests pass: yes
> Fixes the following tickets: #6130
> License of the code: MIT

I don't believe this is a BC break, but just to confirm:  the MongoDbSessionHandler constructor signature changed, as I removed the `Mongo` type hint.

Bug fix entails allowing MongoClient to be used by default if the new driver is available, since the original Mongo class is deprecated. I also removed the assumption about `MongoCollection::update()`'s return value, since it may be a status array now.

---------------------------------------------------------------------------

by jmikola at 2012-12-13T22:04:47Z

Lots of test failures, but they appear to be unrelated.
This commit is contained in:
Fabien Potencier 2012-12-14 08:19:02 +01:00
commit c6bd807726
3 changed files with 42 additions and 50 deletions

View File

@ -36,13 +36,18 @@ class MongoDbSessionHandler implements \SessionHandlerInterface
/**
* Constructor.
*
* @param \Mongo $mongo A "Mongo" instance
* @param array $options An associative array of field options
* @param \Mongo|\MongoClient $mongo A MongoClient or Mongo instance
* @param array $options An associative array of field options
*
* @throws \InvalidArgumentException When MongoClient or Mongo instance not provided
* @throws \InvalidArgumentException When "database" or "collection" not provided
*/
public function __construct(\Mongo $mongo, array $options)
public function __construct($mongo, array $options)
{
if (!($mongo instanceof \MongoClient || $mongo instanceof \Mongo)) {
throw new \InvalidArgumentException('MongoClient or Mongo instance required');
}
if (!isset($options['database']) || !isset($options['collection'])) {
throw new \InvalidArgumentException('You must provide the "database" and "collection" option for MongoDBSessionHandler');
}
@ -137,7 +142,7 @@ class MongoDbSessionHandler implements \SessionHandlerInterface
private function getCollection()
{
if (null === $this->collection) {
$this->collection = $this->mongo->selectDB($this->options['database'])->selectCollection($this->options['collection']);
$this->collection = $this->mongo->selectCollection($this->options['database'], $this->options['collection']);
}
return $this->collection;

View File

@ -27,11 +27,13 @@ class MongoDbSessionHandlerTest extends \PHPUnit_Framework_TestCase
protected function setUp()
{
if (!class_exists('\Mongo')) {
$this->markTestSkipped('MongoDbSessionHandler requires the php "mongo" extension');
if (!extension_loaded('mongo')) {
$this->markTestSkipped('MongoDbSessionHandler requires the PHP "mongo" extension.');
}
$this->mongo = $this->getMockBuilder('Mongo')
$mongoClass = (version_compare(phpversion('mongo'), '1.3.0', '<')) ? 'Mongo' : 'MongoClient';
$this->mongo = $this->getMockBuilder($mongoClass)
->disableOriginalConstructor()
->getMock();
@ -46,6 +48,22 @@ class MongoDbSessionHandlerTest extends \PHPUnit_Framework_TestCase
$this->storage = new MongoDbSessionHandler($this->mongo, $this->options);
}
/**
* @expectedException InvalidArgumentException
*/
public function testConstructorShouldThrowExceptionForInvalidMongo()
{
new MongoDbSessionHandler(new \stdClass(), $this->options);
}
/**
* @expectedException InvalidArgumentException
*/
public function testConstructorShouldThrowExceptionForMissingOptions()
{
new MongoDbSessionHandler($this->mongo, array());
}
public function testOpenMethodAlwaysReturnTrue()
{
$this->assertTrue($this->storage->open('test', 'test'), 'The "open" method should always return true');
@ -58,22 +76,13 @@ class MongoDbSessionHandlerTest extends \PHPUnit_Framework_TestCase
public function testWrite()
{
$database = $this->getMockBuilder('MongoDB')
->disableOriginalConstructor()
->getMock();
$collection = $this->getMockBuilder('MongoCollection')
->disableOriginalConstructor()
->getMock();
$this->mongo->expects($this->once())
->method('selectDB')
->with($this->options['database'])
->will($this->returnValue($database));
$database->expects($this->once())
->method('selectCollection')
->with($this->options['collection'])
->with($this->options['database'], $this->options['collection'])
->will($this->returnValue($collection));
$that = $this;
@ -96,22 +105,13 @@ class MongoDbSessionHandlerTest extends \PHPUnit_Framework_TestCase
public function testReplaceSessionData()
{
$database = $this->getMockBuilder('MongoDB')
->disableOriginalConstructor()
->getMock();
$collection = $this->getMockBuilder('MongoCollection')
->disableOriginalConstructor()
->getMock();
$this->mongo->expects($this->once())
->method('selectDB')
->with($this->options['database'])
->will($this->returnValue($database));
$database->expects($this->once())
->method('selectCollection')
->with($this->options['collection'])
->with($this->options['database'], $this->options['collection'])
->will($this->returnValue($collection));
$data = array();
@ -130,22 +130,13 @@ class MongoDbSessionHandlerTest extends \PHPUnit_Framework_TestCase
public function testDestroy()
{
$database = $this->getMockBuilder('MongoDB')
->disableOriginalConstructor()
->getMock();
$collection = $this->getMockBuilder('MongoCollection')
->disableOriginalConstructor()
->getMock();
$this->mongo->expects($this->once())
->method('selectDB')
->with($this->options['database'])
->will($this->returnValue($database));
$database->expects($this->once())
->method('selectCollection')
->with($this->options['collection'])
->with($this->options['database'], $this->options['collection'])
->will($this->returnValue($collection));
$collection->expects($this->once())
@ -160,22 +151,13 @@ class MongoDbSessionHandlerTest extends \PHPUnit_Framework_TestCase
public function testGc()
{
$database = $this->getMockBuilder('MongoDB')
->disableOriginalConstructor()
->getMock();
$collection = $this->getMockBuilder('MongoCollection')
->disableOriginalConstructor()
->getMock();
$this->mongo->expects($this->once())
->method('selectDB')
->with($this->options['database'])
->will($this->returnValue($database));
$database->expects($this->once())
->method('selectCollection')
->with($this->options['collection'])
->with($this->options['database'], $this->options['collection'])
->will($this->returnValue($collection));
$that = $this;

View File

@ -102,7 +102,9 @@ class MongoDbProfilerStorage implements ProfilerStorageInterface
'time' => $profile->getTime()
);
return $this->getMongo()->update(array('_id' => $profile->getToken()), array_filter($record, function ($v) { return !empty($v); }), array('upsert' => true));
$result = $this->getMongo()->update(array('_id' => $profile->getToken()), array_filter($record, function ($v) { return !empty($v); }), array('upsert' => true));
return (boolean) (isset($result['ok']) ? $result['ok'] : $result);
}
/**
@ -114,12 +116,15 @@ class MongoDbProfilerStorage implements ProfilerStorageInterface
{
if ($this->mongo === null) {
if (preg_match('#^(mongodb://.*)/(.*)/(.*)$#', $this->dsn, $matches)) {
$mongo = new \Mongo($matches[1] . (!empty($matches[2]) ? '/' . $matches[2] : ''));
$server = $matches[1] . (!empty($matches[2]) ? '/' . $matches[2] : '');
$database = $matches[2];
$collection = $matches[3];
$mongoClass = (version_compare(phpversion('mongo'), '1.3.0', '<')) ? '\Mongo' : '\MongoClient';
$mongo = new $mongoClass($server);
$this->mongo = $mongo->selectCollection($database, $collection);
} else {
throw new \RuntimeException(sprintf('Please check your configuration. You are trying to use MongoDB with an invalid dsn "%s". The expected format is "mongodb://user:pass@location/database/collection"', $this->dsn));
throw new \RuntimeException(sprintf('Please check your configuration. You are trying to use MongoDB with an invalid dsn "%s". The expected format is "mongodb://[user:pass@]host/database/collection"', $this->dsn));
}
}