Merge pull request #2328 from github/yer-a-single-rooted-workspace-query

Ensure we're selecting database in single rooted workspace
This commit is contained in:
Elena Tanasoiu
2023-04-18 17:25:09 +01:00
committed by GitHub
5 changed files with 76 additions and 57 deletions

View File

@@ -317,13 +317,15 @@ async function databaseArchiveFetcher(
}); });
await ensureZippedSourceLocation(dbPath); await ensureZippedSourceLocation(dbPath);
const makeSelected = true;
const item = await databaseManager.openDatabase( const item = await databaseManager.openDatabase(
progress, progress,
token, token,
Uri.file(dbPath), Uri.file(dbPath),
makeSelected,
nameOverride, nameOverride,
); );
await databaseManager.setCurrentDatabaseItem(item);
return item; return item;
} else { } else {
throw new Error("Database not found in archive."); throw new Error("Database not found in archive.");

View File

@@ -306,18 +306,21 @@ export class DatabaseUI extends DisposableObject {
`${workspace.workspaceFolders[0].uri}/.tours/codeql-tutorial-database`, `${workspace.workspaceFolders[0].uri}/.tours/codeql-tutorial-database`,
); );
let databaseItem = this.databaseManager.findDatabaseItem(uri); const databaseItem = this.databaseManager.findDatabaseItem(uri);
const isTutorialDatabase = true;
if (databaseItem === undefined) { if (databaseItem === undefined) {
databaseItem = await this.databaseManager.openDatabase( const makeSelected = true;
const nameOverride = "CodeQL Tutorial Database";
const isTutorialDatabase = true;
await this.databaseManager.openDatabase(
progress, progress,
token, token,
uri, uri,
"CodeQL Tutorial Database", makeSelected,
nameOverride,
isTutorialDatabase, isTutorialDatabase,
); );
} }
await this.databaseManager.setCurrentDatabaseItem(databaseItem);
await this.handleTourDependencies(); await this.handleTourDependencies();
} }
} catch (e) { } catch (e) {
@@ -630,7 +633,7 @@ export class DatabaseUI extends DisposableObject {
this.queryServer?.cliServer, this.queryServer?.cliServer,
); );
} else { } else {
await this.setCurrentDatabase(progress, token, uri); await this.databaseManager.openDatabase(progress, token, uri);
} }
} catch (e) { } catch (e) {
// rethrow and let this be handled by default error handling. // rethrow and let this be handled by default error handling.
@@ -752,24 +755,6 @@ export class DatabaseUI extends DisposableObject {
return this.databaseManager.currentDatabaseItem; return this.databaseManager.currentDatabaseItem;
} }
private async setCurrentDatabase(
progress: ProgressCallback,
token: CancellationToken,
uri: Uri,
): Promise<DatabaseItem | undefined> {
let databaseItem = this.databaseManager.findDatabaseItem(uri);
if (databaseItem === undefined) {
databaseItem = await this.databaseManager.openDatabase(
progress,
token,
uri,
);
}
await this.databaseManager.setCurrentDatabaseItem(databaseItem);
return databaseItem;
}
/** /**
* Ask the user for a database directory. Returns the chosen database, or `undefined` if the * Ask the user for a database directory. Returns the chosen database, or `undefined` if the
* operation was canceled. * operation was canceled.
@@ -789,7 +774,11 @@ export class DatabaseUI extends DisposableObject {
if (byFolder) { if (byFolder) {
const fixedUri = await this.fixDbUri(uri); const fixedUri = await this.fixDbUri(uri);
// we are selecting a database folder // we are selecting a database folder
return await this.setCurrentDatabase(progress, token, fixedUri); return await this.databaseManager.openDatabase(
progress,
token,
fixedUri,
);
} else { } else {
// we are selecting a database archive. Must unzip into a workspace-controlled area // we are selecting a database archive. Must unzip into a workspace-controlled area
// before importing. // before importing.

View File

@@ -621,6 +621,7 @@ export class DatabaseManager extends DisposableObject {
progress: ProgressCallback, progress: ProgressCallback,
token: vscode.CancellationToken, token: vscode.CancellationToken,
uri: vscode.Uri, uri: vscode.Uri,
makeSelected = false,
displayName?: string, displayName?: string,
isTutorialDatabase?: boolean, isTutorialDatabase?: boolean,
): Promise<DatabaseItem> { ): Promise<DatabaseItem> {
@@ -629,6 +630,7 @@ export class DatabaseManager extends DisposableObject {
return await this.addExistingDatabaseItem( return await this.addExistingDatabaseItem(
databaseItem, databaseItem,
progress, progress,
makeSelected,
token, token,
isTutorialDatabase, isTutorialDatabase,
); );
@@ -643,6 +645,7 @@ export class DatabaseManager extends DisposableObject {
public async addExistingDatabaseItem( public async addExistingDatabaseItem(
databaseItem: DatabaseItem, databaseItem: DatabaseItem,
progress: ProgressCallback, progress: ProgressCallback,
makeSelected = true,
token: vscode.CancellationToken, token: vscode.CancellationToken,
isTutorialDatabase?: boolean, isTutorialDatabase?: boolean,
): Promise<DatabaseItem> { ): Promise<DatabaseItem> {
@@ -652,6 +655,9 @@ export class DatabaseManager extends DisposableObject {
} }
await this.addDatabaseItem(progress, token, databaseItem); await this.addDatabaseItem(progress, token, databaseItem);
if (makeSelected) {
await this.setCurrentDatabaseItem(databaseItem);
}
await this.addDatabaseSourceArchiveFolder(databaseItem); await this.addDatabaseSourceArchiveFolder(databaseItem);
if (isCodespacesTemplate() && !isTutorialDatabase) { if (isCodespacesTemplate() && !isTutorialDatabase) {

View File

@@ -64,15 +64,14 @@ export class SkeletonQueryWizard {
if (skeletonPackAlreadyExists) { if (skeletonPackAlreadyExists) {
// just create a new example query file in skeleton QL pack // just create a new example query file in skeleton QL pack
await this.createExampleFile(); await this.createExampleFile();
// select existing database for language
await this.selectExistingDatabase();
} else { } else {
// generate a new skeleton QL pack with query file // generate a new skeleton QL pack with query file
await this.createQlPack(); await this.createQlPack();
// download database based on language and select it
await this.downloadDatabase();
} }
// select existing database for language or download a new one
await this.selectOrDownloadDatabase();
// open a query file // open a query file
try { try {
@@ -216,41 +215,19 @@ export class SkeletonQueryWizard {
); );
} }
private async selectExistingDatabase() { private async selectOrDownloadDatabase() {
if (this.language === undefined) {
throw new Error("Language is undefined");
}
if (this.qlPackStoragePath === undefined) { if (this.qlPackStoragePath === undefined) {
throw new Error("QL Pack storage path is undefined"); throw new Error("QL Pack storage path is undefined");
} }
const databaseNwo = QUERY_LANGUAGE_TO_DATABASE_REPO[this.language]; const existingDatabaseItem = await this.findExistingDatabaseItem();
const existingDatabaseItem = await this.findDatabaseItemByNwo(
this.language,
databaseNwo,
this.databaseManager.databaseItems,
);
if (existingDatabaseItem) { if (existingDatabaseItem) {
// select the found database // select the found database
await this.databaseManager.setCurrentDatabaseItem(existingDatabaseItem); await this.databaseManager.setCurrentDatabaseItem(existingDatabaseItem);
} else { } else {
const sameLanguageDatabaseItem = await this.findDatabaseItemByLanguage( // download new database and select it
this.language, await this.downloadDatabase();
this.databaseManager.databaseItems,
);
if (sameLanguageDatabaseItem) {
// select the found database
await this.databaseManager.setCurrentDatabaseItem(
sameLanguageDatabaseItem,
);
} else {
// download new database and select it
await this.downloadDatabase();
}
} }
} }
@@ -286,4 +263,27 @@ export class SkeletonQueryWizard {
} }
return dbs[0]; return dbs[0];
} }
private async findExistingDatabaseItem() {
if (this.language === undefined) {
throw new Error("Language is undefined");
}
const defaultDatabaseNwo = QUERY_LANGUAGE_TO_DATABASE_REPO[this.language];
const defaultDatabaseItem = await this.findDatabaseItemByNwo(
this.language,
defaultDatabaseNwo,
this.databaseManager.databaseItems,
);
if (defaultDatabaseItem !== undefined) {
return defaultDatabaseItem;
}
return await this.findDatabaseItemByLanguage(
this.language,
this.databaseManager.databaseItems,
);
}
} }

View File

@@ -708,6 +708,7 @@ describe("local databases", () => {
describe("openDatabase", () => { describe("openDatabase", () => {
let createSkeletonPacksSpy: jest.SpyInstance; let createSkeletonPacksSpy: jest.SpyInstance;
let resolveDatabaseContentsSpy: jest.SpyInstance; let resolveDatabaseContentsSpy: jest.SpyInstance;
let setCurrentDatabaseItemSpy: jest.SpyInstance;
let addDatabaseSourceArchiveFolderSpy: jest.SpyInstance; let addDatabaseSourceArchiveFolderSpy: jest.SpyInstance;
let mockDbItem: DatabaseItemImpl; let mockDbItem: DatabaseItemImpl;
@@ -722,6 +723,11 @@ describe("local databases", () => {
.spyOn(DatabaseResolver, "resolveDatabaseContents") .spyOn(DatabaseResolver, "resolveDatabaseContents")
.mockResolvedValue({} as DatabaseContentsWithDbScheme); .mockResolvedValue({} as DatabaseContentsWithDbScheme);
setCurrentDatabaseItemSpy = jest.spyOn(
databaseManager,
"setCurrentDatabaseItem",
);
addDatabaseSourceArchiveFolderSpy = jest.spyOn( addDatabaseSourceArchiveFolderSpy = jest.spyOn(
databaseManager, databaseManager,
"addDatabaseSourceArchiveFolder", "addDatabaseSourceArchiveFolder",
@@ -746,6 +752,19 @@ describe("local databases", () => {
expect(resolveDatabaseContentsSpy).toBeCalledTimes(1); expect(resolveDatabaseContentsSpy).toBeCalledTimes(1);
}); });
it("should set the database as the currently selected one", async () => {
const makeSelected = true;
await databaseManager.openDatabase(
{} as ProgressCallback,
{} as CancellationToken,
mockDbItem.databaseUri,
makeSelected,
);
expect(setCurrentDatabaseItemSpy).toBeCalledTimes(1);
});
it("should add database source archive folder", async () => { it("should add database source archive folder", async () => {
await databaseManager.openDatabase( await databaseManager.openDatabase(
{} as ProgressCallback, {} as ProgressCallback,
@@ -762,12 +781,15 @@ describe("local databases", () => {
jest.spyOn(Setting.prototype, "getValue").mockReturnValue(true); jest.spyOn(Setting.prototype, "getValue").mockReturnValue(true);
const isTutorialDatabase = true; const isTutorialDatabase = true;
const makeSelected = true;
const nameOverride = "CodeQL Tutorial Database";
await databaseManager.openDatabase( await databaseManager.openDatabase(
{} as ProgressCallback, {} as ProgressCallback,
{} as CancellationToken, {} as CancellationToken,
mockDbItem.databaseUri, mockDbItem.databaseUri,
"CodeQL Tutorial Database", makeSelected,
nameOverride,
isTutorialDatabase, isTutorialDatabase,
); );