Skip to content

Commit cc07cf5

Browse files
authored
PCBC-940 Support for subdoc read from replica (#121)
1 parent c347b27 commit cc07cf5

11 files changed

+808
-2
lines changed

Couchbase/Collection.php

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,84 @@ function (LookupInSpec $item) {
476476
return new LookupInResult($response, LookupInOptions::getTranscoder($options));
477477
}
478478

479+
/**
480+
* Performs a set of subdocument lookup operations against the document from any replica server in the cluster.
481+
*
482+
* @param string $id the key of the document
483+
* @param array<LookupInSpec> $specs the array of selectors to query against the document
484+
* @param LookupInAnyReplicaOptions|null $options the options to use for the operation
485+
*
486+
* @return LookupInReplicaResult
487+
* @throws DocumentIrretrievableException
488+
* @throws TimeoutException
489+
* @throws CouchbaseException
490+
* @since 4.1.6
491+
*/
492+
public function lookupInAnyReplica(string $id, array $specs, LookupInAnyReplicaOptions $options = null): LookupInReplicaResult
493+
{
494+
$encoded = array_map(
495+
function (LookupInSpec $item) {
496+
return $item->export();
497+
},
498+
$specs
499+
);
500+
if ($options != null && $options->needToFetchExpiry()) {
501+
$encoded[] = ['opcode' => 'get', 'isXattr' => true, 'path' => LookupInMacro::EXPIRY_TIME];
502+
}
503+
$response = Extension\documentLookupInAnyReplica(
504+
$this->core,
505+
$this->bucketName,
506+
$this->scopeName,
507+
$this->name,
508+
$id,
509+
$encoded,
510+
LookupInAnyReplicaOptions::export($options)
511+
);
512+
return new LookupInReplicaResult($response, LookupInAnyReplicaOptions::getTranscoder($options));
513+
}
514+
515+
/**
516+
* Performs a set of subdocument lookup operations against the document from the active server and all replicas in the cluster.
517+
* Returns an array of LookupInReplicaResults, one per server.
518+
*
519+
* @param string $id the key of the document
520+
* @param array<LookupInSpec> $specs the array of selectors to query against the document
521+
* @param LookupInAllReplicasOptions|null $options the options to use for the operation
522+
*
523+
* @return array
524+
* @throws DocumentNotFoundException
525+
* @throws TimeoutException
526+
* @throws CouchbaseException
527+
* @since 4.1.6
528+
*/
529+
public function lookupInAllReplicas(string $id, array $specs, LookupInAllReplicasOptions $options = null): array
530+
{
531+
$encoded = array_map(
532+
function (LookupInSpec $item) {
533+
return $item->export();
534+
},
535+
$specs
536+
);
537+
if ($options != null && $options->needToFetchExpiry()) {
538+
$encoded[] = ['opcode' => 'get', 'isXattr' => true, 'path' => LookupInMacro::EXPIRY_TIME];
539+
}
540+
$responses = Extension\documentLookupInAllReplicas(
541+
$this->core,
542+
$this->bucketName,
543+
$this->scopeName,
544+
$this->name,
545+
$id,
546+
$encoded,
547+
LookupInAllReplicasOptions::export($options)
548+
);
549+
return array_map(
550+
function (array $response) use ($options) {
551+
return new LookupInReplicaResult($response, LookupInAllReplicasOptions::getTranscoder($options));
552+
},
553+
$responses
554+
);
555+
}
556+
479557
/**
480558
* Performs a set of subdocument lookup operations against the document.
481559
*
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
<?php
2+
3+
/**
4+
* Copyright 2014-Present Couchbase, Inc.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
declare(strict_types=1);
20+
21+
namespace Couchbase;
22+
23+
class LookupInAllReplicasOptions
24+
{
25+
private Transcoder $transcoder;
26+
private ?int $timeoutMilliseconds = null;
27+
private ?bool $withExpiry = null;
28+
29+
/**
30+
* @since 4.1.6
31+
*/
32+
public function __construct()
33+
{
34+
$this->transcoder = JsonTranscoder::getInstance();
35+
}
36+
37+
/**
38+
* Static helper to keep code more readable
39+
*
40+
* @return LookupInAllReplicasOptions
41+
* @since 4.1.6
42+
*/
43+
public static function build(): LookupInAllReplicasOptions
44+
{
45+
return new LookupInAllReplicasOptions();
46+
}
47+
48+
/**
49+
* Sets the operation timeout in milliseconds.
50+
*
51+
* @param int $milliseconds the operation timeout to apply
52+
*
53+
* @return LookupInAllReplicasOptions
54+
* @since 4.1.6
55+
*/
56+
public function timeout(int $milliseconds): LookupInAllReplicasOptions
57+
{
58+
$this->timeoutMilliseconds = $milliseconds;
59+
return $this;
60+
}
61+
62+
/**
63+
* Sets whether to include document expiry with the document content.
64+
*
65+
* When used this option will add one extra subdocument path into
66+
* the LookupIn operation. This can cause the set of subdocument paths
67+
* to exceed the maximum number (16) of paths allowed in a subdocument
68+
* operation.
69+
*
70+
* @param bool $fetchExpiry whether to include document expiry
71+
*
72+
* @return LookupInAllReplicasOptions
73+
* @since 4.1.6
74+
*/
75+
public function withExpiry(bool $fetchExpiry): LookupInAllReplicasOptions
76+
{
77+
$this->withExpiry = $fetchExpiry;
78+
return $this;
79+
}
80+
81+
/**
82+
* @internal
83+
* @return bool
84+
* @since 4.1.6
85+
*/
86+
public function needToFetchExpiry(): bool
87+
{
88+
if ($this->withExpiry == null) {
89+
return false;
90+
}
91+
return $this->withExpiry;
92+
}
93+
94+
/**
95+
* Associate custom transcoder with the request.
96+
*
97+
* @param Transcoder $transcoder
98+
*
99+
* @return LookupInAllReplicasOptions
100+
* @since 4.1.6
101+
*/
102+
public function transcoder(Transcoder $transcoder): LookupInAllReplicasOptions
103+
{
104+
$this->transcoder = $transcoder;
105+
return $this;
106+
}
107+
108+
/**
109+
* Returns associated transcoder.
110+
*
111+
* @param LookupInAllReplicasOptions|null $options
112+
*
113+
* @return Transcoder
114+
* @since 4.1.6
115+
*/
116+
public static function getTranscoder(?LookupInAllReplicasOptions $options): Transcoder
117+
{
118+
if ($options == null) {
119+
return JsonTranscoder::getInstance();
120+
}
121+
return $options->transcoder;
122+
}
123+
124+
/**
125+
* @internal
126+
*
127+
* @param LookupInAllReplicasOptions|null $options
128+
*
129+
* @return array
130+
* @since 4.1.6
131+
*/
132+
public static function export(?LookupInAllReplicasOptions $options): array
133+
{
134+
if ($options == null) {
135+
return [];
136+
}
137+
return [
138+
'timeoutMilliseconds' => $options->timeoutMilliseconds,
139+
];
140+
}
141+
}
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
<?php
2+
3+
/**
4+
* Copyright 2014-Present Couchbase, Inc.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
declare(strict_types=1);
20+
21+
namespace Couchbase;
22+
23+
class LookupInAnyReplicaOptions
24+
{
25+
private Transcoder $transcoder;
26+
private ?int $timeoutMilliseconds = null;
27+
private ?bool $withExpiry = null;
28+
29+
/**
30+
* @since 4.1.6
31+
*/
32+
public function __construct()
33+
{
34+
$this->transcoder = JsonTranscoder::getInstance();
35+
}
36+
37+
/**
38+
* Static helper to keep code more readable
39+
*
40+
* @return LookupInAnyReplicaOptions
41+
* @since 4.1.6
42+
*/
43+
public static function build(): LookupInAnyReplicaOptions
44+
{
45+
return new LookupInAnyReplicaOptions();
46+
}
47+
48+
/**
49+
* Sets the operation timeout in milliseconds.
50+
*
51+
* @param int $milliseconds the operation timeout to apply
52+
*
53+
* @return LookupInAnyReplicaOptions
54+
* @since 4.1.6
55+
*/
56+
public function timeout(int $milliseconds): LookupInAnyReplicaOptions
57+
{
58+
$this->timeoutMilliseconds = $milliseconds;
59+
return $this;
60+
}
61+
62+
/**
63+
* Sets whether to include document expiry with the document content.
64+
*
65+
* When used this option will add one extra subdocument path into
66+
* the LookupIn operation. This can cause the set of subdocument paths
67+
* to exceed the maximum number (16) of paths allowed in a subdocument
68+
* operation.
69+
*
70+
* @param bool $fetchExpiry whether to include document expiry
71+
*
72+
* @return LookupInAnyReplicaOptions
73+
* @since 4.1.6
74+
*/
75+
public function withExpiry(bool $fetchExpiry): LookupInAnyReplicaOptions
76+
{
77+
$this->withExpiry = $fetchExpiry;
78+
return $this;
79+
}
80+
81+
/**
82+
* @internal
83+
* @return bool
84+
* @since 4.1.6
85+
*/
86+
public function needToFetchExpiry(): bool
87+
{
88+
if ($this->withExpiry == null) {
89+
return false;
90+
}
91+
return $this->withExpiry;
92+
}
93+
/**
94+
* Associate custom transcoder with the request.
95+
*
96+
* @param Transcoder $transcoder
97+
*
98+
* @return LookupInAnyReplicaOptions
99+
* @since 4.1.6
100+
*/
101+
public function transcoder(Transcoder $transcoder): LookupInAnyReplicaOptions
102+
{
103+
$this->transcoder = $transcoder;
104+
return $this;
105+
}
106+
107+
/**
108+
* Returns associated transcoder.
109+
*
110+
* @param LookupInAnyReplicaOptions|null $options
111+
*
112+
* @return Transcoder
113+
* @since 4.1.6
114+
*/
115+
public static function getTranscoder(?LookupInAnyReplicaOptions $options): Transcoder
116+
{
117+
if ($options == null) {
118+
return JsonTranscoder::getInstance();
119+
}
120+
return $options->transcoder;
121+
}
122+
123+
/**
124+
* @internal
125+
*
126+
* @param LookupInAnyReplicaOptions|null $options
127+
*
128+
* @return array
129+
* @since 4.1.6
130+
*/
131+
public static function export(?LookupInAnyReplicaOptions $options): array
132+
{
133+
if ($options == null) {
134+
return [];
135+
}
136+
return [
137+
'timeoutMilliseconds' => $options->timeoutMilliseconds,
138+
];
139+
}
140+
}

0 commit comments

Comments
 (0)