Skip to content

Commit 68acf01

Browse files
committed
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.
1 parent be188e3 commit 68acf01

File tree

7 files changed

+159
-59
lines changed

7 files changed

+159
-59
lines changed

src/Client.php

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -75,40 +75,45 @@ public function listDatabases(array $options = [])
7575
/**
7676
* Select a collection.
7777
*
78-
* If a write concern or read preference is not specified, the write concern
79-
* or read preference of the Client will be applied, respectively.
78+
* Supported options:
8079
*
81-
* @param string $databaseName Name of the database containing the collection
82-
* @param string $collectionName Name of the collection to select
83-
* @param WriteConcern $writeConcern Default write concern to apply
84-
* @param ReadPreference $readPreference Default read preference to apply
80+
* * readPreference (MongoDB\Driver\ReadPreference): The default read
81+
* preference to use for collection operations. Defaults to the Client's
82+
* read preference.
83+
*
84+
* * writeConcern (MongoDB\Driver\WriteConcern): The default write concern
85+
* to use for collection operations. Defaults to the Client's write
86+
* concern.
87+
*
88+
* @param string $databaseName Name of the database containing the collection
89+
* @param string $collectionName Name of the collection to select
90+
* @param array $options Collection constructor options
8591
* @return Collection
8692
*/
87-
public function selectCollection($databaseName, $collectionName, WriteConcern $writeConcern = null, ReadPreference $readPreference = null)
93+
public function selectCollection($databaseName, $collectionName, array $options = [])
8894
{
89-
$namespace = $databaseName . '.' . $collectionName;
90-
$writeConcern = $writeConcern ?: $this->manager->getWriteConcern();
91-
$readPreference = $readPreference ?: $this->manager->getReadPreference();
92-
93-
return new Collection($this->manager, $namespace, $writeConcern, $readPreference);
95+
return new Collection($this->manager, $databaseName . '.' . $collectionName, $options);
9496
}
9597

9698
/**
9799
* Select a database.
98100
*
99-
* If a write concern or read preference is not specified, the write concern
100-
* or read preference of the Client will be applied, respectively.
101+
* Supported options:
101102
*
102-
* @param string $databaseName Name of the database to select
103-
* @param WriteConcern $writeConcern Default write concern to apply
104-
* @param ReadPreference $readPreference Default read preference to apply
103+
* * readPreference (MongoDB\Driver\ReadPreference): The default read
104+
* preference to use for database operations and selected collections.
105+
* Defaults to the Client's read preference.
106+
*
107+
* * writeConcern (MongoDB\Driver\WriteConcern): The default write concern
108+
* to use for database operations and selected collections. Defaults to
109+
* the Client's write concern.
110+
*
111+
* @param string $databaseName Name of the database to select
112+
* @param array $options Database constructor options
105113
* @return Database
106114
*/
107-
public function selectDatabase($databaseName, WriteConcern $writeConcern = null, ReadPreference $readPreference = null)
115+
public function selectDatabase($databaseName, array $options = [])
108116
{
109-
$writeConcern = $writeConcern ?: $this->manager->getWriteConcern();
110-
$readPreference = $readPreference ?: $this->manager->getReadPreference();
111-
112-
return new Database($this->manager, $databaseName, $writeConcern, $readPreference);
117+
return new Database($this->manager, $databaseName, $options);
113118
}
114119
}

src/Collection.php

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use MongoDB\Driver\Server;
1010
use MongoDB\Driver\WriteConcern;
1111
use MongoDB\Exception\InvalidArgumentException;
12+
use MongoDB\Exception\InvalidArgumentTypeException;
1213
use MongoDB\Exception\UnexpectedTypeException;
1314
use MongoDB\Model\IndexInfoIterator;
1415
use MongoDB\Model\IndexInput;
@@ -48,13 +49,22 @@ class Collection
4849
* This class provides methods for collection-specific operations, such as
4950
* CRUD (i.e. create, read, update, and delete) and index management.
5051
*
51-
* @param Manager $manager Manager instance from the driver
52-
* @param string $namespace Collection namespace (e.g. "db.collection")
53-
* @param WriteConcern $writeConcern Default write concern to apply
54-
* @param ReadPreference $readPreference Default read preference to apply
55-
* @throws InvalidArgumentException if $namespace is invalid
52+
* Supported options:
53+
*
54+
* * readPreference (MongoDB\Driver\ReadPreference): The default read
55+
* preference to use for collection operations. Defaults to the Manager's
56+
* read preference.
57+
*
58+
* * writeConcern (MongoDB\Driver\WriteConcern): The default write concern
59+
* to use for collection operations. Defaults to the Manager's write
60+
* concern.
61+
*
62+
* @param Manager $manager Manager instance from the driver
63+
* @param string $namespace Collection namespace (e.g. "db.collection")
64+
* @param array $options Collection options
65+
* @throws InvalidArgumentException
5666
*/
57-
public function __construct(Manager $manager, $namespace, WriteConcern $writeConcern = null, ReadPreference $readPreference = null)
67+
public function __construct(Manager $manager, $namespace, array $options = [])
5868
{
5969
$parts = explode('.', $namespace, 2);
6070

@@ -65,13 +75,21 @@ public function __construct(Manager $manager, $namespace, WriteConcern $writeCon
6575
$this->databaseName = $parts[0];
6676
$this->collectionName = $parts[1];
6777

78+
if (isset($options['readPreference']) && ! $options['readPreference'] instanceof ReadPreference) {
79+
throw new InvalidArgumentTypeException('"readPreference" option', $options['readPreference'], 'MongoDB\Driver\ReadPreference');
80+
}
81+
82+
if (isset($options['writeConcern']) && ! $options['writeConcern'] instanceof WriteConcern) {
83+
throw new InvalidArgumentTypeException('"writeConcern" option', $options['writeConcern'], 'MongoDB\Driver\WriteConcern');
84+
}
85+
6886
$this->manager = $manager;
69-
$this->writeConcern = $writeConcern ?: $this->manager->getWriteConcern();
70-
$this->readPreference = $readPreference ?: $this->manager->getReadPreference();
87+
$this->readPreference = isset($options['readPreference']) ? $options['readPreference'] : $this->manager->getReadPreference();
88+
$this->writeConcern = isset($options['writeConcern']) ? $options['writeConcern'] : $this->manager->getWriteConcern();
7189
}
7290

7391
/**
74-
* Return the collection namespace.
92+
* Return the collection namespace (e.g. "db.collection").
7593
*
7694
* @param string
7795
*/

src/Database.php

Lines changed: 46 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use MongoDB\Driver\Server;
1212
use MongoDB\Driver\WriteConcern;
1313
use MongoDB\Exception\InvalidArgumentException;
14+
use MongoDB\Exception\InvalidArgumentTypeException;
1415
use MongoDB\Model\CollectionInfoIterator;
1516
use MongoDB\Operation\CreateCollection;
1617
use MongoDB\Operation\DropCollection;
@@ -30,22 +31,39 @@ class Database
3031
* This class provides methods for database-specific operations and serves
3132
* as a gateway for accessing collections.
3233
*
33-
* @param Manager $manager Manager instance from the driver
34-
* @param string $databaseName Database name
35-
* @param WriteConcern $writeConcern Default write concern to apply
36-
* @param ReadPreference $readPreference Default read preference to apply
37-
* @throws InvalidArgumentException if $databaseName is invalid
34+
* Supported options:
35+
*
36+
* * readPreference (MongoDB\Driver\ReadPreference): The default read
37+
* preference to use for database operations and selected collections.
38+
* Defaults to the Manager's read preference.
39+
*
40+
* * writeConcern (MongoDB\Driver\WriteConcern): The default write concern
41+
* to use for database operations and selected collections. Defaults to
42+
* the Manager's write concern.
43+
*
44+
* @param Manager $manager Manager instance from the driver
45+
* @param string $databaseName Database name
46+
* @param array $options Database options
47+
* @throws InvalidArgumentException
3848
*/
39-
public function __construct(Manager $manager, $databaseName, WriteConcern $writeConcern = null, ReadPreference $readPreference = null)
49+
public function __construct(Manager $manager, $databaseName, array $options = [])
4050
{
4151
if (strlen($databaseName) < 1) {
4252
throw new InvalidArgumentException('$databaseName is invalid: ' . $databaseName);
4353
}
4454

55+
if (isset($options['readPreference']) && ! $options['readPreference'] instanceof ReadPreference) {
56+
throw new InvalidArgumentTypeException('"readPreference" option', $options['readPreference'], 'MongoDB\Driver\ReadPreference');
57+
}
58+
59+
if (isset($options['writeConcern']) && ! $options['writeConcern'] instanceof WriteConcern) {
60+
throw new InvalidArgumentTypeException('"writeConcern" option', $options['writeConcern'], 'MongoDB\Driver\WriteConcern');
61+
}
62+
4563
$this->manager = $manager;
4664
$this->databaseName = (string) $databaseName;
47-
$this->writeConcern = $writeConcern ?: $this->manager->getWriteConcern();
48-
$this->readPreference = $readPreference ?: $this->manager->getReadPreference();
65+
$this->readPreference = isset($options['readPreference']) ? $options['readPreference'] : $this->manager->getReadPreference();
66+
$this->writeConcern = isset($options['writeConcern']) ? $options['writeConcern'] : $this->manager->getWriteConcern();
4967
}
5068

5169
/**
@@ -129,20 +147,30 @@ public function listCollections(array $options = [])
129147
/**
130148
* Select a collection within this database.
131149
*
132-
* If a write concern or read preference is not specified, the write concern
133-
* or read preference of the Database will be applied, respectively.
150+
* Supported options:
151+
*
152+
* * readPreference (MongoDB\Driver\ReadPreference): The default read
153+
* preference to use for collection operations. Defaults to the
154+
* Database's read preference.
155+
*
156+
* * writeConcern (MongoDB\Driver\WriteConcern): The default write concern
157+
* to use for collection operations. Defaults to the Database's write
158+
* concern.
134159
*
135-
* @param string $collectionName Name of the collection to select
136-
* @param WriteConcern $writeConcern Default write concern to apply
137-
* @param ReadPreference $readPreference Default read preference to apply
160+
* @param string $collectionName Name of the collection to select
161+
* @param array $options Collection constructor options
138162
* @return Collection
139163
*/
140-
public function selectCollection($collectionName, WriteConcern $writeConcern = null, ReadPreference $readPreference = null)
164+
public function selectCollection($collectionName, array $options = [])
141165
{
142-
$namespace = $this->databaseName . '.' . $collectionName;
143-
$writeConcern = $writeConcern ?: $this->writeConcern;
144-
$readPreference = $readPreference ?: $this->readPreference;
166+
if ( ! isset($options['readPreference'])) {
167+
$options['readPreference'] = $this->readPreference;
168+
}
169+
170+
if ( ! isset($options['writeConcern'])) {
171+
$options['writeConcern'] = $this->writeConcern;
172+
}
145173

146-
return new Collection($this->manager, $namespace, $writeConcern, $readPreference);
174+
return new Collection($this->manager, $this->databaseName . '.' . $collectionName, $options);
147175
}
148176
}

tests/Collection/CollectionFunctionalTest.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,30 @@ public function provideInvalidNamespaceValues()
3131
];
3232
}
3333

34+
/**
35+
* @expectedException MongoDB\Exception\InvalidArgumentTypeException
36+
* @dataProvider provideInvalidConstructorOptions
37+
*/
38+
public function testConstructorOptionTypeChecks(array $options)
39+
{
40+
new Collection($this->manager, $this->getNamespace(), $options);
41+
}
42+
43+
public function provideInvalidConstructorOptions()
44+
{
45+
$options = [];
46+
47+
foreach ($this->getInvalidReadPreferenceValues() as $value) {
48+
$options[][] = ['readPreference' => $value];
49+
}
50+
51+
foreach ($this->getInvalidWriteConcernValues() as $value) {
52+
$options[][] = ['writeConcern' => $value];
53+
}
54+
55+
return $options;
56+
}
57+
3458
public function testToString()
3559
{
3660
$this->assertEquals($this->getNamespace(), (string) $this->collection);

tests/Database/DatabaseFunctionalTest.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,30 @@ public function provideInvalidDatabaseValues()
2828
];
2929
}
3030

31+
/**
32+
* @expectedException MongoDB\Exception\InvalidArgumentTypeException
33+
* @dataProvider provideInvalidConstructorOptions
34+
*/
35+
public function testConstructorOptionTypeChecks(array $options)
36+
{
37+
new Database($this->manager, $this->getDatabaseName(), $options);
38+
}
39+
40+
public function provideInvalidConstructorOptions()
41+
{
42+
$options = [];
43+
44+
foreach ($this->getInvalidReadPreferenceValues() as $value) {
45+
$options[][] = ['readPreference' => $value];
46+
}
47+
48+
foreach ($this->getInvalidWriteConcernValues() as $value) {
49+
$options[][] = ['writeConcern' => $value];
50+
}
51+
52+
return $options;
53+
}
54+
3155
public function testToString()
3256
{
3357
$this->assertEquals($this->getDatabaseName(), (string) $this->database);

tests/Operation/TestCase.php

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -45,16 +45,6 @@ protected function getInvalidStringValues()
4545
return [123, 3.14, true, [], new stdClass];
4646
}
4747

48-
protected function getInvalidReadPreferenceValues()
49-
{
50-
return [123, 3.14, 'foo', true, [], new stdClass];
51-
}
52-
53-
protected function getInvalidWriteConcernValues()
54-
{
55-
return [123, 3.14, 'foo', true, [], new stdClass];
56-
}
57-
5848
protected function wrapValuesForDataProvider(array $values)
5949
{
6050
return array_map(function($value) { return [$value]; }, $values);

tests/TestCase.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace MongoDB\Tests;
44

55
use ReflectionClass;
6+
use stdClass;
67

78
abstract class TestCase extends \PHPUnit_Framework_TestCase
89
{
@@ -28,6 +29,16 @@ protected function getDatabaseName()
2829
return getenv('MONGODB_DATABASE') ?: 'phplib_test';
2930
}
3031

32+
protected function getInvalidReadPreferenceValues()
33+
{
34+
return [123, 3.14, 'foo', true, [], new stdClass];
35+
}
36+
37+
protected function getInvalidWriteConcernValues()
38+
{
39+
return [123, 3.14, 'foo', true, [], new stdClass];
40+
}
41+
3142
/**
3243
* Return the test namespace.
3344
*

0 commit comments

Comments
 (0)