1616from __future__ import annotations
1717
1818import json
19+ from copy import copy
1920from datetime import datetime
2021from typing import (Any ,
2122 Dict ,
2728from acouchbase .n1ql import AsyncN1QLRequest
2829from acouchbase .search import AsyncFullTextSearchRequest
2930from acouchbase .views import AsyncViewRequest
31+ from couchbase .constants import FMT_JSON
3032from couchbase .diagnostics import (ClusterState ,
3133 EndpointDiagnosticsReport ,
3234 EndpointPingReport ,
3638from couchbase .exceptions import exception as CouchbaseBaseException
3739from couchbase .pycbc_core import result
3840from couchbase .subdocument import parse_subdocument_content_as , parse_subdocument_exists
41+ from couchbase .transcoder import Transcoder
3942
4043
4144class Result :
4245 def __init__ (
4346 self ,
44- orig , # type: result
47+ orig , # type: result
48+ transcoder = None , # type: Optional[Transcoder]
49+ is_subdoc = None , # type: Optional[bool]
4550 ):
46-
4751 self ._orig = orig
52+ self ._transcoder = transcoder
53+ self ._decoded_value : Optional [Any ] = None
54+ self ._is_subdoc = is_subdoc if is_subdoc is not None else False
4855
4956 @property
5057 def value (self ) -> Optional [Any ]:
5158 """
5259 Optional[Any]: The content of the document, if it exists.
5360 """
54- return self ._orig .raw_result .get ("value" , None )
61+ if self ._decoded_value is not None :
62+ return self ._decoded_value
63+ self ._decode_value ()
64+ return self ._decoded_value
5565
5666 @property
5767 def cas (self ) -> Optional [int ]:
@@ -81,6 +91,27 @@ def success(self) -> bool:
8191 """
8292 return self .cas != 0
8393
94+ def _decode_value (self ) -> None :
95+ if self ._transcoder is None :
96+ return
97+
98+ value = self ._orig .raw_result .get ('value' , None )
99+ if self ._is_subdoc is False :
100+ flags = self ._orig .raw_result .get ('flags' , None )
101+ self ._decoded_value = self ._transcoder .decode_value (value , flags )
102+ else :
103+ self ._decoded_value = []
104+ for f in value :
105+ if 'value' in f :
106+ tmp = copy (f )
107+ old = tmp .pop ('value' , None )
108+ if old :
109+ # no custom transcoder for subdoc ops, use JSON
110+ tmp ['value' ] = self ._transcoder .decode_value (old , FMT_JSON )
111+ self ._decoded_value .append (tmp )
112+ else :
113+ self ._decoded_value .append (f )
114+
84115
85116class ContentProxy :
86117 """
@@ -353,7 +384,8 @@ class MultiResult:
353384 def __init__ (self ,
354385 orig , # type: result
355386 result_type , # type: Union[GetReplicaResult, GetResult]
356- return_exceptions # type: bool
387+ return_exceptions , # type: bool
388+ transcoders = None # type: Optional[Dict[str, Transcoder]]
357389 ):
358390 self ._orig = orig
359391 self ._all_ok = self ._orig .raw_result .pop ('all_okay' , False )
@@ -369,7 +401,9 @@ def __init__(self,
369401 if isinstance (v , list ):
370402 self ._results [k ] = v
371403 else :
372- self ._results [k ] = result_type (v )
404+ if transcoders is None :
405+ raise InvalidArgumentException ("Transcoders dictionary must be provided" )
406+ self ._results [k ] = result_type (v , transcoder = transcoders [k ])
373407
374408 @property
375409 def all_ok (self ) -> bool :
@@ -394,9 +428,10 @@ def exceptions(self) -> Dict[str, CouchbaseBaseException]:
394428class MultiGetReplicaResult (MultiResult ):
395429 def __init__ (self ,
396430 orig , # type: result
397- return_exceptions # type: bool
431+ return_exceptions , # type: bool
432+ transcoders = None # type: Optional[Dict[str, Transcoder]]
398433 ):
399- super ().__init__ (orig , GetReplicaResult , return_exceptions )
434+ super ().__init__ (orig , GetReplicaResult , return_exceptions , transcoders )
400435
401436 @property
402437 def results (self ) -> Dict [str , GetReplicaResult ]:
@@ -423,9 +458,10 @@ def __repr__(self):
423458class MultiGetResult (MultiResult ):
424459 def __init__ (self ,
425460 orig , # type: result
426- return_exceptions # type: bool
461+ return_exceptions , # type: bool
462+ transcoders # type: Dict[str, Transcoder]
427463 ):
428- super ().__init__ (orig , GetResult , return_exceptions )
464+ super ().__init__ (orig , GetResult , return_exceptions , transcoders )
429465
430466 @property
431467 def results (self ) -> Dict [str , GetResult ]:
@@ -948,8 +984,8 @@ def __init__(
948984
949985class ScanResult (Result ):
950986
951- def __init__ (self , orig , ids_only ):
952- super ().__init__ (orig )
987+ def __init__ (self , orig , ids_only , transcoder ):
988+ super ().__init__ (orig , transcoder = transcoder )
953989 self ._ids_only = ids_only
954990
955991 @property
0 commit comments