Skip to content

Commit b2a3703

Browse files
authored
Render nodes for local database items (#1759)
1 parent 539dd1f commit b2a3703

File tree

7 files changed

+411
-9
lines changed

7 files changed

+411
-9
lines changed

extensions/ql-vscode/src/databases/db-item.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
export enum DbItemKind {
44
RootLocal = 'RootLocal',
5+
LocalList = 'LocalList',
6+
LocalDatabase = 'LocalDatabase',
57
RootRemote = 'RootRemote',
68
RemoteSystemDefinedList = 'RemoteSystemDefinedList',
79
RemoteUserDefinedList = 'RemoteUserDefinedList',
@@ -11,6 +13,25 @@ export enum DbItemKind {
1113

1214
export interface RootLocalDbItem {
1315
kind: DbItemKind.RootLocal;
16+
children: LocalDbItem[];
17+
}
18+
19+
export type LocalDbItem =
20+
| LocalListDbItem
21+
| LocalDatabaseDbItem;
22+
23+
export interface LocalListDbItem {
24+
kind: DbItemKind.LocalList;
25+
listName: string;
26+
databases: LocalDatabaseDbItem[];
27+
}
28+
29+
export interface LocalDatabaseDbItem {
30+
kind: DbItemKind.LocalDatabase;
31+
databaseName: string;
32+
dateAdded: number;
33+
language: string;
34+
storagePath: string;
1435
}
1536

1637
export interface RootRemoteDbItem {
@@ -22,6 +43,7 @@ export type DbItem =
2243
| RootLocalDbItem
2344
| RootRemoteDbItem
2445
| RemoteDbItem
46+
| LocalDbItem;
2547

2648
export type RemoteDbItem =
2749
| RemoteSystemDefinedListDbItem

extensions/ql-vscode/src/databases/db-manager.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export class DbManager {
2929

3030
return ValueResult.ok([
3131
createRemoteTree(configResult.value),
32-
createLocalTree()
32+
createLocalTree(configResult.value)
3333
]);
3434
}
3535

extensions/ql-vscode/src/databases/db-tree-creator.ts

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
import { DbConfig, RemoteRepositoryList } from './config/db-config';
1+
import { DbConfig, LocalDatabase, LocalList, RemoteRepositoryList } from './config/db-config';
22
import {
33
DbItemKind,
4+
LocalDatabaseDbItem,
5+
LocalListDbItem,
46
RemoteOwnerDbItem,
57
RemoteRepoDbItem,
68
RemoteSystemDefinedListDbItem,
@@ -31,10 +33,16 @@ export function createRemoteTree(dbConfig: DbConfig): RootRemoteDbItem {
3133
};
3234
}
3335

34-
export function createLocalTree(): RootLocalDbItem {
35-
// This will be fleshed out further in the future.
36+
export function createLocalTree(dbConfig: DbConfig): RootLocalDbItem {
37+
const localLists = dbConfig.databases.local.lists.map(createLocalList);
38+
const localDbs = dbConfig.databases.local.databases.map(createLocalDb);
39+
3640
return {
37-
kind: DbItemKind.RootLocal
41+
kind: DbItemKind.RootLocal,
42+
children: [
43+
...localLists,
44+
...localDbs
45+
]
3846
};
3947
}
4048

@@ -68,3 +76,21 @@ function createRepoItem(repo: string): RemoteRepoDbItem {
6876
repoFullName: repo
6977
};
7078
}
79+
80+
function createLocalList(list: LocalList): LocalListDbItem {
81+
return {
82+
kind: DbItemKind.LocalList,
83+
listName: list.name,
84+
databases: list.databases.map(createLocalDb)
85+
};
86+
}
87+
88+
function createLocalDb(db: LocalDatabase): LocalDatabaseDbItem {
89+
return {
90+
kind: DbItemKind.LocalDatabase,
91+
databaseName: db.name,
92+
dateAdded: db.dateAdded,
93+
language: db.language,
94+
storagePath: db.storagePath
95+
};
96+
}

extensions/ql-vscode/src/databases/ui/db-item-mapper.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { DbItem, DbItemKind } from '../db-item';
22
import {
3+
createDbTreeViewItemLocalDatabase,
34
createDbTreeViewItemOwner,
45
createDbTreeViewItemRepo,
56
createDbTreeViewItemRoot,
@@ -15,7 +16,7 @@ export function mapDbItemToTreeViewItem(dbItem: DbItem): DbTreeViewItem {
1516
dbItem,
1617
'local',
1718
'Local databases',
18-
[]);
19+
dbItem.children.map(c => mapDbItemToTreeViewItem(c)));
1920

2021
case DbItemKind.RootRemote:
2122
return createDbTreeViewItemRoot(
@@ -45,5 +46,17 @@ export function mapDbItemToTreeViewItem(dbItem: DbItem): DbTreeViewItem {
4546
return createDbTreeViewItemRepo(
4647
dbItem,
4748
dbItem.repoFullName);
49+
50+
case DbItemKind.LocalList:
51+
return createDbTreeViewItemUserDefinedList(
52+
dbItem,
53+
dbItem.listName,
54+
dbItem.databases.map(mapDbItemToTreeViewItem));
55+
56+
case DbItemKind.LocalDatabase:
57+
return createDbTreeViewItemLocalDatabase(
58+
dbItem,
59+
dbItem.databaseName,
60+
dbItem.language);
4861
}
4962
}

extensions/ql-vscode/src/databases/ui/db-tree-view-item.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import * as vscode from 'vscode';
22
import {
33
DbItem,
4+
LocalDatabaseDbItem,
5+
LocalListDbItem,
46
RemoteOwnerDbItem,
57
RemoteRepoDbItem,
68
RemoteSystemDefinedListDbItem,
@@ -70,7 +72,7 @@ export function createDbTreeViewItemSystemDefinedList(
7072
}
7173

7274
export function createDbTreeViewItemUserDefinedList(
73-
dbItem: RemoteUserDefinedListDbItem,
75+
dbItem: LocalListDbItem | RemoteUserDefinedListDbItem,
7476
listName: string,
7577
children: DbTreeViewItem[]
7678
): DbTreeViewItem {
@@ -108,3 +110,17 @@ export function createDbTreeViewItemRepo(
108110
vscode.TreeItemCollapsibleState.None,
109111
[]);
110112
}
113+
114+
export function createDbTreeViewItemLocalDatabase(
115+
dbItem: LocalDatabaseDbItem,
116+
databaseName: string,
117+
language: string
118+
): DbTreeViewItem {
119+
return new DbTreeViewItem(
120+
dbItem,
121+
new vscode.ThemeIcon('database'),
122+
databaseName,
123+
`Language: ${language}`,
124+
vscode.TreeItemCollapsibleState.None,
125+
[]);
126+
}

extensions/ql-vscode/src/vscode-tests/minimal-workspace/databases/db-panel.test.ts

Lines changed: 173 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { DbManager } from '../../../databases/db-manager';
88
import { DbConfigStore } from '../../../databases/config/db-config-store';
99
import { DbTreeDataProvider } from '../../../databases/ui/db-tree-data-provider';
1010
import { DbPanel } from '../../../databases/ui/db-panel';
11-
import { DbItemKind } from '../../../databases/db-item';
11+
import { DbItemKind, LocalDatabaseDbItem } from '../../../databases/db-item';
1212
import { DbTreeViewItem } from '../../../databases/ui/db-tree-view-item';
1313
import { ExtensionApp } from '../../../common/vscode/vscode-app';
1414
import { createMockExtensionContext } from '../../factories/extension-context';
@@ -235,6 +235,151 @@ describe('db panel', async () => {
235235
checkRemoteRepoItem(repoItems[1], 'owner1/repo2');
236236
});
237237

238+
it('should render local list nodes', async () => {
239+
const dbConfig: DbConfig = {
240+
databases: {
241+
remote: {
242+
repositoryLists: [],
243+
owners: [],
244+
repositories: []
245+
},
246+
local: {
247+
lists: [
248+
{
249+
name: 'my-list-1',
250+
databases: [
251+
{
252+
name: 'db1',
253+
dateAdded: 1668428293677,
254+
language: 'cpp',
255+
storagePath: '/path/to/db1/',
256+
},
257+
{
258+
name: 'db2',
259+
dateAdded: 1668428472731,
260+
language: 'cpp',
261+
storagePath: '/path/to/db2/',
262+
},
263+
],
264+
},
265+
{
266+
name: 'my-list-2',
267+
databases: [
268+
{
269+
name: 'db3',
270+
dateAdded: 1668428472731,
271+
language: 'ruby',
272+
storagePath: '/path/to/db3/',
273+
},
274+
],
275+
},
276+
],
277+
databases: []
278+
},
279+
},
280+
};
281+
282+
await saveDbConfig(dbConfig);
283+
284+
const dbTreeItems = await dbTreeDataProvider.getChildren();
285+
286+
expect(dbTreeItems).to.be.ok;
287+
const items = dbTreeItems!;
288+
expect(items.length).to.equal(2);
289+
290+
const localRootNode = items[1];
291+
expect(localRootNode.dbItem).to.be.ok;
292+
expect(localRootNode.collapsibleState).to.equal(vscode.TreeItemCollapsibleState.Collapsed);
293+
expect(localRootNode.children).to.be.ok;
294+
expect(localRootNode.children.length).to.equal(2);
295+
296+
const localListItems = localRootNode.children.filter(item => item.dbItem?.kind === DbItemKind.LocalList);
297+
expect(localListItems.length).to.equal(2);
298+
checkLocalListItem(localListItems[0], 'my-list-1', [{
299+
kind: DbItemKind.LocalDatabase,
300+
databaseName: 'db1',
301+
dateAdded: 1668428293677,
302+
language: 'cpp',
303+
storagePath: '/path/to/db1/',
304+
},
305+
{
306+
kind: DbItemKind.LocalDatabase,
307+
databaseName: 'db2',
308+
dateAdded: 1668428472731,
309+
language: 'cpp',
310+
storagePath: '/path/to/db2/',
311+
}]);
312+
checkLocalListItem(localListItems[1], 'my-list-2', [
313+
{
314+
kind: DbItemKind.LocalDatabase,
315+
databaseName: 'db3',
316+
dateAdded: 1668428472731,
317+
language: 'ruby',
318+
storagePath: '/path/to/db3/',
319+
},
320+
]);
321+
});
322+
323+
it('should render local database nodes', async () => {
324+
const dbConfig: DbConfig = {
325+
databases: {
326+
remote: {
327+
repositoryLists: [],
328+
owners: [],
329+
repositories: []
330+
},
331+
local: {
332+
lists: [],
333+
databases: [
334+
{
335+
name: 'db1',
336+
dateAdded: 1668428293677,
337+
language: 'csharp',
338+
storagePath: '/path/to/db1/',
339+
},
340+
{
341+
name: 'db2',
342+
dateAdded: 1668428472731,
343+
language: 'go',
344+
storagePath: '/path/to/db2/',
345+
}
346+
]
347+
}
348+
}
349+
};
350+
351+
await saveDbConfig(dbConfig);
352+
353+
const dbTreeItems = await dbTreeDataProvider.getChildren();
354+
355+
expect(dbTreeItems).to.be.ok;
356+
const items = dbTreeItems!;
357+
expect(items.length).to.equal(2);
358+
359+
const localRootNode = items[1];
360+
expect(localRootNode.dbItem).to.be.ok;
361+
expect(localRootNode.collapsibleState).to.equal(vscode.TreeItemCollapsibleState.Collapsed);
362+
expect(localRootNode.children).to.be.ok;
363+
expect(localRootNode.children.length).to.equal(2);
364+
365+
const localDatabaseItems = localRootNode.children.filter(item => item.dbItem?.kind === DbItemKind.LocalDatabase);
366+
expect(localDatabaseItems.length).to.equal(2);
367+
checkLocalDatabaseItem(localDatabaseItems[0], {
368+
kind: DbItemKind.LocalDatabase,
369+
databaseName: 'db1',
370+
dateAdded: 1668428293677,
371+
language: 'csharp',
372+
storagePath: '/path/to/db1/',
373+
});
374+
checkLocalDatabaseItem(localDatabaseItems[1], {
375+
kind: DbItemKind.LocalDatabase,
376+
databaseName: 'db2',
377+
dateAdded: 1668428472731,
378+
language: 'go',
379+
storagePath: '/path/to/db2/',
380+
});
381+
});
382+
238383
async function saveDbConfig(dbConfig: DbConfig): Promise<void> {
239384
await fs.writeJson(dbConfigFilePath, dbConfig);
240385

@@ -294,4 +439,31 @@ describe('db panel', async () => {
294439
expect(item.iconPath).to.deep.equal(new vscode.ThemeIcon('database'));
295440
expect(item.collapsibleState).to.equal(vscode.TreeItemCollapsibleState.None);
296441
}
442+
443+
function checkLocalListItem(
444+
item: DbTreeViewItem,
445+
listName: string,
446+
databases: LocalDatabaseDbItem[]
447+
): void {
448+
expect(item.label).to.equal(listName);
449+
expect(item.tooltip).to.be.undefined;
450+
expect(item.iconPath).to.be.undefined;
451+
expect(item.collapsibleState).to.equal(vscode.TreeItemCollapsibleState.Collapsed);
452+
expect(item.children).to.be.ok;
453+
expect(item.children.length).to.equal(databases.length);
454+
455+
for (let i = 0; i < databases.length; i++) {
456+
checkLocalDatabaseItem(item.children[i], databases[i]);
457+
}
458+
}
459+
460+
function checkLocalDatabaseItem(
461+
item: DbTreeViewItem,
462+
database: LocalDatabaseDbItem,
463+
): void {
464+
expect(item.label).to.equal(database.databaseName);
465+
expect(item.tooltip).to.equal(`Language: ${database.language}`);
466+
expect(item.iconPath).to.deep.equal(new vscode.ThemeIcon('database'));
467+
expect(item.collapsibleState).to.equal(vscode.TreeItemCollapsibleState.None);
468+
}
297469
});

0 commit comments

Comments
 (0)