@@ -8,7 +8,7 @@ import { logger } from './logging';
88import { clearCacheInDatabase , UserCancellationException } from './run-queries' ;
99import * as qsClient from './queryserver-client' ;
1010import { upgradeDatabase } from './upgrades' ;
11- import { databaseFetcher } from './databaseFetcher' ;
11+ import promptFetchDatabase , { databaseArchiveFetcher } from './databaseFetcher' ;
1212
1313type ThemableIconPath = { light : string ; dark : string } | string ;
1414
@@ -148,13 +148,13 @@ function getFirst(list: Uri[] | undefined): Uri | undefined {
148148 * XXX: no validation is done other than checking the directory name
149149 * to make sure it really is a database directory.
150150 */
151- async function chooseDatabaseDir ( ) : Promise < Uri | undefined > {
151+ async function chooseDatabaseDir ( byFolder : boolean ) : Promise < Uri | undefined > {
152152 const chosen = await window . showOpenDialog ( {
153- openLabel : 'Choose Database folder or archive' ,
154- canSelectFiles : true ,
155- canSelectFolders : true ,
153+ openLabel : byFolder ? 'Choose Database folder' : 'Choose Database archive',
154+ canSelectFiles : ! byFolder ,
155+ canSelectFolders : byFolder ,
156156 canSelectMany : false ,
157-
157+ filters : byFolder ? { } : { Archives : [ 'zip' ] }
158158 } ) ;
159159 return getFirst ( chosen ) ;
160160}
@@ -174,7 +174,9 @@ export class DatabaseUI extends DisposableObject {
174174 this . treeDataProvider = this . push ( new DatabaseTreeDataProvider ( ctx , databaseManager ) ) ;
175175 this . push ( window . createTreeView ( 'codeQLDatabases' , { treeDataProvider : this . treeDataProvider } ) ) ;
176176
177- ctx . subscriptions . push ( commands . registerCommand ( 'codeQL.chooseDatabase' , this . handleChooseDatabase ) ) ;
177+ ctx . subscriptions . push ( commands . registerCommand ( 'codeQL.chooseDatabaseFolder' , this . handleChooseDatabaseFolder ) ) ;
178+ ctx . subscriptions . push ( commands . registerCommand ( 'codeQL.chooseDatabaseArchive' , this . handleChooseDatabaseArchive ) ) ;
179+ ctx . subscriptions . push ( commands . registerCommand ( 'codeQL.chooseDatabaseInternet' , this . handleChooseDatabaseInternet ) ) ;
178180 ctx . subscriptions . push ( commands . registerCommand ( 'codeQL.setCurrentDatabase' , this . handleSetCurrentDatabase ) ) ;
179181 ctx . subscriptions . push ( commands . registerCommand ( 'codeQL.upgradeCurrentDatabase' , this . handleUpgradeCurrentDatabase ) ) ;
180182 ctx . subscriptions . push ( commands . registerCommand ( 'codeQL.clearCache' , this . handleClearCache ) ) ;
@@ -191,15 +193,28 @@ export class DatabaseUI extends DisposableObject {
191193 await this . databaseManager . setCurrentDatabaseItem ( databaseItem ) ;
192194 }
193195
194- private handleChooseDatabase = async ( ) : Promise < DatabaseItem | undefined > => {
196+ private handleChooseDatabaseFolder = async ( ) : Promise < DatabaseItem | undefined > => {
197+ try {
198+ return await this . chooseAndSetDatabase ( true ) ;
199+ } catch ( e ) {
200+ showAndLogErrorMessage ( e . message ) ;
201+ return undefined ;
202+ }
203+ }
204+
205+ private handleChooseDatabaseArchive = async ( ) : Promise < DatabaseItem | undefined > => {
195206 try {
196- return await this . chooseAndSetDatabase ( ) ;
207+ return await this . chooseAndSetDatabase ( false ) ;
197208 } catch ( e ) {
198209 showAndLogErrorMessage ( e . message ) ;
199210 return undefined ;
200211 }
201212 }
202213
214+ private handleChooseDatabaseInternet = async ( ) : Promise < DatabaseItem | undefined > => {
215+ return await promptFetchDatabase ( this . databaseManager , this . storagePath ) ;
216+ }
217+
203218 private handleSortByName = async ( ) => {
204219 if ( this . treeDataProvider . sortOrder === SortOrder . NameAsc ) {
205220 this . treeDataProvider . sortOrder = SortOrder . NameDesc ;
@@ -275,6 +290,11 @@ export class DatabaseUI extends DisposableObject {
275290 }
276291
277292 private handleSetCurrentDatabase = async ( uri : Uri ) : Promise < DatabaseItem | undefined > => {
293+ // Assume user has selected an archive if the file has a .zip extension
294+ if ( uri . path . endsWith ( '.zip' ) ) {
295+ return await databaseArchiveFetcher ( uri . toString ( ) , this . databaseManager , this . storagePath ) ;
296+ }
297+
278298 return await this . setCurrentDatabase ( uri ) ;
279299 }
280300
@@ -312,7 +332,7 @@ export class DatabaseUI extends DisposableObject {
312332 */
313333 public async getDatabaseItem ( ) : Promise < DatabaseItem | undefined > {
314334 if ( this . databaseManager . currentDatabaseItem === undefined ) {
315- await this . chooseAndSetDatabase ( ) ;
335+ await this . chooseAndSetDatabase ( false ) ;
316336 }
317337
318338 return this . databaseManager . currentDatabaseItem ;
@@ -332,17 +352,21 @@ export class DatabaseUI extends DisposableObject {
332352 * Ask the user for a database directory. Returns the chosen database, or `undefined` if the
333353 * operation was canceled.
334354 */
335- private async chooseAndSetDatabase ( ) : Promise < DatabaseItem | undefined > {
336- const uri = await chooseDatabaseDir ( ) ;
355+ private async chooseAndSetDatabase ( byFolder : boolean ) : Promise < DatabaseItem | undefined > {
356+ const uri = await chooseDatabaseDir ( byFolder ) ;
337357
338- if ( uri ?. path . endsWith ( '.zip' ) ) {
339- return await databaseFetcher ( uri . toString ( ) , this . databaseManager , this . storagePath ) ;
358+ if ( ! uri ) {
359+ return undefined ;
340360 }
341- else if ( uri !== undefined ) {
361+
362+ if ( byFolder ) {
363+ // we are selecting a database folder
342364 return await this . setCurrentDatabase ( uri ) ;
343365 }
344366 else {
345- return undefined ;
367+ // we are selecting a database archive. Must unzip into a workspace-controlled area
368+ // before importing.
369+ return await databaseArchiveFetcher ( uri . toString ( ) , this . databaseManager , this . storagePath ) ;
346370 }
347371 }
348372}
0 commit comments