1# Copyright 2024 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
15from google.cloud.firestore_v1.query_profile import (
16 ExplainMetrics,
17 ExplainOptions,
18 QueryExplainError,
19)
20
21from typing import List, Optional, TypeVar
22
23T = TypeVar("T")
24
25
26class QueryResultsList(List[T]):
27 """A list of received query results from the query call.
28
29 This is a subclass of the built-in list. A new property `explain_metrics`
30 is added to return the query profile results.
31
32 Args:
33 docs (list):
34 The list of query results.
35 explain_options
36 (Optional[:class:`~google.cloud.firestore_v1.query_profile.ExplainOptions`]):
37 Options to enable query profiling for this query. When set,
38 explain_metrics will be available on the returned generator.
39 explain_metrics (Optional[ExplainMetrics]):
40 Query profile results.
41 """
42
43 def __init__(
44 self,
45 docs: List,
46 explain_options: Optional[ExplainOptions] = None,
47 explain_metrics: Optional[ExplainMetrics] = None,
48 ):
49 super().__init__(docs)
50
51 # When explain_options is set, explain_metrics should be non-empty too.
52 if explain_options is not None and explain_metrics is None:
53 raise ValueError(
54 "If explain_options is set, explain_metrics must be non-empty."
55 )
56 elif explain_options is None and explain_metrics is not None:
57 raise ValueError(
58 "If explain_options is empty, explain_metrics must be empty."
59 )
60
61 self._explain_options = explain_options
62 self._explain_metrics = explain_metrics
63
64 @property
65 def explain_options(self) -> Optional[ExplainOptions]:
66 """Query profiling options for getting these query results."""
67 return self._explain_options
68
69 def get_explain_metrics(self) -> ExplainMetrics:
70 """
71 Get the metrics associated with the query execution.
72 Metrics are only available when explain_options is set on the query. If
73 ExplainOptions.analyze is False, only plan_summary is available. If it is
74 True, execution_stats is also available.
75 :rtype: :class:`~google.cloud.firestore_v1.query_profile.ExplainMetrics`
76 :returns: The metrics associated with the query execution.
77 :raises: :class:`~google.cloud.firestore_v1.query_profile.QueryExplainError`
78 if explain_metrics is not available on the query.
79 """
80 if self._explain_options is None:
81 raise QueryExplainError("explain_options not set on query.")
82 elif self._explain_metrics is None:
83 raise QueryExplainError(
84 "explain_metrics is empty despite explain_options is set."
85 )
86 else:
87 return self._explain_metrics