Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 30 additions & 5 deletions lib/OpenCloud/ObjectStore/Resource/Container.php
Original file line number Diff line number Diff line change
Expand Up @@ -184,15 +184,40 @@ public function delete($deleteObjects = false)
*/
public function deleteAllObjects()
{
$requests = array();
$paths = array();

$list = $this->objectList();
$objects = $this->objectList();

foreach ($list as $object) {
$requests[] = $this->getClient()->delete($object->getUrl());
foreach ($objects as $object) {
$paths[] = sprintf('/%s/%s', $this->getName(), $object->getName());
}

return $this->getClient()->send($requests);
$this->getService()->batchDelete($paths);

return $this->waitUntilEmpty();
}

/**
* This is a method that makes batch deletions more convenient. It continually
* polls the resource, waiting for its state to change. If the loop exceeds the
* provided timeout, it breaks and returns FALSE.
*
* @param int $secondsToWait The number of seconds to run the loop
* @return bool
*/
public function waitUntilEmpty($secondsToWait = 60, $interval = 1)
{
$endTime = time() + $secondsToWait;

while (time() < $endTime) {
if ((int) $this->retrieveMetadata()->getProperty('Object-Count') === 0) {
return true;
}

sleep($interval);
}

return false;
}

/**
Expand Down
50 changes: 46 additions & 4 deletions lib/OpenCloud/ObjectStore/Service.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class Service extends AbstractService
{
const DEFAULT_NAME = 'cloudFiles';
const DEFAULT_TYPE = 'object-store';
const BATCH_DELETE_MAX = 10000;

/**
* This holds the associated CDN service (for Rackspace public cloud)
Expand Down Expand Up @@ -169,14 +170,55 @@ public function bulkExtract($path = '', $archive, $archiveType = UrlType::TAR_GZ
}

/**
* This method will delete multiple objects or containers from their account with a single request.
* @deprecated Please use {@see batchDelete()} instead.
*/
public function bulkDelete(array $paths)
{
$this->getLogger()->deprecated(__METHOD__, '::batchDelete()');

return $this->executeBatchDeleteRequest($paths);
}

/**
* Batch delete will delete an array of object paths. By default,
* the API will only accept a maximum of 10,000 object deletions
* per request - so for arrays that exceed this size, it is chunked
* and sent as individual requests.
*
* @param array $paths The objects you want to delete. Each path needs
* be formatted as /{containerName}/{objectName}. If
* you are deleting object_1 and object_2 from the
* photos_container, the array will be:
*
* array(
* '/photos_container/object_1',
* '/photos_container/object_2'
* )
*
* @param array $paths A two-dimensional array of paths:
* array('container_a/file_1', 'container_b/file_78', 'container_c/file_40582')
* @return array The array of responses from the API
* @throws Exception\BulkOperationException
*/
public function batchDelete(array $paths)
{
$chunks = array_chunk($paths, self::BATCH_DELETE_MAX);

$responses = array();

foreach ($chunks as $chunk) {
$responses[] = $this->executeBatchDeleteRequest($chunk);
}

return $responses;
}

/**
* Internal method for dispatching single batch delete requests.
*
* @param array $paths
* @return \Guzzle\Http\Message\Response
* @throws Exception\BulkOperationException
*/
public function bulkDelete(array $paths)
private function executeBatchDeleteRequest(array $paths)
{
$entity = EntityBody::factory(implode(PHP_EOL, $paths));

Expand Down
16 changes: 16 additions & 0 deletions tests/OpenCloud/Tests/ObjectStore/Resource/ContainerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -335,4 +335,20 @@ public function test_Object_Exists_False()
{
$this->assertFalse($this->container->objectExists('test.foo'));
}

public function test_Waiter_Returns_True_For_Empty_Container()
{
$response = new Response(204, array('X-Container-Object-Count' => 0));
$this->addMockSubscriber($response);

$this->assertTrue($this->container->waitUntilEmpty(2, 0));
}

public function test_Waiter_Returns_False_On_Timeout()
{
$response = new Response(204, array('X-Container-Object-Count' => 10));
$this->addMockSubscriber($response);

$this->assertFalse($this->container->waitUntilEmpty(0.1, 1));
}
}
14 changes: 14 additions & 0 deletions tests/OpenCloud/Tests/ObjectStore/ServiceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
*/
namespace OpenCloud\Tests\ObjectStore;

use Guzzle\Http\Message\Response;
use OpenCloud\ObjectStore\Constants\UrlType;
use OpenCloud\ObjectStore\Service;

Expand Down Expand Up @@ -137,6 +138,19 @@ public function test_Bad_Bulk_Delete()
$this->service->bulkDelete(array('nonEmptyContainer'));
}

public function test_Batch_Delete_Returns_Array_Of_Responses()
{
$responses = array_fill(0, 2, new Response(200));

foreach ($responses as $response) {
$this->addMockSubscriber($response);
}

$paths = array_fill(0, 15000, '/foo/bar');

$this->assertEquals($responses, $this->service->batchDelete($paths));
}

public function test_Accounts()
{
$account = $this->service->getAccount();
Expand Down