Skip to content

Commit

Permalink
Fix query string handling for workbench (#305)
Browse files Browse the repository at this point in the history
* fix line break handling for ppl

Signed-off-by: Joshua Li <joshuali925@gmail.com>

* escape quotes in query requests

Signed-off-by: Joshua Li <joshuali925@gmail.com>
  • Loading branch information
joshuali925 authored Nov 30, 2021
1 parent c6cab3e commit 02e6495
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 95 deletions.
201 changes: 107 additions & 94 deletions workbench/public/components/Main/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,23 @@
* SPDX-License-Identifier: Apache-2.0
*/


import React from 'react';
import { EuiSpacer, EuiFlexGroup, EuiFlexItem, EuiButton, EuiTitle } from '@elastic/eui';
import { IHttpResponse, IHttpService } from 'angular';
import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiTitle } from '@elastic/eui';
import { IHttpResponse } from 'angular';
import _ from 'lodash';
import QueryResults from '../QueryResults/QueryResults';
import Switch from '../QueryLanguageSwitch/Switch';
import { SQLPage } from '../SQLPage/SQLPage';
import { PPLPage } from '../PPLPage/PPLPage';
import React from 'react';
import { ChromeBreadcrumb, CoreStart } from '../../../../../src/core/public';
import { MESSAGE_TAB_LABEL } from '../../utils/constants';
import {
getDefaultTabId,
getDefaultTabLabel,
getQueries,
getSelectedResults,
Tree,
} from '../../utils/utils';
import { MESSAGE_TAB_LABEL } from '../../utils/constants';
import { ChromeBreadcrumb, CoreStart } from '../../../../../src/core/public';
import { PPLPage } from '../PPLPage/PPLPage';
import Switch from '../QueryLanguageSwitch/Switch';
import QueryResults from '../QueryResults/QueryResults';
import { SQLPage } from '../SQLPage/SQLPage';

interface ResponseData {
ok: boolean;
Expand Down Expand Up @@ -62,9 +61,9 @@ export type ItemIdToExpandedRowMap = {
};

export type DataRow = {
rowId: number
data: { [key: string]: any }
}
rowId: number;
data: { [key: string]: any };
};

interface MainProps {
httpClient: CoreStart['http'];
Expand Down Expand Up @@ -93,12 +92,16 @@ interface MainState {
const SUCCESS_MESSAGE = 'Success';

const errorQueryResponse = (queryResultResponseDetail: any) => {
let errorMessage = queryResultResponseDetail.errorMessage + ', this query is not runnable. \n \n' +
let errorMessage =
queryResultResponseDetail.errorMessage +
', this query is not runnable. \n \n' +
queryResultResponseDetail.data;
return errorMessage;
}
};

export function getQueryResultsForTable(queryResults: ResponseDetail<string>[]): ResponseDetail<QueryResult>[] {
export function getQueryResultsForTable(
queryResults: ResponseDetail<string>[]
): ResponseDetail<QueryResult>[] {
return queryResults.map(
(queryResultResponseDetail: ResponseDetail<string>): ResponseDetail<QueryResult> => {
if (!queryResultResponseDetail.fulfilled) {
Expand All @@ -107,7 +110,9 @@ export function getQueryResultsForTable(queryResults: ResponseDetail<string>[]):
errorMessage: errorQueryResponse(queryResultResponseDetail),
};
} else {
const responseObj = queryResultResponseDetail.data ? JSON.parse(queryResultResponseDetail.data) : '';
const responseObj = queryResultResponseDetail.data
? JSON.parse(queryResultResponseDetail.data)
: '';
let fields: string[] = [];
let dataRows: DataRow[] = [];

Expand Down Expand Up @@ -141,7 +146,7 @@ export function getQueryResultsForTable(queryResults: ResponseDetail<string>[]):
row['TABLE_NAME'] = field[index];
let dataRow: DataRow = {
rowId: id,
data: row
data: row,
};
dataRows[id] = dataRow;
}
Expand All @@ -168,14 +173,13 @@ export function getQueryResultsForTable(queryResults: ResponseDetail<string>[]):
}
let dataRow: DataRow = {
rowId: id,
data: row
data: row,
};
dataRows[id] = dataRow;
}
break;

default:

}
return {
fulfilled: queryResultResponseDetail.fulfilled,
Expand All @@ -185,7 +189,6 @@ export function getQueryResultsForTable(queryResults: ResponseDetail<string>[]):
message: SUCCESS_MESSAGE,
},
};

}
}
);
Expand Down Expand Up @@ -224,14 +227,12 @@ export class Main extends React.Component<MainProps, MainState> {
}

componentDidMount() {
this.props.setBreadcrumbs(
[
{
text: 'Query Workbench',
href: '#',
},
]
);
this.props.setBreadcrumbs([
{
text: 'Query Workbench',
href: '#',
},
]);
}

processTranslateResponse(response: IHttpResponse<ResponseData>): ResponseDetail<TranslateResult> {
Expand Down Expand Up @@ -265,23 +266,23 @@ export class Main extends React.Component<MainProps, MainState> {
}
if (!response.data.ok) {
let err = response.data.resp;
console.log("Error occurred when processing query response: ", err)
console.log('Error occurred when processing query response: ', err);

// Exclude a special case from the error cases:
// When downloading the csv result, it gets the "Unable to parse/serialize body" response
// But data is also returned in data body. For this case:
// Mark fulfilled to true for this case to write the csv result to downloading file
if (response.data.body && err == "Unable to parse/serialize body") {
if (response.data.body && err == 'Unable to parse/serialize body') {
return {
fulfilled: true,
errorMessage: err,
data: response.data.body
}
data: response.data.body,
};
}
return {
fulfilled: false,
errorMessage: err,
data: ''
data: '',
};
}

Expand Down Expand Up @@ -341,16 +342,18 @@ export class Main extends React.Component<MainProps, MainState> {
let endpoint = '../api/sql_console/' + (_.isEqual(language, 'SQL') ? 'sqlquery' : 'pplquery');
const responsePromise = Promise.all(
queries.map((query: string) =>
this.httpClient.post(endpoint, { body: `{ "query": "${query}" }` }).catch((error: any) => {
this.setState({
messages: [
{
text: error.message,
className: 'error-message',
},
],
});
})
this.httpClient
.post(endpoint, { body: JSON.stringify({ query }) })
.catch((error: any) => {
this.setState({
messages: [
{
text: error.message,
className: 'error-message',
},
],
});
})
)
);

Expand Down Expand Up @@ -388,16 +391,18 @@ export class Main extends React.Component<MainProps, MainState> {
'../api/sql_console/' + (_.isEqual(language, 'SQL') ? 'translatesql' : 'translateppl');
const translationPromise = Promise.all(
queries.map((query: string) =>
this.httpClient.post(endpoint, { body: `{ "query": "${query}" }` }).catch((error: any) => {
this.setState({
messages: [
{
text: error.message,
className: 'error-message',
},
],
});
})
this.httpClient
.post(endpoint, { body: JSON.stringify({ query }) })
.catch((error: any) => {
this.setState({
messages: [
{
text: error.message,
className: 'error-message',
},
],
});
})
)
);

Expand Down Expand Up @@ -432,16 +437,18 @@ export class Main extends React.Component<MainProps, MainState> {
if (queries.length > 0) {
Promise.all(
queries.map((query: string) =>
this.httpClient.post('../api/sql_console/sqljson', { body: `{ "query": "${query}" }` }).catch((error: any) => {
this.setState({
messages: [
{
text: error.message,
className: 'error-message',
},
],
});
})
this.httpClient
.post('../api/sql_console/sqljson', { body: JSON.stringify({ query }) })
.catch((error: any) => {
this.setState({
messages: [
{
text: error.message,
className: 'error-message',
},
],
});
})
)
).then((response) => {
const results: ResponseDetail<string>[] = response.map((response) =>
Expand All @@ -464,16 +471,18 @@ export class Main extends React.Component<MainProps, MainState> {
let endpoint = '../api/sql_console/' + (_.isEqual(language, 'SQL') ? 'sqlquery' : 'pplquery');
Promise.all(
queries.map((query: string) =>
this.httpClient.post(endpoint, { body: `{ "query": "${query}" }` }).catch((error: any) => {
this.setState({
messages: [
{
text: error.message,
className: 'error-message',
},
],
});
})
this.httpClient
.post(endpoint, { body: JSON.stringify({ query }) })
.catch((error: any) => {
this.setState({
messages: [
{
text: error.message,
className: 'error-message',
},
],
});
})
)
).then((jdbcResponse) => {
const jdbcResult: ResponseDetail<string>[] = jdbcResponse.map((jdbcResponse) =>
Expand All @@ -496,16 +505,18 @@ export class Main extends React.Component<MainProps, MainState> {
let endpoint = '../api/sql_console/' + (_.isEqual(language, 'SQL') ? 'sqlcsv' : 'pplcsv');
Promise.all(
queries.map((query: string) =>
this.httpClient.post(endpoint, { body: `{ "query": "${query}" }` }).catch((error: any) => {
this.setState({
messages: [
{
text: error.message,
className: 'error-message',
},
],
});
})
this.httpClient
.post(endpoint, { body: JSON.stringify({ query }) })
.catch((error: any) => {
this.setState({
messages: [
{
text: error.message,
className: 'error-message',
},
],
});
})
)
).then((csvResponse) => {
const csvResult: ResponseDetail<string>[] = csvResponse.map((csvResponse) =>
Expand All @@ -528,16 +539,18 @@ export class Main extends React.Component<MainProps, MainState> {
let endpoint = '../api/sql_console/' + (_.isEqual(language, 'SQL') ? 'sqltext' : 'ppltext');
Promise.all(
queries.map((query: string) =>
this.httpClient.post(endpoint, { body: `{ "query": "${query}" }` }).catch((error: any) => {
this.setState({
messages: [
{
text: error.message,
className: 'error-message',
},
],
});
})
this.httpClient
.post(endpoint, { body: JSON.stringify({ query }) })
.catch((error: any) => {
this.setState({
messages: [
{
text: error.message,
className: 'error-message',
},
],
});
})
)
).then((textResponse) => {
const textResult: ResponseDetail<string>[] = textResponse.map((textResponse) =>
Expand Down
2 changes: 1 addition & 1 deletion workbench/public/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const getQueries = (queriesString: string): string[] => {

return queriesString
.split(';')
.map((query: string) => query.trim())
.map((query: string) => query.trim().replace(/[\r\n]+/g, ' '))
.filter((query: string) => query != '');
};

Expand Down

0 comments on commit 02e6495

Please sign in to comment.