Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
273 changes: 138 additions & 135 deletions extensions/ql-vscode/src/local-queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -225,151 +225,154 @@ export class LocalQueries extends DisposableObject {
}

public getCommands(): LocalQueryCommands {
const runQuery = async (uri: Uri | undefined) =>
withProgress(
async (progress, token) => {
await this.compileAndRunQuery(false, uri, progress, token, undefined);
},
{
title: "Running query",
cancellable: true,
},
);
return {
"codeQL.runQuery": this.runQuery.bind(this),
"codeQL.runQueryContextEditor": this.runQuery.bind(this),
"codeQL.runQueryOnMultipleDatabases":
this.runQueryOnMultipleDatabases.bind(this),
"codeQL.runQueryOnMultipleDatabasesContextEditor":
this.runQueryOnMultipleDatabases.bind(this),
"codeQL.runQueries": this.runQueries.bind(this),
"codeQL.quickEval": this.quickEval.bind(this),
"codeQL.quickEvalContextEditor": this.quickEval.bind(this),
"codeQL.codeLensQuickEval": this.codeLensQuickEval.bind(this),
"codeQL.quickQuery": this.quickQuery.bind(this),
};
}

const runQueryOnMultipleDatabases = async (uri: Uri | undefined) =>
withProgress(
async (progress, token) =>
await this.compileAndRunQueryOnMultipleDatabases(
progress,
token,
uri,
),
{
title: "Running query on selected databases",
cancellable: true,
},
);
private async runQuery(uri: Uri | undefined): Promise<void> {
await withProgress(
async (progress, token) => {
await this.compileAndRunQuery(false, uri, progress, token, undefined);
},
{
title: "Running query",
cancellable: true,
},
);
}

private async runQueryOnMultipleDatabases(
uri: Uri | undefined,
): Promise<void> {
await withProgress(
async (progress, token) =>
await this.compileAndRunQueryOnMultipleDatabases(progress, token, uri),
{
title: "Running query on selected databases",
cancellable: true,
},
);
}

const runQueries = async (_: Uri | undefined, multi: Uri[]) =>
withProgress(
async (progress, token) => {
const maxQueryCount = MAX_QUERIES.getValue() as number;
const [files, dirFound] = await gatherQlFiles(
multi.map((uri) => uri.fsPath),
private async runQueries(_: Uri | undefined, multi: Uri[]): Promise<void> {
await withProgress(
async (progress, token) => {
const maxQueryCount = MAX_QUERIES.getValue() as number;
const [files, dirFound] = await gatherQlFiles(
multi.map((uri) => uri.fsPath),
);
if (files.length > maxQueryCount) {
throw new Error(
`You tried to run ${files.length} queries, but the maximum is ${maxQueryCount}. Try selecting fewer queries or changing the 'codeQL.runningQueries.maxQueries' setting.`,
);
if (files.length > maxQueryCount) {
throw new Error(
`You tried to run ${files.length} queries, but the maximum is ${maxQueryCount}. Try selecting fewer queries or changing the 'codeQL.runningQueries.maxQueries' setting.`,
);
}
// warn user and display selected files when a directory is selected because some ql
// files may be hidden from the user.
if (dirFound) {
const fileString = files.map((file) => basename(file)).join(", ");
const res = await showBinaryChoiceDialog(
`You are about to run ${files.length} queries: ${fileString} Do you want to continue?`,
);
if (!res) {
return;
}
}
const queryUris = files.map((path) =>
Uri.parse(`file:${path}`, true),
}
// warn user and display selected files when a directory is selected because some ql
// files may be hidden from the user.
if (dirFound) {
const fileString = files.map((file) => basename(file)).join(", ");
const res = await showBinaryChoiceDialog(
`You are about to run ${files.length} queries: ${fileString} Do you want to continue?`,
);

// Use a wrapped progress so that messages appear with the queries remaining in it.
let queriesRemaining = queryUris.length;

function wrappedProgress(update: ProgressUpdate) {
const message =
queriesRemaining > 1
? `${queriesRemaining} remaining. ${update.message}`
: update.message;
progress({
...update,
message,
});
if (!res) {
return;
}

wrappedProgress({
maxStep: queryUris.length,
step: queryUris.length - queriesRemaining,
message: "",
}
const queryUris = files.map((path) => Uri.parse(`file:${path}`, true));

// Use a wrapped progress so that messages appear with the queries remaining in it.
let queriesRemaining = queryUris.length;

function wrappedProgress(update: ProgressUpdate) {
const message =
queriesRemaining > 1
? `${queriesRemaining} remaining. ${update.message}`
: update.message;
progress({
...update,
message,
});
}

await Promise.all(
queryUris.map(async (uri) =>
this.compileAndRunQuery(
false,
uri,
wrappedProgress,
token,
undefined,
).then(() => queriesRemaining--),
),
);
},
{
title: "Running queries",
cancellable: true,
},
);

const quickEval = async (uri: Uri) =>
withProgress(
async (progress, token) => {
await this.compileAndRunQuery(true, uri, progress, token, undefined);
},
{
title: "Running query",
cancellable: true,
},
);

const codeLensQuickEval = async (uri: Uri, range: Range) =>
withProgress(
async (progress, token) =>
await this.compileAndRunQuery(
true,
uri,
progress,
token,
undefined,
range,
wrappedProgress({
maxStep: queryUris.length,
step: queryUris.length - queriesRemaining,
message: "",
});

await Promise.all(
queryUris.map(async (uri) =>
this.compileAndRunQuery(
false,
uri,
wrappedProgress,
token,
undefined,
).then(() => queriesRemaining--),
),
{
title: "Running query",
cancellable: true,
},
);
);
},
{
title: "Running queries",
cancellable: true,
},
);
}

const quickQuery = async () =>
withProgress(
async (progress, token) =>
displayQuickQuery(
this.app,
this.cliServer,
this.databaseUI,
progress,
token,
),
{
title: "Run Quick Query",
},
);
private async quickEval(uri: Uri): Promise<void> {
await withProgress(
async (progress, token) => {
await this.compileAndRunQuery(true, uri, progress, token, undefined);
},
{
title: "Running query",
cancellable: true,
},
);
}

return {
"codeQL.runQuery": runQuery,
"codeQL.runQueryContextEditor": runQuery,
"codeQL.runQueryOnMultipleDatabases": runQueryOnMultipleDatabases,
"codeQL.runQueryOnMultipleDatabasesContextEditor":
runQueryOnMultipleDatabases,
"codeQL.runQueries": runQueries,
"codeQL.quickEval": quickEval,
"codeQL.quickEvalContextEditor": quickEval,
"codeQL.codeLensQuickEval": codeLensQuickEval,
"codeQL.quickQuery": quickQuery,
};
private async codeLensQuickEval(uri: Uri, range: Range): Promise<void> {
await withProgress(
async (progress, token) =>
await this.compileAndRunQuery(
true,
uri,
progress,
token,
undefined,
range,
),
{
title: "Running query",
cancellable: true,
},
);
}

private async quickQuery(): Promise<void> {
await withProgress(
async (progress, token) =>
displayQuickQuery(
this.app,
this.cliServer,
this.databaseUI,
progress,
token,
),
{
title: "Run Quick Query",
},
);
}

/**
Expand Down