• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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