3434from google .cloud ._helpers import _date_from_iso8601_date
3535from google .cloud .spanner_v1 .types import ExecuteSqlRequest
3636from google .cloud .spanner_v1 .types import TransactionOptions
37+ from google .cloud .spanner_v1 .types import ClientContext
38+ from google .cloud .spanner_v1 .types import RequestOptions
3739from google .cloud .spanner_v1 .data_types import JsonObject , Interval
3840from google .cloud .spanner_v1 .request_id_header import (
3941 with_request_id ,
@@ -172,15 +174,15 @@ def _merge_query_options(base, merge):
172174 If the resultant object only has empty fields, returns None.
173175 """
174176 combined = base or ExecuteSqlRequest .QueryOptions ()
175- if type (combined ) is dict :
177+ if isinstance (combined , dict ) :
176178 combined = ExecuteSqlRequest .QueryOptions (
177179 optimizer_version = combined .get ("optimizer_version" , "" ),
178180 optimizer_statistics_package = combined .get (
179181 "optimizer_statistics_package" , ""
180182 ),
181183 )
182184 merge = merge or ExecuteSqlRequest .QueryOptions ()
183- if type (merge ) is dict :
185+ if isinstance (merge , dict ) :
184186 merge = ExecuteSqlRequest .QueryOptions (
185187 optimizer_version = merge .get ("optimizer_version" , "" ),
186188 optimizer_statistics_package = merge .get ("optimizer_statistics_package" , "" ),
@@ -191,6 +193,95 @@ def _merge_query_options(base, merge):
191193 return combined
192194
193195
196+ def _merge_client_context (base , merge ):
197+ """Merge higher precedence ClientContext with current ClientContext.
198+
199+ :type base: :class:`~google.cloud.spanner_v1.types.ClientContext`
200+ or :class:`dict` or None
201+ :param base: The current ClientContext that is intended for use.
202+
203+ :type merge: :class:`~google.cloud.spanner_v1.types.ClientContext`
204+ or :class:`dict` or None
205+ :param merge:
206+ The ClientContext that has a higher priority than base. These options
207+ should overwrite the fields in base.
208+
209+ :rtype: :class:`~google.cloud.spanner_v1.types.ClientContext`
210+ or None
211+ :returns:
212+ ClientContext object formed by merging the two given ClientContexts.
213+ """
214+ if base is None and merge is None :
215+ return None
216+
217+ # Avoid in-place modification of base
218+ combined_pb = ClientContext ()._pb
219+ if base :
220+ base_pb = ClientContext (base )._pb if isinstance (base , dict ) else base ._pb
221+ combined_pb .MergeFrom (base_pb )
222+ if merge :
223+ merge_pb = ClientContext (merge )._pb if isinstance (merge , dict ) else merge ._pb
224+ combined_pb .MergeFrom (merge_pb )
225+
226+ combined = ClientContext (combined_pb )
227+
228+ if not combined .secure_context :
229+ return None
230+ return combined
231+
232+
233+ def _validate_client_context (client_context ):
234+ """Validate and convert client_context.
235+
236+ :type client_context: :class:`~google.cloud.spanner_v1.types.ClientContext`
237+ or :class:`dict`
238+ :param client_context: (Optional) Client context to use.
239+
240+ :rtype: :class:`~google.cloud.spanner_v1.types.ClientContext`
241+ :returns: Validated ClientContext object or None.
242+ :raises TypeError: if client_context is not a ClientContext or a dict.
243+ """
244+ if client_context is not None :
245+ if isinstance (client_context , dict ):
246+ client_context = ClientContext (client_context )
247+ elif not isinstance (client_context , ClientContext ):
248+ raise TypeError ("client_context must be a ClientContext or a dict" )
249+ return client_context
250+
251+
252+ def _merge_request_options (request_options , client_context ):
253+ """Merge RequestOptions and ClientContext.
254+
255+ :type request_options: :class:`~google.cloud.spanner_v1.types.RequestOptions`
256+ or :class:`dict` or None
257+ :param request_options: The current RequestOptions that is intended for use.
258+
259+ :type client_context: :class:`~google.cloud.spanner_v1.types.ClientContext`
260+ or :class:`dict` or None
261+ :param client_context:
262+ The ClientContext to merge into request_options.
263+
264+ :rtype: :class:`~google.cloud.spanner_v1.types.RequestOptions`
265+ or None
266+ :returns:
267+ RequestOptions object formed by merging the given ClientContext.
268+ """
269+ if request_options is None and client_context is None :
270+ return None
271+
272+ if request_options is None :
273+ request_options = RequestOptions ()
274+ elif isinstance (request_options , dict ):
275+ request_options = RequestOptions (request_options )
276+
277+ if client_context :
278+ request_options .client_context = _merge_client_context (
279+ client_context , request_options .client_context
280+ )
281+
282+ return request_options
283+
284+
194285def _assert_numeric_precision_and_scale (value ):
195286 """
196287 Asserts that input numeric field is within Spanner supported range.
0 commit comments