1- import { pathExists , remove } from "fs-extra" ;
2- import { glob } from "glob" ;
3- import { join , basename , resolve , dirname , extname } from "path" ;
1+ import { remove } from "fs-extra" ;
2+ import { join , dirname , extname } from "path" ;
43import * as vscode from "vscode" ;
54import * as cli from "../codeql-cli/cli" ;
65import { ExtensionContext } from "vscode" ;
76import {
8- showAndLogWarningMessage ,
9- showAndLogInformationMessage ,
107 showAndLogExceptionWithTelemetry ,
118 isFolderAlreadyInWorkspace ,
129 getFirstWorkspaceFolder ,
1310 showNeverAskAgainDialog ,
1411} from "../helpers" ;
1512import { ProgressCallback , withProgress } from "../common/vscode/progress" ;
16- import { encodeArchiveBasePath } from "../common/vscode/archive-filesystem-provider" ;
1713import { DisposableObject } from "../pure/disposable-object" ;
1814import { Logger , extLogger } from "../common" ;
1915import { asError , getErrorMessage } from "../pure/helpers-pure" ;
@@ -35,14 +31,11 @@ import {
3531 PersistedDatabaseItem ,
3632} from "./local-databases/database-item" ;
3733import { DatabaseItemImpl } from "./local-databases/database-item-impl" ;
38- import {
39- DatabaseContents ,
40- DatabaseContentsWithDbScheme ,
41- DatabaseKind ,
42- } from "./local-databases/database-contents" ;
34+ import { DatabaseResolver } from "./local-databases/database-resolver" ;
4335
4436export { DatabaseContentsWithDbScheme } from "./local-databases/database-contents" ;
4537export { DatabaseItem } from "./local-databases/database-item" ;
38+ export { DatabaseResolver } from "./local-databases/database-resolver" ;
4639
4740/**
4841 * databases.ts
@@ -66,136 +59,6 @@ const CURRENT_DB = "currentDatabase";
6659 */
6760const DB_LIST = "databaseList" ;
6861
69- /**
70- * An error thrown when we cannot find a valid database in a putative
71- * database directory.
72- */
73- class InvalidDatabaseError extends Error { }
74-
75- async function findDataset ( parentDirectory : string ) : Promise < vscode . Uri > {
76- /*
77- * Look directly in the root
78- */
79- let dbRelativePaths = await glob ( "db-*/" , {
80- cwd : parentDirectory ,
81- } ) ;
82-
83- if ( dbRelativePaths . length === 0 ) {
84- /*
85- * Check If they are in the old location
86- */
87- dbRelativePaths = await glob ( "working/db-*/" , {
88- cwd : parentDirectory ,
89- } ) ;
90- }
91- if ( dbRelativePaths . length === 0 ) {
92- throw new InvalidDatabaseError (
93- `'${ parentDirectory } ' does not contain a dataset directory.` ,
94- ) ;
95- }
96-
97- const dbAbsolutePath = join ( parentDirectory , dbRelativePaths [ 0 ] ) ;
98- if ( dbRelativePaths . length > 1 ) {
99- void showAndLogWarningMessage (
100- `Found multiple dataset directories in database, using '${ dbAbsolutePath } '.` ,
101- ) ;
102- }
103-
104- return vscode . Uri . file ( dbAbsolutePath ) ;
105- }
106-
107- // exported for testing
108- export async function findSourceArchive (
109- databasePath : string ,
110- ) : Promise < vscode . Uri | undefined > {
111- const relativePaths = [ "src" , "output/src_archive" ] ;
112-
113- for ( const relativePath of relativePaths ) {
114- const basePath = join ( databasePath , relativePath ) ;
115- const zipPath = `${ basePath } .zip` ;
116-
117- // Prefer using a zip archive over a directory.
118- if ( await pathExists ( zipPath ) ) {
119- return encodeArchiveBasePath ( zipPath ) ;
120- } else if ( await pathExists ( basePath ) ) {
121- return vscode . Uri . file ( basePath ) ;
122- }
123- }
124-
125- void showAndLogInformationMessage (
126- `Could not find source archive for database '${ databasePath } '. Assuming paths are absolute.` ,
127- ) ;
128- return undefined ;
129- }
130-
131- /** Gets the relative paths of all `.dbscheme` files in the given directory. */
132- async function getDbSchemeFiles ( dbDirectory : string ) : Promise < string [ ] > {
133- return await glob ( "*.dbscheme" , { cwd : dbDirectory } ) ;
134- }
135-
136- export class DatabaseResolver {
137- public static async resolveDatabaseContents (
138- uri : vscode . Uri ,
139- ) : Promise < DatabaseContentsWithDbScheme > {
140- if ( uri . scheme !== "file" ) {
141- throw new Error (
142- `Database URI scheme '${ uri . scheme } ' not supported; only 'file' URIs are supported.` ,
143- ) ;
144- }
145- const databasePath = uri . fsPath ;
146- if ( ! ( await pathExists ( databasePath ) ) ) {
147- throw new InvalidDatabaseError (
148- `Database '${ databasePath } ' does not exist.` ,
149- ) ;
150- }
151-
152- const contents = await this . resolveDatabase ( databasePath ) ;
153-
154- if ( contents === undefined ) {
155- throw new InvalidDatabaseError (
156- `'${ databasePath } ' is not a valid database.` ,
157- ) ;
158- }
159-
160- // Look for a single dbscheme file within the database.
161- // This should be found in the dataset directory, regardless of the form of database.
162- const dbPath = contents . datasetUri . fsPath ;
163- const dbSchemeFiles = await getDbSchemeFiles ( dbPath ) ;
164- if ( dbSchemeFiles . length === 0 ) {
165- throw new InvalidDatabaseError (
166- `Database '${ databasePath } ' does not contain a CodeQL dbscheme under '${ dbPath } '.` ,
167- ) ;
168- } else if ( dbSchemeFiles . length > 1 ) {
169- throw new InvalidDatabaseError (
170- `Database '${ databasePath } ' contains multiple CodeQL dbschemes under '${ dbPath } '.` ,
171- ) ;
172- } else {
173- const dbSchemeUri = vscode . Uri . file ( resolve ( dbPath , dbSchemeFiles [ 0 ] ) ) ;
174- return {
175- ...contents ,
176- dbSchemeUri,
177- } ;
178- }
179- }
180-
181- public static async resolveDatabase (
182- databasePath : string ,
183- ) : Promise < DatabaseContents > {
184- const name = basename ( databasePath ) ;
185-
186- // Look for dataset and source archive.
187- const datasetUri = await findDataset ( databasePath ) ;
188- const sourceArchiveUri = await findSourceArchive ( databasePath ) ;
189-
190- return {
191- kind : DatabaseKind . Database ,
192- name,
193- datasetUri,
194- sourceArchiveUri,
195- } ;
196- }
197- }
198-
19962export enum DatabaseEventKind {
20063 Add = "Add" ,
20164 Remove = "Remove" ,
0 commit comments