Skip to content

Commit 7cff1fb

Browse files
authored
Add core classes and models for the new (experimental) databases panel (#1704)
1 parent 684c492 commit 7cff1fb

File tree

7 files changed

+209
-0
lines changed

7 files changed

+209
-0
lines changed
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// This file contains models that are used to represent the databases.
2+
3+
export enum DbItemKind {
4+
RootLocal = 'RootLocal',
5+
RootRemote = 'RootRemote',
6+
RemoteSystemDefinedList = 'RemoteSystemDefinedList',
7+
RemoteUserDefinedList = 'RemoteUserDefinedList',
8+
RemoteOwner = 'RemoteOwner',
9+
RemoteRepo = 'RemoteRepo'
10+
}
11+
12+
export interface RootLocalDbItem {
13+
kind: DbItemKind.RootLocal;
14+
}
15+
16+
export interface RootRemoteDbItem {
17+
kind: DbItemKind.RootRemote;
18+
children: RemoteDbItem[];
19+
}
20+
21+
export type DbItem =
22+
| RootLocalDbItem
23+
| RootRemoteDbItem
24+
| RemoteDbItem
25+
26+
export type RemoteDbItem =
27+
| RemoteSystemDefinedListDbItem
28+
| RemoteUserDefinedListDbItem
29+
| RemoteOwnerDbItem
30+
| RemoteRepoDbItem;
31+
32+
export interface RemoteSystemDefinedListDbItem {
33+
kind: DbItemKind.RemoteSystemDefinedList;
34+
listName: string;
35+
listDisplayName: string;
36+
listDescription: string;
37+
}
38+
39+
export interface RemoteUserDefinedListDbItem {
40+
kind: DbItemKind.RemoteUserDefinedList;
41+
listName: string;
42+
repos: RemoteRepoDbItem[];
43+
}
44+
45+
export interface RemoteOwnerDbItem {
46+
kind: DbItemKind.RemoteOwner;
47+
ownerName: string;
48+
}
49+
50+
export interface RemoteRepoDbItem {
51+
kind: DbItemKind.RemoteRepo;
52+
repoFullName: string;
53+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { logger } from '../logging';
2+
import { DbConfigStore } from './db-config-store';
3+
import { DbItem } from './db-item';
4+
5+
export class DbManager {
6+
constructor(
7+
private readonly dbConfigStore: DbConfigStore
8+
) {
9+
}
10+
11+
public loadDatabases(): void {
12+
const config = this.dbConfigStore.getConfig();
13+
void logger.log(`Loaded databases: ${JSON.stringify(config)}`);
14+
15+
// This will be fleshed out in a future change.
16+
}
17+
18+
public getDbItems(): DbItem[] {
19+
// This will be fleshed out in a future change.
20+
return [];
21+
}
22+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import * as vscode from 'vscode';
2+
import { isCanary, isNewQueryRunExperienceEnabled } from '../config';
3+
import { logger } from '../logging';
4+
import { DisposableObject } from '../pure/disposable-object';
5+
import { DbConfigStore } from './db-config-store';
6+
import { DbManager } from './db-manager';
7+
import { DbPanel } from './ui/db-panel';
8+
9+
export class DbModule extends DisposableObject {
10+
public async initialize(
11+
extensionContext: vscode.ExtensionContext
12+
): Promise<void> {
13+
if (extensionContext.extensionMode !== vscode.ExtensionMode.Development ||
14+
!isCanary() ||
15+
!isNewQueryRunExperienceEnabled()) {
16+
// Currently, we only want to expose the new database panel when we
17+
// are in development and canary mode and the developer has enabled the
18+
// new query run experience.
19+
return;
20+
}
21+
22+
void logger.log('Initializing database module');
23+
24+
const storagePath = extensionContext.storageUri?.fsPath || extensionContext.globalStorageUri.fsPath;
25+
const dbConfigStore = new DbConfigStore(storagePath);
26+
await dbConfigStore.initialize();
27+
28+
const dbManager = new DbManager(dbConfigStore);
29+
dbManager.loadDatabases();
30+
31+
const dbPanel = new DbPanel(dbManager);
32+
33+
this.push(dbPanel);
34+
this.push(dbConfigStore);
35+
}
36+
}
37+
38+
export async function initializeDbModule(
39+
extensionContext: vscode.ExtensionContext
40+
): Promise<DbModule> {
41+
const dbModule = new DbModule();
42+
await dbModule.initialize(extensionContext);
43+
return dbModule;
44+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import * as vscode from 'vscode';
2+
import { DisposableObject } from '../../pure/disposable-object';
3+
import { DbManager } from '../db-manager';
4+
import { DbTreeDataProvider } from './db-tree-data-provider';
5+
6+
export class DbPanel extends DisposableObject {
7+
private readonly dataProvider: DbTreeDataProvider;
8+
9+
public constructor(
10+
dbManager: DbManager
11+
) {
12+
super();
13+
14+
this.dataProvider = new DbTreeDataProvider(dbManager);
15+
16+
const treeView = vscode.window.createTreeView('codeQLDatabasesExperimental', {
17+
treeDataProvider: this.dataProvider,
18+
canSelectMany: false
19+
});
20+
21+
this.push(treeView);
22+
}
23+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { logger } from '../../logging';
2+
import { ProviderResult, TreeDataProvider, TreeItem } from 'vscode';
3+
import { DbTreeViewItem } from './db-tree-view-item';
4+
import { DbManager } from '../db-manager';
5+
6+
export class DbTreeDataProvider implements TreeDataProvider<DbTreeViewItem> {
7+
private dbTreeItems: DbTreeViewItem[];
8+
9+
public constructor(
10+
private readonly dbManager: DbManager
11+
) {
12+
this.dbTreeItems = this.createTree();
13+
}
14+
15+
/**
16+
* Called when expanding a node (including the root node).
17+
* @param node The node to expand.
18+
* @returns The children of the node.
19+
*/
20+
public getChildren(node?: DbTreeViewItem): ProviderResult<DbTreeViewItem[]> {
21+
if (!node) {
22+
// We're at the root.
23+
return Promise.resolve(this.dbTreeItems);
24+
} else {
25+
return Promise.resolve(node.children);
26+
}
27+
}
28+
29+
/**
30+
* Returns the UI presentation of the element that gets displayed in the view.
31+
* @param node The node to represent.
32+
* @returns The UI presentation of the node.
33+
*/
34+
public getTreeItem(node: DbTreeViewItem): TreeItem | Thenable<TreeItem> {
35+
return node;
36+
}
37+
38+
private createTree(): DbTreeViewItem[] {
39+
const dbItems = this.dbManager.getDbItems();
40+
41+
// This will be fleshed out in a future change.
42+
void logger.log(`Creating database tree with ${dbItems.length} items`);
43+
44+
return [];
45+
}
46+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import * as vscode from 'vscode';
2+
import { DbItem } from '../db-item';
3+
4+
/**
5+
* Represents an item in the database tree view.
6+
*/
7+
export class DbTreeViewItem extends vscode.TreeItem {
8+
constructor(
9+
public readonly dbItem: DbItem,
10+
public readonly label: string,
11+
public readonly tooltip: string,
12+
public readonly collapsibleState: vscode.TreeItemCollapsibleState,
13+
public readonly children: DbTreeViewItem[]
14+
) {
15+
super(label, collapsibleState);
16+
}
17+
}

extensions/ql-vscode/src/extension.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ import { VariantAnalysisManager } from './remote-queries/variant-analysis-manage
118118
import { createVariantAnalysisContentProvider } from './remote-queries/variant-analysis-content-provider';
119119
import { VSCodeMockGitHubApiServer } from './mocks/vscode-mock-gh-api-server';
120120
import { VariantAnalysisResultsManager } from './remote-queries/variant-analysis-results-manager';
121+
import { initializeDbModule } from './databases/db-module';
121122

122123
/**
123124
* extension.ts
@@ -1229,6 +1230,9 @@ async function activateWithInstalledDistribution(
12291230
void logger.log('Reading query history');
12301231
await qhm.readQueryHistory();
12311232

1233+
const dbModule = await initializeDbModule(ctx);
1234+
ctx.subscriptions.push(dbModule);
1235+
12321236
void logger.log('Successfully finished extension initialization.');
12331237

12341238
return {

0 commit comments

Comments
 (0)