Ensure Open Query Text works for in progress queries
Same with "Open query that produced these results". In order to do this, needed to move the query id generation into the InitialQueryInfo.
This commit is contained in:
@@ -82,12 +82,12 @@ export class CompareInterfaceManager extends DisposableObject {
|
||||
// otherwise we will wind up with duplicated rows
|
||||
name: from.getShortLabel(),
|
||||
status: from.completedQuery.statusString,
|
||||
time: from.time,
|
||||
time: from.startTime,
|
||||
},
|
||||
toQuery: {
|
||||
name: to.getShortLabel(),
|
||||
status: to.completedQuery.statusString,
|
||||
time: to.time,
|
||||
time: to.startTime,
|
||||
},
|
||||
},
|
||||
columns: fromResultSet.schema.columns,
|
||||
|
||||
@@ -500,11 +500,11 @@ async function activateWithInstalledDistribution(
|
||||
|
||||
const initialInfo = await createInitialQueryInfo(selectedQuery, databaseInfo, quickEval, range);
|
||||
const item = new FullQueryInfo(initialInfo, queryHistoryConfigurationListener);
|
||||
qhm.addCompletedQuery(item);
|
||||
qhm.addQuery(item);
|
||||
await qhm.refreshTreeView(item);
|
||||
|
||||
try {
|
||||
const info = await compileAndRunQueryAgainstDatabase(
|
||||
const completedQueryInfo = await compileAndRunQueryAgainstDatabase(
|
||||
cliServer,
|
||||
qs,
|
||||
databaseItem,
|
||||
@@ -512,7 +512,7 @@ async function activateWithInstalledDistribution(
|
||||
progress,
|
||||
token,
|
||||
);
|
||||
item.completeThisQuery(info);
|
||||
item.completeThisQuery(completedQueryInfo);
|
||||
await showResultsForCompletedQuery(item as FullCompletedQueryInfo, WebviewReveal.NotForced);
|
||||
// Note we must update the query history view after showing results as the
|
||||
// display and sorting might depend on the number of results
|
||||
|
||||
@@ -406,12 +406,8 @@ export class QueryHistoryManager extends DisposableObject {
|
||||
throw new Error(NO_QUERY_SELECTED);
|
||||
}
|
||||
|
||||
if (!finalSingleItem.completedQuery) {
|
||||
throw new Error('Select a completed query.');
|
||||
}
|
||||
|
||||
const textDocument = await workspace.openTextDocument(
|
||||
Uri.file(finalSingleItem.completedQuery.query.program.queryPath)
|
||||
Uri.file(finalSingleItem.initialInfo.queryPath)
|
||||
);
|
||||
const editor = await window.showTextDocument(
|
||||
textDocument,
|
||||
@@ -580,18 +576,14 @@ export class QueryHistoryManager extends DisposableObject {
|
||||
throw new Error(NO_QUERY_SELECTED);
|
||||
}
|
||||
|
||||
if (!singleItem.completedQuery) {
|
||||
return;
|
||||
}
|
||||
|
||||
const rawQueryName = singleItem.getQueryName();
|
||||
const queryName = rawQueryName.endsWith('.ql') ? rawQueryName : rawQueryName + '.ql';
|
||||
const params = new URLSearchParams({
|
||||
isQuickEval: String(!!singleItem.completedQuery.query.quickEvalPosition),
|
||||
isQuickEval: String(!!singleItem.initialInfo.quickEvalPosition),
|
||||
queryText: encodeURIComponent(await this.getQueryText(singleItem)),
|
||||
});
|
||||
const uri = Uri.parse(
|
||||
`codeql:${singleItem.completedQuery.query.queryID}-${queryName}?${params.toString()}`, true
|
||||
`codeql:${singleItem.initialInfo.id}-${queryName}?${params.toString()}`, true
|
||||
);
|
||||
const doc = await workspace.openTextDocument(uri);
|
||||
await window.showTextDocument(doc, { preview: false });
|
||||
@@ -670,32 +662,10 @@ export class QueryHistoryManager extends DisposableObject {
|
||||
}
|
||||
|
||||
async getQueryText(queryHistoryItem: FullQueryInfo): Promise<string> {
|
||||
if (queryHistoryItem.initialInfo.queryText) {
|
||||
return queryHistoryItem.initialInfo.queryText;
|
||||
}
|
||||
|
||||
if (!queryHistoryItem.completedQuery) {
|
||||
return '<No label>';
|
||||
}
|
||||
|
||||
const query = queryHistoryItem.completedQuery.query;
|
||||
|
||||
if (query.quickEvalPosition) {
|
||||
// capture all selected lines
|
||||
const startLine = query.quickEvalPosition.line;
|
||||
const endLine = query.quickEvalPosition.endLine;
|
||||
const textDocument = await workspace.openTextDocument(
|
||||
query.quickEvalPosition.fileName
|
||||
);
|
||||
return textDocument.getText(
|
||||
new Range(startLine - 1, 0, endLine, 0)
|
||||
);
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
return queryHistoryItem.initialInfo.queryText;
|
||||
}
|
||||
|
||||
addCompletedQuery(item: FullQueryInfo) {
|
||||
addQuery(item: FullQueryInfo) {
|
||||
this.treeDataProvider.pushQuery(item);
|
||||
this.updateTreeViewSelectionIfVisible();
|
||||
}
|
||||
|
||||
@@ -22,13 +22,14 @@ import { DatabaseInfo } from './pure/interface-types';
|
||||
*/
|
||||
export interface InitialQueryInfo {
|
||||
userSpecifiedLabel?: string; // if missing, use a default label
|
||||
readonly queryText?: string; // text of the selected file
|
||||
readonly queryText: string; // text of the selected file, or the selected text when doing quick eval
|
||||
readonly isQuickQuery: boolean;
|
||||
readonly isQuickEval: boolean;
|
||||
readonly quickEvalPosition?: messages.Position;
|
||||
readonly queryPath: string;
|
||||
readonly databaseInfo: DatabaseInfo
|
||||
readonly start: Date;
|
||||
readonly id: number; // an incrementing number for each query
|
||||
}
|
||||
|
||||
export enum QueryStatus {
|
||||
@@ -183,14 +184,14 @@ export class FullQueryInfo {
|
||||
/**/
|
||||
}
|
||||
|
||||
get time() {
|
||||
get startTime() {
|
||||
return this.initialInfo.start.toLocaleString(env.language);
|
||||
}
|
||||
|
||||
interpolate(template: string): string {
|
||||
const { resultCount = 0, statusString = 'in progress' } = this.completedQuery || {};
|
||||
const replacements: { [k: string]: string } = {
|
||||
t: this.time,
|
||||
t: this.startTime,
|
||||
q: this.getQueryName(),
|
||||
d: this.initialInfo.databaseInfo.name,
|
||||
r: resultCount.toString(),
|
||||
|
||||
@@ -54,24 +54,21 @@ export const tmpDirDisposal = {
|
||||
* output and results.
|
||||
*/
|
||||
export class QueryEvaluatonInfo {
|
||||
private static nextQueryId = 0;
|
||||
|
||||
readonly compiledQueryPath: string;
|
||||
readonly dilPath: string;
|
||||
readonly csvPath: string;
|
||||
readonly resultsPaths: ResultsPaths;
|
||||
readonly dataset: Uri; // guarantee the existence of a well-defined dataset dir at this point
|
||||
readonly queryID: number;
|
||||
|
||||
constructor(
|
||||
public readonly queryID: number,
|
||||
public readonly program: messages.QlProgram,
|
||||
public readonly dbItem: DatabaseItem,
|
||||
public readonly queryDbscheme: string, // the dbscheme file the query expects, based on library path resolution
|
||||
public readonly quickEvalPosition?: messages.Position,
|
||||
public readonly metadata?: QueryMetadata,
|
||||
public readonly templates?: messages.TemplateDefinitions,
|
||||
public readonly templates?: messages.TemplateDefinitions
|
||||
) {
|
||||
this.queryID = QueryEvaluatonInfo.nextQueryId++;
|
||||
this.compiledQueryPath = path.join(tmpDir.name, `compiledQuery${this.queryID}.qlo`);
|
||||
this.dilPath = path.join(tmpDir.name, `results${this.queryID}.dil`);
|
||||
this.csvPath = path.join(tmpDir.name, `results${this.queryID}.csv`);
|
||||
@@ -617,7 +614,7 @@ export async function compileAndRunQueryAgainstDatabase(
|
||||
}
|
||||
}
|
||||
|
||||
const query = new QueryEvaluatonInfo(qlProgram, db, packConfig.dbscheme, initialInfo.quickEvalPosition, metadata, templates);
|
||||
const query = new QueryEvaluatonInfo(initialInfo.id, qlProgram, db, packConfig.dbscheme, initialInfo.quickEvalPosition, metadata, templates);
|
||||
|
||||
const upgradeDir = await tmp.dir({ dir: upgradesTmpDir.name, unsafeCleanup: true });
|
||||
try {
|
||||
@@ -688,6 +685,7 @@ export async function compileAndRunQueryAgainstDatabase(
|
||||
}
|
||||
}
|
||||
|
||||
let queryId = 0;
|
||||
export async function createInitialQueryInfo(
|
||||
selectedQueryUri: Uri | undefined,
|
||||
databaseInfo: DatabaseInfo,
|
||||
@@ -701,9 +699,10 @@ export async function createInitialQueryInfo(
|
||||
isQuickEval,
|
||||
isQuickQuery: isQuickQueryPath(queryPath),
|
||||
databaseInfo,
|
||||
id: queryId++,
|
||||
start: new Date(),
|
||||
... (isQuickEval ? {
|
||||
queryText: quickEvalText,
|
||||
queryText: quickEvalText!, // if this query is quick eval, it must have quick eval text
|
||||
quickEvalPosition: quickEvalPosition
|
||||
} : {
|
||||
queryText: await fs.readFile(queryPath, 'utf8')
|
||||
|
||||
@@ -170,15 +170,6 @@ describe('query-results', () => {
|
||||
await completedQuery.updateSortState(mockServer, 'result-name');
|
||||
expect(completedQuery.sortedResultsInfo.size).to.eq(0);
|
||||
});
|
||||
|
||||
// interpolate
|
||||
// time
|
||||
// label
|
||||
// getShortLabel
|
||||
// getQueryFileName
|
||||
// getQueryName
|
||||
|
||||
// status
|
||||
});
|
||||
|
||||
it('should interpretResults', async () => {
|
||||
|
||||
@@ -84,8 +84,10 @@ describe('run-queries', () => {
|
||||
});
|
||||
});
|
||||
|
||||
let queryNum = 0;
|
||||
function createMockQueryInfo() {
|
||||
return new QueryEvaluatonInfo(
|
||||
queryNum++,
|
||||
'my-program' as unknown as QlProgram,
|
||||
{
|
||||
contents: {
|
||||
|
||||
Reference in New Issue
Block a user