Skip to content

Commit 9b06329

Browse files
committed
Update renameCollection API
1 parent 63f7dff commit 9b06329

File tree

7 files changed

+198
-94
lines changed

7 files changed

+198
-94
lines changed

src/Collection.php

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,15 +1009,20 @@ public function mapReduce(JavascriptInterface $map, JavascriptInterface $reduce,
10091009
* Renames the collection.
10101010
*
10111011
* @see RenameCollection::__construct() for supported options
1012-
* @param string $toNamespace New namespace of the collection
1013-
* @param array $options Additional options
1012+
* @param string $toCollectionName New name of the collection
1013+
* @param string $toDatabaseName New database name of the collection
1014+
* @param array $options Additional options
10141015
* @return array|object Command result document
10151016
* @throws UnsupportedException if options are not supported by the selected server
10161017
* @throws InvalidArgumentException for parameter/option parsing errors
10171018
* @throws DriverRuntimeException for other driver errors (e.g. connection errors)
10181019
*/
1019-
public function rename($toNamespace, array $options = [])
1020+
public function rename(string $toCollectionName, ?string $toDatabaseName = null, array $options = [])
10201021
{
1022+
if (! isset($toDatabaseName)) {
1023+
$toDatabaseName = $this->getDatabaseName();
1024+
}
1025+
10211026
if (! isset($options['typeMap'])) {
10221027
$options['typeMap'] = $this->typeMap;
10231028
}
@@ -1028,7 +1033,7 @@ public function rename($toNamespace, array $options = [])
10281033
$options['writeConcern'] = $this->writeConcern;
10291034
}
10301035

1031-
$operation = new RenameCollection($this->getNamespace(), $toNamespace, $options);
1036+
$operation = new RenameCollection($this->getDatabaseName(), $this->getCollectionName(), $toDatabaseName, $toCollectionName, $options);
10321037

10331038
return $operation->execute($server);
10341039
}

src/Database.php

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -475,16 +475,21 @@ public function modifyCollection($collectionName, array $collectionOptions, arra
475475
* Rename a collection within this database.
476476
*
477477
* @see RenameCollection::__construct() for supported options
478-
* @param string $fromNamespace Namespace of the collection to rename
479-
* @param string $toNamespace New namespace of the collection
480-
* @param array $options Additional options
478+
* @param string $fromCollectionName Collection name
479+
* @param string $toCollectionName New name of the collection
480+
* @param string $toDatabaseName New database name of the collection
481+
* @param array $options Additional options
481482
* @return array|object Command result document
482483
* @throws UnsupportedException if options are unsupported on the selected server
483484
* @throws InvalidArgumentException for parameter/option parsing errors
484485
* @throws DriverRuntimeException for other driver errors (e.g. connection errors)
485486
*/
486-
public function renameCollection($fromNamespace, $toNamespace, array $options = [])
487+
public function renameCollection(string $fromCollectionName, string $toCollectionName, ?string $toDatabaseName = null, array $options = [])
487488
{
489+
if (! isset($toDatabaseName)) {
490+
$toDatabaseName = $this->getDatabaseName();
491+
}
492+
488493
if (! isset($options['typeMap'])) {
489494
$options['typeMap'] = $this->typeMap;
490495
}
@@ -495,7 +500,7 @@ public function renameCollection($fromNamespace, $toNamespace, array $options =
495500
$options['writeConcern'] = $this->writeConcern;
496501
}
497502

498-
$operation = new RenameCollection($fromNamespace, $toNamespace, $options);
503+
$operation = new RenameCollection($this->getDatabaseName(), $fromCollectionName, $toDatabaseName, $toCollectionName, $options);
499504

500505
return $operation->execute($server);
501506
}

src/Operation/RenameCollection.php

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22
/*
3-
* Copyright 2015-2017 MongoDB, Inc.
3+
* Copyright 2021-present MongoDB, Inc.
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
66
* you may not use this file except in compliance with the License.
@@ -30,7 +30,7 @@
3030
use function MongoDB\server_supports_feature;
3131

3232
/**
33-
* Operation for the rename command.
33+
* Operation for the renameCollection command.
3434
*
3535
* @api
3636
* @see \MongoDB\Collection::rename()
@@ -39,12 +39,6 @@
3939
*/
4040
class RenameCollection implements Executable
4141
{
42-
/** @var integer */
43-
private static $errorCodeNamespaceNotFound = 26;
44-
45-
/** @var string */
46-
private static $errorMessageNamespaceNotFound = 'ns not found';
47-
4842
/** @var integer */
4943
private static $wireVersionForWriteConcern = 5;
5044

@@ -58,7 +52,7 @@ class RenameCollection implements Executable
5852
private $options;
5953

6054
/**
61-
* Constructs a rename command.
55+
* Constructs a renameCollection command.
6256
*
6357
* Supported options:
6458
*
@@ -71,18 +65,20 @@ class RenameCollection implements Executable
7165
*
7266
* * writeConcern (MongoDB\Driver\WriteConcern): Write concern.
7367
*
74-
* * dropTarget (boolean): If true, mongod will drop the target of
75-
* renameCollection prior to renaming the collection.
76-
*
7768
* This is not supported for server versions < 3.4 and will result in an
7869
* exception at execution time if used.
7970
*
80-
* @param string $fromNamespace Namespace of the collection to rename
81-
* @param string $toNamespace New namespace of the collection
82-
* @param array $options Command options
71+
* * dropTarget (boolean): If true, MongoDB will drop the target before
72+
* renaming the collection.
73+
*
74+
* @param string $fromDatabaseName Database name
75+
* @param string $fromCollectionName Collection name
76+
* @param string $toDatabaseName New database name
77+
* @param string $toCollectionName New collection name
78+
* @param array $options Command options
8379
* @throws InvalidArgumentException for parameter/option parsing errors
8480
*/
85-
public function __construct($fromNamespace, $toNamespace, array $options = [])
81+
public function __construct($fromDatabaseName, $fromCollectionName, $toDatabaseName, $toCollectionName, array $options = [])
8682
{
8783
if (isset($options['session']) && ! $options['session'] instanceof Session) {
8884
throw InvalidArgumentException::invalidType('"session" option', $options['session'], Session::class);
@@ -104,8 +100,8 @@ public function __construct($fromNamespace, $toNamespace, array $options = [])
104100
throw InvalidArgumentException::invalidType('"dropTarget" option', $options['dropTarget'], 'boolean');
105101
}
106102

107-
$this->fromNamespace = (string) $fromNamespace;
108-
$this->toNamespace = (string) $toNamespace;
103+
$this->fromNamespace = (string) $fromDatabaseName . '.' . (string) $fromCollectionName;
104+
$this->toNamespace = (string) $toDatabaseName . '.' . (string) $toCollectionName;
109105
$this->options = $options;
110106
}
111107

@@ -129,10 +125,16 @@ public function execute(Server $server)
129125
throw UnsupportedException::writeConcernNotSupportedInTransaction();
130126
}
131127

132-
$command = new Command([
128+
$commandOptions = [
133129
'renameCollection' => $this->fromNamespace,
134130
'to' => $this->toNamespace,
135-
]);
131+
];
132+
133+
if (isset($this->options['dropTarget'])) {
134+
$commandOptions['dropTarget'] = $this->options['dropTarget'];
135+
}
136+
137+
$command = new Command($commandOptions);
136138

137139
$cursor = $server->executeWriteCommand('admin', $command, $this->createOptions());
138140

@@ -161,10 +163,6 @@ private function createOptions()
161163
$options['writeConcern'] = $this->options['writeConcern'];
162164
}
163165

164-
if (isset($this->options['dropTarget'])) {
165-
$options['dropTarget'] = $this->options['dropTarget'];
166-
}
167-
168166
return $options;
169167
}
170168
}

tests/Collection/CollectionFunctionalTest.php

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@
1313
use MongoDB\Exception\UnsupportedException;
1414
use MongoDB\MapReduceResult;
1515
use MongoDB\Operation\Count;
16-
use MongoDB\Operation\DropCollection;
17-
use MongoDB\Operation\FindOne;
1816
use MongoDB\Tests\CommandObserver;
1917

2018
use function array_filter;
@@ -334,23 +332,41 @@ public function testFindWithinTransaction(): void
334332
}
335333
}
336334

337-
public function testRename(): void
335+
public function testRenameToSameDatabase(): void
338336
{
339-
$renamedCollection = $this->getCollectionName() . '.renamed';
340-
$operation = new DropCollection($this->getDatabaseName(), $renamedCollection);
341-
$operation->execute($this->getPrimaryServer());
337+
$toCollectionName = $this->getCollectionName() . '.renamed';
338+
$toCollection = new Collection($this->manager, $this->getDatabaseName(), $toCollectionName);
342339

343-
$writeResult = $this->collection->insertOne(['_id' => 1, 'x' => 'foo']);
340+
$writeResult = $this->collection->insertOne(['_id' => 1]);
344341
$this->assertEquals(1, $writeResult->getInsertedCount());
345342

346-
$commandResult = $this->collection->rename($this->getDatabaseName() . '.' . $renamedCollection);
343+
$commandResult = $this->collection->rename($toCollectionName, null, ['dropTarget' => true]);
347344
$this->assertCommandSucceeded($commandResult);
348345
$this->assertCollectionDoesNotExist($this->getCollectionName());
349-
$this->assertCollectionExists($renamedCollection);
346+
$this->assertCollectionExists($toCollectionName);
350347

351-
$operation = new FindOne($this->getDatabaseName(), $renamedCollection, []);
352-
$cursor = $operation->execute($this->getPrimaryServer());
353-
$this->assertSameDocument(['_id' => 1, 'x' => 'foo'], $cursor);
348+
$document = $toCollection->findOne();
349+
$this->assertSameDocument(['_id' => 1], $document);
350+
$toCollection->drop();
351+
}
352+
353+
public function testRenameToDifferentDatabase(): void
354+
{
355+
$toCollectionName = $this->getCollectionName() . '.renamed';
356+
$toDatabaseName = $this->getDatabaseName() . '_renamed';
357+
$toCollection = new Collection($this->manager, $toDatabaseName, $toCollectionName);
358+
359+
$writeResult = $this->collection->insertOne(['_id' => 1]);
360+
$this->assertEquals(1, $writeResult->getInsertedCount());
361+
362+
$commandResult = $this->collection->rename($toCollectionName, $toDatabaseName, ['dropTarget' => true]);
363+
$this->assertCommandSucceeded($commandResult);
364+
$this->assertCollectionDoesNotExist($this->getCollectionName());
365+
$this->assertCollectionExists($toCollectionName, $toDatabaseName);
366+
367+
$document = $toCollection->findOne();
368+
$this->assertSameDocument(['_id' => 1], $document);
369+
$toCollection->drop();
354370
}
355371

356372
public function testWithOptionsInheritsOptions(): void

tests/Database/DatabaseFunctionalTest.php

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace MongoDB\Tests\Database;
44

5+
use MongoDB\Collection;
56
use MongoDB\Database;
67
use MongoDB\Driver\BulkWrite;
78
use MongoDB\Driver\Cursor;
@@ -10,8 +11,6 @@
1011
use MongoDB\Driver\WriteConcern;
1112
use MongoDB\Exception\InvalidArgumentException;
1213
use MongoDB\Operation\CreateIndexes;
13-
use MongoDB\Operation\DropCollection;
14-
use MongoDB\Operation\FindOne;
1514

1615
use function array_key_exists;
1716
use function current;
@@ -213,27 +212,57 @@ public function testModifyCollection(): void
213212
}
214213
}
215214

216-
public function testRenameCollection(): void
215+
public function testRenameCollectionToSameDatabase(): void
217216
{
218-
$renamedCollection = $this->getCollectionName() . '.renamed';
219-
$renamedNamespace = $this->getDatabaseName() . '.' . $renamedCollection;
220-
$operation = new DropCollection($this->getDatabaseName(), $renamedCollection);
221-
$operation->execute($this->getPrimaryServer());
217+
$toCollectionName = $this->getCollectionName() . '.renamed';
218+
$toCollection = new Collection($this->manager, $this->getDatabaseName(), $toCollectionName);
222219

223220
$bulkWrite = new BulkWrite();
224-
$bulkWrite->insert(['_id' => 1, 'x' => 'foo']);
221+
$bulkWrite->insert(['_id' => 1]);
225222

226223
$writeResult = $this->manager->executeBulkWrite($this->getNamespace(), $bulkWrite);
227224
$this->assertEquals(1, $writeResult->getInsertedCount());
228225

229-
$commandResult = $this->database->renameCollection($this->getNamespace(), $renamedNamespace);
226+
$commandResult = $this->database->renameCollection(
227+
$this->getCollectionName(),
228+
$toCollectionName,
229+
null,
230+
['dropTarget' => true]
231+
);
230232
$this->assertCommandSucceeded($commandResult);
231-
$this->assertCollectionCount($this->getNamespace(), 0);
232-
$this->assertCollectionCount($renamedNamespace, 1);
233+
$this->assertCollectionDoesNotExist($this->getCollectionName());
234+
$this->assertCollectionExists($toCollectionName);
235+
236+
$document = $toCollection->findOne();
237+
$this->assertSameDocument(['_id' => 1], $document);
238+
$toCollection->drop();
239+
}
240+
241+
public function testRenameCollectionToDifferentDatabase(): void
242+
{
243+
$toCollectionName = $this->getCollectionName() . '.renamed';
244+
$toDatabaseName = $this->getDatabaseName() . '_renamed';
245+
$toCollection = new Collection($this->manager, $toDatabaseName, $toCollectionName);
246+
247+
$bulkWrite = new BulkWrite();
248+
$bulkWrite->insert(['_id' => 1]);
249+
250+
$writeResult = $this->manager->executeBulkWrite($this->getNamespace(), $bulkWrite);
251+
$this->assertEquals(1, $writeResult->getInsertedCount());
252+
253+
$commandResult = $this->database->renameCollection(
254+
$this->getCollectionName(),
255+
$toCollectionName,
256+
$toDatabaseName,
257+
['dropTarget' => true]
258+
);
259+
$this->assertCommandSucceeded($commandResult);
260+
$this->assertCollectionDoesNotExist($this->getCollectionName());
261+
$this->assertCollectionExists($toCollectionName, $toDatabaseName);
233262

234-
$operation = new FindOne($this->getDatabaseName(), $renamedCollection, []);
235-
$cursor = $operation->execute($this->getPrimaryServer());
236-
$this->assertSameDocument(['_id' => 1, 'x' => 'foo'], $cursor);
263+
$document = $toCollection->findOne();
264+
$this->assertSameDocument(['_id' => 1], $document);
265+
$toCollection->drop();
237266
}
238267

239268
public function testSelectCollectionInheritsOptions(): void

tests/FunctionalTestCase.php

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,10 +154,17 @@ protected function assertCollectionCount($namespace, $count): void
154154
* Asserts that a collection with the given name does not exist on the
155155
* server.
156156
*
157+
* If $databaseName is not specified, the current database will be used.
158+
*
157159
* @param string $collectionName
160+
* @param string $databaseName
158161
*/
159-
protected function assertCollectionDoesNotExist(string $collectionName): void
162+
protected function assertCollectionDoesNotExist(string $collectionName, ?string $databaseName = null): void
160163
{
164+
if (! isset($databaseName)) {
165+
$databaseName = $this->getDatabaseName();
166+
}
167+
161168
$operation = new ListCollections($this->getDatabaseName());
162169
$collections = $operation->execute($this->getPrimaryServer());
163170

@@ -176,20 +183,27 @@ protected function assertCollectionDoesNotExist(string $collectionName): void
176183
/**
177184
* Asserts that a collection with the given name exists on the server.
178185
*
186+
* If $databaseName is not specified, the current database will be used.
179187
* An optional $callback may be provided, which should take a CollectionInfo
180188
* argument as its first and only parameter. If a CollectionInfo matching
181189
* the given name is found, it will be passed to the callback, which may
182190
* perform additional assertions.
183191
*
192+
* @param string $collectionName
193+
* @param string $databaseName
184194
* @param callable $callback
185195
*/
186-
protected function assertCollectionExists($collectionName, ?callable $callback = null): void
196+
protected function assertCollectionExists(string $collectionName, ?string $databaseName = null, ?callable $callback = null): void
187197
{
198+
if (! isset($databaseName)) {
199+
$databaseName = $this->getDatabaseName();
200+
}
201+
188202
if ($callback !== null && ! is_callable($callback)) {
189203
throw new InvalidArgumentException('$callback is not a callable');
190204
}
191205

192-
$operation = new ListCollections($this->getDatabaseName());
206+
$operation = new ListCollections($databaseName);
193207
$collections = $operation->execute($this->getPrimaryServer());
194208

195209
$foundCollection = null;

0 commit comments

Comments
 (0)