Skip to content

Commit

Permalink
feat: add sortedSetRemoveElement api (#222)
Browse files Browse the repository at this point in the history
  • Loading branch information
rishtigupta authored Oct 17, 2024
1 parent 2c44adb commit f1948f2
Show file tree
Hide file tree
Showing 4 changed files with 207 additions and 2 deletions.
51 changes: 50 additions & 1 deletion src/Cache/CacheClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
use Momento\Cache\CacheOperationTypes\CreateCacheResponse;
use Momento\Cache\CacheOperationTypes\DeleteCacheResponse;
use Momento\Cache\CacheOperationTypes\ListCachesResponse;
use Momento\Cache\CacheOperationTypes\SortedSetRemoveElementResponse;
use Momento\Cache\CacheOperationTypes\UpdateTtlResponse;
use Momento\Cache\Errors\InvalidArgumentError;
use Momento\Cache\Internal\IdleDataClientWrapper;
Expand Down Expand Up @@ -1730,7 +1731,7 @@ public function setRemoveElement(string $cacheName, string $setName, string $ele
* @param float $score The score to assign to the value.
* @param CollectionTtl|null $ttl TTL for the sorted set in the cache. This TTL takes precedence over the TTL used when initializing a cache client. Defaults to the client TTL.
* @return ResponseFuture<SortedSetPutElementResponse> A waitable future which
* will provide the result of the set operation upon a blocking call to
* will provide the result of the sorted set put element operation upon a blocking call to
* wait.
* <code>$response = $responseFuture->wait();</code><br />
* The response represents the result of the sorted set put element operation.
Expand Down Expand Up @@ -1904,6 +1905,54 @@ private function getNextDataClient(): ScsDataClient
return $client;
}

/**
* Remove an element to a sorted set.
*
* @param string $cacheName Name of the cache that contains the sorted set.
* @param string $sortedSetName The set to remove the element from.
* @param string $value The value to remove.
* @return ResponseFuture<SortedSetRemoveElementResponse> A waitable future which
* will provide the result of the sorted set remove element operation upon a blocking call to
* wait.
* <code>$response = $responseFuture->wait();</code><br />
* The response represents the result of the sorted set remove element operation.
* This result is resolved to a type-safe object of one of the following
* types:<br>
* * SortedSetRemoveElementSuccess<br>
* * SortedSetRemoveElementError<br>
* <code>
* if ($error = $response->asError()) {
* // handle error condition
* }
* </code>
* If inspection of the response is not required, one need not call wait as
* we implicitly wait for completion of the request on destruction of the
* response future.
*/
public function sortedSetRemoveElementAsync(string $cacheName, string $sortedSetName, string $value): ResponseFuture
{
return $this->getNextDataClient()->sortedSetRemoveElement($cacheName, $sortedSetName, $value);
}

/**
* Remove an element to a sorted set.
*
* @param string $cacheName Name of the cache that contains the sorted set.
* @param string $sortedSetName The set to remove the element from.
* @param string $value The value to add.
* @return SortedSetRemoveElementResponse Represents the result of the sorted set remove element operation.
* This result is resolved to a type-safe object of one of the following types:<br>
* * SortedSetRemoveElementSuccess<br>
* * SortedSetRemoveElementError<br>
* if ($error = $response->asError()) {<br>
* &nbsp;&nbsp;// handle error condition<br>
* }</code>
*/
public function sortedSetRemoveElement(string $cacheName, string $sortedSetName, string $value): SortedSetRemoveElementResponse
{
return $this->sortedSetRemoveElementAsync($cacheName, $sortedSetName, $value)->wait();
}

/**
* Gets the cache values stored for given keys.
*
Expand Down
58 changes: 58 additions & 0 deletions src/Cache/CacheOperationTypes/CacheOperationTypes.php
Original file line number Diff line number Diff line change
Expand Up @@ -3508,6 +3508,64 @@ public function __construct(string $value, SdkError $error)
}
}

/**
* Parent response type for a sorted set remove element request. The
* response object is resolved to a type-safe object of one of
* the following subtypes:
*
* * SortedSetRemoveElementSuccess
* * SortedSetRemoveElementError
*
* Pattern matching can be used to operate on the appropriate subtype.
* For example:
* <code>
* if ($response->asSuccess()) {
* // handle success as appropriate
* } elseif ($error = $response->asError())
* // handle error as appropriate
* }
* </code>
*/
abstract class SortedSetRemoveElementResponse extends ResponseBase
{
/**
* @return SortedSetRemoveElementSuccess|null Returns the success subtype if the request was successful and null otherwise.
*/
public function asSuccess(): ?SortedSetRemoveElementSuccess
{
if ($this->isSuccess()) {
return $this;
}
return null;
}

/**
* @return SortedSetRemoveElementError|null Returns the error subtype if the request returned an error and null otherwise.
*/
public function asError(): ?SortedSetRemoveElementError
{
if ($this->isError()) {
return $this;
}
return null;
}
}

/**
* Indicates that the request that generated it was successful.
*/
class SortedSetRemoveElementSuccess extends SortedSetRemoveElementResponse
{
}

/**
* Contains information about an error returned from the request.
*/
class SortedSetRemoveElementError extends SortedSetRemoveElementResponse
{
use ErrorBody;
}

abstract class GetBatchResponse extends ResponseBase
{
/**
Expand Down
45 changes: 45 additions & 0 deletions src/Cache/Internal/ScsDataClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
use Cache_client\_SortedSetFetchRequest;
use Cache_client\_SortedSetGetScoreRequest;
use Cache_client\_SortedSetPutRequest;
use Cache_client\_SortedSetRemoveRequest;
use Cache_client\_UpdateTtlRequest;
use Cache_client\ECacheResult;
use Common\_Unbounded;
Expand Down Expand Up @@ -198,6 +199,9 @@
use Momento\Cache\CacheOperationTypes\SortedSetPutElementError;
use Momento\Cache\CacheOperationTypes\SortedSetPutElementResponse;
use Momento\Cache\CacheOperationTypes\SortedSetPutElementSuccess;
use Momento\Cache\CacheOperationTypes\SortedSetRemoveElementError;
use Momento\Cache\CacheOperationTypes\SortedSetRemoveElementResponse;
use Momento\Cache\CacheOperationTypes\SortedSetRemoveElementSuccess;
use Momento\Cache\CacheOperationTypes\UpdateTtlError;
use Momento\Cache\CacheOperationTypes\UpdateTtlMiss;
use Momento\Cache\CacheOperationTypes\UpdateTtlResponse;
Expand Down Expand Up @@ -1640,6 +1644,47 @@ function () use ($call): SortedSetFetchResponse {
);
}

/**
* @return ResponseFuture<SortedSetRemoveElementResponse>
*/
public function sortedSetRemoveElement(string $cacheName, string $sortedSetName, string $value): ResponseFuture
{
try {
validateCacheName($cacheName);
validateSortedSetName($sortedSetName);
validateValueName($value);
$sortedSetRemoveElementRequest = new _SortedSetRemoveRequest();
$sortedSetRemoveElementRequest->setSetName($sortedSetName);
$sortedSetRemoveElementRequest->setSome(new _SortedSetRemoveRequest\_Some());
$sortedSetRemoveElementRequest->getSome()->setValues([$value]);

$call = $this->grpcManager->client->SortedSetRemove(
$sortedSetRemoveElementRequest,
["cache" => [$cacheName]],
["timeout" => $this->timeout],
);
} catch (SdkError $e) {
return ResponseFuture::createResolved(new SortedSetRemoveElementError($e));
} catch (Exception $e) {
return ResponseFuture::createResolved(new SortedSetRemoveElementError(new UnknownError($e->getMessage(), 0, $e)));
}

return ResponseFuture::createPending(
function () use ($call): SortedSetRemoveElementResponse {
try {
$this->processCall($call);

return new SortedSetRemoveElementSuccess();
} catch (SdkError $e) {
return new SortedSetRemoveElementError($e);
} catch (Exception $e) {
return new SortedSetRemoveElementError(new UnknownError($e->getMessage(), 0, $e));
}
}
);

}

/**
* @return ResponseFuture<SortedSetGetScoreResponse>
*/
Expand Down
55 changes: 54 additions & 1 deletion tests/Cache/CacheClientTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3112,7 +3112,7 @@ public function testSortedSetAddElement_HappyPath()
$this->assertEquals($score, $valuesArray[$value], "The score for value '$value' does not match the expected score.");
}

public function testSortedSetAddElementWithNonexistantCache_ThrowsException()
public function testSortedSetAddElementWithNonexistentCache_ThrowsException()
{
$cacheName = uniqid();
$sortedSetName = uniqid();
Expand Down Expand Up @@ -3297,6 +3297,59 @@ public function testSortedSetFetchByRankWithNegativeStartRankLessThanEndRank_Thr
$this->assertEquals(MomentoErrorCode::INVALID_ARGUMENT_ERROR, $response->asError()->errorCode());
}

public function testSortedSetRemoveElement_HappyPath()
{
$sortedSetName = uniqid();
$value = uniqid();
$response = $this->client->sortedSetRemoveElement($this->TEST_CACHE_NAME, $sortedSetName, $value);
$this->assertNull($response->asError());
$this->assertNotNull($response->asSuccess(), "Expected a success but got: $response");

$response = $this->client->sortedSetFetchByRank($this->TEST_CACHE_NAME, $sortedSetName);
$this->assertNull($response->asError());
$this->assertNotNull($response->asMiss(), "Expected a miss but got: $response");
}

public function testSortedSetRemoveElementWithNonexistentCache_ThrowsException()
{
$cacheName = uniqid();
$sortedSetName = uniqid();
$value = uniqid();

$response = $this->client->sortedSetRemoveElement($cacheName, $sortedSetName, $value);
$this->assertNotNull($response->asError(), "Expected error but got: $response");
$this->assertEquals(MomentoErrorCode::CACHE_NOT_FOUND_ERROR, $response->asError()->errorCode());
}

public function testSortedSetRemoveElementWithNullCacheName_ThrowsException()
{
$sortedSetName = uniqid();
$value = uniqid();

$response = $this->client->sortedSetRemoveElement((string)null, $sortedSetName, $value);
$this->assertNotNull($response->asError(), "Expected error but got: $response");
$this->assertEquals(MomentoErrorCode::INVALID_ARGUMENT_ERROR, $response->asError()->errorCode());
}

public function testSortedSetRemoveElementWithEmptyCacheName_ThrowsException()
{
$sortedSetName = uniqid();
$value = uniqid();

$response = $this->client->sortedSetRemoveElement("", $sortedSetName, $value);
$this->assertNotNull($response->asError(), "Expected error but got: $response");
$this->assertEquals(MomentoErrorCode::INVALID_ARGUMENT_ERROR, $response->asError()->errorCode());
}

public function testSortedSetRemoveElementWithEmptyValue_ThrowsException()
{
$sortedSetName = uniqid();

$response = $this->client->sortedSetRemoveElement($this->TEST_CACHE_NAME, $sortedSetName, (string)null);
$this->assertNotNull($response->asError(), "Expected error but got: $response");
$this->assertEquals(MomentoErrorCode::INVALID_ARGUMENT_ERROR, $response->asError()->errorCode());
}

public function testSortedSetGetScore_HappyPath()
{
$sortedSetName = uniqid();
Expand Down

0 comments on commit f1948f2

Please sign in to comment.