1// Copyright (C) 2023 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 {sqliteString} from '../../base/string_utils'; 16 17import { 18 ArgSetIdColumn, 19 dependendentColumns, 20 DisplayConfig, 21 RegularSqlTableColumn, 22} from './table_description'; 23 24// This file contains the defintions of different column types that can be 25// displayed in the table viewer. 26 27export interface Column { 28 // SQL expression calculating the value of this column. 29 expression: string; 30 // Unique name for this column. 31 // The relevant bit of SQL fetching this column will be ${expression} as 32 // ${alias}. 33 alias: string; 34 // Title to be displayed in the table header. 35 title: string; 36 // How the value of this column should be rendered. 37 display?: DisplayConfig; 38} 39 40export function columnFromSqlTableColumn(c: RegularSqlTableColumn): Column { 41 return { 42 expression: c.name, 43 alias: c.name, 44 title: c.title || c.name, 45 display: c.display, 46 }; 47} 48 49export function argColumn( 50 tableName: string, 51 c: ArgSetIdColumn, 52 argName: string, 53): Column { 54 const escape = (name: string) => name.replace(/[^A-Za-z0-9]/g, '_'); 55 return { 56 expression: `extract_arg(${tableName}.${c.name}, ${sqliteString(argName)})`, 57 alias: `_arg_${c.name}_${escape(argName)}`, 58 title: `${c.title ?? c.name} ${argName}`, 59 }; 60} 61 62// A single instruction from a select part of the SQL statement, i.e. 63// select `expression` as `alias`. 64export type SqlProjection = { 65 expression: string; 66 alias: string; 67}; 68 69export function formatSqlProjection(p: SqlProjection): string { 70 return `${p.expression} as ${p.alias}`; 71} 72 73// Returns a list of projections (i.e. parts of the SELECT clause) that should 74// be added to the query fetching the data to be able to display the given 75// column (e.g. `foo` or `f(bar) as baz`). 76// Some table columns are backed by multiple SQL columns (e.g. slice_id is 77// backed by id, ts, dur and track_id), so we need to return a list. 78export function sqlProjectionsForColumn(column: Column): SqlProjection[] { 79 const result: SqlProjection[] = [ 80 { 81 expression: column.expression, 82 alias: column.alias, 83 }, 84 ]; 85 for (const dependency of dependendentColumns(column.display)) { 86 result.push({ 87 expression: dependency, 88 alias: dependency, 89 }); 90 } 91 return result; 92} 93