-
Notifications
You must be signed in to change notification settings - Fork 226
Add command to run queries on multiple databases #898
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
e2fe589
b1721b7
a99d915
6c55f19
c3b8f5a
c4c0c8a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,7 +10,8 @@ import { | |
| Uri, | ||
| window as Window, | ||
| env, | ||
| window | ||
| window, | ||
| QuickPickItem | ||
| } from 'vscode'; | ||
| import { LanguageClient } from 'vscode-languageclient'; | ||
| import * as os from 'os'; | ||
|
|
@@ -29,7 +30,7 @@ import { | |
| QueryServerConfigListener | ||
| } from './config'; | ||
| import * as languageSupport from './languageSupport'; | ||
| import { DatabaseManager } from './databases'; | ||
| import { DatabaseItem, DatabaseManager } from './databases'; | ||
| import { DatabaseUI } from './databases-ui'; | ||
| import { | ||
| TemplateQueryDefinitionProvider, | ||
|
|
@@ -467,9 +468,11 @@ async function activateWithInstalledDistribution( | |
| selectedQuery: Uri | undefined, | ||
| progress: ProgressCallback, | ||
| token: CancellationToken, | ||
| databaseItem: DatabaseItem | undefined, | ||
| ): Promise<void> { | ||
| if (qs !== undefined) { | ||
| const dbItem = await databaseUI.getDatabaseItem(progress, token); | ||
| // If no databaseItem is specified, use the database currently selected in the Databases UI | ||
| const dbItem = databaseItem || await databaseUI.getDatabaseItem(progress, token); | ||
| if (dbItem === undefined) { | ||
| throw new Error('Can\'t run query without a selected database'); | ||
| } | ||
|
|
@@ -549,13 +552,66 @@ async function activateWithInstalledDistribution( | |
| progress: ProgressCallback, | ||
| token: CancellationToken, | ||
| uri: Uri | undefined | ||
| ) => await compileAndRunQuery(false, uri, progress, token), | ||
| ) => await compileAndRunQuery(false, uri, progress, token, undefined), | ||
| { | ||
| title: 'Running query', | ||
| cancellable: true | ||
| } | ||
| ) | ||
| ); | ||
| interface DatabaseQuickPickItem extends QuickPickItem { | ||
| databaseItem: DatabaseItem; | ||
| } | ||
| ctx.subscriptions.push( | ||
| commandRunnerWithProgress( | ||
| 'codeQL.runQueryOnMultipleDatabases', | ||
| async ( | ||
| progress: ProgressCallback, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Future note: A cool enhancement might be to have the progress bar reflect how many of the selected databases the query has completed on. Dealing with progress monitors is tricky, so let's think about this later, writing it here just to record the idea. |
||
| token: CancellationToken, | ||
| uri: Uri | undefined | ||
| ) => { | ||
| const quickPickItems = dbm.databaseItems.map<DatabaseQuickPickItem>(dbItem => ( | ||
| { | ||
| databaseItem: dbItem, | ||
| label: dbItem.name, | ||
| description: dbItem.language, | ||
|
shati-patel marked this conversation as resolved.
|
||
| } | ||
| )); | ||
| /** | ||
| * Databases that were selected in the quick pick menu. | ||
| */ | ||
| const quickpick = await window.showQuickPick<DatabaseQuickPickItem>( | ||
| quickPickItems, | ||
| { canPickMany: true } | ||
| ); | ||
| if (quickpick !== undefined) { | ||
| // Collect all skipped databases and display them at the end (instead of popping up individual errors) | ||
| const skippedDatabases = []; | ||
| const errors = []; | ||
| for (const item of quickpick) { | ||
| try { | ||
| await compileAndRunQuery(false, uri, progress, token, item.databaseItem); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We don't know the language of the query at this point do we? It would be very cool to automatically filter out databases that are of the wrong language. But no problem if we can't do that yet.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Indeed 😅 I couldn't work out how to extract that language information before displaying the quick pick, so I stuck with this for now! |
||
| } catch (error) { | ||
| skippedDatabases.push(item.label); | ||
| errors.push(error.message); | ||
| } | ||
| } | ||
| if (skippedDatabases.length > 0) { | ||
| void logger.log(`Errors:\n${errors.join('\n')}`); | ||
| void helpers.showAndLogWarningMessage( | ||
| `The following databases were skipped:\n${skippedDatabases.join('\n')}.\nFor details about the errors, see the logs.` | ||
| ); | ||
| } | ||
| } else { | ||
| void helpers.showAndLogErrorMessage('No databases selected.'); | ||
| } | ||
| }, | ||
| { | ||
| title: 'Running query on selected databases', | ||
| cancellable: true | ||
| } | ||
| ) | ||
| ); | ||
| ctx.subscriptions.push( | ||
| commandRunnerWithProgress( | ||
| 'codeQL.runQueries', | ||
|
|
@@ -611,7 +667,7 @@ async function activateWithInstalledDistribution( | |
| }); | ||
|
|
||
| await Promise.all(queryUris.map(async uri => | ||
| compileAndRunQuery(false, uri, wrappedProgress, token) | ||
| compileAndRunQuery(false, uri, wrappedProgress, token, undefined) | ||
| .then(() => queriesRemaining--) | ||
| )); | ||
| }, | ||
|
|
@@ -627,7 +683,7 @@ async function activateWithInstalledDistribution( | |
| progress: ProgressCallback, | ||
| token: CancellationToken, | ||
| uri: Uri | undefined | ||
| ) => await compileAndRunQuery(true, uri, progress, token), | ||
| ) => await compileAndRunQuery(true, uri, progress, token, undefined), | ||
| { | ||
| title: 'Running query', | ||
| cancellable: true | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor: you could use only one variable throughout:
and replace
dbItemin the two uses below withdatabaseItem.Why do this? To avoid accidentally introducing code later that uses
databaseItemwhen we should be usingdbItem. (This is a classic mistake I have made often when two variables have similar names but only one variable has the fully initialised value...)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed! Thanks for the tip—I can definitely see myself getting confused by variables otherwise 🙃