From 5beb5f8b3237b012c334dcc40c910fca2d2f3c00 Mon Sep 17 00:00:00 2001 From: Chloe Date: Sun, 1 Mar 2020 19:51:56 -0800 Subject: [PATCH] Support the result table to display results of DESCRIBE/SHOW/DELETE queries (#37) * Added slash at the start of 'opendistro' path; supported to show the result table for describe/show/delete queries * Changed show/describe/delete queries to request for jdbc format; enable the result table to display the results --- public/components/Main/main.tsx | 78 +++++++++++++++++++++++++++++- server/services/utils/constants.ts | 4 +- 2 files changed, 78 insertions(+), 4 deletions(-) diff --git a/public/components/Main/main.tsx b/public/components/Main/main.tsx index 96b9662..cbefed4 100644 --- a/public/components/Main/main.tsx +++ b/public/components/Main/main.tsx @@ -93,9 +93,73 @@ export function getQueryResultsForTable(queryResultsRaw: ResponseDetail[ } else { let databaseRecords: { [key: string]: any }[] = []; const responseObj = queryResultResponseDetail.data ? JSON.parse(queryResultResponseDetail.data) : ''; - const hits = _.get(responseObj, "hits[hits]", []); let databaseFields: string[] = []; + let fields: string[] = []; + + // the following block is to deal with describe/show/delete query from jdbc results + if (_.has(responseObj, 'schema')) { + const schema: object[] = _.get(responseObj, 'schema'); + const datarows: any[][] = _.get(responseObj, 'datarows'); + let queryType: string = 'show'; + + for (const column of schema.values()) { + if (_.isEqual(_.get(column, 'name'), 'deleted_rows')) { + queryType = 'delete'; + } else if (_.isEqual(_.get(column, 'name'), 'DATA_TYPE')) { + queryType = 'describe' + } + } + switch (queryType) { + case 'delete': + case 'describe': + for (const [id, field] of schema.entries()) { + fields[id] = _.get(field, 'name'); + } + databaseFields = fields; + databaseFields.unshift("id"); + for (const [id, datarow] of datarows.entries()) { + let databaseRecord: { [key: string]: any } = {}; + databaseRecord['id'] = id; + for (const index of schema.keys()) { + const fieldname = databaseFields[index+1]; + databaseRecord[fieldname] = datarow[index]; + } + databaseRecords.push(databaseRecord); + } + break; + case 'show': + databaseFields[0] = 'TABLE_NAME'; + databaseFields.unshift('id'); + let index: number = -1; + for (const [id, field] of schema.entries()) { + if (_.eq(_.get(field, 'name'), 'TABLE_NAME')) { + index = id; + break; + } + } + for (const [id, datarow] of datarows.entries()) { + let databaseRecord: { [key: string]: any } = {}; + databaseRecord['id'] = id; + databaseRecord['TABLE_NAME'] = datarow[index]; + databaseRecords.push(databaseRecord); + } + break; + default: + let databaseRecord: { [key: string]: any } = {}; + databaseRecord['id'] = 'null'; + databaseRecords.push(databaseRecord); + } + return { + fulfilled: queryResultResponseDetail.fulfilled, + data: { + fields: databaseFields, + records: databaseRecords, + message: SUCCESS_MESSAGE + } + } + } + // the following block is to deal with aggregation result if (_.has(responseObj, "aggregations")) { const aggregations = _.get(responseObj, "aggregations", {}); let databaseRecord: { [key: string]: any } = {}; @@ -118,6 +182,7 @@ export function getQueryResultsForTable(queryResultsRaw: ResponseDetail[ } } + const hits = _.get(responseObj, "hits[hits]", []); if (hits.length > 0) { databaseFields=(Object.keys(hits[0]["_source"])); databaseFields.unshift("id"); @@ -258,6 +323,15 @@ export class Main extends React.Component { }); } + isSelectQuery(query: string): boolean { + return _.startsWith(_.trim(query).toLowerCase(), "select"); + } + + requestedFormat(query: string): string { + if (this.isSelectQuery(query)) return ""; + return "jdbc"; + } + onRun = (queriesString: string): void => { const queries: string[] = getQueries(queriesString); @@ -266,7 +340,7 @@ export class Main extends React.Component { const esRawResponsePromise = Promise.all( queries.map((query: string) => this.httpClient - .post("../api/sql_console/query", {query}) + .post("../api/sql_console/query".concat(this.requestedFormat(query)), {query}) .catch((error: any) => { this.setState({ messages: [ diff --git a/server/services/utils/constants.ts b/server/services/utils/constants.ts index 838b5cd..f269082 100644 --- a/server/services/utils/constants.ts +++ b/server/services/utils/constants.ts @@ -13,8 +13,8 @@ * permissions and limitations under the License. */ -export const TRANSLATE_ROUTE = `_opendistro/_sql/_explain`; -export const QUERY_ROUTE = `_opendistro/_sql`; +export const TRANSLATE_ROUTE = `/_opendistro/_sql/_explain`; +export const QUERY_ROUTE = `/_opendistro/_sql`; export const FORMAT_CSV = `format=csv`; export const FORMAT_ESRAW = `format=json`; export const FORMAT_TEXT = `format=raw`;