Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/google/cloud/firestore_v1/base_batch.py: 42%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

50 statements  

1# Copyright 2020 Google LLC All rights reserved. 

2# 

3# Licensed under the Apache License, Version 2.0 (the "License"); 

4# you may not use this file except in compliance with the License. 

5# You may obtain a copy of the License at 

6# 

7# http://www.apache.org/licenses/LICENSE-2.0 

8# 

9# Unless required by applicable law or agreed to in writing, software 

10# distributed under the License is distributed on an "AS IS" BASIS, 

11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

12# See the License for the specific language governing permissions and 

13# limitations under the License. 

14 

15"""Helpers for batch requests to the Google Cloud Firestore API.""" 

16from __future__ import annotations 

17import abc 

18from typing import Any, Dict, Union 

19 

20# Types needed only for Type Hints 

21from google.api_core import retry as retries 

22 

23from google.cloud.firestore_v1 import _helpers 

24from google.cloud.firestore_v1.base_document import BaseDocumentReference 

25from google.cloud.firestore_v1.types import write as write_pb 

26 

27 

28class BaseBatch(metaclass=abc.ABCMeta): 

29 """Accumulate write operations to be sent in a batch. 

30 

31 This has the same set of methods for write operations that 

32 :class:`~google.cloud.firestore_v1.document.DocumentReference` does, 

33 e.g. :meth:`~google.cloud.firestore_v1.document.DocumentReference.create`. 

34 

35 Args: 

36 client (:class:`~google.cloud.firestore_v1.client.Client`): 

37 The client that created this batch. 

38 """ 

39 

40 def __init__(self, client) -> None: 

41 self._client = client 

42 self._write_pbs: list[write_pb.Write] = [] 

43 self._document_references: Dict[str, BaseDocumentReference] = {} 

44 self.write_results: list[write_pb.WriteResult] | None = None 

45 self.commit_time = None 

46 

47 def __len__(self): 

48 return len(self._document_references) 

49 

50 def __contains__(self, reference: BaseDocumentReference): 

51 return reference._document_path in self._document_references 

52 

53 def _add_write_pbs(self, write_pbs: list[write_pb.Write]) -> None: 

54 """Add `Write`` protobufs to this transaction. 

55 

56 This method intended to be over-ridden by subclasses. 

57 

58 Args: 

59 write_pbs (List[google.cloud.firestore_v1.\ 

60 write_pb2.Write]): A list of write protobufs to be added. 

61 """ 

62 self._write_pbs.extend(write_pbs) 

63 

64 @abc.abstractmethod 

65 def commit(self): 

66 """Sends all accumulated write operations to the server. The details of this 

67 write depend on the implementing class.""" 

68 raise NotImplementedError() 

69 

70 def create( 

71 self, reference: BaseDocumentReference, document_data: dict[str, Any] 

72 ) -> None: 

73 """Add a "change" to this batch to create a document. 

74 

75 If the document given by ``reference`` already exists, then this 

76 batch will fail when :meth:`commit`-ed. 

77 

78 Args: 

79 reference (:class:`~google.cloud.firestore_v1.document.DocumentReference`): 

80 A document reference to be created in this batch. 

81 document_data (dict): Property names and values to use for 

82 creating a document. 

83 """ 

84 write_pbs = _helpers.pbs_for_create(reference._document_path, document_data) 

85 self._document_references[reference._document_path] = reference 

86 self._add_write_pbs(write_pbs) 

87 

88 def set( 

89 self, 

90 reference: BaseDocumentReference, 

91 document_data: dict, 

92 merge: Union[bool, list] = False, 

93 ) -> None: 

94 """Add a "change" to replace a document. 

95 

96 See 

97 :meth:`google.cloud.firestore_v1.document.DocumentReference.set` for 

98 more information on how ``option`` determines how the change is 

99 applied. 

100 

101 Args: 

102 reference (:class:`~google.cloud.firestore_v1.document.DocumentReference`): 

103 A document reference that will have values set in this batch. 

104 document_data (dict): 

105 Property names and values to use for replacing a document. 

106 merge (Optional[bool] or Optional[List<apispec>]): 

107 If True, apply merging instead of overwriting the state 

108 of the document. 

109 """ 

110 if merge is not False: 

111 write_pbs = _helpers.pbs_for_set_with_merge( 

112 reference._document_path, document_data, merge 

113 ) 

114 else: 

115 write_pbs = _helpers.pbs_for_set_no_merge( 

116 reference._document_path, document_data 

117 ) 

118 

119 self._document_references[reference._document_path] = reference 

120 self._add_write_pbs(write_pbs) 

121 

122 def update( 

123 self, 

124 reference: BaseDocumentReference, 

125 field_updates: dict[str, Any], 

126 option: _helpers.WriteOption | None = None, 

127 ) -> None: 

128 """Add a "change" to update a document. 

129 

130 See 

131 :meth:`google.cloud.firestore_v1.document.DocumentReference.update` 

132 for more information on ``field_updates`` and ``option``. 

133 

134 Args: 

135 reference (:class:`~google.cloud.firestore_v1.document.DocumentReference`): 

136 A document reference that will be updated in this batch. 

137 field_updates (dict): 

138 Field names or paths to update and values to update with. 

139 option (Optional[:class:`~google.cloud.firestore_v1.client.WriteOption`]): 

140 A write option to make assertions / preconditions on the server 

141 state of the document before applying changes. 

142 """ 

143 if option.__class__.__name__ == "ExistsOption": 

144 raise ValueError("you must not pass an explicit write option to " "update.") 

145 write_pbs = _helpers.pbs_for_update( 

146 reference._document_path, field_updates, option 

147 ) 

148 self._document_references[reference._document_path] = reference 

149 self._add_write_pbs(write_pbs) 

150 

151 def delete( 

152 self, 

153 reference: BaseDocumentReference, 

154 option: _helpers.WriteOption | None = None, 

155 ) -> None: 

156 """Add a "change" to delete a document. 

157 

158 See 

159 :meth:`google.cloud.firestore_v1.document.DocumentReference.delete` 

160 for more information on how ``option`` determines how the change is 

161 applied. 

162 

163 Args: 

164 reference (:class:`~google.cloud.firestore_v1.document.DocumentReference`): 

165 A document reference that will be deleted in this batch. 

166 option (Optional[:class:`~google.cloud.firestore_v1.client.WriteOption`]): 

167 A write option to make assertions / preconditions on the server 

168 state of the document before applying changes. 

169 """ 

170 write_pb = _helpers.pb_for_delete(reference._document_path, option) 

171 self._document_references[reference._document_path] = reference 

172 self._add_write_pbs([write_pb]) 

173 

174 

175class BaseWriteBatch(BaseBatch): 

176 """Base class for a/sync implementations of the `commit` RPC. `commit` is useful 

177 for lower volumes or when the order of write operations is important.""" 

178 

179 def _prep_commit( 

180 self, 

181 retry: retries.Retry | retries.AsyncRetry | object | None, 

182 timeout: float | None, 

183 ): 

184 """Shared setup for async/sync :meth:`commit`.""" 

185 request = { 

186 "database": self._client._database_string, 

187 "writes": self._write_pbs, 

188 "transaction": None, 

189 } 

190 kwargs = _helpers.make_retry_timeout_kwargs(retry, timeout) 

191 return request, kwargs