feat(spanner): add Client Context support to options (#1499) · googleapis/google-cloud-python@0da5f78

@@ -34,6 +34,8 @@

3434

from google.cloud._helpers import _date_from_iso8601_date

3535

from google.cloud.spanner_v1.types import ExecuteSqlRequest

3636

from 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

3739

from google.cloud.spanner_v1.data_types import JsonObject, Interval

3840

from 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

192194193195196+

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+194285

def _assert_numeric_precision_and_scale(value):

195286

"""

196287

Asserts that input numeric field is within Spanner supported range.