Skip to content

Commit

Permalink
feat: add SetContainsElements API (#209)
Browse files Browse the repository at this point in the history
* feat: add SetContainsElements API
  • Loading branch information
cprice404 authored Sep 24, 2024
1 parent 4b63c2f commit eec6083
Show file tree
Hide file tree
Showing 4 changed files with 399 additions and 2 deletions.
58 changes: 56 additions & 2 deletions src/Cache/CacheClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
use Momento\Cache\CacheOperationTypes\ListRemoveValueResponse;
use Momento\Cache\CacheOperationTypes\SetAddElementResponse;
use Momento\Cache\CacheOperationTypes\SetAddElementsResponse;
use Momento\Cache\CacheOperationTypes\SetContainsElementsResponse;
use Momento\Cache\CacheOperationTypes\SetBatchResponse;
use Momento\Cache\CacheOperationTypes\SetFetchResponse;
use Momento\Cache\CacheOperationTypes\SetIfAbsentOrEqualResponse;
Expand Down Expand Up @@ -1461,7 +1462,7 @@ public function setAddElement(string $cacheName, string $setName, string $elemen
* @param string $cacheName Name of the cache that contains the set.
* @param string $setName The set to add the element to.
* @param list<string> $elements The elements to add.
* @param CollectionTtl|null $ttl TTL for the dictionary in cache. This TTL takes precedence over the TTL used when initializing a cache client. Defaults to client TTL.
* @param CollectionTtl|null $ttl TTL for the set in cache. This TTL takes precedence over the TTL used when initializing a cache client. Defaults to client TTL.
* @return ResponseFuture<SetAddElementsResponse> A waitable future which
* will provide the result of the set operation upon a blocking call to
* wait.
Expand Down Expand Up @@ -1491,7 +1492,7 @@ public function setAddElementsAsync(string $cacheName, string $setName, array $e
* @param string $cacheName Name of the cache that contains the set.
* @param string $setName The set to add the element to.
* @param list<string> $elements The elements to add.
* @param CollectionTtl|null $ttl TTL for the dictionary in cache. This TTL takes precedence over the TTL used when initializing a cache client. Defaults to client TTL.
* @param CollectionTtl|null $ttl TTL for the set in cache. This TTL takes precedence over the TTL used when initializing a cache client. Defaults to client TTL.
* @return SetAddElementsResponse Represents the result of the set add elements operation.
* This result is resolved to a type-safe object of one of the following types:<br>
* * SetAddElementsSuccess<br>
Expand All @@ -1505,6 +1506,59 @@ public function setAddElements(string $cacheName, string $setName, array $elemen
return $this->setAddElementsAsync($cacheName, $setName, $elements, $ttl)->wait();
}


/**
* Check whether a set includes specified elements.
*
* @param string $cacheName Name of the cache that contains the set.
* @param string $setName The set to look for elements in
* @param list<string> $elements The elements to check for.
* @return ResponseFuture<SetContainsElementsResponse> A waitable future which
* will provide the result of the set operation upon a blocking call to
* wait.
* <code>$response = $responseFuture->wait();</code><br />
* The response represents the result of the SetContainsElements operation.
* This result is resolved to a type-safe object of one of the following
* types:<br>
* * SetContainsElementsHit: the set exists, and the <code>containsElementsDictionary</code> function on this object can be used to inspect which elements exist in the set.<br>
* * SetContainsElementsMiss: the set does not exist<br>
* * SetContainsElementsError<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 setContainsElementsAsync(string $cacheName, string $setName, array $elements): ResponseFuture
{
return $this->getNextDataClient()->setContainsElements($cacheName, $setName, $elements);
}

/**
* Check whether a set includes specified elements.
*
* @param string $cacheName Name of the cache that contains the set.
* @param string $setName The set to look for elements in.
* @param list<string> $elements The elements to check for.
* @return SetContainsElementsResponse Represents the result of the set add elements operation.
* This result is resolved to a type-safe object of one of the following types:<br>
* * SetContainsElementsHit: the set exists, and the <code>containsElements</code> function on this object can be used to inspect which elements exist in the set.<br>
* * SetContainsElementsMiss: the set does not exist<br>
* * SetContainsElementsError<br>
* if ($error = $response->asError()) {<br>
* &nbsp;&nbsp;// handle error condition<br>
* }</code>
*/
public function setContainsElements(string $cacheName, string $setName, array $elements): SetContainsElementsResponse
{
return $this->setContainsElementsAsync($cacheName, $setName, $elements)->wait();
}



/**
* Fetch an entire set from the cache.
*
Expand Down
114 changes: 114 additions & 0 deletions src/Cache/CacheOperationTypes/CacheOperationTypes.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use Cache_client\_ListPopFrontResponse;
use Cache_client\_ListPushBackResponse;
use Cache_client\_ListPushFrontResponse;
use Cache_client\_SetContainsResponse;
use Cache_client\_SetFetchResponse;
use Cache_client\_SetLengthResponse;
use Cache_client\_SetResponse;
Expand Down Expand Up @@ -2868,6 +2869,119 @@ class SetAddElementsError extends SetAddElementsResponse
use ErrorBody;
}

/**
* Parent response type for a SetContainsElements request. The
* response object is resolved to a type-safe object of one of
* the following subtypes:
*
* * SetContainsElementsHit
* * SetContainsElementsMiss
* * SetContainsElementsError
*
* Pattern matching can be used to operate on the appropriate subtype.
* For example:
* <code>
* if ($success = $response->asHit()) {
* // a dictionary containing a key for each `element` in your request; the value is a boolean indicating whether the element is in the set
* return $success->containsElementsDictionary();
* } elseif ($response->asMiss())
* // handle miss as appropriate
* } elseif ($error = $response->asError())
* // handle error as appropriate
* }
* </code>
*/
abstract class SetContainsElementsResponse extends ResponseBase
{

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

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

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

/**
* Contains the result of a cache hit.
*/
class SetContainsElementsHit extends SetContainsElementsResponse
{
private array $values = [];
private array $valuesDictionary = [];

public function __construct(_SetContainsResponse $response, array $elements) {
parent::__construct();
foreach ($response->getFound()->getContains()->getIterator() as $index=>$value) {
$this->values[] = (bool)$value;
$this->valuesDictionary[$elements[$index]] = (bool)$value;
}
}

/**
* @return array List of booleans corresponding to the supplied elements.
*/
public function containsElements() : array {
return $this->values;
}

/**
* @return array Dictionary mapping supplied elements to booleans indicating whether the key exists in the set.
*/
public function containsElementsDictionary() : array
{
return $this->valuesDictionary;
}

public function __toString()
{
$numElements = count($this->values);
return parent::__toString() . ": $numElements elements";
}
}

/**
* Indicates that the request that generated it was a cache miss.
*/
class SetContainsElementsMiss extends SetContainsElementsResponse
{
}

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


/**
* Parent response type for a set fetch request. The
* response object is resolved to a type-safe object of one of
Expand Down
47 changes: 47 additions & 0 deletions src/Cache/Internal/ScsDataClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
use Cache_client\_ListPushFrontRequest;
use Cache_client\_ListRemoveRequest;
use Cache_client\_SetBatchRequest;
use Cache_client\_SetContainsRequest;
use Cache_client\_SetDifferenceRequest;
use Cache_client\_SetDifferenceRequest\_Subtrahend;
use Cache_client\_SetDifferenceRequest\_Subtrahend\_Set;
Expand Down Expand Up @@ -117,6 +118,10 @@
use Momento\Cache\CacheOperationTypes\SetAddElementsResponse;
use Momento\Cache\CacheOperationTypes\SetAddElementsError;
use Momento\Cache\CacheOperationTypes\SetAddElementsSuccess;
use Momento\Cache\CacheOperationTypes\SetContainsElementsResponse;
use Momento\Cache\CacheOperationTypes\SetContainsElementsError;
use Momento\Cache\CacheOperationTypes\SetContainsElementsHit;
use Momento\Cache\CacheOperationTypes\SetContainsElementsMiss;
use Momento\Cache\CacheOperationTypes\SetBatchError;
use Momento\Cache\CacheOperationTypes\SetBatchResponse;
use Momento\Cache\CacheOperationTypes\SetBatchSuccess;
Expand Down Expand Up @@ -1329,6 +1334,48 @@ function () use ($call): SetAddElementsResponse {
);
}

/**
* @param list<string> $elements
* @return ResponseFuture<SetContainsElementsResponse>
*/
public function setContainsElements(string $cacheName, string $setName, array $elements): ResponseFuture
{
try {
validateCacheName($cacheName);
validateSetName($setName);
validateElements($elements);
$setContainsElementsRequest = new _SetContainsRequest();
$setContainsElementsRequest->setSetName($setName);
$setContainsElementsRequest->setElements($elements);
$call = $this->grpcManager->client->SetContains(
$setContainsElementsRequest,
["cache" => [$cacheName]],
["timeout" => $this->timeout],
);
} catch (SdkError $e) {
return ResponseFuture::createResolved(new SetContainsElementsError($e));
} catch (Exception $e) {
return ResponseFuture::createResolved(new SetContainsElementsError(new UnknownError($e->getMessage(), 0, $e)));
}

return ResponseFuture::createPending(
function () use ($call, $elements): SetContainsElementsResponse {
try {
$response = $this->processCall($call);

if ($response->hasFound()) {
return new SetContainsElementsHit($response, $elements);
}
return new SetContainsElementsMiss();
} catch (SdkError $e) {
return new SetContainsElementsError($e);
} catch (Exception $e) {
return new SetContainsElementsError(new UnknownError($e->getMessage(), 0, $e));
}
}
);
}

/**
* @return ResponseFuture<SetFetchResponse>
*/
Expand Down
Loading

0 comments on commit eec6083

Please sign in to comment.