Skip to content

Commit bca7ecb

Browse files
committed
Add source to database item
This adds a source property to the database item to store the source of the database, for example GitHub or an internet URL. This will be used to automatically check for updates to GitHub-downloaded databases in the future.
1 parent bc2847a commit bca7ecb

File tree

20 files changed

+206
-13
lines changed

20 files changed

+206
-13
lines changed

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// Contains models and consts for the data we want to store in the database config.
22
// Changes to these models should be done carefully and account for backwards compatibility of data.
33

4+
import { DatabaseSource } from "../local-databases/database-source";
5+
46
export const DB_CONFIG_VERSION = 1;
57

68
export interface DbConfig {
@@ -88,6 +90,7 @@ export interface LocalDatabase {
8890
name: string;
8991
dateAdded: number;
9092
language: string;
93+
source: DatabaseSource;
9194
storagePath: string;
9295
}
9396

extensions/ql-vscode/src/databases/database-fetcher.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import { allowHttp } from "../config";
3333
import { showAndLogInformationMessage } from "../common/logging";
3434
import { AppOctokit } from "../common/octokit";
3535
import { getLanguageDisplayName } from "../common/query-language";
36+
import { DatabaseSource } from "./local-databases/database-source";
3637

3738
/**
3839
* Prompts a user to fetch a database from a remote location. Database is assumed to be an archive file.
@@ -62,6 +63,10 @@ export async function promptImportInternetDatabase(
6263
databaseManager,
6364
storagePath,
6465
undefined,
66+
{
67+
type: "url",
68+
url: databaseUrl,
69+
},
6570
progress,
6671
cli,
6772
);
@@ -199,7 +204,7 @@ export async function downloadGitHubDatabase(
199204
return;
200205
}
201206

202-
const { databaseUrl, name, owner } = result;
207+
const { databaseUrl, name, owner, commitOid } = result;
203208

204209
/**
205210
* The 'token' property of the token object returned by `octokit.auth()`.
@@ -221,6 +226,11 @@ export async function downloadGitHubDatabase(
221226
databaseManager,
222227
storagePath,
223228
`${owner}/${name}`,
229+
{
230+
type: "github",
231+
repository: nwo,
232+
commitOid,
233+
},
224234
progress,
225235
cli,
226236
makeSelected,
@@ -250,6 +260,10 @@ export async function importArchiveDatabase(
250260
databaseManager,
251261
storagePath,
252262
undefined,
263+
{
264+
type: "archive",
265+
path: databaseUrl,
266+
},
253267
progress,
254268
cli,
255269
);
@@ -282,6 +296,7 @@ export async function importArchiveDatabase(
282296
* @param databaseManager the DatabaseManager
283297
* @param storagePath where to store the unzipped database.
284298
* @param nameOverride a name for the database that overrides the default
299+
* @param source the source of the database
285300
* @param progress callback to send progress messages to
286301
* @param makeSelected make the new database selected in the databases panel (default: true)
287302
* @param addSourceArchiveFolder whether to add a workspace folder containing the source archive to the workspace
@@ -292,6 +307,7 @@ async function databaseArchiveFetcher(
292307
databaseManager: DatabaseManager,
293308
storagePath: string,
294309
nameOverride: string | undefined,
310+
source: DatabaseSource,
295311
progress: ProgressCallback,
296312
cli?: CodeQLCliServer,
297313
makeSelected = true,
@@ -336,6 +352,7 @@ async function databaseArchiveFetcher(
336352

337353
const item = await databaseManager.openDatabase(
338354
Uri.file(dbPath),
355+
source,
339356
makeSelected,
340357
nameOverride,
341358
{
@@ -533,6 +550,7 @@ export async function convertGithubNwoToDatabaseUrl(
533550
databaseUrl: string;
534551
owner: string;
535552
name: string;
553+
commitOid: string | null;
536554
}
537555
| undefined
538556
> {
@@ -553,10 +571,18 @@ export async function convertGithubNwoToDatabaseUrl(
553571
}
554572
}
555573

574+
const databaseForLanguage = response.data.find(
575+
(db: any) => db.language === language,
576+
);
577+
if (!databaseForLanguage) {
578+
throw new Error(`No database found for language '${language}'`);
579+
}
580+
556581
return {
557582
databaseUrl: `https://api.github.com/repos/${owner}/${repo}/code-scanning/codeql/databases/${language}`,
558583
owner,
559584
name: repo,
585+
commitOid: databaseForLanguage.commit_oid,
560586
};
561587
} catch (e) {
562588
void extLogger.log(`Error: ${getErrorMessage(e)}`);

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// This file contains models that are used to represent the databases.
22

3+
import { DatabaseSource } from "./local-databases/database-source";
4+
35
export enum DbItemKind {
46
RootLocal = "RootLocal",
57
LocalList = "LocalList",
@@ -38,6 +40,7 @@ export interface LocalDatabaseDbItem {
3840
databaseName: string;
3941
dateAdded: number;
4042
language: string;
43+
source: DatabaseSource;
4144
storagePath: string;
4245
parentListName?: string;
4346
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ function createLocalDb(
197197
databaseName: db.name,
198198
dateAdded: db.dateAdded,
199199
language: db.language,
200+
source: db.source,
200201
storagePath: db.storagePath,
201202
selected: !!selected,
202203
parentListName: listName,

extensions/ql-vscode/src/databases/local-databases-ui.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,9 @@ export class DatabaseUI extends DisposableObject {
367367

368368
await this.databaseManager.openDatabase(
369369
uri,
370+
{
371+
type: "folder",
372+
},
370373
makeSelected,
371374
nameOverride,
372375
{
@@ -704,7 +707,9 @@ export class DatabaseUI extends DisposableObject {
704707
this.queryServer?.cliServer,
705708
);
706709
} else {
707-
await this.databaseManager.openDatabase(uri);
710+
await this.databaseManager.openDatabase(uri, {
711+
type: "folder",
712+
});
708713
}
709714
} catch (e) {
710715
// rethrow and let this be handled by default error handling.
@@ -819,7 +824,9 @@ export class DatabaseUI extends DisposableObject {
819824
if (byFolder) {
820825
const fixedUri = await this.fixDbUri(uri);
821826
// we are selecting a database folder
822-
return await this.databaseManager.openDatabase(fixedUri);
827+
return await this.databaseManager.openDatabase(fixedUri, {
828+
type: "folder",
829+
});
823830
} else {
824831
// we are selecting a database archive. Must unzip into a workspace-controlled area
825832
// before importing.

extensions/ql-vscode/src/databases/local-databases/database-item-impl.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { isLikelyDatabaseRoot } from "./db-contents-heuristics";
1414
import { stat } from "fs-extra";
1515
import { containsPath, pathsEqual } from "../../common/files";
1616
import { DatabaseContents } from "./database-contents";
17+
import { DatabaseSource } from "./database-source";
1718

1819
export class DatabaseItemImpl implements DatabaseItem {
1920
// These are only public in the implementation, they are readonly in the interface
@@ -61,6 +62,10 @@ export class DatabaseItemImpl implements DatabaseItem {
6162
return this.options.dateAdded;
6263
}
6364

65+
public get source(): DatabaseSource | undefined {
66+
return this.options.source;
67+
}
68+
6469
public resolveSourceFile(uriStr: string | undefined): vscode.Uri {
6570
const sourceArchive = this.sourceArchive;
6671
const uri = uriStr ? vscode.Uri.parse(uriStr, true) : undefined;

extensions/ql-vscode/src/databases/local-databases/database-item.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import vscode from "vscode";
22
import * as cli from "../../codeql-cli/cli";
33
import { DatabaseContents } from "./database-contents";
44
import { DatabaseOptions } from "./database-options";
5+
import { DatabaseSource } from "./database-source";
56

67
/** An item in the list of available databases */
78
export interface DatabaseItem {
@@ -25,6 +26,11 @@ export interface DatabaseItem {
2526
*/
2627
readonly dateAdded: number | undefined;
2728

29+
/**
30+
* The source this database item was added from or undefined if unknown.
31+
*/
32+
readonly source: DatabaseSource | undefined;
33+
2834
/** If the database is invalid, describes why. */
2935
readonly error: Error | undefined;
3036

extensions/ql-vscode/src/databases/local-databases/database-manager.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import { DatabaseChangedEvent, DatabaseEventKind } from "./database-events";
3434
import { DatabaseResolver } from "./database-resolver";
3535
import { telemetryListener } from "../../common/vscode/telemetry";
3636
import { LanguageContextStore } from "../../language-context-store";
37+
import { DatabaseSource } from "./database-source";
3738

3839
/**
3940
* The name of the key in the workspaceState dictionary in which we
@@ -131,14 +132,19 @@ export class DatabaseManager extends DisposableObject {
131132
*/
132133
public async openDatabase(
133134
uri: vscode.Uri,
135+
source: DatabaseSource | undefined,
134136
makeSelected = true,
135137
displayName?: string,
136138
{
137139
isTutorialDatabase = false,
138140
addSourceArchiveFolder = true,
139141
}: OpenDatabaseOptions = {},
140142
): Promise<DatabaseItem> {
141-
const databaseItem = await this.createDatabaseItem(uri, displayName);
143+
const databaseItem = await this.createDatabaseItem(
144+
uri,
145+
source,
146+
displayName,
147+
);
142148

143149
return await this.addExistingDatabaseItem(
144150
databaseItem,
@@ -189,6 +195,7 @@ export class DatabaseManager extends DisposableObject {
189195
*/
190196
private async createDatabaseItem(
191197
uri: vscode.Uri,
198+
source: DatabaseSource | undefined,
192199
displayName: string | undefined,
193200
): Promise<DatabaseItemImpl> {
194201
const contents = await DatabaseResolver.resolveDatabaseContents(uri);
@@ -197,6 +204,7 @@ export class DatabaseManager extends DisposableObject {
197204
displayName,
198205
dateAdded: Date.now(),
199206
language: await this.getPrimaryLanguage(uri.fsPath),
207+
source,
200208
};
201209
const databaseItem = new DatabaseItemImpl(uri, contents, fullOptions);
202210

@@ -212,6 +220,7 @@ export class DatabaseManager extends DisposableObject {
212220
*/
213221
public async createOrOpenDatabaseItem(
214222
uri: vscode.Uri,
223+
source: DatabaseSource | undefined,
215224
): Promise<DatabaseItem> {
216225
const existingItem = this.findDatabaseItem(uri);
217226
if (existingItem !== undefined) {
@@ -220,7 +229,7 @@ export class DatabaseManager extends DisposableObject {
220229
}
221230

222231
// We don't add this to the list automatically, but the user can add it later.
223-
return this.createDatabaseItem(uri, undefined);
232+
return this.createDatabaseItem(uri, source, undefined);
224233
}
225234

226235
public async createSkeletonPacks(databaseItem: DatabaseItem) {
@@ -355,6 +364,7 @@ export class DatabaseManager extends DisposableObject {
355364
let displayName: string | undefined = undefined;
356365
let dateAdded = undefined;
357366
let language = undefined;
367+
let source = undefined;
358368
if (state.options) {
359369
if (typeof state.options.displayName === "string") {
360370
displayName = state.options.displayName;
@@ -363,6 +373,7 @@ export class DatabaseManager extends DisposableObject {
363373
dateAdded = state.options.dateAdded;
364374
}
365375
language = state.options.language;
376+
source = state.options.source;
366377
}
367378

368379
const dbBaseUri = vscode.Uri.parse(state.uri, true);
@@ -375,6 +386,7 @@ export class DatabaseManager extends DisposableObject {
375386
displayName,
376387
dateAdded,
377388
language,
389+
source,
378390
};
379391
const item = new DatabaseItemImpl(dbBaseUri, undefined, fullOptions);
380392

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1+
import { DatabaseSource } from "./database-source";
2+
13
export interface DatabaseOptions {
24
displayName?: string;
35
dateAdded?: number | undefined;
46
language?: string;
7+
source?: DatabaseSource;
58
}
69

710
export interface FullDatabaseOptions extends DatabaseOptions {
811
dateAdded: number | undefined;
912
language: string | undefined;
13+
source: DatabaseSource | undefined;
1014
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
interface DatabaseSourceFolder {
2+
type: "folder";
3+
}
4+
5+
interface DatabaseSourceArchive {
6+
type: "archive";
7+
path: string;
8+
}
9+
10+
interface DatabaseSourceGitHub {
11+
type: "github";
12+
repository: string;
13+
commitOid: string | null;
14+
}
15+
16+
interface DatabaseSourceInternet {
17+
type: "url";
18+
url: string;
19+
}
20+
21+
interface DatabaseSourceDebugger {
22+
type: "debugger";
23+
}
24+
25+
export type DatabaseSource =
26+
| DatabaseSourceFolder
27+
| DatabaseSourceArchive
28+
| DatabaseSourceGitHub
29+
| DatabaseSourceInternet
30+
| DatabaseSourceDebugger;

0 commit comments

Comments
 (0)