Skip to content

Commit 5b6f54e

Browse files
committed
Merge pull request #7
2 parents 7146455 + 7ba1966 commit 5b6f54e

22 files changed

+994
-54
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
{ "name": "Derick Rethans", "email": "[email protected]" }
1111
],
1212
"require": {
13-
"ext-mongodb": "*"
13+
"ext-mongodb": ">=0.5.1"
1414
},
1515
"require-dev": {
1616
"fzaninotto/faker": "~1.0"

src/Client.php

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
use MongoDB\Driver\Manager;
88
use MongoDB\Driver\ReadPreference;
99
use MongoDB\Driver\WriteConcern;
10-
use ArrayIterator;
10+
use MongoDB\Model\DatabaseInfoIterator;
11+
use MongoDB\Model\DatabaseInfoLegacyIterator;
1112
use stdClass;
1213
use UnexpectedValueException;
1314

@@ -54,32 +55,28 @@ public function dropDatabase($databaseName)
5455
* List databases.
5556
*
5657
* @see http://docs.mongodb.org/manual/reference/command/listDatabases/
57-
* @return Traversable
58+
* @return DatabaseInfoIterator
5859
* @throws UnexpectedValueException if the command result is malformed
5960
*/
6061
public function listDatabases()
6162
{
6263
$command = new Command(array('listDatabases' => 1));
6364

6465
$cursor = $this->manager->executeCommand('admin', $command);
66+
$cursor->setTypeMap(array('document' => 'array'));
6567
$result = current($cursor->toArray());
6668

6769
if ( ! isset($result['databases']) || ! is_array($result['databases'])) {
6870
throw new UnexpectedValueException('listDatabases command did not return a "databases" array');
6971
}
7072

71-
$databases = array_map(
72-
function(stdClass $database) { return (array) $database; },
73-
$result['databases']
74-
);
75-
76-
/* Return a Traversable instead of an array in case listDatabases is
73+
/* Return an Iterator instead of an array in case listDatabases is
7774
* eventually changed to return a command cursor, like the collection
7875
* and index enumeration commands. This makes the "totalSize" command
7976
* field inaccessible, but users can manually invoke the command if they
8077
* need that value.
8178
*/
82-
return new ArrayIterator($databases);
79+
return new DatabaseInfoLegacyIterator($result['databases']);
8380
}
8481

8582
/**

src/Collection.php

Lines changed: 154 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,19 @@
22

33
namespace MongoDB;
44

5+
use MongoDB\Driver\BulkWrite;
56
use MongoDB\Driver\Command;
67
use MongoDB\Driver\Cursor;
78
use MongoDB\Driver\Manager;
89
use MongoDB\Driver\Query;
910
use MongoDB\Driver\ReadPreference;
10-
use MongoDB\Driver\BulkWrite;
11+
use MongoDB\Driver\Server;
1112
use MongoDB\Driver\WriteConcern;
13+
use MongoDB\Exception\InvalidArgumentException;
14+
use MongoDB\Exception\UnexpectedTypeException;
15+
use MongoDB\Model\IndexInfoIterator;
16+
use MongoDB\Model\IndexInfoIteratorIterator;
17+
use MongoDB\Model\IndexInput;
1218

1319
class Collection
1420
{
@@ -244,34 +250,68 @@ public function count(array $filter = array(), array $options = array())
244250
}
245251

246252
/**
247-
* Create a single index in the collection.
253+
* Create a single index for the collection.
248254
*
249255
* @see http://docs.mongodb.org/manual/reference/command/createIndexes/
250256
* @see http://docs.mongodb.org/manual/reference/method/db.collection.createIndex/
251-
* @param array|object $keys
252-
* @param array $options
257+
* @see Collection::createIndexes()
258+
* @param array|object $key Document containing fields mapped to values,
259+
* which denote order or an index type
260+
* @param array $options Index options
253261
* @return string The name of the created index
254262
*/
255-
public function createIndex($keys, array $options = array())
263+
public function createIndex($key, array $options = array())
256264
{
257-
// TODO
265+
return current($this->createIndexes(array(array('key' => $key) + $options)));
258266
}
259267

260268
/**
261-
* Create multiple indexes in the collection.
269+
* Create one or more indexes for the collection.
270+
*
271+
* Each element in the $indexes array must have a "key" document, which
272+
* contains fields mapped to an order or type. Other options may follow.
273+
* For example:
274+
*
275+
* $indexes = [
276+
* // Create a unique index on the "username" field
277+
* [ 'key' => [ 'username' => 1 ], 'unique' => true ],
278+
* // Create a 2dsphere index on the "loc" field with a custom name
279+
* [ 'key' => [ 'loc' => '2dsphere' ], 'name' => 'geo' ],
280+
* ];
262281
*
263-
* TODO: decide if $models should be an array of associative arrays, using
264-
* createIndex()'s parameter names as keys, or tuples, using parameters in
265-
* order (e.g. [keys, options]).
282+
* If the "name" option is unspecified, a name will be generated from the
283+
* "key" document.
266284
*
267285
* @see http://docs.mongodb.org/manual/reference/command/createIndexes/
268286
* @see http://docs.mongodb.org/manual/reference/method/db.collection.createIndex/
269-
* @param array $models
287+
* @param array $indexes List of index specifications
270288
* @return string[] The names of the created indexes
289+
* @throws InvalidArgumentException if an index specification is invalid
271290
*/
272-
public function createIndexes(array $models)
291+
public function createIndexes(array $indexes)
273292
{
274-
// TODO
293+
if (empty($indexes)) {
294+
return array();
295+
}
296+
297+
foreach ($indexes as $i => $index) {
298+
if ( ! is_array($index)) {
299+
throw new UnexpectedTypeException($index, 'array');
300+
}
301+
302+
if ( ! isset($index['ns'])) {
303+
$index['ns'] = $this->ns;
304+
}
305+
306+
$indexes[$i] = new IndexInput($index);
307+
}
308+
309+
$readPreference = new ReadPreference(ReadPreference::RP_PRIMARY);
310+
$server = $this->manager->selectServer($readPreference);
311+
312+
return (FeatureDetection::isSupported($server, FeatureDetection::API_CREATEINDEXES_CMD))
313+
? $this->createIndexesCommand($server, $indexes)
314+
: $this->createIndexesLegacy($server, $indexes);
275315
}
276316

277317
/**
@@ -354,11 +394,24 @@ public function drop()
354394
* @see http://docs.mongodb.org/manual/reference/method/db.collection.dropIndex/
355395
* @param string $indexName
356396
* @return Cursor
357-
* @throws InvalidArgumentException if "*" is specified
397+
* @throws InvalidArgumentException if $indexName is an empty string or "*"
358398
*/
359399
public function dropIndex($indexName)
360400
{
361-
// TODO
401+
$indexName = (string) $indexName;
402+
403+
if ($indexName === '') {
404+
throw new InvalidArgumentException('Index name cannot be empty');
405+
}
406+
407+
if ($indexName === '*') {
408+
throw new InvalidArgumentException('dropIndexes() must be used to drop multiple indexes');
409+
}
410+
411+
$command = new Command(array('dropIndexes' => $this->collname, 'index' => $indexName));
412+
$readPreference = new ReadPreference(ReadPreference::RP_PRIMARY);
413+
414+
return $this->manager->executeCommand($this->dbname, $command, $readPreference);
362415
}
363416

364417
/**
@@ -370,7 +423,10 @@ public function dropIndex($indexName)
370423
*/
371424
public function dropIndexes()
372425
{
373-
// TODO
426+
$command = new Command(array('dropIndexes' => $this->collname, 'index' => '*'));
427+
$readPreference = new ReadPreference(ReadPreference::RP_PRIMARY);
428+
429+
return $this->manager->executeCommand($this->dbname, $command, $readPreference);
374430
}
375431

376432
/**
@@ -949,15 +1005,20 @@ public function insertOne(array $document)
9491005
}
9501006

9511007
/**
952-
* Returns information for all indexes in the collection.
1008+
* Returns information for all indexes for the collection.
9531009
*
9541010
* @see http://docs.mongodb.org/manual/reference/command/listIndexes/
9551011
* @see http://docs.mongodb.org/manual/reference/method/db.collection.getIndexes/
956-
* @return Cursor
1012+
* @return IndexInfoIterator
9571013
*/
9581014
public function listIndexes()
9591015
{
960-
// TODO
1016+
$readPreference = new ReadPreference(ReadPreference::RP_PRIMARY);
1017+
$server = $this->manager->selectServer($readPreference);
1018+
1019+
return (FeatureDetection::isSupported($server, FeatureDetection::API_LISTINDEXES_CMD))
1020+
? $this->listIndexesCommand($server)
1021+
: $this->listIndexesLegacy($server);
9611022
}
9621023

9631024
/**
@@ -1136,4 +1197,78 @@ protected function _update($filter, $update, $options)
11361197
$bulk->update($filter, $update, $options);
11371198
return $this->manager->executeBulkWrite($this->ns, $bulk, $this->wc);
11381199
}
1200+
1201+
/**
1202+
* Create one or more indexes for the collection using the createIndexes
1203+
* command.
1204+
*
1205+
* @param Server $server
1206+
* @param IndexInput[] $indexes
1207+
* @return string[] The names of the created indexes
1208+
*/
1209+
private function createIndexesCommand(Server $server, array $indexes)
1210+
{
1211+
$command = new Command(array(
1212+
'createIndexes' => $this->collname,
1213+
'indexes' => $indexes,
1214+
));
1215+
$server->executeCommand($this->dbname, $command);
1216+
1217+
return array_map(function(IndexInput $index) { return (string) $index; }, $indexes);
1218+
}
1219+
1220+
/**
1221+
* Create one or more indexes for the collection by inserting into the
1222+
* "system.indexes" collection (MongoDB <2.6).
1223+
*
1224+
* @param Server $server
1225+
* @param IndexInput[] $indexes
1226+
* @return string[] The names of the created indexes
1227+
*/
1228+
private function createIndexesLegacy(Server $server, array $indexes)
1229+
{
1230+
$bulk = new BulkWrite(true);
1231+
1232+
foreach ($indexes as $index) {
1233+
// TODO: Remove this once PHPC-274 is resolved (see: PHPLIB-87)
1234+
$bulk->insert($index->bsonSerialize());
1235+
}
1236+
1237+
$server->executeBulkWrite($this->dbname . '.system.indexes', $bulk);
1238+
1239+
return array_map(function(IndexInput $index) { return (string) $index; }, $indexes);
1240+
}
1241+
1242+
/**
1243+
* Returns information for all indexes for this collection using the
1244+
* listIndexes command.
1245+
*
1246+
* @see http://docs.mongodb.org/manual/reference/command/listIndexes/
1247+
* @param Server $server
1248+
* @return IndexInfoIteratorIterator
1249+
*/
1250+
private function listIndexesCommand(Server $server)
1251+
{
1252+
$command = new Command(array('listIndexes' => $this->collname));
1253+
$cursor = $server->executeCommand($this->dbname, $command);
1254+
$cursor->setTypeMap(array('document' => 'array'));
1255+
1256+
return new IndexInfoIteratorIterator($cursor);
1257+
}
1258+
1259+
/**
1260+
* Returns information for all indexes for this collection by querying the
1261+
* "system.indexes" collection (MongoDB <2.8).
1262+
*
1263+
* @param Server $server
1264+
* @return IndexInfoIteratorIterator
1265+
*/
1266+
private function listIndexesLegacy(Server $server)
1267+
{
1268+
$query = new Query(array('ns' => $this->ns));
1269+
$cursor = $server->executeQuery($this->dbname . '.system.indexes', $query);
1270+
$cursor->setTypeMap(array('document' => 'array'));
1271+
1272+
return new IndexInfoIteratorIterator($cursor);
1273+
}
11391274
}

src/Database.php

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,7 @@ public function listCollections(array $options = array())
101101
$readPreference = new ReadPreference(ReadPreference::RP_PRIMARY);
102102
$server = $this->manager->selectServer($readPreference);
103103

104-
$serverInfo = $server->getInfo();
105-
$maxWireVersion = isset($serverInfo['maxWireVersion']) ? $serverInfo['maxWireVersion'] : 0;
106-
107-
return ($maxWireVersion >= 3)
104+
return (FeatureDetection::isSupported($server, FeatureDetection::API_LISTCOLLECTIONS_CMD))
108105
? $this->listCollectionsCommand($server, $options)
109106
: $this->listCollectionsLegacy($server, $options);
110107
}
@@ -141,13 +138,14 @@ private function listCollectionsCommand(Server $server, array $options = array()
141138
{
142139
$command = new Command(array('listCollections' => 1) + $options);
143140
$cursor = $server->executeCommand($this->databaseName, $command);
141+
$cursor->setTypeMap(array('document' => 'array'));
144142

145143
return new CollectionInfoCommandIterator($cursor);
146144
}
147145

148146
/**
149-
* Returns information for all collections in this database by querying
150-
* the "system.namespaces" collection (MongoDB <2.8).
147+
* Returns information for all collections in this database by querying the
148+
* "system.namespaces" collection (MongoDB <2.8).
151149
*
152150
* @param Server $server
153151
* @param array $options
@@ -177,6 +175,7 @@ private function listCollectionsLegacy(Server $server, array $options = array())
177175
$namespace = $this->databaseName . '.system.namespaces';
178176
$query = new Query($filter);
179177
$cursor = $server->executeQuery($namespace, $query);
178+
$cursor->setTypeMap(array('document' => 'array'));
180179

181180
return new CollectionInfoLegacyIterator($cursor);
182181
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
namespace MongoDB\Exception;
4+
5+
class BadMethodCallException extends \BadMethodCallException implements Exception
6+
{
7+
}

src/Exception/Exception.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
namespace MongoDB\Exception;
4+
5+
interface Exception
6+
{
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
namespace MongoDB\Exception;
4+
5+
class InvalidArgumentException extends \InvalidArgumentException implements Exception
6+
{
7+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace MongoDB\Exception;
4+
5+
class UnexpectedTypeException extends InvalidArgumentException
6+
{
7+
public function __construct($value, $expectedType)
8+
{
9+
parent::__construct(sprintf('Expected argument of type "%s", "%s" given', $expectedType, is_object($value) ? get_class($value) : gettype($value)));
10+
}
11+
}

0 commit comments

Comments
 (0)