Commit 68acf014 authored by Jeremy Mikola's avatar Jeremy Mikola

PHPLIB-144: Use arrays to take Database and Collection options

If we've learned anything from the legacy driver, it's that options arrays will prove more flexible than nullable, positional arguments in the long run.
parent be188e3e
...@@ -75,40 +75,45 @@ class Client ...@@ -75,40 +75,45 @@ class Client
/** /**
* Select a collection. * Select a collection.
* *
* If a write concern or read preference is not specified, the write concern * Supported options:
* or read preference of the Client will be applied, respectively.
* *
* @param string $databaseName Name of the database containing the collection * * readPreference (MongoDB\Driver\ReadPreference): The default read
* @param string $collectionName Name of the collection to select * preference to use for collection operations. Defaults to the Client's
* @param WriteConcern $writeConcern Default write concern to apply * read preference.
* @param ReadPreference $readPreference Default read preference to apply *
* * writeConcern (MongoDB\Driver\WriteConcern): The default write concern
* to use for collection operations. Defaults to the Client's write
* concern.
*
* @param string $databaseName Name of the database containing the collection
* @param string $collectionName Name of the collection to select
* @param array $options Collection constructor options
* @return Collection * @return Collection
*/ */
public function selectCollection($databaseName, $collectionName, WriteConcern $writeConcern = null, ReadPreference $readPreference = null) public function selectCollection($databaseName, $collectionName, array $options = [])
{ {
$namespace = $databaseName . '.' . $collectionName; return new Collection($this->manager, $databaseName . '.' . $collectionName, $options);
$writeConcern = $writeConcern ?: $this->manager->getWriteConcern();
$readPreference = $readPreference ?: $this->manager->getReadPreference();
return new Collection($this->manager, $namespace, $writeConcern, $readPreference);
} }
/** /**
* Select a database. * Select a database.
* *
* If a write concern or read preference is not specified, the write concern * Supported options:
* or read preference of the Client will be applied, respectively.
* *
* @param string $databaseName Name of the database to select * * readPreference (MongoDB\Driver\ReadPreference): The default read
* @param WriteConcern $writeConcern Default write concern to apply * preference to use for database operations and selected collections.
* @param ReadPreference $readPreference Default read preference to apply * Defaults to the Client's read preference.
*
* * writeConcern (MongoDB\Driver\WriteConcern): The default write concern
* to use for database operations and selected collections. Defaults to
* the Client's write concern.
*
* @param string $databaseName Name of the database to select
* @param array $options Database constructor options
* @return Database * @return Database
*/ */
public function selectDatabase($databaseName, WriteConcern $writeConcern = null, ReadPreference $readPreference = null) public function selectDatabase($databaseName, array $options = [])
{ {
$writeConcern = $writeConcern ?: $this->manager->getWriteConcern(); return new Database($this->manager, $databaseName, $options);
$readPreference = $readPreference ?: $this->manager->getReadPreference();
return new Database($this->manager, $databaseName, $writeConcern, $readPreference);
} }
} }
...@@ -9,6 +9,7 @@ use MongoDB\Driver\ReadPreference; ...@@ -9,6 +9,7 @@ use MongoDB\Driver\ReadPreference;
use MongoDB\Driver\Server; use MongoDB\Driver\Server;
use MongoDB\Driver\WriteConcern; use MongoDB\Driver\WriteConcern;
use MongoDB\Exception\InvalidArgumentException; use MongoDB\Exception\InvalidArgumentException;
use MongoDB\Exception\InvalidArgumentTypeException;
use MongoDB\Exception\UnexpectedTypeException; use MongoDB\Exception\UnexpectedTypeException;
use MongoDB\Model\IndexInfoIterator; use MongoDB\Model\IndexInfoIterator;
use MongoDB\Model\IndexInput; use MongoDB\Model\IndexInput;
...@@ -48,13 +49,22 @@ class Collection ...@@ -48,13 +49,22 @@ class Collection
* This class provides methods for collection-specific operations, such as * This class provides methods for collection-specific operations, such as
* CRUD (i.e. create, read, update, and delete) and index management. * CRUD (i.e. create, read, update, and delete) and index management.
* *
* @param Manager $manager Manager instance from the driver * Supported options:
* @param string $namespace Collection namespace (e.g. "db.collection") *
* @param WriteConcern $writeConcern Default write concern to apply * * readPreference (MongoDB\Driver\ReadPreference): The default read
* @param ReadPreference $readPreference Default read preference to apply * preference to use for collection operations. Defaults to the Manager's
* @throws InvalidArgumentException if $namespace is invalid * read preference.
*
* * writeConcern (MongoDB\Driver\WriteConcern): The default write concern
* to use for collection operations. Defaults to the Manager's write
* concern.
*
* @param Manager $manager Manager instance from the driver
* @param string $namespace Collection namespace (e.g. "db.collection")
* @param array $options Collection options
* @throws InvalidArgumentException
*/ */
public function __construct(Manager $manager, $namespace, WriteConcern $writeConcern = null, ReadPreference $readPreference = null) public function __construct(Manager $manager, $namespace, array $options = [])
{ {
$parts = explode('.', $namespace, 2); $parts = explode('.', $namespace, 2);
...@@ -65,13 +75,21 @@ class Collection ...@@ -65,13 +75,21 @@ class Collection
$this->databaseName = $parts[0]; $this->databaseName = $parts[0];
$this->collectionName = $parts[1]; $this->collectionName = $parts[1];
if (isset($options['readPreference']) && ! $options['readPreference'] instanceof ReadPreference) {
throw new InvalidArgumentTypeException('"readPreference" option', $options['readPreference'], 'MongoDB\Driver\ReadPreference');
}
if (isset($options['writeConcern']) && ! $options['writeConcern'] instanceof WriteConcern) {
throw new InvalidArgumentTypeException('"writeConcern" option', $options['writeConcern'], 'MongoDB\Driver\WriteConcern');
}
$this->manager = $manager; $this->manager = $manager;
$this->writeConcern = $writeConcern ?: $this->manager->getWriteConcern(); $this->readPreference = isset($options['readPreference']) ? $options['readPreference'] : $this->manager->getReadPreference();
$this->readPreference = $readPreference ?: $this->manager->getReadPreference(); $this->writeConcern = isset($options['writeConcern']) ? $options['writeConcern'] : $this->manager->getWriteConcern();
} }
/** /**
* Return the collection namespace. * Return the collection namespace (e.g. "db.collection").
* *
* @param string * @param string
*/ */
......
...@@ -11,6 +11,7 @@ use MongoDB\Driver\ReadPreference; ...@@ -11,6 +11,7 @@ use MongoDB\Driver\ReadPreference;
use MongoDB\Driver\Server; use MongoDB\Driver\Server;
use MongoDB\Driver\WriteConcern; use MongoDB\Driver\WriteConcern;
use MongoDB\Exception\InvalidArgumentException; use MongoDB\Exception\InvalidArgumentException;
use MongoDB\Exception\InvalidArgumentTypeException;
use MongoDB\Model\CollectionInfoIterator; use MongoDB\Model\CollectionInfoIterator;
use MongoDB\Operation\CreateCollection; use MongoDB\Operation\CreateCollection;
use MongoDB\Operation\DropCollection; use MongoDB\Operation\DropCollection;
...@@ -30,22 +31,39 @@ class Database ...@@ -30,22 +31,39 @@ class Database
* This class provides methods for database-specific operations and serves * This class provides methods for database-specific operations and serves
* as a gateway for accessing collections. * as a gateway for accessing collections.
* *
* @param Manager $manager Manager instance from the driver * Supported options:
* @param string $databaseName Database name *
* @param WriteConcern $writeConcern Default write concern to apply * * readPreference (MongoDB\Driver\ReadPreference): The default read
* @param ReadPreference $readPreference Default read preference to apply * preference to use for database operations and selected collections.
* @throws InvalidArgumentException if $databaseName is invalid * Defaults to the Manager's read preference.
*
* * writeConcern (MongoDB\Driver\WriteConcern): The default write concern
* to use for database operations and selected collections. Defaults to
* the Manager's write concern.
*
* @param Manager $manager Manager instance from the driver
* @param string $databaseName Database name
* @param array $options Database options
* @throws InvalidArgumentException
*/ */
public function __construct(Manager $manager, $databaseName, WriteConcern $writeConcern = null, ReadPreference $readPreference = null) public function __construct(Manager $manager, $databaseName, array $options = [])
{ {
if (strlen($databaseName) < 1) { if (strlen($databaseName) < 1) {
throw new InvalidArgumentException('$databaseName is invalid: ' . $databaseName); throw new InvalidArgumentException('$databaseName is invalid: ' . $databaseName);
} }
if (isset($options['readPreference']) && ! $options['readPreference'] instanceof ReadPreference) {
throw new InvalidArgumentTypeException('"readPreference" option', $options['readPreference'], 'MongoDB\Driver\ReadPreference');
}
if (isset($options['writeConcern']) && ! $options['writeConcern'] instanceof WriteConcern) {
throw new InvalidArgumentTypeException('"writeConcern" option', $options['writeConcern'], 'MongoDB\Driver\WriteConcern');
}
$this->manager = $manager; $this->manager = $manager;
$this->databaseName = (string) $databaseName; $this->databaseName = (string) $databaseName;
$this->writeConcern = $writeConcern ?: $this->manager->getWriteConcern(); $this->readPreference = isset($options['readPreference']) ? $options['readPreference'] : $this->manager->getReadPreference();
$this->readPreference = $readPreference ?: $this->manager->getReadPreference(); $this->writeConcern = isset($options['writeConcern']) ? $options['writeConcern'] : $this->manager->getWriteConcern();
} }
/** /**
...@@ -129,20 +147,30 @@ class Database ...@@ -129,20 +147,30 @@ class Database
/** /**
* Select a collection within this database. * Select a collection within this database.
* *
* If a write concern or read preference is not specified, the write concern * Supported options:
* or read preference of the Database will be applied, respectively. *
* * readPreference (MongoDB\Driver\ReadPreference): The default read
* preference to use for collection operations. Defaults to the
* Database's read preference.
*
* * writeConcern (MongoDB\Driver\WriteConcern): The default write concern
* to use for collection operations. Defaults to the Database's write
* concern.
* *
* @param string $collectionName Name of the collection to select * @param string $collectionName Name of the collection to select
* @param WriteConcern $writeConcern Default write concern to apply * @param array $options Collection constructor options
* @param ReadPreference $readPreference Default read preference to apply
* @return Collection * @return Collection
*/ */
public function selectCollection($collectionName, WriteConcern $writeConcern = null, ReadPreference $readPreference = null) public function selectCollection($collectionName, array $options = [])
{ {
$namespace = $this->databaseName . '.' . $collectionName; if ( ! isset($options['readPreference'])) {
$writeConcern = $writeConcern ?: $this->writeConcern; $options['readPreference'] = $this->readPreference;
$readPreference = $readPreference ?: $this->readPreference; }
if ( ! isset($options['writeConcern'])) {
$options['writeConcern'] = $this->writeConcern;
}
return new Collection($this->manager, $namespace, $writeConcern, $readPreference); return new Collection($this->manager, $this->databaseName . '.' . $collectionName, $options);
} }
} }
...@@ -31,6 +31,30 @@ class CollectionFunctionalTest extends FunctionalTestCase ...@@ -31,6 +31,30 @@ class CollectionFunctionalTest extends FunctionalTestCase
]; ];
} }
/**
* @expectedException MongoDB\Exception\InvalidArgumentTypeException
* @dataProvider provideInvalidConstructorOptions
*/
public function testConstructorOptionTypeChecks(array $options)
{
new Collection($this->manager, $this->getNamespace(), $options);
}
public function provideInvalidConstructorOptions()
{
$options = [];
foreach ($this->getInvalidReadPreferenceValues() as $value) {
$options[][] = ['readPreference' => $value];
}
foreach ($this->getInvalidWriteConcernValues() as $value) {
$options[][] = ['writeConcern' => $value];
}
return $options;
}
public function testToString() public function testToString()
{ {
$this->assertEquals($this->getNamespace(), (string) $this->collection); $this->assertEquals($this->getNamespace(), (string) $this->collection);
......
...@@ -28,6 +28,30 @@ class DatabaseFunctionalTest extends FunctionalTestCase ...@@ -28,6 +28,30 @@ class DatabaseFunctionalTest extends FunctionalTestCase
]; ];
} }
/**
* @expectedException MongoDB\Exception\InvalidArgumentTypeException
* @dataProvider provideInvalidConstructorOptions
*/
public function testConstructorOptionTypeChecks(array $options)
{
new Database($this->manager, $this->getDatabaseName(), $options);
}
public function provideInvalidConstructorOptions()
{
$options = [];
foreach ($this->getInvalidReadPreferenceValues() as $value) {
$options[][] = ['readPreference' => $value];
}
foreach ($this->getInvalidWriteConcernValues() as $value) {
$options[][] = ['writeConcern' => $value];
}
return $options;
}
public function testToString() public function testToString()
{ {
$this->assertEquals($this->getDatabaseName(), (string) $this->database); $this->assertEquals($this->getDatabaseName(), (string) $this->database);
......
...@@ -45,16 +45,6 @@ abstract class TestCase extends BaseTestCase ...@@ -45,16 +45,6 @@ abstract class TestCase extends BaseTestCase
return [123, 3.14, true, [], new stdClass]; return [123, 3.14, true, [], new stdClass];
} }
protected function getInvalidReadPreferenceValues()
{
return [123, 3.14, 'foo', true, [], new stdClass];
}
protected function getInvalidWriteConcernValues()
{
return [123, 3.14, 'foo', true, [], new stdClass];
}
protected function wrapValuesForDataProvider(array $values) protected function wrapValuesForDataProvider(array $values)
{ {
return array_map(function($value) { return [$value]; }, $values); return array_map(function($value) { return [$value]; }, $values);
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
namespace MongoDB\Tests; namespace MongoDB\Tests;
use ReflectionClass; use ReflectionClass;
use stdClass;
abstract class TestCase extends \PHPUnit_Framework_TestCase abstract class TestCase extends \PHPUnit_Framework_TestCase
{ {
...@@ -28,6 +29,16 @@ abstract class TestCase extends \PHPUnit_Framework_TestCase ...@@ -28,6 +29,16 @@ abstract class TestCase extends \PHPUnit_Framework_TestCase
return getenv('MONGODB_DATABASE') ?: 'phplib_test'; return getenv('MONGODB_DATABASE') ?: 'phplib_test';
} }
protected function getInvalidReadPreferenceValues()
{
return [123, 3.14, 'foo', true, [], new stdClass];
}
protected function getInvalidWriteConcernValues()
{
return [123, 3.14, 'foo', true, [], new stdClass];
}
/** /**
* Return the test namespace. * Return the test namespace.
* *
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment