Skip to content

Commit a3bf702

Browse files
committed
PHPLIB-138: Support typeMap option for core classes
1 parent 99635c0 commit a3bf702

File tree

6 files changed

+83
-15
lines changed

6 files changed

+83
-15
lines changed

src/Client.php

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ class Client
1515
{
1616
private $manager;
1717
private $uri;
18+
private $typeMap;
1819

1920
/**
2021
* Constructs a new Client instance.
@@ -23,15 +24,29 @@ class Client
2324
* cluster of servers. It serves as a gateway for accessing individual
2425
* databases and collections.
2526
*
27+
* Supported driver-specific options:
28+
*
29+
* * typeMap (array): Default type map for cursors and BSON documents.
30+
*
31+
* Other options are documented in MongoDB\Driver\Manager::__construct().
32+
*
2633
* @see http://docs.mongodb.org/manual/reference/connection-string/
34+
* @see http://php.net/manual/en/mongodb-driver-manager.construct.php
35+
* @see http://php.net/manual/en/mongodb.persistence.php#mongodb.persistence.typemaps
2736
* @param string $uri MongoDB connection string
28-
* @param array $options Additional connection string options
37+
* @param array $uriOptions Additional connection string options
2938
* @param array $driverOptions Driver-specific options
39+
* @throws InvalidArgumentException
3040
*/
31-
public function __construct($uri = 'mongodb://localhost:27017', array $options = [], array $driverOptions = [])
41+
public function __construct($uri = 'mongodb://localhost:27017', array $uriOptions = [], array $driverOptions = [])
3242
{
33-
$this->manager = new Manager($uri, $options, $driverOptions);
43+
if (isset($driverOptions['typeMap']) && ! is_array($driverOptions['typeMap'])) {
44+
throw new InvalidArgumentTypeException('"typeMap" driver option', $driverOptions['typeMap'], 'array');
45+
}
46+
47+
$this->manager = new Manager($uri, $uriOptions, $driverOptions);
3448
$this->uri = (string) $uri;
49+
$this->typeMap = isset($driverOptions['typeMap']) ? $driverOptions['typeMap'] : null;
3550
}
3651

3752
/**
@@ -45,6 +60,7 @@ public function __debugInfo()
4560
return [
4661
'manager' => $this->manager,
4762
'uri' => $this->uri,
63+
'typeMap' => $this->typeMap,
4864
];
4965
}
5066

@@ -97,28 +113,23 @@ public function listDatabases(array $options = [])
97113
*/
98114
public function selectCollection($databaseName, $collectionName, array $options = [])
99115
{
116+
$options += ['typeMap' => $this->typeMap];
117+
100118
return new Collection($this->manager, $databaseName . '.' . $collectionName, $options);
101119
}
102120

103121
/**
104122
* Select a database.
105123
*
106-
* Supported options:
107-
*
108-
* * readPreference (MongoDB\Driver\ReadPreference): The default read
109-
* preference to use for database operations and selected collections.
110-
* Defaults to the Client's read preference.
111-
*
112-
* * writeConcern (MongoDB\Driver\WriteConcern): The default write concern
113-
* to use for database operations and selected collections. Defaults to
114-
* the Client's write concern.
115-
*
124+
* @see Database::__construct() for supported options
116125
* @param string $databaseName Name of the database to select
117126
* @param array $options Database constructor options
118127
* @return Database
119128
*/
120129
public function selectDatabase($databaseName, array $options = [])
121130
{
131+
$options += ['typeMap' => $this->typeMap];
132+
122133
return new Database($this->manager, $databaseName, $options);
123134
}
124135
}

src/Collection.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ class Collection
4545
private $manager;
4646
private $readConcern;
4747
private $readPreference;
48+
private $typeMap;
4849
private $writeConcern;
4950

5051
/**
@@ -62,6 +63,8 @@ class Collection
6263
* preference to use for collection operations. Defaults to the Manager's
6364
* read preference.
6465
*
66+
* * typeMap (array): Default type map for cursors and BSON documents.
67+
*
6568
* * writeConcern (MongoDB\Driver\WriteConcern): The default write concern
6669
* to use for collection operations. Defaults to the Manager's write
6770
* concern.
@@ -90,13 +93,18 @@ public function __construct(Manager $manager, $namespace, array $options = [])
9093
throw new InvalidArgumentTypeException('"readPreference" option', $options['readPreference'], 'MongoDB\Driver\ReadPreference');
9194
}
9295

96+
if (isset($options['typeMap']) && ! is_array($options['typeMap'])) {
97+
throw new InvalidArgumentTypeException('"typeMap" option', $options['typeMap'], 'array');
98+
}
99+
93100
if (isset($options['writeConcern']) && ! $options['writeConcern'] instanceof WriteConcern) {
94101
throw new InvalidArgumentTypeException('"writeConcern" option', $options['writeConcern'], 'MongoDB\Driver\WriteConcern');
95102
}
96103

97104
$this->manager = $manager;
98105
$this->readConcern = isset($options['readConcern']) ? $options['readConcern'] : $this->manager->getReadConcern();
99106
$this->readPreference = isset($options['readPreference']) ? $options['readPreference'] : $this->manager->getReadPreference();
107+
$this->typeMap = isset($options['typeMap']) ? $options['typeMap'] : null;
100108
$this->writeConcern = isset($options['writeConcern']) ? $options['writeConcern'] : $this->manager->getWriteConcern();
101109
}
102110

@@ -114,6 +122,7 @@ public function __debugInfo()
114122
'manager' => $this->manager,
115123
'readConcern' => $this->readConcern,
116124
'readPreference' => $this->readPreference,
125+
'typeMap' => $this->typeMap,
117126
'writeConcern' => $this->writeConcern,
118127
];
119128
}
@@ -664,6 +673,7 @@ public function withOptions(array $options = [])
664673
$options += [
665674
'readConcern' => $this->readConcern,
666675
'readPreference' => $this->readPreference,
676+
'typeMap' => $this->typeMap,
667677
'writeConcern' => $this->writeConcern,
668678
];
669679

src/Database.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ class Database
2525
private $manager;
2626
private $readConcern;
2727
private $readPreference;
28+
private $typeMap;
2829
private $writeConcern;
2930

3031
/**
@@ -43,6 +44,8 @@ class Database
4344
* preference to use for database operations and selected collections.
4445
* Defaults to the Manager's read preference.
4546
*
47+
* * typeMap (array): Default type map for cursors and BSON documents.
48+
*
4649
* * writeConcern (MongoDB\Driver\WriteConcern): The default write concern
4750
* to use for database operations and selected collections. Defaults to
4851
* the Manager's write concern.
@@ -66,6 +69,10 @@ public function __construct(Manager $manager, $databaseName, array $options = []
6669
throw new InvalidArgumentTypeException('"readPreference" option', $options['readPreference'], 'MongoDB\Driver\ReadPreference');
6770
}
6871

72+
if (isset($options['typeMap']) && ! is_array($options['typeMap'])) {
73+
throw new InvalidArgumentTypeException('"typeMap" option', $options['typeMap'], 'array');
74+
}
75+
6976
if (isset($options['writeConcern']) && ! $options['writeConcern'] instanceof WriteConcern) {
7077
throw new InvalidArgumentTypeException('"writeConcern" option', $options['writeConcern'], 'MongoDB\Driver\WriteConcern');
7178
}
@@ -74,6 +81,7 @@ public function __construct(Manager $manager, $databaseName, array $options = []
7481
$this->databaseName = (string) $databaseName;
7582
$this->readConcern = isset($options['readConcern']) ? $options['readConcern'] : $this->manager->getReadConcern();
7683
$this->readPreference = isset($options['readPreference']) ? $options['readPreference'] : $this->manager->getReadPreference();
84+
$this->typeMap = isset($options['typeMap']) ? $options['typeMap'] : null;
7785
$this->writeConcern = isset($options['writeConcern']) ? $options['writeConcern'] : $this->manager->getWriteConcern();
7886
}
7987

@@ -90,6 +98,7 @@ public function __debugInfo()
9098
'manager' => $this->manager,
9199
'readConcern' => $this->readConcern,
92100
'readPreference' => $this->readPreference,
101+
'typeMap' => $this->typeMap,
93102
'writeConcern' => $this->writeConcern,
94103
];
95104
}
@@ -211,6 +220,7 @@ public function selectCollection($collectionName, array $options = [])
211220
$options += [
212221
'readConcern' => $this->readConcern,
213222
'readPreference' => $this->readPreference,
223+
'typeMap' => $this->typeMap,
214224
'writeConcern' => $this->writeConcern,
215225
];
216226

@@ -229,6 +239,7 @@ public function withOptions(array $options = [])
229239
$options += [
230240
'readConcern' => $this->readConcern,
231241
'readPreference' => $this->readPreference,
242+
'typeMap' => $this->typeMap,
232243
'writeConcern' => $this->writeConcern,
233244
];
234245

tests/ClientTest.php

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,20 @@ public function testSelectCollectionInheritsOptions()
3636
'w' => WriteConcern::MAJORITY,
3737
];
3838

39-
$client = new Client($this->getUri(), $uriOptions);
39+
$driverOptions = [
40+
'typeMap' => ['root' => 'array'],
41+
];
42+
43+
$client = new Client($this->getUri(), $uriOptions, $driverOptions);
4044
$collection = $client->selectCollection($this->getDatabaseName(), $this->getCollectionName());
4145
$debug = $collection->__debugInfo();
4246

4347
$this->assertInstanceOf('MongoDB\Driver\ReadConcern', $debug['readConcern']);
4448
$this->assertSame(ReadConcern::LOCAL, $debug['readConcern']->getLevel());
4549
$this->assertInstanceOf('MongoDB\Driver\ReadPreference', $debug['readPreference']);
4650
$this->assertSame(ReadPreference::RP_SECONDARY_PREFERRED, $debug['readPreference']->getMode());
51+
$this->assertInternalType('array', $debug['typeMap']);
52+
$this->assertSame(['root' => 'array'], $debug['typeMap']);
4753
$this->assertInstanceOf('MongoDB\Driver\WriteConcern', $debug['writeConcern']);
4854
$this->assertSame(WriteConcern::MAJORITY, $debug['writeConcern']->getW());
4955
}
@@ -53,6 +59,7 @@ public function testSelectCollectionPassesOptions()
5359
$collectionOptions = [
5460
'readConcern' => new ReadConcern(ReadConcern::LOCAL),
5561
'readPreference' => new ReadPreference(ReadPreference::RP_SECONDARY_PREFERRED),
62+
'typeMap' => ['root' => 'array'],
5663
'writeConcern' => new WriteConcern(WriteConcern::MAJORITY),
5764
];
5865

@@ -64,6 +71,8 @@ public function testSelectCollectionPassesOptions()
6471
$this->assertSame(ReadConcern::LOCAL, $debug['readConcern']->getLevel());
6572
$this->assertInstanceOf('MongoDB\Driver\ReadPreference', $debug['readPreference']);
6673
$this->assertSame(ReadPreference::RP_SECONDARY_PREFERRED, $debug['readPreference']->getMode());
74+
$this->assertInternalType('array', $debug['typeMap']);
75+
$this->assertSame(['root' => 'array'], $debug['typeMap']);
6776
$this->assertInstanceOf('MongoDB\Driver\WriteConcern', $debug['writeConcern']);
6877
$this->assertSame(WriteConcern::MAJORITY, $debug['writeConcern']->getW());
6978
}
@@ -78,14 +87,20 @@ public function testSelectDatabaseInheritsOptions()
7887
'w' => WriteConcern::MAJORITY,
7988
];
8089

81-
$client = new Client($this->getUri(), $uriOptions);
90+
$driverOptions = [
91+
'typeMap' => ['root' => 'array'],
92+
];
93+
94+
$client = new Client($this->getUri(), $uriOptions, $driverOptions);
8295
$database = $client->selectDatabase($this->getDatabaseName());
8396
$debug = $database->__debugInfo();
8497

8598
$this->assertInstanceOf('MongoDB\Driver\ReadConcern', $debug['readConcern']);
8699
$this->assertSame(ReadConcern::LOCAL, $debug['readConcern']->getLevel());
87100
$this->assertInstanceOf('MongoDB\Driver\ReadPreference', $debug['readPreference']);
88101
$this->assertSame(ReadPreference::RP_SECONDARY_PREFERRED, $debug['readPreference']->getMode());
102+
$this->assertInternalType('array', $debug['typeMap']);
103+
$this->assertSame(['root' => 'array'], $debug['typeMap']);
89104
$this->assertInstanceOf('MongoDB\Driver\WriteConcern', $debug['writeConcern']);
90105
$this->assertSame(WriteConcern::MAJORITY, $debug['writeConcern']->getW());
91106
}
@@ -95,6 +110,7 @@ public function testSelectDatabasePassesOptions()
95110
$databaseOptions = [
96111
'readConcern' => new ReadConcern(ReadConcern::LOCAL),
97112
'readPreference' => new ReadPreference(ReadPreference::RP_SECONDARY_PREFERRED),
113+
'typeMap' => ['root' => 'array'],
98114
'writeConcern' => new WriteConcern(WriteConcern::MAJORITY),
99115
];
100116

@@ -106,6 +122,8 @@ public function testSelectDatabasePassesOptions()
106122
$this->assertSame(ReadConcern::LOCAL, $debug['readConcern']->getLevel());
107123
$this->assertInstanceOf('MongoDB\Driver\ReadPreference', $debug['readPreference']);
108124
$this->assertSame(ReadPreference::RP_SECONDARY_PREFERRED, $debug['readPreference']->getMode());
125+
$this->assertInternalType('array', $debug['typeMap']);
126+
$this->assertSame(['root' => 'array'], $debug['typeMap']);
109127
$this->assertInstanceOf('MongoDB\Driver\WriteConcern', $debug['writeConcern']);
110128
$this->assertSame(WriteConcern::MAJORITY, $debug['writeConcern']->getW());
111129
}

tests/Collection/CollectionFunctionalTest.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ public function testWithOptionsInheritsReadPreferenceAndWriteConcern()
117117
$collectionOptions = [
118118
'readConcern' => new ReadConcern(ReadConcern::LOCAL),
119119
'readPreference' => new ReadPreference(ReadPreference::RP_SECONDARY_PREFERRED),
120+
'typeMap' => ['root' => 'array'],
120121
'writeConcern' => new WriteConcern(WriteConcern::MAJORITY),
121122
];
122123

@@ -128,6 +129,8 @@ public function testWithOptionsInheritsReadPreferenceAndWriteConcern()
128129
$this->assertSame(ReadConcern::LOCAL, $debug['readConcern']->getLevel());
129130
$this->assertInstanceOf('MongoDB\Driver\ReadPreference', $debug['readPreference']);
130131
$this->assertSame(ReadPreference::RP_SECONDARY_PREFERRED, $debug['readPreference']->getMode());
132+
$this->assertInternalType('array', $debug['typeMap']);
133+
$this->assertSame(['root' => 'array'], $debug['typeMap']);
131134
$this->assertInstanceOf('MongoDB\Driver\WriteConcern', $debug['writeConcern']);
132135
$this->assertSame(WriteConcern::MAJORITY, $debug['writeConcern']->getW());
133136
}
@@ -137,6 +140,7 @@ public function testWithOptionsPassesReadPreferenceAndWriteConcern()
137140
$collectionOptions = [
138141
'readConcern' => new ReadConcern(ReadConcern::LOCAL),
139142
'readPreference' => new ReadPreference(ReadPreference::RP_SECONDARY_PREFERRED),
143+
'typeMap' => ['root' => 'array'],
140144
'writeConcern' => new WriteConcern(WriteConcern::MAJORITY),
141145
];
142146

@@ -147,6 +151,8 @@ public function testWithOptionsPassesReadPreferenceAndWriteConcern()
147151
$this->assertSame(ReadConcern::LOCAL, $debug['readConcern']->getLevel());
148152
$this->assertInstanceOf('MongoDB\Driver\ReadPreference', $debug['readPreference']);
149153
$this->assertSame(ReadPreference::RP_SECONDARY_PREFERRED, $debug['readPreference']->getMode());
154+
$this->assertInternalType('array', $debug['typeMap']);
155+
$this->assertSame(['root' => 'array'], $debug['typeMap']);
150156
$this->assertInstanceOf('MongoDB\Driver\WriteConcern', $debug['writeConcern']);
151157
$this->assertSame(WriteConcern::MAJORITY, $debug['writeConcern']->getW());
152158
}

tests/Database/DatabaseFunctionalTest.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ public function testSelectCollectionInheritsOptions()
106106
$databaseOptions = [
107107
'readConcern' => new ReadConcern(ReadConcern::LOCAL),
108108
'readPreference' => new ReadPreference(ReadPreference::RP_SECONDARY_PREFERRED),
109+
'typeMap' => ['root' => 'array'],
109110
'writeConcern' => new WriteConcern(WriteConcern::MAJORITY),
110111
];
111112

@@ -117,6 +118,8 @@ public function testSelectCollectionInheritsOptions()
117118
$this->assertSame(ReadConcern::LOCAL, $debug['readConcern']->getLevel());
118119
$this->assertInstanceOf('MongoDB\Driver\ReadPreference', $debug['readPreference']);
119120
$this->assertSame(ReadPreference::RP_SECONDARY_PREFERRED, $debug['readPreference']->getMode());
121+
$this->assertInternalType('array', $debug['typeMap']);
122+
$this->assertSame(['root' => 'array'], $debug['typeMap']);
120123
$this->assertInstanceOf('MongoDB\Driver\WriteConcern', $debug['writeConcern']);
121124
$this->assertSame(WriteConcern::MAJORITY, $debug['writeConcern']->getW());
122125
}
@@ -126,6 +129,7 @@ public function testSelectCollectionPassesOptions()
126129
$collectionOptions = [
127130
'readConcern' => new ReadConcern(ReadConcern::LOCAL),
128131
'readPreference' => new ReadPreference(ReadPreference::RP_SECONDARY_PREFERRED),
132+
'typeMap' => ['root' => 'array'],
129133
'writeConcern' => new WriteConcern(WriteConcern::MAJORITY),
130134
];
131135

@@ -136,6 +140,8 @@ public function testSelectCollectionPassesOptions()
136140
$this->assertSame(ReadConcern::LOCAL, $debug['readConcern']->getLevel());
137141
$this->assertInstanceOf('MongoDB\Driver\ReadPreference', $debug['readPreference']);
138142
$this->assertSame(ReadPreference::RP_SECONDARY_PREFERRED, $debug['readPreference']->getMode());
143+
$this->assertInternalType('array', $debug['typeMap']);
144+
$this->assertSame(['root' => 'array'], $debug['typeMap']);
139145
$this->assertInstanceOf('MongoDB\Driver\WriteConcern', $debug['writeConcern']);
140146
$this->assertSame(WriteConcern::MAJORITY, $debug['writeConcern']->getW());
141147
}
@@ -145,6 +151,7 @@ public function testWithOptionsInheritsOptions()
145151
$databaseOptions = [
146152
'readConcern' => new ReadConcern(ReadConcern::LOCAL),
147153
'readPreference' => new ReadPreference(ReadPreference::RP_SECONDARY_PREFERRED),
154+
'typeMap' => ['root' => 'array'],
148155
'writeConcern' => new WriteConcern(WriteConcern::MAJORITY),
149156
];
150157

@@ -156,6 +163,8 @@ public function testWithOptionsInheritsOptions()
156163
$this->assertSame(ReadConcern::LOCAL, $debug['readConcern']->getLevel());
157164
$this->assertInstanceOf('MongoDB\Driver\ReadPreference', $debug['readPreference']);
158165
$this->assertSame(ReadPreference::RP_SECONDARY_PREFERRED, $debug['readPreference']->getMode());
166+
$this->assertInternalType('array', $debug['typeMap']);
167+
$this->assertSame(['root' => 'array'], $debug['typeMap']);
159168
$this->assertInstanceOf('MongoDB\Driver\WriteConcern', $debug['writeConcern']);
160169
$this->assertSame(WriteConcern::MAJORITY, $debug['writeConcern']->getW());
161170
}
@@ -165,6 +174,7 @@ public function testWithOptionsPassesOptions()
165174
$databaseOptions = [
166175
'readConcern' => new ReadConcern(ReadConcern::LOCAL),
167176
'readPreference' => new ReadPreference(ReadPreference::RP_SECONDARY_PREFERRED),
177+
'typeMap' => ['root' => 'array'],
168178
'writeConcern' => new WriteConcern(WriteConcern::MAJORITY),
169179
];
170180

@@ -175,6 +185,8 @@ public function testWithOptionsPassesOptions()
175185
$this->assertSame(ReadConcern::LOCAL, $debug['readConcern']->getLevel());
176186
$this->assertInstanceOf('MongoDB\Driver\ReadPreference', $debug['readPreference']);
177187
$this->assertSame(ReadPreference::RP_SECONDARY_PREFERRED, $debug['readPreference']->getMode());
188+
$this->assertInternalType('array', $debug['typeMap']);
189+
$this->assertSame(['root' => 'array'], $debug['typeMap']);
178190
$this->assertInstanceOf('MongoDB\Driver\WriteConcern', $debug['writeConcern']);
179191
$this->assertSame(WriteConcern::MAJORITY, $debug['writeConcern']->getW());
180192
}

0 commit comments

Comments
 (0)