| // Copyright (C) 2026 The Android Open Source Project |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| import type {Engine} from '../../../trace_processor/engine'; |
| import {NUM, type QueryResult} from '../../../trace_processor/query_result'; |
| import { |
| ChartSource, |
| DEFAULT_MEASURE_ALIAS, |
| type QueryConfig, |
| SQLChartLoader, |
| } from './chart_sql_source'; |
| import type {ChartAggregation} from './chart_utils'; |
| |
| /** A single aggregated numeric value, used by both Gauge and Scorecard. */ |
| export interface SingleValueData { |
| readonly value: number; |
| } |
| |
| /** Constructor options for SQLSingleValueLoader. */ |
| export interface SQLSingleValueLoaderOpts { |
| readonly engine: Engine; |
| readonly query: string; |
| readonly measureColumn: string; |
| } |
| |
| /** Per-use configuration for the single-value loader. */ |
| export interface SingleValueLoaderConfig { |
| readonly aggregation: ChartAggregation; |
| } |
| |
| /** |
| * SQL-based single-value loader. |
| * Computes a single aggregated value (COUNT, SUM, AVG, etc.) from a column. |
| * Used by both Gauge and Scorecard charts. |
| */ |
| export class SQLSingleValueLoader extends SQLChartLoader< |
| SingleValueLoaderConfig, |
| SingleValueData |
| > { |
| private readonly measureColumn: string; |
| |
| constructor(opts: SQLSingleValueLoaderOpts) { |
| super( |
| opts.engine, |
| new ChartSource({ |
| query: opts.query, |
| schema: {[opts.measureColumn]: 'real'}, |
| }), |
| ); |
| this.measureColumn = opts.measureColumn; |
| } |
| |
| protected buildQueryConfig(config: SingleValueLoaderConfig): QueryConfig { |
| return { |
| type: 'aggregated', |
| dimensions: [], |
| measures: [{column: this.measureColumn, aggregation: config.aggregation}], |
| }; |
| } |
| |
| protected parseResult(queryResult: QueryResult): SingleValueData { |
| const iter = queryResult.iter({[DEFAULT_MEASURE_ALIAS]: NUM}); |
| if (iter.valid()) { |
| return {value: iter[DEFAULT_MEASURE_ALIAS]}; |
| } |
| return {value: 0}; |
| } |
| } |