Skip to content

Commit

Permalink
Merge pull request #370 from aeisenberg/aeisenberg/import-notify
Browse files Browse the repository at this point in the history
Refactor how we import database archives
  • Loading branch information
jcreedcmu authored May 15, 2020
2 parents bb3aa79 + a137a72 commit 691c9af
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 12 deletions.
41 changes: 35 additions & 6 deletions extensions/ql-vscode/src/databaseFetcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,23 @@ import { Uri, ProgressOptions, ProgressLocation, commands, window } from "vscode
import * as fs from "fs-extra";
import * as path from "path";
import { DatabaseManager, DatabaseItem } from "./databases";
import { ProgressCallback, showAndLogErrorMessage, withProgress } from "./helpers";
import { ProgressCallback, showAndLogErrorMessage, withProgress, showAndLogInformationMessage } from "./helpers";

/**
* Prompts a user to fetch a database from a remote location. Database is assumed to be an archive file.
*
* @param databasesManager the DatabaseManager
* @param storagePath where to store the unzipped database.
*/
export default async function promptFetchDatabase(databasesManager: DatabaseManager, storagePath: string): Promise<DatabaseItem | undefined> {
export async function promptImportInternetDatabase(databasesManager: DatabaseManager, storagePath: string): Promise<DatabaseItem | undefined> {
let item: DatabaseItem | undefined = undefined;

try {
const databaseUrl = await window.showInputBox({
prompt: 'Enter URL of zipfile of database to download'
});
if (databaseUrl) {
validateUrl(databaseUrl);
validateHttpsUrl(databaseUrl);

const progressOptions: ProgressOptions = {
location: ProgressLocation.Notification,
Expand All @@ -30,13 +30,41 @@ export default async function promptFetchDatabase(databasesManager: DatabaseMana
await withProgress(progressOptions, async progress => (item = await databaseArchiveFetcher(databaseUrl, databasesManager, storagePath, progress)));
commands.executeCommand('codeQLDatabases.focus');
}
showAndLogInformationMessage('Database downloaded and imported successfully.');
} catch (e) {
showAndLogErrorMessage(e.message);
}

return item;
}


/**
* Imports a database from a local archive.
*
* @param databaseUrl the file url of the archive to import
* @param databasesManager the DatabaseManager
* @param storagePath where to store the unzipped database.
*/
export async function importArchiveDatabase(databaseUrl: string, databasesManager: DatabaseManager, storagePath: string): Promise<DatabaseItem | undefined> {
let item: DatabaseItem | undefined = undefined;
try {
const progressOptions: ProgressOptions = {
location: ProgressLocation.Notification,
title: 'Importing database from archive',
cancellable: false,
};
await withProgress(progressOptions, async progress => (item = await databaseArchiveFetcher(databaseUrl, databasesManager, storagePath, progress)));
commands.executeCommand('codeQLDatabases.focus');

showAndLogInformationMessage('Database unzipped and imported successfully.');
} catch (e) {
showAndLogErrorMessage(e.message);
}
return item;
}


/**
* Fetches an archive database. The database might be on the internet
* or in the local filesystem.
Expand All @@ -46,15 +74,15 @@ export default async function promptFetchDatabase(databasesManager: DatabaseMana
* @param storagePath where to store the unzipped database.
* @param progressCallback optional callback to send progress messages to
*/
export async function databaseArchiveFetcher(
async function databaseArchiveFetcher(
databaseUrl: string,
databasesManager: DatabaseManager,
storagePath: string,
progressCallback?: ProgressCallback
): Promise<DatabaseItem> {
progressCallback?.({
maxStep: 3,
message: 'Downloading database',
message: 'Getting database',
step: 1
});
if (!storagePath) {
Expand All @@ -75,6 +103,7 @@ export async function databaseArchiveFetcher(
step: 3
});

// find the path to the database. The actual database might be in a sub-folder
const dbPath = await findDirWithFile(unzipPath, '.dbinfo', 'codeql-database.yml');
if (dbPath) {
const item = await databasesManager.openDatabase(Uri.parse(dbPath));
Expand Down Expand Up @@ -106,7 +135,7 @@ async function getStorageFolder(storagePath: string, urlStr: string) {
}


function validateUrl(databaseUrl: string) {
function validateHttpsUrl(databaseUrl: string) {
let uri;
try {
uri = Uri.parse(databaseUrl, true);
Expand Down
8 changes: 4 additions & 4 deletions extensions/ql-vscode/src/databases-ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { logger } from './logging';
import { clearCacheInDatabase, UserCancellationException } from './run-queries';
import * as qsClient from './queryserver-client';
import { upgradeDatabase } from './upgrades';
import promptFetchDatabase, { databaseArchiveFetcher } from './databaseFetcher';
import { importArchiveDatabase, promptImportInternetDatabase } from './databaseFetcher';

type ThemableIconPath = { light: string; dark: string } | string;

Expand Down Expand Up @@ -212,7 +212,7 @@ export class DatabaseUI extends DisposableObject {
}

private handleChooseDatabaseInternet = async (): Promise<DatabaseItem | undefined> => {
return await promptFetchDatabase(this.databaseManager, this.storagePath);
return await promptImportInternetDatabase(this.databaseManager, this.storagePath);
}

private handleSortByName = async () => {
Expand Down Expand Up @@ -292,7 +292,7 @@ export class DatabaseUI extends DisposableObject {
private handleSetCurrentDatabase = async (uri: Uri): Promise<DatabaseItem | undefined> => {
// Assume user has selected an archive if the file has a .zip extension
if (uri.path.endsWith('.zip')) {
return await databaseArchiveFetcher(uri.toString(), this.databaseManager, this.storagePath);
return await importArchiveDatabase(uri.toString(), this.databaseManager, this.storagePath);
}

return await this.setCurrentDatabase(uri);
Expand Down Expand Up @@ -366,7 +366,7 @@ export class DatabaseUI extends DisposableObject {
else {
// we are selecting a database archive. Must unzip into a workspace-controlled area
// before importing.
return await databaseArchiveFetcher(uri.toString(), this.databaseManager, this.storagePath);
return await importArchiveDatabase(uri.toString(), this.databaseManager, this.storagePath);
}
}
}
4 changes: 2 additions & 2 deletions extensions/ql-vscode/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { displayQuickQuery } from './quick-query';
import { compileAndRunQueryAgainstDatabase, tmpDirDisposal, UserCancellationException } from './run-queries';
import { QLTestAdapterFactory } from './test-adapter';
import { TestUIService } from './test-ui';
import promptFetchDatabase from './databaseFetcher';
import { promptImportInternetDatabase } from './databaseFetcher';

/**
* extension.ts
Expand Down Expand Up @@ -335,7 +335,7 @@ async function activateWithInstalledDistribution(ctx: ExtensionContext, distribu
await qs.restartQueryServer();
helpers.showAndLogInformationMessage('CodeQL Query Server restarted.', { outputLogger: queryServerLogger });
}));
ctx.subscriptions.push(commands.registerCommand('codeQL.downloadDatabase', () => promptFetchDatabase(dbm, getContextStoragePath(ctx))));
ctx.subscriptions.push(commands.registerCommand('codeQL.downloadDatabase', () => promptImportInternetDatabase(dbm, getContextStoragePath(ctx))));

ctx.subscriptions.push(client.start());

Expand Down

0 comments on commit 691c9af

Please sign in to comment.