diff --git a/src/Client.php b/src/Client.php index 8879ed6..9fcfee8 100644 --- a/src/Client.php +++ b/src/Client.php @@ -29,6 +29,7 @@ use Etcdserverpb\ResponseOp; use Etcdserverpb\TxnRequest; use Etcdserverpb\TxnResponse; +use Generator; use Grpc\ChannelCredentials; use Mvccpb\KeyValue; @@ -129,7 +130,7 @@ public function put(string $key, $value, bool $prevKv = false, int $leaseID = 0, $request->setLease($leaseID); /** @var PutResponse $response */ - list($response, $status) = $client->Put($request, $this->getMetaData(), $this->getOptions())->wait(); + [$response, $status] = $client->Put($request, $this->getMetaData(), $this->getOptions())->wait(); $this->validateStatus($status); if ($prevKv) { @@ -152,7 +153,7 @@ public function get(string $key) $request->setKey($key); /** @var RangeResponse $response */ - list($response, $status) = $client->Range($request, $this->getMetaData(), $this->getOptions())->wait(); + [$response, $status] = $client->Range($request, $this->getMetaData(), $this->getOptions())->wait(); $this->validateStatus($status); $field = $response->getKvs(); @@ -164,6 +165,45 @@ public function get(string $key) return $field[0]->getValue(); } + /** + * Get range of values by key prefix + * + * @param string $prefix + * @param int $limit + * @return Generator + * @throws InvalidResponseStatusCodeException + */ + public function getWithPrefix(string $prefix, int $limit = 100): Generator + { + $client = $this->getKvClient(); + $rangeEnd = $prefix."\xff"; + + do{ + $request = (new RangeRequest()) + ->setKey($prefix) + ->setRangeEnd($rangeEnd) + ->setLimit($limit); + + /** @var RangeResponse $response */ + [$response, $status] = $client->Range($request, $this->getMetaData(), $this->getOptions())->wait(); + $this->validateStatus($status); + + $field = $response->getKvs(); + if (count($field) === 0) { + return; + } + + foreach ($field as $kv) { + yield $kv; + } + + if(!isset($kv)) { + return; + } + $prefix = $kv->getKey()."\x00"; + }while (true); + } + /** * Delete a key * @@ -179,7 +219,7 @@ public function delete(string $key) $request->setKey($key); /** @var DeleteRangeResponse $response */ - list($response, $status) = $client->DeleteRange($request, $this->getMetaData(), $this->getOptions())->wait(); + [$response, $status] = $client->DeleteRange($request, $this->getMetaData(), $this->getOptions())->wait(); $this->validateStatus($status); if ($response->getDeleted() > 0) { @@ -242,7 +282,7 @@ public function getLeaseID(int $ttl) $leaseRequest->setTTL($ttl); /** @var LeaseGrantResponse $response */ - list($response, $status) = $lease->LeaseGrant($leaseRequest, $this->getMetaData())->wait(); + [$response, $status] = $lease->LeaseGrant($leaseRequest, $this->getMetaData())->wait(); $this->validateStatus($status); return (int)$response->getID(); @@ -260,7 +300,7 @@ public function revokeLeaseID(int $leaseID) $leaseRequest = new LeaseRevokeRequest(); $leaseRequest->setID($leaseID); - list(, $status) = $lease->LeaseRevoke($leaseRequest, $this->getMetaData())->wait(); + [, $status] = $lease->LeaseRevoke($leaseRequest, $this->getMetaData())->wait(); $this->validateStatus($status); } @@ -312,7 +352,7 @@ public function txnRequest(array $requestOperations, ?array $failureOperations, $request->setFailure($failureOperations); /** @var TxnResponse $response */ - list($response, $status) = $client->Txn($request, $this->getMetaData(), $this->getOptions())->wait(); + [$response, $status] = $client->Txn($request, $this->getMetaData(), $this->getOptions())->wait(); $this->validateStatus($status); return $response; @@ -504,7 +544,7 @@ protected function getAuthenticationToken(): string $request->setPassword($this->password); /** @var AuthenticateResponse $response */ - list($response, $status) = $client->Authenticate($request, [], $this->getOptions())->wait(); + [$response, $status] = $client->Authenticate($request, [], $this->getOptions())->wait(); $this->validateStatus($status); $this->token = $response->getToken(); @@ -604,4 +644,4 @@ protected function getFailOperation(string $key, bool $returnNewValueOnFail) return $failOperation; } -} \ No newline at end of file +} diff --git a/src/ClientInterface.php b/src/ClientInterface.php index 52e4b15..4132ddc 100644 --- a/src/ClientInterface.php +++ b/src/ClientInterface.php @@ -7,6 +7,8 @@ use Etcdserverpb\RequestOp; use Etcdserverpb\TxnResponse; use Exception; +use Generator; +use Mvccpb\KeyValue; /** * Interface ClientInterface @@ -44,6 +46,16 @@ public function put(string $key, $value, bool $prevKv = false, int $leaseID = 0, */ public function get(string $key); + /** + * Get range of values by key prefix + * + * @param string $prefix + * @param int $limit The limit number of keys to be returned in one request (size of page) + * @return Generator + * @throws InvalidResponseStatusCodeException + */ + public function getWithPrefix(string $prefix, int $limit = 100): Generator; + /** * Delete a key * @@ -172,4 +184,4 @@ public function refreshLease(int $leaseID); * ] */ public function getResponses(TxnResponse $txnResponse, ?string $type = null, bool $simpleArray = false): array; -} \ No newline at end of file +} diff --git a/src/FailoverClient.php b/src/FailoverClient.php index d2a4003..628e1df 100644 --- a/src/FailoverClient.php +++ b/src/FailoverClient.php @@ -10,6 +10,7 @@ use Etcdserverpb\Compare; use Etcdserverpb\RequestOp; use Etcdserverpb\TxnResponse; +use Generator; /** * Class FailoverClient @@ -104,6 +105,17 @@ public function get(string $key) return $this->callClientMethod(__FUNCTION__, false, $key); } + /** + * @param string $prefix + * @param int $limit + * @inheritDoc + * @throws NoClientAvailableException + */ + public function getWithPrefix(string $prefix, int $limit = 100): Generator + { + return $this->callClientMethod(__FUNCTION__, false, $prefix, $limit); + } + /** * @inheritDoc * @throws NoClientAvailableException @@ -321,4 +333,4 @@ protected function callClientMethod(string $name, bool $isLocalCall, ...$argumen } } } -} \ No newline at end of file +} diff --git a/src/ShardedClient.php b/src/ShardedClient.php index 426dc45..3bbe6ab 100644 --- a/src/ShardedClient.php +++ b/src/ShardedClient.php @@ -8,6 +8,7 @@ use Etcdserverpb\TxnResponse; use Flexihash\Exception; use Flexihash\Flexihash; +use Generator; /** * Class ShardedClient @@ -114,6 +115,17 @@ public function get(string $key) return $this->getClientFromKey($key)->get($key); } + /** + * @param string $prefix + * @param int $limit + * @inheritDoc + * @throws Exception + */ + public function getWithPrefix(string $prefix, int $limit = 100): Generator + { + return $this->getClientFromKey($prefix)->getWithPrefix($prefix, $limit); + } + /** * @inheritDoc * @throws Exception @@ -233,4 +245,4 @@ public function getResponses(TxnResponse $txnResponse, ?string $type = null, boo { return $this->getRandomClient()->getResponses($txnResponse, $type, $simpleArray); } -} \ No newline at end of file +}