Add time taken by last query in SQL view (#7421)

* Add time taken by query

* Fix time to 2 dp; set state in on state change; hide time taken at first

* Refactored code: defined query result interface; more concise shorthand expression

* Use single quote
This commit is contained in:
Qi Shu 2019-04-10 23:35:47 -07:00 committed by Clint Wylie
parent bbb620125d
commit 4ea37e2614
3 changed files with 38 additions and 11 deletions

View File

@ -28,11 +28,16 @@
}
.buttons {
position: relative;
button{
margin-right: 15px;
}
.query-elapsed {
position: absolute;
right: 10px;
}
}
}

View File

@ -40,6 +40,7 @@ export interface SqlControlProps extends React.Props<any> {
initSql: string | null;
onRun: (query: string) => void;
onExplain: (query: string) => void;
queryElapsed: number | null;
}
export interface SqlControlState {
@ -166,7 +167,7 @@ export class SqlControl extends React.Component<SqlControlProps, SqlControlState
}
render() {
const { onRun, onExplain } = this.props;
const { onRun, onExplain, queryElapsed } = this.props;
const { query, autoCompleteOn } = this.state;
const isRune = query.trim().startsWith('{');
@ -217,7 +218,11 @@ export class SqlControl extends React.Component<SqlControlProps, SqlControlState
<Button rightIcon={IconNames.CARET_RIGHT} onClick={() => onRun(query)}>
{isRune ? 'Rune' : 'Run'}
</Button>
{!isRune ? SqlControlPopover : null}
{!isRune && SqlControlPopover}
{
queryElapsed &&
<span className={'query-elapsed'}> Last query took {(queryElapsed / 1000).toFixed(2)} seconds</span>
}
</div>
</div>;
}

View File

@ -29,7 +29,8 @@ import {
localStorageGet, LocalStorageKeys,
localStorageSet, parseQueryPlan,
queryDruidRune,
queryDruidSql, QueryManager, SemiJoinQueryExplanation
queryDruidSql, QueryManager,
SemiJoinQueryExplanation
} from '../utils';
import './sql-view.scss';
@ -46,11 +47,17 @@ export interface SqlViewState {
explainResult: BasicQueryExplanation | SemiJoinQueryExplanation | string | null;
loadingExplain: boolean;
explainError: Error | null;
queryElapsed: number | null;
}
interface SqlQueryResult {
queryResult: HeaderRows;
queryElapsed: number;
}
export class SqlView extends React.Component<SqlViewProps, SqlViewState> {
private sqlQueryManager: QueryManager<string, HeaderRows>;
private sqlQueryManager: QueryManager<string, SqlQueryResult>;
private explainQueryManager: QueryManager<string, any>;
constructor(props: SqlViewProps, context: any) {
@ -62,34 +69,42 @@ export class SqlView extends React.Component<SqlViewProps, SqlViewState> {
explainDialogOpen: false,
loadingExplain: false,
explainResult: null,
explainError: null
explainError: null,
queryElapsed: null
};
}
componentDidMount(): void {
this.sqlQueryManager = new QueryManager({
processQuery: async (query: string) => {
const startTime = new Date();
if (query.trim().startsWith('{')) {
// Secret way to issue a native JSON "rune" query
const runeQuery = Hjson.parse(query);
return decodeRune(runeQuery, await queryDruidRune(runeQuery));
const result = await queryDruidRune(runeQuery);
return {
queryResult: decodeRune(runeQuery, result),
queryElapsed: new Date().valueOf() - startTime.valueOf()
};
} else {
const result = await queryDruidSql({
query,
resultFormat: 'array',
header: true
});
return {
header: (result && result.length) ? result[0] : [],
rows: (result && result.length) ? result.slice(1) : []
queryResult: {
header: (result && result.length) ? result[0] : [],
rows: (result && result.length) ? result.slice(1) : []
},
queryElapsed: new Date().valueOf() - startTime.valueOf()
};
}
},
onStateChange: ({ result, loading, error }) => {
this.setState({
result,
result: result ? result.queryResult : null,
queryElapsed: result ? result.queryElapsed : null,
loading,
error
});
@ -158,6 +173,7 @@ export class SqlView extends React.Component<SqlViewProps, SqlViewState> {
render() {
const { initSql } = this.props;
const { queryElapsed } = this.state;
return <div className="sql-view app-view">
<SqlControl
@ -167,6 +183,7 @@ export class SqlView extends React.Component<SqlViewProps, SqlViewState> {
this.sqlQueryManager.runQuery(q);
}}
onExplain={(q: string) => this.getExplain(q)}
queryElapsed={queryElapsed}
/>
{this.renderResultTable()}
{this.renderExplainDialog()}