Only clear problems view when a database is removed

This commit adds DatabaseChangedEvent and ensures that all events
fired by the DatabaseManager includes one of these kinds.

Currently, the only kind that we care about is `Remove`. We ensure that
the problems view is only cleared on Remove events.
This commit is contained in:
Andrew Eisenberg
2020-10-01 13:33:41 -07:00
parent 672b20d4aa
commit 7961816906
3 changed files with 61 additions and 29 deletions

View File

@@ -16,6 +16,7 @@ import * as fs from 'fs-extra';
import * as cli from './cli';
import {
DatabaseChangedEvent,
DatabaseItem,
DatabaseManager,
getUpgradesDirectories,
@@ -72,9 +73,7 @@ class DatabaseTreeDataProvider extends DisposableObject
implements TreeDataProvider<DatabaseItem> {
private _sortOrder = SortOrder.NameAsc;
private readonly _onDidChangeTreeData = new EventEmitter<
DatabaseItem | undefined
>();
private readonly _onDidChangeTreeData = new EventEmitter<DatabaseItem | undefined>();
private currentDatabaseItem: DatabaseItem | undefined;
constructor(
@@ -101,19 +100,19 @@ class DatabaseTreeDataProvider extends DisposableObject
return this._onDidChangeTreeData.event;
}
private handleDidChangeDatabaseItem = (
databaseItem: DatabaseItem | undefined
): void => {
this._onDidChangeTreeData.fire(databaseItem);
private handleDidChangeDatabaseItem = (event: DatabaseChangedEvent): void => {
// Note that events from the databse manager are instances of DatabaseChangedEvent
// and events fired by the UI are instances of DatabaseItem
this._onDidChangeTreeData.fire(event.item);
};
private handleDidChangeCurrentDatabaseItem = (
databaseItem: DatabaseItem | undefined
event: DatabaseChangedEvent
): void => {
if (this.currentDatabaseItem) {
this._onDidChangeTreeData.fire(this.currentDatabaseItem);
}
this.currentDatabaseItem = databaseItem;
this.currentDatabaseItem = event.item;
if (this.currentDatabaseItem) {
this._onDidChangeTreeData.fire(this.currentDatabaseItem);
}

View File

@@ -249,6 +249,24 @@ export interface DatabaseItem {
belongsToSourceArchiveExplorerUri(uri: vscode.Uri): boolean;
}
export enum DatabaseEventKind {
Add = 'Add',
Remove = 'Remove',
// Fired when databases are refreshed from persisted state
Refresh = 'Refresh',
// Fired when the current database changes
Change = 'Change',
Rename = 'Rename'
}
export interface DatabaseChangedEvent {
kind: DatabaseEventKind;
item: DatabaseItem | undefined;
}
class DatabaseItemImpl implements DatabaseItem {
private _error: Error | undefined = undefined;
private _contents: DatabaseContents | undefined;
@@ -257,7 +275,7 @@ class DatabaseItemImpl implements DatabaseItem {
public constructor(public readonly databaseUri: vscode.Uri,
contents: DatabaseContents | undefined, private options: FullDatabaseOptions,
private readonly onChanged: (item: DatabaseItemImpl) => void) {
private readonly onChanged: (event: DatabaseChangedEvent) => void) {
this._contents = contents;
}
@@ -312,7 +330,10 @@ class DatabaseItemImpl implements DatabaseItem {
}
}
finally {
this.onChanged(this);
this.onChanged({
kind: DatabaseEventKind.Refresh,
item: this
});
}
}
@@ -452,11 +473,11 @@ function eventFired<T>(event: vscode.Event<T>, timeoutMs = 1000): Promise<T | un
}
export class DatabaseManager extends DisposableObject {
private readonly _onDidChangeDatabaseItem = this.push(new vscode.EventEmitter<DatabaseItem | undefined>());
private readonly _onDidChangeDatabaseItem = this.push(new vscode.EventEmitter<DatabaseChangedEvent>());
readonly onDidChangeDatabaseItem = this._onDidChangeDatabaseItem.event;
private readonly _onDidChangeCurrentDatabaseItem = this.push(new vscode.EventEmitter<DatabaseItem | undefined>());
private readonly _onDidChangeCurrentDatabaseItem = this.push(new vscode.EventEmitter<DatabaseChangedEvent>());
readonly onDidChangeCurrentDatabaseItem = this._onDidChangeCurrentDatabaseItem.event;
private readonly _databaseItems: DatabaseItemImpl[] = [];
@@ -484,8 +505,8 @@ export class DatabaseManager extends DisposableObject {
displayName: realOptions.displayName,
dateAdded: realOptions.dateAdded || Date.now()
};
const databaseItem = new DatabaseItemImpl(uri, contents, fullOptions, (item) => {
this._onDidChangeDatabaseItem.fire(item);
const databaseItem = new DatabaseItemImpl(uri, contents, fullOptions, (event) => {
this._onDidChangeDatabaseItem.fire(event);
});
await this.addDatabaseItem(databaseItem);
await this.addDatabaseSourceArchiveFolder(databaseItem);
@@ -556,8 +577,8 @@ export class DatabaseManager extends DisposableObject {
dateAdded
};
const item = new DatabaseItemImpl(vscode.Uri.parse(state.uri), undefined, fullOptions,
(item) => {
this._onDidChangeDatabaseItem.fire(item);
(event) => {
this._onDidChangeDatabaseItem.fire(event);
});
await this.addDatabaseItem(item);
@@ -605,7 +626,10 @@ export class DatabaseManager extends DisposableObject {
if (this._currentDatabaseItem !== item) {
this._currentDatabaseItem = item;
this.updatePersistedCurrentDatabaseItem();
this._onDidChangeCurrentDatabaseItem.fire(item);
this._onDidChangeCurrentDatabaseItem.fire({
item,
kind: DatabaseEventKind.Change
});
}
}
@@ -631,13 +655,19 @@ export class DatabaseManager extends DisposableObject {
private async addDatabaseItem(item: DatabaseItemImpl) {
this._databaseItems.push(item);
this.updatePersistedDatabaseList();
this._onDidChangeDatabaseItem.fire(undefined);
this._onDidChangeDatabaseItem.fire({
item: undefined,
kind: DatabaseEventKind.Add
});
}
public async renameDatabaseItem(item: DatabaseItem, newName: string) {
item.name = newName;
this.updatePersistedDatabaseList();
this._onDidChangeDatabaseItem.fire(item);
this._onDidChangeDatabaseItem.fire({
item,
kind: DatabaseEventKind.Rename
});
}
public removeDatabaseItem(item: DatabaseItem) {
@@ -664,7 +694,10 @@ export class DatabaseManager extends DisposableObject {
e => logger.log(`Failed to delete '${item.databaseUri.path}'. Reason: ${e.message}`));
}
this._onDidChangeDatabaseItem.fire(undefined);
this._onDidChangeDatabaseItem.fire({
item: undefined,
kind: DatabaseEventKind.Remove
});
}
private updatePersistedCurrentDatabaseItem(): void {

View File

@@ -13,7 +13,7 @@ import {
} from 'vscode';
import * as cli from './cli';
import { CodeQLCliServer } from './cli';
import { DatabaseItem, DatabaseManager } from './databases';
import { DatabaseEventKind, DatabaseItem, DatabaseManager } from './databases';
import { showAndLogErrorMessage } from './helpers';
import { assertNever } from './helpers-pure';
import {
@@ -134,13 +134,13 @@ export class InterfaceManager extends DisposableObject {
);
this.push(
this.databaseManager.onDidChangeDatabaseItem(() => {
// Consider only clearing database items when a database
// is removed and only clearing items from that database.
this._diagnosticCollection.clear();
this.postMessage({
t: 'untoggleShowProblems'
});
this.databaseManager.onDidChangeDatabaseItem(({ kind }) => {
if (kind === DatabaseEventKind.Remove) {
this._diagnosticCollection.clear();
this.postMessage({
t: 'untoggleShowProblems'
});
}
})
);
}