blob: 678849cbb2ae5c33dd6c063c57afe3e0c32ccbb2 [file]
// Copyright (C) 2023 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 m from 'mithril';
import {
type QueryResponse,
runQueryForQueryTable,
} from '../../components/query_table/queries';
import type {DataSource} from '../../components/widgets/datagrid/data_source';
import {InMemoryDataSource} from '../../components/widgets/datagrid/in_memory_data_source';
import type {Trace} from '../../public/trace';
import type {Tab} from '../../public/tab';
import {DetailsShell} from '../../widgets/details_shell';
import {type ResultsData, ResultsTable} from './results_table';
interface QueryResultTabConfig {
readonly query: string;
readonly title: string;
}
export class QueryResultsTab implements Tab {
private queryResponse?: QueryResponse;
private dataSource?: DataSource;
constructor(
private readonly trace: Trace,
private readonly args: QueryResultTabConfig,
) {
// Run the query and load data when the tab is created
this.loadData();
}
private async loadData() {
const result = await runQueryForQueryTable(
this.args.query,
this.trace.engine,
);
this.queryResponse = result;
if (result.error === undefined) {
this.dataSource = new InMemoryDataSource(this.queryResponse.rows);
}
}
getTitle(): string {
const suffix = this.queryResponse
? ` (${this.queryResponse.rows.length})`
: '';
return `${this.args.title}${suffix}`;
}
render(): m.Children {
const resp = this.queryResponse;
return m(
DetailsShell,
{
title: this.args.title,
description: resp ? this.args.query : 'Loading...',
},
resp && this.renderResponse(resp),
);
}
private renderResponse(resp: QueryResponse): m.Children {
const data: ResultsData = resp.error
? {kind: 'error', errorMessage: resp.error}
: {
kind: 'success',
columns: resp.columns,
rows: resp.rows,
dataSource: this.dataSource!,
rowCount: resp.totalRowCount,
queryTimeMs: resp.durationMs,
query: this.args.query,
lastStatementSql: resp.lastStatementSql,
statementCount: resp.statementCount,
statementWithOutputCount: resp.statementWithOutputCount,
};
return m(ResultsTable, {
data,
fillHeight: true,
trace: this.trace,
onIdClick: (sqlTable, id, doubleClick) => {
this.trace.selection.selectSqlEvent(sqlTable, id, {
switchToCurrentSelectionTab: doubleClick,
scrollToSelection: true,
});
},
});
}
isLoading() {
return this.queryResponse === undefined;
}
}