1// Copyright (C) 2025 The Android Open Source Project 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 15import protos from '../../protos'; 16import m from 'mithril'; 17import { 18 ColumnControllerRow, 19 columnControllerRowFromName, 20 newColumnControllerRows, 21} from './query_builder/column_controller'; 22import { 23 GroupByAgg, 24 placeholderNewColumnName, 25} from './query_builder/operations/groupy_by'; 26import {Filter} from './query_builder/operations/filter'; 27 28export enum NodeType { 29 // Sources 30 kStdlibTable, 31 kSimpleSlices, 32 kSqlSource, 33} 34 35// All information required to create a new node. 36export interface QueryNodeState { 37 prevNode?: QueryNode; 38 sourceCols: ColumnControllerRow[]; 39 40 filters: Filter[]; 41 groupByColumns: ColumnControllerRow[]; 42 aggregations: GroupByAgg[]; 43} 44 45export interface QueryNode { 46 readonly type: NodeType; 47 readonly prevNode?: QueryNode; 48 readonly nextNode?: QueryNode; 49 50 // Columns that are available in the source data. 51 readonly sourceCols: ColumnControllerRow[]; 52 53 // Columns that are available after applying all operations. 54 readonly finalCols: ColumnControllerRow[]; 55 56 // State of the node. This is used to store the user's input and can be used 57 // to fully recover the node. 58 readonly state: QueryNodeState; 59 60 validate(): boolean; 61 getTitle(): string; 62 getDetails(): m.Child; 63 getState(): QueryNodeState; 64 getStructuredQuery(): protos.PerfettoSqlStructuredQuery | undefined; 65} 66 67export function createSelectColumnsProto( 68 node: QueryNode, 69): protos.PerfettoSqlStructuredQuery.SelectColumn[] | undefined { 70 if (node.finalCols.every((c) => c.checked)) return; 71 const selectedColumns: protos.PerfettoSqlStructuredQuery.SelectColumn[] = []; 72 73 for (const c of node.finalCols) { 74 if (c.checked === false) continue; 75 const newC = new protos.PerfettoSqlStructuredQuery.SelectColumn(); 76 newC.columnName = c.column.name; 77 if (c.alias) { 78 newC.alias = c.alias; 79 } 80 selectedColumns.push(newC); 81 } 82 return selectedColumns; 83} 84 85export function createFinalColumns(node: QueryNode) { 86 if (node.state.groupByColumns.find((c) => c.checked)) { 87 const selected = node.state.groupByColumns.filter((c) => c.checked); 88 for (const agg of node.state.aggregations) { 89 selected.push( 90 columnControllerRowFromName( 91 agg.newColumnName ?? placeholderNewColumnName(agg), 92 ), 93 ); 94 } 95 return newColumnControllerRows(selected, true); 96 } 97 98 return newColumnControllerRows(node.sourceCols, true); 99} 100