Merge branch 'main' into koesie10/replace-faker-uuid
This commit is contained in:
@@ -47,17 +47,5 @@ export function decodeBqrsToExternalApiUsages(
|
||||
method.usages.push(usage);
|
||||
});
|
||||
|
||||
const externalApiUsages = Array.from(methodsByApiName.values());
|
||||
externalApiUsages.sort((a, b) => {
|
||||
// Sort first by supported, putting unmodeled methods first.
|
||||
if (a.supported && !b.supported) {
|
||||
return 1;
|
||||
}
|
||||
if (!a.supported && b.supported) {
|
||||
return -1;
|
||||
}
|
||||
// Then sort by number of usages descending
|
||||
return b.usages.length - a.usages.length;
|
||||
});
|
||||
return externalApiUsages;
|
||||
return Array.from(methodsByApiName.values());
|
||||
}
|
||||
|
||||
@@ -300,7 +300,6 @@ export class DataExtensionsEditorView extends AbstractWebview<
|
||||
this.app.workspaceStoragePath ?? this.app.globalStoragePath,
|
||||
this.app.credentials,
|
||||
(update) => this.showProgress(update),
|
||||
tokenSource.token,
|
||||
this.cliServer,
|
||||
);
|
||||
if (!database) {
|
||||
@@ -354,16 +353,12 @@ export class DataExtensionsEditorView extends AbstractWebview<
|
||||
|
||||
// After the flow model has been generated, we can remove the temporary database
|
||||
// which we used for generating the flow model.
|
||||
await this.databaseManager.removeDatabaseItem(
|
||||
() =>
|
||||
this.showProgress({
|
||||
step: 3900,
|
||||
maxStep: 4000,
|
||||
message: "Removing temporary database",
|
||||
}),
|
||||
tokenSource.token,
|
||||
database,
|
||||
);
|
||||
await this.showProgress({
|
||||
step: 3900,
|
||||
maxStep: 4000,
|
||||
message: "Removing temporary database",
|
||||
});
|
||||
await this.databaseManager.removeDatabaseItem(database);
|
||||
|
||||
await this.clearProgress();
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import fetch, { Response } from "node-fetch";
|
||||
import { zip } from "zip-a-folder";
|
||||
import { Open } from "unzipper";
|
||||
import { Uri, CancellationToken, window, InputBoxOptions } from "vscode";
|
||||
import { Uri, window, InputBoxOptions } from "vscode";
|
||||
import { CodeQLCliServer } from "../codeql-cli/cli";
|
||||
import {
|
||||
ensureDir,
|
||||
@@ -44,7 +44,6 @@ export async function promptImportInternetDatabase(
|
||||
databaseManager: DatabaseManager,
|
||||
storagePath: string,
|
||||
progress: ProgressCallback,
|
||||
token: CancellationToken,
|
||||
cli?: CodeQLCliServer,
|
||||
): Promise<DatabaseItem | undefined> {
|
||||
const databaseUrl = await window.showInputBox({
|
||||
@@ -63,7 +62,6 @@ export async function promptImportInternetDatabase(
|
||||
storagePath,
|
||||
undefined,
|
||||
progress,
|
||||
token,
|
||||
cli,
|
||||
);
|
||||
|
||||
@@ -86,7 +84,6 @@ export async function promptImportInternetDatabase(
|
||||
* @param storagePath where to store the unzipped database.
|
||||
* @param credentials the credentials to use to authenticate with GitHub
|
||||
* @param progress the progress callback
|
||||
* @param token the cancellation token
|
||||
* @param cli the CodeQL CLI server
|
||||
*/
|
||||
export async function promptImportGithubDatabase(
|
||||
@@ -95,7 +92,6 @@ export async function promptImportGithubDatabase(
|
||||
storagePath: string,
|
||||
credentials: Credentials | undefined,
|
||||
progress: ProgressCallback,
|
||||
token: CancellationToken,
|
||||
cli?: CodeQLCliServer,
|
||||
): Promise<DatabaseItem | undefined> {
|
||||
const githubRepo = await askForGitHubRepo(progress);
|
||||
@@ -109,7 +105,6 @@ export async function promptImportGithubDatabase(
|
||||
storagePath,
|
||||
credentials,
|
||||
progress,
|
||||
token,
|
||||
cli,
|
||||
);
|
||||
|
||||
@@ -157,7 +152,6 @@ export async function askForGitHubRepo(
|
||||
* @param storagePath where to store the unzipped database.
|
||||
* @param credentials the credentials to use to authenticate with GitHub
|
||||
* @param progress the progress callback
|
||||
* @param token the cancellation token
|
||||
* @param cli the CodeQL CLI server
|
||||
* @param language the language to download. If undefined, the user will be prompted to choose a language.
|
||||
**/
|
||||
@@ -167,7 +161,6 @@ export async function downloadGitHubDatabase(
|
||||
storagePath: string,
|
||||
credentials: Credentials | undefined,
|
||||
progress: ProgressCallback,
|
||||
token: CancellationToken,
|
||||
cli?: CodeQLCliServer,
|
||||
language?: string,
|
||||
): Promise<DatabaseItem | undefined> {
|
||||
@@ -213,7 +206,6 @@ export async function downloadGitHubDatabase(
|
||||
storagePath,
|
||||
`${owner}/${name}`,
|
||||
progress,
|
||||
token,
|
||||
cli,
|
||||
);
|
||||
}
|
||||
@@ -231,7 +223,6 @@ export async function importArchiveDatabase(
|
||||
databaseManager: DatabaseManager,
|
||||
storagePath: string,
|
||||
progress: ProgressCallback,
|
||||
token: CancellationToken,
|
||||
cli?: CodeQLCliServer,
|
||||
): Promise<DatabaseItem | undefined> {
|
||||
try {
|
||||
@@ -242,7 +233,6 @@ export async function importArchiveDatabase(
|
||||
storagePath,
|
||||
undefined,
|
||||
progress,
|
||||
token,
|
||||
cli,
|
||||
);
|
||||
if (item) {
|
||||
@@ -275,7 +265,6 @@ export async function importArchiveDatabase(
|
||||
* @param storagePath where to store the unzipped database.
|
||||
* @param nameOverride a name for the database that overrides the default
|
||||
* @param progress callback to send progress messages to
|
||||
* @param token cancellation token
|
||||
*/
|
||||
async function databaseArchiveFetcher(
|
||||
databaseUrl: string,
|
||||
@@ -284,7 +273,6 @@ async function databaseArchiveFetcher(
|
||||
storagePath: string,
|
||||
nameOverride: string | undefined,
|
||||
progress: ProgressCallback,
|
||||
token: CancellationToken,
|
||||
cli?: CodeQLCliServer,
|
||||
): Promise<DatabaseItem> {
|
||||
progress({
|
||||
@@ -327,8 +315,6 @@ async function databaseArchiveFetcher(
|
||||
const makeSelected = true;
|
||||
|
||||
const item = await databaseManager.openDatabase(
|
||||
progress,
|
||||
token,
|
||||
Uri.file(dbPath),
|
||||
makeSelected,
|
||||
nameOverride,
|
||||
|
||||
@@ -314,7 +314,7 @@ export class DatabaseUI extends DisposableObject {
|
||||
|
||||
private async handleSetDefaultTourDatabase(): Promise<void> {
|
||||
return withProgress(
|
||||
async (progress, token) => {
|
||||
async () => {
|
||||
try {
|
||||
if (!workspace.workspaceFolders?.length) {
|
||||
throw new Error("No workspace folder is open.");
|
||||
@@ -332,8 +332,6 @@ export class DatabaseUI extends DisposableObject {
|
||||
const isTutorialDatabase = true;
|
||||
|
||||
await this.databaseManager.openDatabase(
|
||||
progress,
|
||||
token,
|
||||
uri,
|
||||
makeSelected,
|
||||
nameOverride,
|
||||
@@ -485,13 +483,12 @@ export class DatabaseUI extends DisposableObject {
|
||||
|
||||
private async handleChooseDatabaseInternet(): Promise<void> {
|
||||
return withProgress(
|
||||
async (progress, token) => {
|
||||
async (progress) => {
|
||||
await promptImportInternetDatabase(
|
||||
this.app.commands,
|
||||
this.databaseManager,
|
||||
this.storagePath,
|
||||
progress,
|
||||
token,
|
||||
this.queryServer?.cliServer,
|
||||
);
|
||||
},
|
||||
@@ -503,7 +500,7 @@ export class DatabaseUI extends DisposableObject {
|
||||
|
||||
private async handleChooseDatabaseGithub(): Promise<void> {
|
||||
return withProgress(
|
||||
async (progress, token) => {
|
||||
async (progress) => {
|
||||
const credentials = isCanary() ? this.app.credentials : undefined;
|
||||
|
||||
await promptImportGithubDatabase(
|
||||
@@ -512,7 +509,6 @@ export class DatabaseUI extends DisposableObject {
|
||||
this.storagePath,
|
||||
credentials,
|
||||
progress,
|
||||
token,
|
||||
this.queryServer?.cliServer,
|
||||
);
|
||||
},
|
||||
@@ -608,14 +604,13 @@ export class DatabaseUI extends DisposableObject {
|
||||
|
||||
private async handleClearCache(): Promise<void> {
|
||||
return withProgress(
|
||||
async (progress, token) => {
|
||||
async (_progress, token) => {
|
||||
if (
|
||||
this.queryServer !== undefined &&
|
||||
this.databaseManager.currentDatabaseItem !== undefined
|
||||
) {
|
||||
await this.queryServer.clearCacheInDatabase(
|
||||
this.databaseManager.currentDatabaseItem,
|
||||
progress,
|
||||
token,
|
||||
);
|
||||
}
|
||||
@@ -633,7 +628,7 @@ export class DatabaseUI extends DisposableObject {
|
||||
|
||||
private async handleSetCurrentDatabase(uri: Uri): Promise<void> {
|
||||
return withProgress(
|
||||
async (progress, token) => {
|
||||
async (progress) => {
|
||||
try {
|
||||
// Assume user has selected an archive if the file has a .zip extension
|
||||
if (uri.path.endsWith(".zip")) {
|
||||
@@ -643,11 +638,10 @@ export class DatabaseUI extends DisposableObject {
|
||||
this.databaseManager,
|
||||
this.storagePath,
|
||||
progress,
|
||||
token,
|
||||
this.queryServer?.cliServer,
|
||||
);
|
||||
} else {
|
||||
await this.databaseManager.openDatabase(progress, token, uri);
|
||||
await this.databaseManager.openDatabase(uri);
|
||||
}
|
||||
} catch (e) {
|
||||
// rethrow and let this be handled by default error handling.
|
||||
@@ -668,10 +662,10 @@ export class DatabaseUI extends DisposableObject {
|
||||
databaseItems: DatabaseItem[],
|
||||
): Promise<void> {
|
||||
return withProgress(
|
||||
async (progress, token) => {
|
||||
async () => {
|
||||
await Promise.all(
|
||||
databaseItems.map((dbItem) =>
|
||||
this.databaseManager.removeDatabaseItem(progress, token, dbItem),
|
||||
this.databaseManager.removeDatabaseItem(dbItem),
|
||||
),
|
||||
);
|
||||
},
|
||||
@@ -758,15 +752,11 @@ export class DatabaseUI extends DisposableObject {
|
||||
|
||||
return await withInheritedProgress(
|
||||
progress,
|
||||
async (progress, token) => {
|
||||
async (progress) => {
|
||||
if (byFolder) {
|
||||
const fixedUri = await this.fixDbUri(uri);
|
||||
// we are selecting a database folder
|
||||
return await this.databaseManager.openDatabase(
|
||||
progress,
|
||||
token,
|
||||
fixedUri,
|
||||
);
|
||||
return await this.databaseManager.openDatabase(fixedUri);
|
||||
} else {
|
||||
// we are selecting a database archive. Must unzip into a workspace-controlled area
|
||||
// before importing.
|
||||
@@ -776,7 +766,6 @@ export class DatabaseUI extends DisposableObject {
|
||||
this.databaseManager,
|
||||
this.storagePath,
|
||||
progress,
|
||||
token,
|
||||
this.queryServer?.cliServer,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -104,8 +104,6 @@ export class DatabaseManager extends DisposableObject {
|
||||
* databases.
|
||||
*/
|
||||
public async openDatabase(
|
||||
progress: ProgressCallback,
|
||||
token: vscode.CancellationToken,
|
||||
uri: vscode.Uri,
|
||||
makeSelected = true,
|
||||
displayName?: string,
|
||||
@@ -115,9 +113,7 @@ export class DatabaseManager extends DisposableObject {
|
||||
|
||||
return await this.addExistingDatabaseItem(
|
||||
databaseItem,
|
||||
progress,
|
||||
makeSelected,
|
||||
token,
|
||||
isTutorialDatabase,
|
||||
);
|
||||
}
|
||||
@@ -130,9 +126,7 @@ export class DatabaseManager extends DisposableObject {
|
||||
*/
|
||||
private async addExistingDatabaseItem(
|
||||
databaseItem: DatabaseItemImpl,
|
||||
progress: ProgressCallback,
|
||||
makeSelected: boolean,
|
||||
token: vscode.CancellationToken,
|
||||
isTutorialDatabase?: boolean,
|
||||
): Promise<DatabaseItem> {
|
||||
const existingItem = this.findDatabaseItem(databaseItem.databaseUri);
|
||||
@@ -143,7 +137,7 @@ export class DatabaseManager extends DisposableObject {
|
||||
return existingItem;
|
||||
}
|
||||
|
||||
await this.addDatabaseItem(progress, token, databaseItem);
|
||||
await this.addDatabaseItem(databaseItem);
|
||||
if (makeSelected) {
|
||||
await this.setCurrentDatabaseItem(databaseItem);
|
||||
}
|
||||
@@ -260,14 +254,11 @@ export class DatabaseManager extends DisposableObject {
|
||||
}
|
||||
}
|
||||
|
||||
private async reregisterDatabases(
|
||||
progress: ProgressCallback,
|
||||
token: vscode.CancellationToken,
|
||||
) {
|
||||
private async reregisterDatabases(progress: ProgressCallback) {
|
||||
let completed = 0;
|
||||
await Promise.all(
|
||||
this._databaseItems.map(async (databaseItem) => {
|
||||
await this.registerDatabase(progress, token, databaseItem);
|
||||
await this.registerDatabase(databaseItem);
|
||||
completed++;
|
||||
progress({
|
||||
maxStep: this._databaseItems.length,
|
||||
@@ -324,8 +315,6 @@ export class DatabaseManager extends DisposableObject {
|
||||
}
|
||||
|
||||
private async createDatabaseItemFromPersistedState(
|
||||
progress: ProgressCallback,
|
||||
token: vscode.CancellationToken,
|
||||
state: PersistedDatabaseItem,
|
||||
): Promise<DatabaseItemImpl> {
|
||||
let displayName: string | undefined = undefined;
|
||||
@@ -356,12 +345,12 @@ export class DatabaseManager extends DisposableObject {
|
||||
|
||||
// Avoid persisting the database state after adding since that should happen only after
|
||||
// all databases have been added.
|
||||
await this.addDatabaseItem(progress, token, item, false);
|
||||
await this.addDatabaseItem(item, false);
|
||||
return item;
|
||||
}
|
||||
|
||||
public async loadPersistedState(): Promise<void> {
|
||||
return withProgress(async (progress, token) => {
|
||||
return withProgress(async (progress) => {
|
||||
const currentDatabaseUri =
|
||||
this.ctx.workspaceState.get<string>(CURRENT_DB);
|
||||
const databases = this.ctx.workspaceState.get<PersistedDatabaseItem[]>(
|
||||
@@ -388,13 +377,11 @@ export class DatabaseManager extends DisposableObject {
|
||||
});
|
||||
|
||||
const databaseItem = await this.createDatabaseItemFromPersistedState(
|
||||
progress,
|
||||
token,
|
||||
database,
|
||||
);
|
||||
try {
|
||||
await this.refreshDatabase(databaseItem);
|
||||
await this.registerDatabase(progress, token, databaseItem);
|
||||
await this.registerDatabase(databaseItem);
|
||||
if (currentDatabaseUri === database.uri) {
|
||||
await this.setCurrentDatabaseItem(databaseItem, true);
|
||||
}
|
||||
@@ -489,8 +476,6 @@ export class DatabaseManager extends DisposableObject {
|
||||
}
|
||||
|
||||
private async addDatabaseItem(
|
||||
progress: ProgressCallback,
|
||||
token: vscode.CancellationToken,
|
||||
item: DatabaseItemImpl,
|
||||
updatePersistedState = true,
|
||||
) {
|
||||
@@ -504,7 +489,7 @@ export class DatabaseManager extends DisposableObject {
|
||||
// Database items reconstituted from persisted state
|
||||
// will not have their contents yet.
|
||||
if (item.contents?.datasetUri) {
|
||||
await this.registerDatabase(progress, token, item);
|
||||
await this.registerDatabase(item);
|
||||
}
|
||||
// note that we use undefined as the item in order to reset the entire tree
|
||||
this._onDidChangeDatabaseItem.fire({
|
||||
@@ -523,11 +508,7 @@ export class DatabaseManager extends DisposableObject {
|
||||
});
|
||||
}
|
||||
|
||||
public async removeDatabaseItem(
|
||||
progress: ProgressCallback,
|
||||
token: vscode.CancellationToken,
|
||||
item: DatabaseItem,
|
||||
) {
|
||||
public async removeDatabaseItem(item: DatabaseItem) {
|
||||
if (this._currentDatabaseItem === item) {
|
||||
this._currentDatabaseItem = undefined;
|
||||
}
|
||||
@@ -549,7 +530,7 @@ export class DatabaseManager extends DisposableObject {
|
||||
}
|
||||
|
||||
// Remove this database item from the allow-list
|
||||
await this.deregisterDatabase(progress, token, item);
|
||||
await this.deregisterDatabase(item);
|
||||
|
||||
// Delete folder from file system only if it is controlled by the extension
|
||||
if (this.isExtensionControlledLocation(item.databaseUri)) {
|
||||
@@ -572,22 +553,15 @@ export class DatabaseManager extends DisposableObject {
|
||||
});
|
||||
}
|
||||
|
||||
public async removeAllDatabases(
|
||||
progress: ProgressCallback,
|
||||
token: vscode.CancellationToken,
|
||||
) {
|
||||
public async removeAllDatabases() {
|
||||
for (const item of this.databaseItems) {
|
||||
await this.removeDatabaseItem(progress, token, item);
|
||||
await this.removeDatabaseItem(item);
|
||||
}
|
||||
}
|
||||
|
||||
private async deregisterDatabase(
|
||||
progress: ProgressCallback,
|
||||
token: vscode.CancellationToken,
|
||||
dbItem: DatabaseItem,
|
||||
) {
|
||||
private async deregisterDatabase(dbItem: DatabaseItem) {
|
||||
try {
|
||||
await this.qs.deregisterDatabase(progress, token, dbItem);
|
||||
await this.qs.deregisterDatabase(dbItem);
|
||||
} catch (e) {
|
||||
const message = getErrorMessage(e);
|
||||
if (message === "Connection is disposed.") {
|
||||
@@ -600,12 +574,8 @@ export class DatabaseManager extends DisposableObject {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
private async registerDatabase(
|
||||
progress: ProgressCallback,
|
||||
token: vscode.CancellationToken,
|
||||
dbItem: DatabaseItem,
|
||||
) {
|
||||
await this.qs.registerDatabase(progress, token, dbItem);
|
||||
private async registerDatabase(dbItem: DatabaseItem) {
|
||||
await this.qs.registerDatabase(dbItem);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -284,7 +284,7 @@ export class LocalQueries extends DisposableObject {
|
||||
|
||||
private async createSkeletonQuery(): Promise<void> {
|
||||
await withProgress(
|
||||
async (progress: ProgressCallback, token: CancellationToken) => {
|
||||
async (progress: ProgressCallback) => {
|
||||
const credentials = isCanary() ? this.app.credentials : undefined;
|
||||
const contextStoragePath =
|
||||
this.app.workspaceStoragePath || this.app.globalStoragePath;
|
||||
@@ -294,7 +294,6 @@ export class LocalQueries extends DisposableObject {
|
||||
credentials,
|
||||
this.app.logger,
|
||||
this.databaseManager,
|
||||
token,
|
||||
contextStoragePath,
|
||||
);
|
||||
await skeletonQueryWizard.execute();
|
||||
|
||||
@@ -7,8 +7,9 @@ export function pluralize(
|
||||
numItems: number | undefined,
|
||||
singular: string,
|
||||
plural: string,
|
||||
numberFormatter: (value: number) => string = (value) => value.toString(),
|
||||
): string {
|
||||
return numItems !== undefined
|
||||
? `${numItems} ${numItems === 1 ? singular : plural}`
|
||||
? `${numberFormatter(numItems)} ${numItems === 1 ? singular : plural}`
|
||||
: "";
|
||||
}
|
||||
|
||||
@@ -55,10 +55,9 @@ export class LegacyQueryRunner extends QueryRunner {
|
||||
}
|
||||
async clearCacheInDatabase(
|
||||
dbItem: DatabaseItem,
|
||||
progress: ProgressCallback,
|
||||
token: CancellationToken,
|
||||
): Promise<void> {
|
||||
await clearCacheInDatabase(this.qs, dbItem, progress, token);
|
||||
await clearCacheInDatabase(this.qs, dbItem, token);
|
||||
}
|
||||
|
||||
public async compileAndRunQueryAgainstDatabaseCore(
|
||||
@@ -88,11 +87,7 @@ export class LegacyQueryRunner extends QueryRunner {
|
||||
);
|
||||
}
|
||||
|
||||
async deregisterDatabase(
|
||||
progress: ProgressCallback,
|
||||
token: CancellationToken,
|
||||
dbItem: DatabaseItem,
|
||||
): Promise<void> {
|
||||
async deregisterDatabase(dbItem: DatabaseItem): Promise<void> {
|
||||
if (dbItem.contents) {
|
||||
const databases: Dataset[] = [
|
||||
{
|
||||
@@ -100,19 +95,10 @@ export class LegacyQueryRunner extends QueryRunner {
|
||||
workingSet: "default",
|
||||
},
|
||||
];
|
||||
await this.qs.sendRequest(
|
||||
deregisterDatabases,
|
||||
{ databases },
|
||||
token,
|
||||
progress,
|
||||
);
|
||||
await this.qs.sendRequest(deregisterDatabases, { databases });
|
||||
}
|
||||
}
|
||||
async registerDatabase(
|
||||
progress: ProgressCallback,
|
||||
token: CancellationToken,
|
||||
dbItem: DatabaseItem,
|
||||
): Promise<void> {
|
||||
async registerDatabase(dbItem: DatabaseItem): Promise<void> {
|
||||
if (dbItem.contents) {
|
||||
const databases: Dataset[] = [
|
||||
{
|
||||
@@ -120,12 +106,7 @@ export class LegacyQueryRunner extends QueryRunner {
|
||||
workingSet: "default",
|
||||
},
|
||||
];
|
||||
await this.qs.sendRequest(
|
||||
registerDatabases,
|
||||
{ databases },
|
||||
token,
|
||||
progress,
|
||||
);
|
||||
await this.qs.sendRequest(registerDatabases, { databases });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -200,7 +200,6 @@ export class QueryInProgress {
|
||||
export async function clearCacheInDatabase(
|
||||
qs: qsClient.QueryServerClient,
|
||||
dbItem: DatabaseItem,
|
||||
progress: ProgressCallback,
|
||||
token: CancellationToken,
|
||||
): Promise<messages.ClearCacheResult> {
|
||||
if (dbItem.contents === undefined) {
|
||||
@@ -217,7 +216,7 @@ export async function clearCacheInDatabase(
|
||||
db,
|
||||
};
|
||||
|
||||
return qs.sendRequest(messages.clearCache, params, token, progress);
|
||||
return qs.sendRequest(messages.clearCache, params, token);
|
||||
}
|
||||
|
||||
function reportNoUpgradePath(
|
||||
|
||||
@@ -56,7 +56,6 @@ export class NewQueryRunner extends QueryRunner {
|
||||
|
||||
async clearCacheInDatabase(
|
||||
dbItem: DatabaseItem,
|
||||
progress: ProgressCallback,
|
||||
token: CancellationToken,
|
||||
): Promise<void> {
|
||||
if (dbItem.contents === undefined) {
|
||||
@@ -68,7 +67,7 @@ export class NewQueryRunner extends QueryRunner {
|
||||
dryRun: false,
|
||||
db,
|
||||
};
|
||||
await this.qs.sendRequest(clearCache, params, token, progress);
|
||||
await this.qs.sendRequest(clearCache, params, token);
|
||||
}
|
||||
|
||||
public async compileAndRunQueryAgainstDatabaseCore(
|
||||
@@ -98,34 +97,16 @@ export class NewQueryRunner extends QueryRunner {
|
||||
);
|
||||
}
|
||||
|
||||
async deregisterDatabase(
|
||||
progress: ProgressCallback,
|
||||
token: CancellationToken,
|
||||
dbItem: DatabaseItem,
|
||||
): Promise<void> {
|
||||
async deregisterDatabase(dbItem: DatabaseItem): Promise<void> {
|
||||
if (dbItem.contents) {
|
||||
const databases: string[] = [dbItem.databaseUri.fsPath];
|
||||
await this.qs.sendRequest(
|
||||
deregisterDatabases,
|
||||
{ databases },
|
||||
token,
|
||||
progress,
|
||||
);
|
||||
await this.qs.sendRequest(deregisterDatabases, { databases });
|
||||
}
|
||||
}
|
||||
async registerDatabase(
|
||||
progress: ProgressCallback,
|
||||
token: CancellationToken,
|
||||
dbItem: DatabaseItem,
|
||||
): Promise<void> {
|
||||
async registerDatabase(dbItem: DatabaseItem): Promise<void> {
|
||||
if (dbItem.contents) {
|
||||
const databases: string[] = [dbItem.databaseUri.fsPath];
|
||||
await this.qs.sendRequest(
|
||||
registerDatabases,
|
||||
{ databases },
|
||||
token,
|
||||
progress,
|
||||
);
|
||||
await this.qs.sendRequest(registerDatabases, { databases });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -61,9 +61,9 @@ export abstract class QueryRunner {
|
||||
token: CancellationToken,
|
||||
) => Promise<void>,
|
||||
): void;
|
||||
|
||||
abstract clearCacheInDatabase(
|
||||
dbItem: DatabaseItem,
|
||||
progress: ProgressCallback,
|
||||
token: CancellationToken,
|
||||
): Promise<void>;
|
||||
|
||||
@@ -83,17 +83,9 @@ export abstract class QueryRunner {
|
||||
logger: BaseLogger,
|
||||
): Promise<CoreQueryResults>;
|
||||
|
||||
abstract deregisterDatabase(
|
||||
progress: ProgressCallback,
|
||||
token: CancellationToken,
|
||||
dbItem: DatabaseItem,
|
||||
): Promise<void>;
|
||||
abstract deregisterDatabase(dbItem: DatabaseItem): Promise<void>;
|
||||
|
||||
abstract registerDatabase(
|
||||
progress: ProgressCallback,
|
||||
token: CancellationToken,
|
||||
dbItem: DatabaseItem,
|
||||
): Promise<void>;
|
||||
abstract registerDatabase(dbItem: DatabaseItem): Promise<void>;
|
||||
|
||||
abstract upgradeDatabaseExplicit(
|
||||
dbItem: DatabaseItem,
|
||||
|
||||
@@ -48,7 +48,7 @@ export class TestRunner extends DisposableObject {
|
||||
}
|
||||
}
|
||||
|
||||
await this.removeDatabasesBeforeTests(databasesUnderTest, token);
|
||||
await this.removeDatabasesBeforeTests(databasesUnderTest);
|
||||
try {
|
||||
const workspacePaths = getOnDiskWorkspaceFolders();
|
||||
for await (const event of this.cliServer.runTests(tests, workspacePaths, {
|
||||
@@ -66,24 +66,16 @@ export class TestRunner extends DisposableObject {
|
||||
await this.reopenDatabasesAfterTests(
|
||||
databasesUnderTest,
|
||||
currentDatabaseUri,
|
||||
token,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private async removeDatabasesBeforeTests(
|
||||
databasesUnderTest: DatabaseItem[],
|
||||
token: CancellationToken,
|
||||
): Promise<void> {
|
||||
for (const database of databasesUnderTest) {
|
||||
try {
|
||||
await this.databaseManager.removeDatabaseItem(
|
||||
(_) => {
|
||||
/* no progress reporting */
|
||||
},
|
||||
token,
|
||||
database,
|
||||
);
|
||||
await this.databaseManager.removeDatabaseItem(database);
|
||||
} catch (e) {
|
||||
// This method is invoked from Test Explorer UI, and testing indicates that Test
|
||||
// Explorer UI swallows any thrown exception without reporting it to the user.
|
||||
@@ -103,17 +95,12 @@ export class TestRunner extends DisposableObject {
|
||||
private async reopenDatabasesAfterTests(
|
||||
databasesUnderTest: DatabaseItem[],
|
||||
currentDatabaseUri: Uri | undefined,
|
||||
token: CancellationToken,
|
||||
): Promise<void> {
|
||||
for (const closedDatabase of databasesUnderTest) {
|
||||
const uri = closedDatabase.databaseUri;
|
||||
if (await isFileAccessible(uri)) {
|
||||
try {
|
||||
const reopenedDatabase = await this.databaseManager.openDatabase(
|
||||
(_) => {
|
||||
/* no progress reporting */
|
||||
},
|
||||
token,
|
||||
uri,
|
||||
false,
|
||||
);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { join } from "path";
|
||||
import { CancellationToken, Uri, workspace, window as Window } from "vscode";
|
||||
import { Uri, workspace, window as Window } from "vscode";
|
||||
import { CodeQLCliServer } from "./codeql-cli/cli";
|
||||
import { BaseLogger } from "./common";
|
||||
import { Credentials } from "./common/authentication";
|
||||
@@ -51,7 +51,6 @@ export class SkeletonQueryWizard {
|
||||
private readonly credentials: Credentials | undefined,
|
||||
private readonly logger: BaseLogger,
|
||||
private readonly databaseManager: DatabaseManager,
|
||||
private readonly token: CancellationToken,
|
||||
private readonly databaseStoragePath: string | undefined,
|
||||
) {}
|
||||
|
||||
@@ -258,7 +257,6 @@ export class SkeletonQueryWizard {
|
||||
this.databaseStoragePath,
|
||||
this.credentials,
|
||||
this.progress,
|
||||
this.token,
|
||||
this.cliServer,
|
||||
this.language,
|
||||
);
|
||||
|
||||
@@ -16,6 +16,7 @@ import { basename } from "../common/path";
|
||||
import { ViewTitle } from "../common";
|
||||
import { DataExtensionEditorViewState } from "../../data-extensions-editor/shared/view-state";
|
||||
import { ModeledMethodsList } from "./ModeledMethodsList";
|
||||
import { percentFormatter } from "./formatters";
|
||||
|
||||
const DataExtensionsEditorContainer = styled.div`
|
||||
margin-top: 1rem;
|
||||
@@ -213,8 +214,12 @@ export function DataExtensionsEditor({
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
<div>{modeledPercentage.toFixed(2)}% modeled</div>
|
||||
<div>{unModeledPercentage.toFixed(2)}% unmodeled</div>
|
||||
<div>
|
||||
{percentFormatter.format(modeledPercentage / 100)} modeled
|
||||
</div>
|
||||
<div>
|
||||
{percentFormatter.format(unModeledPercentage / 100)} unmodeled
|
||||
</div>
|
||||
</DetailsContainer>
|
||||
|
||||
<EditorContainer>
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
import * as React from "react";
|
||||
import { useCallback, useMemo, useState } from "react";
|
||||
import styled from "styled-components";
|
||||
import { ExternalApiUsage } from "../../data-extensions-editor/external-api-usage";
|
||||
import { ModeledMethod } from "../../data-extensions-editor/modeled-method";
|
||||
import { pluralize } from "../../pure/word";
|
||||
import { ModeledMethodDataGrid } from "./ModeledMethodDataGrid";
|
||||
import { calculateModeledPercentage } from "./modeled";
|
||||
import { decimalFormatter, percentFormatter } from "./formatters";
|
||||
import { Codicon } from "../common";
|
||||
|
||||
const LibraryContainer = styled.div`
|
||||
margin-bottom: 1rem;
|
||||
`;
|
||||
|
||||
const TitleContainer = styled.button`
|
||||
display: flex;
|
||||
gap: 0.5em;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
font-size: 1.2em;
|
||||
font-weight: bold;
|
||||
|
||||
color: var(--vscode-editor-foreground);
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
`;
|
||||
|
||||
const StatusContainer = styled.div`
|
||||
display: flex;
|
||||
gap: 1em;
|
||||
align-items: center;
|
||||
|
||||
margin-top: 0.5em;
|
||||
margin-bottom: 0.5em;
|
||||
margin-left: 1em;
|
||||
`;
|
||||
|
||||
type Props = {
|
||||
libraryName: string;
|
||||
externalApiUsages: ExternalApiUsage[];
|
||||
modeledMethods: Record<string, ModeledMethod>;
|
||||
onChange: (
|
||||
externalApiUsage: ExternalApiUsage,
|
||||
modeledMethod: ModeledMethod,
|
||||
) => void;
|
||||
};
|
||||
|
||||
export const LibraryRow = ({
|
||||
libraryName,
|
||||
externalApiUsages,
|
||||
modeledMethods,
|
||||
onChange,
|
||||
}: Props) => {
|
||||
const modeledPercentage = useMemo(() => {
|
||||
return calculateModeledPercentage(externalApiUsages);
|
||||
}, [externalApiUsages]);
|
||||
|
||||
const [isExpanded, setExpanded] = useState(modeledPercentage < 100);
|
||||
|
||||
const toggleExpanded = useCallback(async () => {
|
||||
setExpanded((oldIsExpanded) => !oldIsExpanded);
|
||||
}, []);
|
||||
|
||||
const usagesCount = useMemo(() => {
|
||||
return externalApiUsages.reduce((acc, curr) => acc + curr.usages.length, 0);
|
||||
}, [externalApiUsages]);
|
||||
|
||||
return (
|
||||
<LibraryContainer>
|
||||
<TitleContainer onClick={toggleExpanded} aria-expanded={isExpanded}>
|
||||
{isExpanded ? (
|
||||
<Codicon name="chevron-down" label="Collapse" />
|
||||
) : (
|
||||
<Codicon name="chevron-right" label="Expand" />
|
||||
)}
|
||||
{libraryName}
|
||||
{isExpanded ? null : (
|
||||
<>
|
||||
{" "}
|
||||
(
|
||||
{pluralize(
|
||||
externalApiUsages.length,
|
||||
"method",
|
||||
"methods",
|
||||
decimalFormatter.format.bind(decimalFormatter),
|
||||
)}
|
||||
, {percentFormatter.format(modeledPercentage / 100)} modeled)
|
||||
</>
|
||||
)}
|
||||
</TitleContainer>
|
||||
{isExpanded && (
|
||||
<>
|
||||
<StatusContainer>
|
||||
<div>
|
||||
{pluralize(
|
||||
externalApiUsages.length,
|
||||
"method",
|
||||
"methods",
|
||||
decimalFormatter.format.bind(decimalFormatter),
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
{pluralize(
|
||||
usagesCount,
|
||||
"usage",
|
||||
"usages",
|
||||
decimalFormatter.format.bind(decimalFormatter),
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
{percentFormatter.format(modeledPercentage / 100)} modeled
|
||||
</div>
|
||||
</StatusContainer>
|
||||
<ModeledMethodDataGrid
|
||||
externalApiUsages={externalApiUsages}
|
||||
modeledMethods={modeledMethods}
|
||||
onChange={onChange}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</LibraryContainer>
|
||||
);
|
||||
};
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
import { MethodRow } from "./MethodRow";
|
||||
import { ExternalApiUsage } from "../../data-extensions-editor/external-api-usage";
|
||||
import { ModeledMethod } from "../../data-extensions-editor/modeled-method";
|
||||
import { useMemo } from "react";
|
||||
|
||||
type Props = {
|
||||
externalApiUsages: ExternalApiUsage[];
|
||||
@@ -22,6 +23,22 @@ export const ModeledMethodDataGrid = ({
|
||||
modeledMethods,
|
||||
onChange,
|
||||
}: Props) => {
|
||||
const sortedExternalApiUsages = useMemo(() => {
|
||||
const sortedExternalApiUsages = [...externalApiUsages];
|
||||
sortedExternalApiUsages.sort((a, b) => {
|
||||
// Sort first by supported, putting unmodeled methods first.
|
||||
if (a.supported && !b.supported) {
|
||||
return 1;
|
||||
}
|
||||
if (!a.supported && b.supported) {
|
||||
return -1;
|
||||
}
|
||||
// Then sort by number of usages descending
|
||||
return b.usages.length - a.usages.length;
|
||||
});
|
||||
return sortedExternalApiUsages;
|
||||
}, [externalApiUsages]);
|
||||
|
||||
return (
|
||||
<VSCodeDataGrid>
|
||||
<VSCodeDataGridRow rowType="header">
|
||||
@@ -47,7 +64,7 @@ export const ModeledMethodDataGrid = ({
|
||||
Kind
|
||||
</VSCodeDataGridCell>
|
||||
</VSCodeDataGridRow>
|
||||
{externalApiUsages.map((externalApiUsage) => (
|
||||
{sortedExternalApiUsages.map((externalApiUsage) => (
|
||||
<MethodRow
|
||||
key={externalApiUsage.signature}
|
||||
externalApiUsage={externalApiUsage}
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
import * as React from "react";
|
||||
import { useMemo } from "react";
|
||||
import styled from "styled-components";
|
||||
import { ExternalApiUsage } from "../../data-extensions-editor/external-api-usage";
|
||||
import { ModeledMethod } from "../../data-extensions-editor/modeled-method";
|
||||
import { ModeledMethodDataGrid } from "./ModeledMethodDataGrid";
|
||||
|
||||
const LibraryContainer = styled.div`
|
||||
margin-bottom: 1rem;
|
||||
`;
|
||||
import { calculateModeledPercentage } from "./modeled";
|
||||
import { LibraryRow } from "./LibraryRow";
|
||||
|
||||
type Props = {
|
||||
externalApiUsages: ExternalApiUsage[];
|
||||
@@ -35,20 +31,59 @@ export const ModeledMethodsList = ({
|
||||
}, [externalApiUsages]);
|
||||
|
||||
const sortedLibraryNames = useMemo(() => {
|
||||
return Object.keys(groupedByLibrary).sort();
|
||||
return Object.keys(groupedByLibrary).sort((a, b) => {
|
||||
const supportedPercentageA = calculateModeledPercentage(
|
||||
groupedByLibrary[a],
|
||||
);
|
||||
const supportedPercentageB = calculateModeledPercentage(
|
||||
groupedByLibrary[b],
|
||||
);
|
||||
|
||||
// Sort first by supported percentage ascending
|
||||
if (supportedPercentageA > supportedPercentageB) {
|
||||
return 1;
|
||||
}
|
||||
if (supportedPercentageA < supportedPercentageB) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
const numberOfUsagesA = groupedByLibrary[a].reduce(
|
||||
(acc, curr) => acc + curr.usages.length,
|
||||
0,
|
||||
);
|
||||
const numberOfUsagesB = groupedByLibrary[b].reduce(
|
||||
(acc, curr) => acc + curr.usages.length,
|
||||
0,
|
||||
);
|
||||
|
||||
// If the number of usages is equal, sort by number of methods descending
|
||||
if (numberOfUsagesA === numberOfUsagesB) {
|
||||
const numberOfMethodsA = groupedByLibrary[a].length;
|
||||
const numberOfMethodsB = groupedByLibrary[b].length;
|
||||
|
||||
// If the number of methods is equal, sort by library name ascending
|
||||
if (numberOfMethodsA === numberOfMethodsB) {
|
||||
return a.localeCompare(b);
|
||||
}
|
||||
|
||||
return numberOfMethodsB - numberOfMethodsA;
|
||||
}
|
||||
|
||||
// Then sort by number of usages descending
|
||||
return numberOfUsagesB - numberOfUsagesA;
|
||||
});
|
||||
}, [groupedByLibrary]);
|
||||
|
||||
return (
|
||||
<>
|
||||
{sortedLibraryNames.map((libraryName) => (
|
||||
<LibraryContainer key={libraryName}>
|
||||
<h3>{libraryName}</h3>
|
||||
<ModeledMethodDataGrid
|
||||
externalApiUsages={groupedByLibrary[libraryName]}
|
||||
modeledMethods={modeledMethods}
|
||||
onChange={onChange}
|
||||
/>
|
||||
</LibraryContainer>
|
||||
<LibraryRow
|
||||
key={libraryName}
|
||||
libraryName={libraryName}
|
||||
externalApiUsages={groupedByLibrary[libraryName]}
|
||||
modeledMethods={modeledMethods}
|
||||
onChange={onChange}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
export const decimalFormatter = new Intl.NumberFormat("en-US", {
|
||||
style: "decimal",
|
||||
maximumFractionDigits: 2,
|
||||
});
|
||||
|
||||
export const percentFormatter = new Intl.NumberFormat("en-US", {
|
||||
style: "percent",
|
||||
maximumFractionDigits: 2,
|
||||
});
|
||||
@@ -1,5 +1,5 @@
|
||||
[
|
||||
"v2.13.3",
|
||||
"v2.13.4",
|
||||
"v2.12.7",
|
||||
"v2.11.6",
|
||||
"v2.7.6",
|
||||
|
||||
@@ -168,6 +168,26 @@ describe("decodeBqrsToExternalApiUsages", () => {
|
||||
// - Iterating over a map (as done by .values()) is guaranteed to be in insertion order
|
||||
// - Sorting the array of usages is guaranteed to be a stable sort
|
||||
expect(decodeBqrsToExternalApiUsages(chunk)).toEqual([
|
||||
{
|
||||
signature: "java.io.PrintStream#println(String)",
|
||||
packageName: "java.io",
|
||||
typeName: "PrintStream",
|
||||
methodName: "println",
|
||||
methodParameters: "(String)",
|
||||
supported: true,
|
||||
usages: [
|
||||
{
|
||||
label: "println(...)",
|
||||
url: {
|
||||
uri: "file:/home/runner/work/sql2o-example/sql2o-example/src/main/java/org/example/HelloController.java",
|
||||
startLine: 29,
|
||||
startColumn: 9,
|
||||
endLine: 29,
|
||||
endColumn: 49,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
signature:
|
||||
"org.springframework.boot.SpringApplication#run(Class,String[])",
|
||||
@@ -279,26 +299,6 @@ describe("decodeBqrsToExternalApiUsages", () => {
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
signature: "java.io.PrintStream#println(String)",
|
||||
packageName: "java.io",
|
||||
typeName: "PrintStream",
|
||||
methodName: "println",
|
||||
methodParameters: "(String)",
|
||||
supported: true,
|
||||
usages: [
|
||||
{
|
||||
label: "println(...)",
|
||||
url: {
|
||||
uri: "file:/home/runner/work/sql2o-example/sql2o-example/src/main/java/org/example/HelloController.java",
|
||||
startLine: 29,
|
||||
startColumn: 9,
|
||||
endLine: 29,
|
||||
endColumn: 49,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
signature: "org.sql2o.Sql2o#Sql2o(String,String,String)",
|
||||
packageName: "org.sql2o",
|
||||
|
||||
@@ -14,5 +14,22 @@ describe("word helpers", () => {
|
||||
it("should return the empty string if the number is undefined", () => {
|
||||
expect(pluralize(undefined, "thing", "things")).toBe("");
|
||||
});
|
||||
it("should return an unformatted number when no formatter is specified", () => {
|
||||
expect(pluralize(1_000_000, "thing", "things")).toBe("1000000 things");
|
||||
});
|
||||
it("should return a formatted number when a formatter is specified", () => {
|
||||
const formatter = new Intl.NumberFormat("en-US", {
|
||||
style: "decimal",
|
||||
});
|
||||
|
||||
expect(
|
||||
pluralize(
|
||||
1_000_000,
|
||||
"thing",
|
||||
"things",
|
||||
formatter.format.bind(formatter),
|
||||
),
|
||||
).toBe("1,000,000 things");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { join } from "path";
|
||||
import { CancellationToken, Uri, window } from "vscode";
|
||||
import { Uri, window } from "vscode";
|
||||
|
||||
import { CodeQLCliServer } from "../../../../src/codeql-cli/cli";
|
||||
import { DatabaseManager } from "../../../../src/databases/local-databases";
|
||||
@@ -52,7 +52,6 @@ describe("database-fetcher", () => {
|
||||
databaseManager,
|
||||
storagePath,
|
||||
progressCallback,
|
||||
{} as CancellationToken,
|
||||
cli,
|
||||
);
|
||||
expect(dbItem).toBe(databaseManager.currentDatabaseItem);
|
||||
@@ -74,7 +73,6 @@ describe("database-fetcher", () => {
|
||||
databaseManager,
|
||||
storagePath,
|
||||
progressCallback,
|
||||
{} as CancellationToken,
|
||||
cli,
|
||||
);
|
||||
expect(dbItem).toBeDefined();
|
||||
|
||||
@@ -142,14 +142,7 @@ describeWithCodeQL()("using the legacy query server", () => {
|
||||
const parsedResults = new Checkpoint<void>();
|
||||
|
||||
it("should register the database if necessary", async () => {
|
||||
await qs.sendRequest(
|
||||
messages.registerDatabases,
|
||||
{ databases: [db] },
|
||||
token,
|
||||
(() => {
|
||||
/**/
|
||||
}) as any,
|
||||
);
|
||||
await qs.sendRequest(messages.registerDatabases, { databases: [db] });
|
||||
});
|
||||
|
||||
it(`should be able to compile query ${queryName}`, async () => {
|
||||
|
||||
@@ -152,14 +152,7 @@ describeWithCodeQL()("using the new query server", () => {
|
||||
return;
|
||||
}
|
||||
|
||||
await qs.sendRequest(
|
||||
messages.registerDatabases,
|
||||
{ databases: [db] },
|
||||
token,
|
||||
(() => {
|
||||
/**/
|
||||
}) as any,
|
||||
);
|
||||
await qs.sendRequest(messages.registerDatabases, { databases: [db] });
|
||||
});
|
||||
|
||||
it(`should be able to run query ${queryName}`, async () => {
|
||||
|
||||
@@ -11,7 +11,6 @@ import { QlPackGenerator } from "../../../src/qlpack-generator";
|
||||
import * as workspaceFolders from "../../../src/common/vscode/workspace-folders";
|
||||
import { createFileSync, ensureDirSync, removeSync } from "fs-extra";
|
||||
import { join } from "path";
|
||||
import { CancellationTokenSource } from "vscode-jsonrpc";
|
||||
import { testCredentialsWithStub } from "../../factories/authentication";
|
||||
import {
|
||||
DatabaseItem,
|
||||
@@ -47,7 +46,6 @@ describe("SkeletonQueryWizard", () => {
|
||||
typeof workspace.openTextDocument
|
||||
>;
|
||||
|
||||
const token = new CancellationTokenSource().token;
|
||||
const credentials = testCredentialsWithStub();
|
||||
const chosenLanguage = "ruby";
|
||||
|
||||
@@ -117,7 +115,6 @@ describe("SkeletonQueryWizard", () => {
|
||||
credentials,
|
||||
extLogger,
|
||||
mockDatabaseManager,
|
||||
token,
|
||||
storagePath,
|
||||
);
|
||||
|
||||
@@ -252,7 +249,6 @@ describe("SkeletonQueryWizard", () => {
|
||||
credentials,
|
||||
extLogger,
|
||||
mockDatabaseManagerWithItems,
|
||||
token,
|
||||
storagePath,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -1,12 +1,7 @@
|
||||
import { join } from "path";
|
||||
import { load, dump } from "js-yaml";
|
||||
import { realpathSync, readFileSync, writeFileSync } from "fs-extra";
|
||||
import {
|
||||
CancellationToken,
|
||||
CancellationTokenSource,
|
||||
Uri,
|
||||
extensions,
|
||||
} from "vscode";
|
||||
import { Uri, extensions } from "vscode";
|
||||
import {
|
||||
DatabaseItem,
|
||||
DatabaseManager,
|
||||
@@ -14,7 +9,6 @@ import {
|
||||
import { CodeQLCliServer } from "../../src/codeql-cli/cli";
|
||||
import { removeWorkspaceRefs } from "../../src/variant-analysis/run-remote-query";
|
||||
import { CodeQLExtensionInterface } from "../../src/extension";
|
||||
import { ProgressCallback } from "../../src/common/vscode/progress";
|
||||
import { importArchiveDatabase } from "../../src/databases/database-fetcher";
|
||||
import { createMockCommandManager } from "../__mocks__/commandsMock";
|
||||
|
||||
@@ -49,7 +43,6 @@ export async function ensureTestDatabase(
|
||||
(_p) => {
|
||||
/**/
|
||||
},
|
||||
new CancellationTokenSource().token,
|
||||
cli,
|
||||
);
|
||||
|
||||
@@ -77,10 +70,7 @@ export async function getActivatedExtension(): Promise<CodeQLExtensionInterface>
|
||||
}
|
||||
|
||||
export async function cleanDatabases(databaseManager: DatabaseManager) {
|
||||
await databaseManager.removeAllDatabases(
|
||||
{} as ProgressCallback,
|
||||
{} as CancellationToken,
|
||||
);
|
||||
await databaseManager.removeAllDatabases();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as tmp from "tmp";
|
||||
import * as fs from "fs-extra";
|
||||
import { join } from "path";
|
||||
import { CancellationToken, ExtensionContext, Uri, workspace } from "vscode";
|
||||
import { ExtensionContext, Uri, workspace } from "vscode";
|
||||
|
||||
import {
|
||||
DatabaseContentsWithDbScheme,
|
||||
@@ -12,7 +12,6 @@ import {
|
||||
FullDatabaseOptions,
|
||||
} from "../../../src/databases/local-databases";
|
||||
import { Logger } from "../../../src/common";
|
||||
import { ProgressCallback } from "../../../src/common/vscode/progress";
|
||||
import { CodeQLCliServer, DbInfo } from "../../../src/codeql-cli/cli";
|
||||
import {
|
||||
encodeArchiveBasePath,
|
||||
@@ -119,11 +118,7 @@ describe("local databases", () => {
|
||||
const mockDbItem = createMockDB(dir);
|
||||
const onDidChangeDatabaseItem = jest.fn();
|
||||
databaseManager.onDidChangeDatabaseItem(onDidChangeDatabaseItem);
|
||||
await (databaseManager as any).addDatabaseItem(
|
||||
{} as ProgressCallback,
|
||||
{} as CancellationToken,
|
||||
mockDbItem,
|
||||
);
|
||||
await (databaseManager as any).addDatabaseItem(mockDbItem);
|
||||
|
||||
expect((databaseManager as any)._databaseItems).toEqual([mockDbItem]);
|
||||
expect(updateSpy).toBeCalledWith("databaseList", [
|
||||
@@ -141,11 +136,7 @@ describe("local databases", () => {
|
||||
onDidChangeDatabaseItem.mockClear();
|
||||
|
||||
// now remove the item
|
||||
await databaseManager.removeDatabaseItem(
|
||||
{} as ProgressCallback,
|
||||
{} as CancellationToken,
|
||||
mockDbItem,
|
||||
);
|
||||
await databaseManager.removeDatabaseItem(mockDbItem);
|
||||
expect((databaseManager as any)._databaseItems).toEqual([]);
|
||||
expect(updateSpy).toBeCalledWith("databaseList", []);
|
||||
expect(onDidChangeDatabaseItem).toBeCalledWith({
|
||||
@@ -159,11 +150,7 @@ describe("local databases", () => {
|
||||
const mockDbItem = createMockDB(dir);
|
||||
const onDidChangeDatabaseItem = jest.fn();
|
||||
databaseManager.onDidChangeDatabaseItem(onDidChangeDatabaseItem);
|
||||
await (databaseManager as any).addDatabaseItem(
|
||||
{} as ProgressCallback,
|
||||
{} as CancellationToken,
|
||||
mockDbItem,
|
||||
);
|
||||
await (databaseManager as any).addDatabaseItem(mockDbItem);
|
||||
|
||||
await databaseManager.renameDatabaseItem(mockDbItem, "new name");
|
||||
|
||||
@@ -188,11 +175,7 @@ describe("local databases", () => {
|
||||
databaseManager.onDidChangeDatabaseItem(onDidChangeDatabaseItem);
|
||||
const mockDbItem = createMockDB(dir);
|
||||
|
||||
await (databaseManager as any).addDatabaseItem(
|
||||
{} as ProgressCallback,
|
||||
{} as CancellationToken,
|
||||
mockDbItem,
|
||||
);
|
||||
await (databaseManager as any).addDatabaseItem(mockDbItem);
|
||||
|
||||
expect(databaseManager.databaseItems).toEqual([mockDbItem]);
|
||||
expect(updateSpy).toBeCalledWith("databaseList", [
|
||||
@@ -235,19 +218,11 @@ describe("local databases", () => {
|
||||
.spyOn(mockDbItem, "belongsToSourceArchiveExplorerUri")
|
||||
.mockReturnValue(true);
|
||||
|
||||
await (databaseManager as any).addDatabaseItem(
|
||||
{} as ProgressCallback,
|
||||
{} as CancellationToken,
|
||||
mockDbItem,
|
||||
);
|
||||
await (databaseManager as any).addDatabaseItem(mockDbItem);
|
||||
|
||||
updateSpy.mockClear();
|
||||
|
||||
await databaseManager.removeDatabaseItem(
|
||||
{} as ProgressCallback,
|
||||
{} as CancellationToken,
|
||||
mockDbItem,
|
||||
);
|
||||
await databaseManager.removeDatabaseItem(mockDbItem);
|
||||
|
||||
expect(databaseManager.databaseItems).toEqual([]);
|
||||
expect(updateSpy).toBeCalledWith("databaseList", []);
|
||||
@@ -268,22 +243,14 @@ describe("local databases", () => {
|
||||
jest
|
||||
.spyOn(mockDbItem, "belongsToSourceArchiveExplorerUri")
|
||||
.mockReturnValue(true);
|
||||
await (databaseManager as any).addDatabaseItem(
|
||||
{} as ProgressCallback,
|
||||
{} as CancellationToken,
|
||||
mockDbItem,
|
||||
);
|
||||
await (databaseManager as any).addDatabaseItem(mockDbItem);
|
||||
updateSpy.mockClear();
|
||||
|
||||
// pretend that the database location is not controlled by the extension
|
||||
(databaseManager as any).ctx.storageUri = Uri.file("hucairz");
|
||||
extensionContextStoragePath = "hucairz";
|
||||
|
||||
await databaseManager.removeDatabaseItem(
|
||||
{} as ProgressCallback,
|
||||
{} as CancellationToken,
|
||||
mockDbItem,
|
||||
);
|
||||
await databaseManager.removeDatabaseItem(mockDbItem);
|
||||
|
||||
expect(databaseManager.databaseItems).toEqual([]);
|
||||
expect(updateSpy).toBeCalledWith("databaseList", []);
|
||||
@@ -301,22 +268,14 @@ describe("local databases", () => {
|
||||
// registration messages.
|
||||
const mockDbItem = createMockDB(dir);
|
||||
|
||||
await (databaseManager as any).addDatabaseItem(
|
||||
{} as ProgressCallback,
|
||||
{} as CancellationToken,
|
||||
mockDbItem,
|
||||
);
|
||||
await (databaseManager as any).addDatabaseItem(mockDbItem);
|
||||
// Should have registered this database
|
||||
expect(registerSpy).toBeCalledWith({}, {}, mockDbItem);
|
||||
expect(registerSpy).toBeCalledWith(mockDbItem);
|
||||
|
||||
await databaseManager.removeDatabaseItem(
|
||||
{} as ProgressCallback,
|
||||
{} as CancellationToken,
|
||||
mockDbItem,
|
||||
);
|
||||
await databaseManager.removeDatabaseItem(mockDbItem);
|
||||
|
||||
// Should have deregistered this database
|
||||
expect(deregisterSpy).toBeCalledWith({}, {}, mockDbItem);
|
||||
expect(deregisterSpy).toBeCalledWith(mockDbItem);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -753,31 +712,19 @@ describe("local databases", () => {
|
||||
});
|
||||
|
||||
it("should resolve the database contents", async () => {
|
||||
await databaseManager.openDatabase(
|
||||
{} as ProgressCallback,
|
||||
{} as CancellationToken,
|
||||
mockDbItem.databaseUri,
|
||||
);
|
||||
await databaseManager.openDatabase(mockDbItem.databaseUri);
|
||||
|
||||
expect(resolveDatabaseContentsSpy).toBeCalledTimes(2);
|
||||
});
|
||||
|
||||
it("should set the database as the currently selected one", async () => {
|
||||
await databaseManager.openDatabase(
|
||||
{} as ProgressCallback,
|
||||
{} as CancellationToken,
|
||||
mockDbItem.databaseUri,
|
||||
);
|
||||
await databaseManager.openDatabase(mockDbItem.databaseUri);
|
||||
|
||||
expect(setCurrentDatabaseItemSpy).toBeCalledTimes(1);
|
||||
});
|
||||
|
||||
it("should add database source archive folder", async () => {
|
||||
await databaseManager.openDatabase(
|
||||
{} as ProgressCallback,
|
||||
{} as CancellationToken,
|
||||
mockDbItem.databaseUri,
|
||||
);
|
||||
await databaseManager.openDatabase(mockDbItem.databaseUri);
|
||||
|
||||
expect(addDatabaseSourceArchiveFolderSpy).toBeCalledTimes(1);
|
||||
});
|
||||
@@ -792,8 +739,6 @@ describe("local databases", () => {
|
||||
const nameOverride = "CodeQL Tutorial Database";
|
||||
|
||||
await databaseManager.openDatabase(
|
||||
{} as ProgressCallback,
|
||||
{} as CancellationToken,
|
||||
mockDbItem.databaseUri,
|
||||
makeSelected,
|
||||
nameOverride,
|
||||
@@ -808,11 +753,7 @@ describe("local databases", () => {
|
||||
it("should create a skeleton QL pack", async () => {
|
||||
jest.spyOn(Setting.prototype, "getValue").mockReturnValue(true);
|
||||
|
||||
await databaseManager.openDatabase(
|
||||
{} as ProgressCallback,
|
||||
{} as CancellationToken,
|
||||
mockDbItem.databaseUri,
|
||||
);
|
||||
await databaseManager.openDatabase(mockDbItem.databaseUri);
|
||||
|
||||
expect(createSkeletonPacksSpy).toBeCalledTimes(1);
|
||||
});
|
||||
@@ -823,11 +764,7 @@ describe("local databases", () => {
|
||||
it("should not create a skeleton QL pack", async () => {
|
||||
jest.spyOn(Setting.prototype, "getValue").mockReturnValue(false);
|
||||
|
||||
await databaseManager.openDatabase(
|
||||
{} as ProgressCallback,
|
||||
{} as CancellationToken,
|
||||
mockDbItem.databaseUri,
|
||||
);
|
||||
await databaseManager.openDatabase(mockDbItem.databaseUri);
|
||||
expect(createSkeletonPacksSpy).toBeCalledTimes(0);
|
||||
});
|
||||
});
|
||||
@@ -836,11 +773,7 @@ describe("local databases", () => {
|
||||
it("should not create a skeleton QL pack", async () => {
|
||||
jest.spyOn(Setting.prototype, "getValue").mockReturnValue(undefined);
|
||||
|
||||
await databaseManager.openDatabase(
|
||||
{} as ProgressCallback,
|
||||
{} as CancellationToken,
|
||||
mockDbItem.databaseUri,
|
||||
);
|
||||
await databaseManager.openDatabase(mockDbItem.databaseUri);
|
||||
expect(createSkeletonPacksSpy).toBeCalledTimes(0);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -155,16 +155,10 @@ describe("test-runner", () => {
|
||||
).toBeGreaterThan(openDatabaseSpy.mock.invocationCallOrder[0]);
|
||||
|
||||
expect(removeDatabaseItemSpy).toBeCalledTimes(1);
|
||||
expect(removeDatabaseItemSpy).toBeCalledWith(
|
||||
expect.anything(),
|
||||
expect.anything(),
|
||||
preTestDatabaseItem,
|
||||
);
|
||||
expect(removeDatabaseItemSpy).toBeCalledWith(preTestDatabaseItem);
|
||||
|
||||
expect(openDatabaseSpy).toBeCalledTimes(1);
|
||||
expect(openDatabaseSpy).toBeCalledWith(
|
||||
expect.anything(),
|
||||
expect.anything(),
|
||||
preTestDatabaseItem.databaseUri,
|
||||
false,
|
||||
);
|
||||
|
||||
@@ -232,8 +232,6 @@ describe("run-queries", () => {
|
||||
it("should register", async () => {
|
||||
const qs = createMockQueryServerClient();
|
||||
const runner = new LegacyQueryRunner(qs);
|
||||
const mockProgress = "progress-monitor";
|
||||
const mockCancel = "cancel-token";
|
||||
const datasetUri = Uri.file("dataset-uri");
|
||||
|
||||
const dbItem: DatabaseItem = {
|
||||
@@ -242,33 +240,22 @@ describe("run-queries", () => {
|
||||
},
|
||||
} as any;
|
||||
|
||||
await runner.registerDatabase(
|
||||
mockProgress as any,
|
||||
mockCancel as any,
|
||||
dbItem,
|
||||
);
|
||||
await runner.registerDatabase(dbItem);
|
||||
|
||||
expect(qs.sendRequest).toHaveBeenCalledTimes(1);
|
||||
expect(qs.sendRequest).toHaveBeenCalledWith(
|
||||
registerDatabases,
|
||||
{
|
||||
databases: [
|
||||
{
|
||||
dbDir: datasetUri.fsPath,
|
||||
workingSet: "default",
|
||||
},
|
||||
],
|
||||
},
|
||||
mockCancel,
|
||||
mockProgress,
|
||||
);
|
||||
expect(qs.sendRequest).toHaveBeenCalledWith(registerDatabases, {
|
||||
databases: [
|
||||
{
|
||||
dbDir: datasetUri.fsPath,
|
||||
workingSet: "default",
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it("should deregister", async () => {
|
||||
const qs = createMockQueryServerClient();
|
||||
const runner = new LegacyQueryRunner(qs);
|
||||
const mockProgress = "progress-monitor";
|
||||
const mockCancel = "cancel-token";
|
||||
const datasetUri = Uri.file("dataset-uri");
|
||||
|
||||
const dbItem: DatabaseItem = {
|
||||
@@ -277,26 +264,17 @@ describe("run-queries", () => {
|
||||
},
|
||||
} as any;
|
||||
|
||||
await runner.deregisterDatabase(
|
||||
mockProgress as any,
|
||||
mockCancel as any,
|
||||
dbItem,
|
||||
);
|
||||
await runner.deregisterDatabase(dbItem);
|
||||
|
||||
expect(qs.sendRequest).toHaveBeenCalledTimes(1);
|
||||
expect(qs.sendRequest).toHaveBeenCalledWith(
|
||||
deregisterDatabases,
|
||||
{
|
||||
databases: [
|
||||
{
|
||||
dbDir: datasetUri.fsPath,
|
||||
workingSet: "default",
|
||||
},
|
||||
],
|
||||
},
|
||||
mockCancel,
|
||||
mockProgress,
|
||||
);
|
||||
expect(qs.sendRequest).toHaveBeenCalledWith(deregisterDatabases, {
|
||||
databases: [
|
||||
{
|
||||
dbDir: datasetUri.fsPath,
|
||||
workingSet: "default",
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user