11import * as vscode from 'vscode' ;
22
33import { decodeSourceArchiveUri , zipArchiveScheme } from '../archive-filesystem-provider' ;
4- import { ColumnKindCode , EntityValue , getResultSetSchema } from '../bqrs-cli-types' ;
4+ import { ColumnKindCode , EntityValue , getResultSetSchema , ResultSetSchema } from '../bqrs-cli-types' ;
55import { CodeQLCliServer } from '../cli' ;
66import { DatabaseManager , DatabaseItem } from '../databases' ;
77import fileRangeFromURI from './fileRangeFromURI' ;
88import * as messages from '../messages' ;
99import { QueryServerClient } from '../queryserver-client' ;
1010import { QueryWithResults , compileAndRunQueryAgainstDatabase } from '../run-queries' ;
11+ import { ProgressCallback } from '../helpers' ;
1112import { KeyType } from './keyType' ;
1213import { qlpackOfDatabase , resolveQueries } from './queryResolver' ;
1314
@@ -28,6 +29,8 @@ export interface FullLocationLink extends vscode.LocationLink {
2829 * @param dbm The database manager
2930 * @param uriString The selected source file and location
3031 * @param keyType The contextual query type to run
32+ * @param progress A progress callback
33+ * @param token A CancellationToken
3134 * @param filter A function that will filter extraneous results
3235 */
3336export async function getLocationsForUriString (
@@ -36,37 +39,42 @@ export async function getLocationsForUriString(
3639 dbm : DatabaseManager ,
3740 uriString : string ,
3841 keyType : KeyType ,
42+ progress : ProgressCallback ,
43+ token : vscode . CancellationToken ,
3944 filter : ( src : string , dest : string ) => boolean
4045) : Promise < FullLocationLink [ ] > {
4146 const uri = decodeSourceArchiveUri ( vscode . Uri . parse ( uriString ) ) ;
4247 const sourceArchiveUri = vscode . Uri . file ( uri . sourceArchiveZipPath ) . with ( { scheme : zipArchiveScheme } ) ;
4348
4449 const db = dbm . findDatabaseItemBySourceArchive ( sourceArchiveUri ) ;
45- if ( db ) {
46- const qlpack = await qlpackOfDatabase ( cli , db ) ;
47- if ( qlpack === undefined ) {
48- throw new Error ( 'Can\'t infer qlpack from database source archive' ) ;
49- }
50- const links : FullLocationLink [ ] = [ ] ;
51- for ( const query of await resolveQueries ( cli , qlpack , keyType ) ) {
52- const templates : messages . TemplateDefinitions = {
53- [ TEMPLATE_NAME ] : {
54- values : {
55- tuples : [ [ {
56- stringValue : uri . pathWithinSourceArchive
57- } ] ]
58- }
59- }
60- } ;
61- const results = await compileAndRunQueryAgainstDatabase ( cli , qs , db , false , vscode . Uri . file ( query ) , templates ) ;
62- if ( results . result . resultType == messages . QueryResultType . SUCCESS ) {
63- links . push ( ...await getLinksFromResults ( results , cli , db , filter ) ) ;
64- }
65- }
66- return links ;
67- } else {
50+ if ( ! db ) {
6851 return [ ] ;
6952 }
53+
54+ const qlpack = await qlpackOfDatabase ( cli , db ) ;
55+ if ( qlpack === undefined ) {
56+ throw new Error ( 'Can\'t infer qlpack from database source archive' ) ;
57+ }
58+ const templates = createTemplates ( uri . pathWithinSourceArchive ) ;
59+
60+ const links : FullLocationLink [ ] = [ ] ;
61+ for ( const query of await resolveQueries ( cli , qlpack , keyType ) ) {
62+ const results = await compileAndRunQueryAgainstDatabase (
63+ cli ,
64+ qs ,
65+ db ,
66+ false ,
67+ vscode . Uri . file ( query ) ,
68+ progress ,
69+ token ,
70+ templates
71+ ) ;
72+
73+ if ( results . result . resultType == messages . QueryResultType . SUCCESS ) {
74+ links . push ( ...await getLinksFromResults ( results , cli , db , filter ) ) ;
75+ }
76+ }
77+ return links ;
7078}
7179
7280async function getLinksFromResults (
@@ -79,10 +87,7 @@ async function getLinksFromResults(
7987 const bqrsPath = results . query . resultsPaths . resultsPath ;
8088 const info = await cli . bqrsInfo ( bqrsPath ) ;
8189 const selectInfo = getResultSetSchema ( SELECT_QUERY_NAME , info ) ;
82- if ( selectInfo && selectInfo . columns . length == 3
83- && selectInfo . columns [ 0 ] . kind == ColumnKindCode . ENTITY
84- && selectInfo . columns [ 1 ] . kind == ColumnKindCode . ENTITY
85- && selectInfo . columns [ 2 ] . kind == ColumnKindCode . STRING ) {
90+ if ( isValidSelect ( selectInfo ) ) {
8691 // TODO: Page this
8792 const allTuples = await cli . bqrsDecode ( bqrsPath , SELECT_QUERY_NAME ) ;
8893 for ( const tuple of allTuples . tuples ) {
@@ -101,3 +106,22 @@ async function getLinksFromResults(
101106 }
102107 return localLinks ;
103108}
109+
110+ function createTemplates ( path : string ) : messages . TemplateDefinitions {
111+ return {
112+ [ TEMPLATE_NAME ] : {
113+ values : {
114+ tuples : [ [ {
115+ stringValue : path
116+ } ] ]
117+ }
118+ }
119+ } ;
120+ }
121+
122+ function isValidSelect ( selectInfo : ResultSetSchema | undefined ) {
123+ return selectInfo && selectInfo . columns . length == 3
124+ && selectInfo . columns [ 0 ] . kind == ColumnKindCode . ENTITY
125+ && selectInfo . columns [ 1 ] . kind == ColumnKindCode . ENTITY
126+ && selectInfo . columns [ 2 ] . kind == ColumnKindCode . STRING ;
127+ }
0 commit comments