Skip to content

Commit 176fac0

Browse files
alexetaeisenberg
authored andcommitted
QueryServer: Add support for new query-server
1 parent e5fe214 commit 176fac0

11 files changed

Lines changed: 900 additions & 14 deletions

File tree

extensions/ql-vscode/src/cli.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1405,4 +1405,9 @@ export class CliVersionConstraint {
14051405
async supportsSourceMap() {
14061406
return this.isVersionAtLeast(CliVersionConstraint.CLI_VERSION_WITH_SOURCEMAP);
14071407
}
1408+
1409+
async supportsNewQueryServer() {
1410+
// return this.isVersionAtLeast(CliVersionConstraint.CLI_VERSION_WITH_NEW_QUERY_SERVER);
1411+
return true;
1412+
}
14081413
}

extensions/ql-vscode/src/extension.ts

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ import { WebviewReveal } from './interface-utils';
7373
import { ideServerLogger, logger, ProgressReporter, queryServerLogger } from './logging';
7474
import { QueryHistoryManager } from './query-history';
7575
import { CompletedLocalQueryInfo, LocalQueryInfo } from './query-results';
76-
import * as qsClient from './legacy-query-server/queryserver-client';
76+
import * as legacyQueryServer from './legacy-query-server/queryserver-client';
77+
import * as newQueryServer from './query-server/queryserver-client';
7778
import { displayQuickQuery } from './quick-query';
7879
import { QLTestAdapterFactory } from './test-adapter';
7980
import { TestUIService } from './test-ui';
@@ -104,6 +105,7 @@ import { LogScannerService } from './log-insights/log-scanner-service';
104105
import { createInitialQueryInfo } from './run-queries-shared';
105106
import { LegacyQueryRunner } from './legacy-query-server/legacyRunner';
106107
import { QueryRunner } from './queryRunner';
108+
import { NewQueryRunner } from './query-server/query-runner';
107109

108110
/**
109111
* extension.ts
@@ -390,6 +392,8 @@ export async function activate(ctx: ExtensionContext): Promise<CodeQLExtensionIn
390392
});
391393
}
392394

395+
const PACK_GLOBS = ['**/codeql-pack.yml', '**/qlpack.yml', '**/queries.xml', '**/codeql-pack.lock.yml', '**/qlpack.lock.yml', '.codeqlmanifest.json', 'codeql-workspace.yml'];
396+
393397
async function activateWithInstalledDistribution(
394398
ctx: ExtensionContext,
395399
distributionManager: DistributionManager,
@@ -420,6 +424,15 @@ async function activateWithInstalledDistribution(
420424
void logger.log('Initializing query server client.');
421425
const qs = await createQueryServer(qlConfigurationListener, cliServer, ctx);
422426

427+
428+
for (const glob of PACK_GLOBS) {
429+
const fsWatcher = workspace.createFileSystemWatcher(glob);
430+
ctx.subscriptions.push(fsWatcher);
431+
fsWatcher.onDidChange(async (_uri) => {
432+
await qs.clearPackCache();
433+
});
434+
}
435+
423436
void logger.log('Initializing database manager.');
424437
const dbm = new DatabaseManager(ctx, qs, cliServer, logger);
425438
ctx.subscriptions.push(dbm);
@@ -1135,15 +1148,28 @@ async function createQueryServer(qlConfigurationListener: QueryServerConfigListe
11351148
{ title: 'CodeQL query server', location: ProgressLocation.Window },
11361149
task
11371150
);
1138-
const qs = new qsClient.QueryServerClient(
1139-
qlConfigurationListener,
1140-
cliServer,
1141-
qsOpts,
1142-
progressCallback
1143-
);
1144-
ctx.subscriptions.push(qs);
1145-
await qs.startQueryServer();
1146-
return new LegacyQueryRunner(qs);
1151+
if (await cliServer.cliConstraints.supportsNewQueryServer()) {
1152+
const qs = new newQueryServer.QueryServerClient(
1153+
qlConfigurationListener,
1154+
cliServer,
1155+
qsOpts,
1156+
progressCallback
1157+
);
1158+
ctx.subscriptions.push(qs);
1159+
await qs.startQueryServer();
1160+
return new NewQueryRunner(qs);
1161+
1162+
} else {
1163+
const qs = new legacyQueryServer.QueryServerClient(
1164+
qlConfigurationListener,
1165+
cliServer,
1166+
qsOpts,
1167+
progressCallback
1168+
);
1169+
ctx.subscriptions.push(qs);
1170+
await qs.startQueryServer();
1171+
return new LegacyQueryRunner(qs);
1172+
}
11471173
}
11481174

11491175
function getContextStoragePath(ctx: ExtensionContext) {

extensions/ql-vscode/src/legacy-query-server/legacyRunner.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,10 @@ export class LegacyQueryRunner extends QueryRunner {
5656
async upgradeDatabaseExplicit(dbItem: DatabaseItem, progress: ProgressCallback, token: CancellationToken): Promise<void> {
5757
await upgradeDatabaseExplicit(this.qs, dbItem, progress, token);
5858
}
59+
60+
async clearPackCache(): Promise<void> {
61+
/**
62+
* Nothing needs to be done
63+
*/
64+
}
5965
}

extensions/ql-vscode/src/legacy-query-server/upgrades.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { getOnDiskWorkspaceFolders, showAndLogErrorMessage, tmpDir } from '../he
33
import { ProgressCallback, UserCancellationException } from '../commandRunner';
44
import { logger } from '../logging';
55
import * as messages from '../pure/legacy-messages';
6-
import * as qsClient from '../legacy-query-server/queryserver-client';
6+
import * as qsClient from './queryserver-client';
77
import * as tmp from 'tmp-promise';
88
import * as path from 'path';
99
import { DatabaseItem } from '../databases';
Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
/**
2+
* Types for messages exchanged during jsonrpc communication with the
3+
* the CodeQL query server.
4+
*
5+
* This file exists in the queryserver and in the vscode extension, and
6+
* should be kept in sync between them.
7+
*
8+
* A note about the namespaces below, which look like they are
9+
* essentially enums, namely Severity, ResultColumnKind, and
10+
* QueryResultType. By design, for the sake of extensibility, clients
11+
* receiving messages of this protocol are supposed to accept any
12+
* number for any of these types. We commit to the given meaning of
13+
* the numbers listed in constants in the namespaces, and we commit to
14+
* the fact that any unknown QueryResultType value counts as an error.
15+
*/
16+
17+
import * as rpc from 'vscode-jsonrpc';
18+
import * as shared from './messages-shared';
19+
20+
21+
22+
/**
23+
* Parameters to clear the cache
24+
*/
25+
export interface ClearCacheParams {
26+
/**
27+
* The dataset for which we want to clear the cache
28+
*/
29+
db: string;
30+
/**
31+
* Whether the cache should actually be cleared.
32+
*/
33+
dryRun: boolean;
34+
}
35+
36+
/**
37+
* Parameters for trimming the cache of a dataset
38+
*/
39+
export interface TrimCacheParams {
40+
/**
41+
* The dataset that we want to trim the cache of.
42+
*/
43+
db: string;
44+
}
45+
46+
/**
47+
* The result of trimming or clearing the cache.
48+
*/
49+
export interface ClearCacheResult {
50+
/**
51+
* A user friendly message saying what was or would be
52+
* deleted.
53+
*/
54+
deletionMessage: string;
55+
}
56+
57+
58+
export type QueryResultType = number;
59+
/**
60+
* The result of running a query. This namespace is intentionally not
61+
* an enum, see "for the sake of extensibility" comment above.
62+
*/
63+
// eslint-disable-next-line @typescript-eslint/no-namespace
64+
export namespace QueryResultType {
65+
/**
66+
* The query ran successfully
67+
*/
68+
export const SUCCESS = 0;
69+
/**
70+
* The query failed due to an reason
71+
* that isn't listed
72+
*/
73+
export const OTHER_ERROR = 1;
74+
/**
75+
* The query failed do to compilation erorrs
76+
*/
77+
export const COMPILATION_ERROR = 2;
78+
/**
79+
* The query failed due to running out of
80+
* memory
81+
*/
82+
export const OOM = 3;
83+
/**
84+
* The query failed because it was cancelled.
85+
*/
86+
export const CANCELLATION = 4;
87+
/**
88+
* The dbscheme basename was not the same
89+
*/
90+
export const DBSCHEME_MISMATCH_NAME = 5;
91+
/**
92+
* No upgrade was found
93+
*/
94+
export const DBSCHEME_NO_UPGRADE = 6;
95+
}
96+
97+
98+
export interface RegisterDatabasesParams {
99+
databases: string[];
100+
}
101+
102+
export interface DeregisterDatabasesParams {
103+
databases: string[];
104+
}
105+
106+
export type RegisterDatabasesResult = {
107+
registeredDatabases: string[];
108+
};
109+
110+
export type DeregisterDatabasesResult = {
111+
registeredDatabases: string[];
112+
};
113+
114+
115+
export interface RunQueryParams {
116+
/**
117+
* The path of the query
118+
*/
119+
queryPath: string,
120+
/**
121+
* The output path
122+
*/
123+
outputPath: string,
124+
/**
125+
* The database path
126+
*/
127+
db: string,
128+
additionalPacks: string[],
129+
target: CompilationTarget,
130+
externalInputs: Record<string, string>,
131+
singletonExternalInputs: Record<string, string>,
132+
dilPath?: string,
133+
logPath?: string
134+
}
135+
136+
export interface RunQueryResult {
137+
resultType: QueryResultType,
138+
message?: string,
139+
expectedDbschemeName?: string,
140+
evaluationTime: number;
141+
}
142+
143+
144+
145+
export interface UpgradeParams {
146+
db: string,
147+
additionalPacks: string[],
148+
}
149+
150+
export type UpgradeResult = Record<string, unknown>;
151+
152+
export type ClearPackCacheParams = Record<string, unknown>;
153+
export type ClearPackCacheResult = Record<string, unknown>;
154+
155+
/**
156+
* A position within a QL file.
157+
*/
158+
export type Position = shared.Position;
159+
160+
/**
161+
* The way of compiling the query, as a normal query
162+
* or a subset of it. Note that precisely one of the two options should be set.
163+
*/
164+
export type CompilationTarget = shared.CompilationTarget;
165+
166+
export type QuickEvalOptions = shared.QuickEvalOptions;
167+
168+
export type WithProgressId<T> = shared.WithProgressId<T>;
169+
export type ProgressMessage = shared.ProgressMessage;
170+
171+
/**
172+
* Clear the cache of a dataset
173+
*/
174+
export const clearCache = new rpc.RequestType<WithProgressId<ClearCacheParams>, ClearCacheResult, void, void>('evaluation/clearCache');
175+
/**
176+
* Trim the cache of a dataset
177+
*/
178+
export const trimCache = new rpc.RequestType<WithProgressId<TrimCacheParams>, ClearCacheResult, void, void>('evaluation/trimCache');
179+
180+
/**
181+
* Clear the pack cache
182+
*/
183+
export const clearPackCache = new rpc.RequestType<WithProgressId<ClearPackCacheParams>, ClearPackCacheResult, void, void>('evaluation/clearPackCache');
184+
185+
/**
186+
* Run a query on a database
187+
*/
188+
export const runQuery = new rpc.RequestType<WithProgressId<RunQueryParams>, RunQueryResult, void, void>('evaluation/runQuery');
189+
190+
export const registerDatabases = new rpc.RequestType<
191+
WithProgressId<RegisterDatabasesParams>,
192+
RegisterDatabasesResult,
193+
void,
194+
void
195+
>('evaluation/registerDatabases');
196+
197+
export const deregisterDatabases = new rpc.RequestType<
198+
WithProgressId<DeregisterDatabasesParams>,
199+
DeregisterDatabasesResult,
200+
void,
201+
void
202+
>('evaluation/deregisterDatabases');
203+
204+
205+
export const upgradeDatabase = new rpc.RequestType<
206+
WithProgressId<UpgradeParams>,
207+
UpgradeResult,
208+
void,
209+
void
210+
>('evaluation/upgrade');
211+
212+
/**
213+
* A notification that the progress has been changed.
214+
*/
215+
export const progress = shared.progress;

0 commit comments

Comments
 (0)