diff --git a/extensions/ql-vscode/src/adapt.ts b/extensions/ql-vscode/src/adapt.ts index 7a7f47ed6..0dcf7bd46 100644 --- a/extensions/ql-vscode/src/adapt.ts +++ b/extensions/ql-vscode/src/adapt.ts @@ -110,7 +110,7 @@ export function adaptBqrs(schema: AdaptedSchema, page: DecodedBqrsChunk): RawRes * for this transition is to make pagination possible in such a way * that only one page needs to be sent from the extension to the webview. */ -export type ParsedResultSets = ExtensionParsedResultSets | WebviewParsedResultSets; +export type ParsedResultSets = ExtensionParsedResultSets; /** * The old method doesn't require any nontrivial information to be included here, diff --git a/extensions/ql-vscode/src/interface.ts b/extensions/ql-vscode/src/interface.ts index 00ab30e5e..e99779906 100644 --- a/extensions/ql-vscode/src/interface.ts +++ b/extensions/ql-vscode/src/interface.ts @@ -41,7 +41,6 @@ import { ParsedResultSets, RawResultSet, } from './adapt'; -import { EXPERIMENTAL_BQRS_SETTING } from './config'; import { WebviewReveal, fileUriToWebviewUri, @@ -335,40 +334,34 @@ export class InterfaceManager extends DisposableObject { } const getParsedResultSets = async (): Promise => { - if (EXPERIMENTAL_BQRS_SETTING.getValue()) { - const resultSetSchemas = await this.getResultSetSchemas(results); - const resultSetNames = resultSetSchemas.map(schema => schema.name); - // This may not wind up being the page we actually show, if there are interpreted results, - // but speculatively send it anyway. - const selectedTable = getDefaultResultSetName(resultSetNames); - const schema = resultSetSchemas.find( - (resultSet) => resultSet.name == selectedTable - )!; - if (schema === undefined) { - return { t: 'WebviewParsed' }; - } + const resultSetSchemas = await this.getResultSetSchemas(results); + const resultSetNames = resultSetSchemas.map(schema => schema.name); - const chunk = await this.cliServer.bqrsDecode( - results.query.resultsPaths.resultsPath, - schema.name, - RAW_RESULTS_PAGE_SIZE, - schema.pagination?.offsets[0] - ); - const adaptedSchema = adaptSchema(schema); - const resultSet = adaptBqrs(adaptedSchema, chunk); - return { - t: 'ExtensionParsed', - pageNumber: 0, - numPages: numPagesOfResultSet(resultSet), - numInterpretedPages: numInterpretedPages(this._interpretation), - resultSet: { t: 'RawResultSet', ...resultSet }, - selectedTable: undefined, - resultSetNames, - }; - } else { - return { t: 'WebviewParsed' }; - } + // This may not wind up being the page we actually show, if there are interpreted results, + // but speculatively send it anyway. + const selectedTable = getDefaultResultSetName(resultSetNames); + const schema = resultSetSchemas.find( + (resultSet) => resultSet.name == selectedTable + )!; + + const chunk = await this.cliServer.bqrsDecode( + results.query.resultsPaths.resultsPath, + schema.name, + RAW_RESULTS_PAGE_SIZE, + schema.pagination?.offsets[0] + ); + const adaptedSchema = adaptSchema(schema); + const resultSet = adaptBqrs(adaptedSchema, chunk); + return { + t: 'ExtensionParsed', + pageNumber: 0, + numPages: numPagesOfResultSet(resultSet), + numInterpretedPages: numInterpretedPages(this._interpretation), + resultSet: { t: 'RawResultSet', ...resultSet }, + selectedTable: undefined, + resultSetNames, + }; }; await this.postMessage({ diff --git a/extensions/ql-vscode/src/view/result-tables.tsx b/extensions/ql-vscode/src/view/result-tables.tsx index 6cb3172fa..f874e983f 100644 --- a/extensions/ql-vscode/src/view/result-tables.tsx +++ b/extensions/ql-vscode/src/view/result-tables.tsx @@ -117,9 +117,6 @@ export class ResultTables case 'ExtensionParsed': selectedPage = (props.parsedResultSets.pageNumber + 1) + ''; break; - case 'WebviewParsed': - selectedPage = ''; - break; } this.state = { selectedTable, selectedPage }; } @@ -167,8 +164,6 @@ export class ResultTables switch (parsedResultSets.t) { case 'ExtensionParsed': return parsedResultSets.pageNumber * RAW_RESULTS_PAGE_SIZE; - case 'WebviewParsed': - return 0; } } diff --git a/extensions/ql-vscode/src/view/results.tsx b/extensions/ql-vscode/src/view/results.tsx index 675daa4bc..5f25a87ed 100644 --- a/extensions/ql-vscode/src/view/results.tsx +++ b/extensions/ql-vscode/src/view/results.tsx @@ -1,12 +1,5 @@ import * as React from 'react'; import * as Rdom from 'react-dom'; -import * as bqrs from 'semmle-bqrs'; -import { - ElementBase, - PrimitiveColumnValue, - PrimitiveTypeKind, - tryGetResolvableLocation, -} from 'semmle-bqrs'; import { assertNever } from '../helpers-pure'; import { DatabaseInfo, @@ -22,8 +15,6 @@ import { import { EventHandlers as EventHandlerList } from './event-handler-list'; import { ResultTables } from './result-tables'; import { - ResultValue, - ResultRow, ParsedResultSets, } from '../adapt'; import { ResultSet } from '../interface-types'; @@ -36,91 +27,6 @@ import { vscode } from './vscode-api'; * Displaying query results. */ -async function* getChunkIterator( - response: Response -): AsyncIterableIterator { - if (!response.ok) { - throw new Error( - `Failed to load results: (${response.status}) ${response.statusText}` - ); - } - const reader = response.body!.getReader(); - while (true) { - const { value, done } = await reader.read(); - if (done) { - return; - } - yield value!; - } -} - -function translatePrimitiveValue( - value: PrimitiveColumnValue, - type: PrimitiveTypeKind -): ResultValue { - switch (type) { - case 'i': - case 'f': - case 's': - case 'd': - case 'b': - return value.toString(); - - case 'u': - return { - uri: value as string, - }; - } -} - -async function parseResultSets( - response: Response -): Promise { - const chunks = getChunkIterator(response); - - const resultSets: ResultSet[] = []; - - await bqrs.parse(chunks, (resultSetSchema) => { - const columnTypes = resultSetSchema.columns.map((column) => column.type); - const rows: ResultRow[] = []; - resultSets.push({ - t: 'RawResultSet', - schema: resultSetSchema, - rows: rows, - }); - - return (tuple) => { - const row: ResultValue[] = []; - tuple.forEach((value, index) => { - const type = columnTypes[index]; - if (type.type === 'e') { - const element: ElementBase = value as ElementBase; - const label = - element.label !== undefined ? element.label : element.id.toString(); //REVIEW: URLs? - const resolvableLocation = tryGetResolvableLocation(element.location); - if (resolvableLocation !== undefined) { - row.push({ - label: label, - location: resolvableLocation, - }); - } else { - // No location link. - row.push(label); - } - } else { - row.push( - translatePrimitiveValue(value as PrimitiveColumnValue, type.type) - ); - } - }); - - rows.push(row); - }; - }); - - return resultSets; -} - interface ResultsInfo { parsedResultSets: ParsedResultSets; resultsPath: string; @@ -270,8 +176,6 @@ class App extends React.Component<{}, ResultsViewState> { ): Promise { const parsedResultSets = resultsInfo.parsedResultSets; switch (parsedResultSets.t) { - case 'WebviewParsed': - return await this.fetchResultSets(resultsInfo); case 'ExtensionParsed': { return [{ t: 'RawResultSet', ...parsedResultSets.resultSet }]; } @@ -321,35 +225,6 @@ class App extends React.Component<{}, ResultsViewState> { }); } - /** - * This is deprecated, because it calls `fetch`. We are moving - * towards doing all bqrs parsing in the extension. - */ - private async fetchResultSets( - resultsInfo: ResultsInfo - ): Promise { - const unsortedResponse = await fetch(resultsInfo.resultsPath); - const unsortedResultSets = await parseResultSets(unsortedResponse); - return Promise.all( - unsortedResultSets.map(async (unsortedResultSet) => { - const sortedResultSetInfo = resultsInfo.sortedResultsMap.get( - unsortedResultSet.schema.name - ); - if (sortedResultSetInfo === undefined) { - return unsortedResultSet; - } - const response = await fetch(sortedResultSetInfo.resultsPath); - const resultSets = await parseResultSets(response); - if (resultSets.length != 1) { - throw new Error( - `Expected sorted BQRS to contain a single result set, encountered ${resultSets.length} result sets.` - ); - } - return resultSets[0]; - }) - ); - } - private getSortStates( resultsInfo: ResultsInfo ): Map {