Skip to content

Commit 3c80249

Browse files
committed
Move compareInterpretedResults into compare-view.ts
1 parent b7437d3 commit 3c80249

File tree

2 files changed

+104
-115
lines changed

2 files changed

+104
-115
lines changed

extensions/ql-vscode/src/compare/compare-view.ts

Lines changed: 104 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
1-
import { ViewColumn } from "vscode";
1+
import { Uri, ViewColumn } from "vscode";
2+
import { join } from "path";
23

34
import type {
45
FromCompareViewMessage,
6+
InterpretedQueryCompareResult,
57
QueryCompareResult,
68
RawQueryCompareResult,
79
ToCompareViewMessage,
810
} from "../common/interface-types";
9-
import { ALERTS_TABLE_NAME } from "../common/interface-types";
11+
import {
12+
ALERTS_TABLE_NAME,
13+
SELECT_TABLE_NAME,
14+
} from "../common/interface-types";
1015
import type { Logger } from "../common/logging";
1116
import { showAndLogExceptionWithTelemetry } from "../common/logging";
1217
import { extLogger } from "../common/logging/vscode";
@@ -31,11 +36,10 @@ import {
3136
findResultSetNames,
3237
getResultSetNames,
3338
} from "./result-set-names";
34-
import { compareInterpretedResults } from "./interpreted-results";
3539
import { isCanary } from "../config";
3640
import { nanoid } from "nanoid";
3741

38-
export interface ComparePair {
42+
interface ComparePair {
3943
from: CompletedLocalQueryInfo;
4044
fromInfo: CompareQueryInfo;
4145
to: CompletedLocalQueryInfo;
@@ -44,14 +48,39 @@ export interface ComparePair {
4448
commonResultSetNames: readonly string[];
4549
}
4650

47-
export function findSchema(info: BqrsInfo, name: string) {
51+
function findSchema(info: BqrsInfo, name: string) {
4852
const schema = info["result-sets"].find((schema) => schema.name === name);
4953
if (schema === undefined) {
5054
throw new Error(`Schema ${name} not found.`);
5155
}
5256
return schema;
5357
}
5458

59+
/**
60+
* Check that `fromInfo` and `toInfo` have comparable schemas for the given
61+
* result set names and get them if so.
62+
*/
63+
function getComparableSchemas(
64+
fromInfo: CompareQueryInfo,
65+
toInfo: CompareQueryInfo,
66+
fromResultSetName: string,
67+
toResultSetName: string,
68+
): { fromSchema: BqrsResultSetSchema; toSchema: BqrsResultSetSchema } {
69+
const fromSchema = findSchema(fromInfo.schemas, fromResultSetName);
70+
const toSchema = findSchema(toInfo.schemas, toResultSetName);
71+
72+
if (fromSchema.columns.length !== toSchema.columns.length) {
73+
throw new Error("CodeQL Compare: Columns do not match.");
74+
}
75+
if (fromSchema.rows === 0) {
76+
throw new Error("CodeQL Compare: Source query has no results.");
77+
}
78+
if (toSchema.rows === 0) {
79+
throw new Error("CodeQL Compare: Target query has no results.");
80+
}
81+
return { fromSchema, toSchema };
82+
}
83+
5584
export class CompareView extends AbstractWebview<
5685
ToCompareViewMessage,
5786
FromCompareViewMessage
@@ -178,11 +207,7 @@ export class CompareView extends AbstractWebview<
178207
let message: string | undefined;
179208
try {
180209
if (currentResultSetName === ALERTS_TABLE_NAME) {
181-
result = await compareInterpretedResults(
182-
this.databaseManager,
183-
this.cliServer,
184-
this.comparePair,
185-
);
210+
result = await this.compareInterpretedResults(this.comparePair);
186211
} else {
187212
result = await this.compareResults(
188213
this.comparePair,
@@ -424,6 +449,75 @@ export class CompareView extends AbstractWebview<
424449
}
425450
}
426451

452+
private async compareInterpretedResults(
453+
comparePair: ComparePair,
454+
): Promise<InterpretedQueryCompareResult> {
455+
const { from: fromQuery, fromInfo, to: toQuery, toInfo } = comparePair;
456+
457+
// `ALERTS_TABLE_NAME` is inserted by `getResultSetNames` into the schema
458+
// names even if it does not occur as a result set. Hence we check for
459+
// `SELECT_TABLE_NAME` first, and use that if it exists.
460+
const tableName = fromInfo.schemaNames.includes(SELECT_TABLE_NAME)
461+
? SELECT_TABLE_NAME
462+
: ALERTS_TABLE_NAME;
463+
464+
getComparableSchemas(fromInfo, toInfo, tableName, tableName);
465+
466+
const database = this.databaseManager.findDatabaseItem(
467+
Uri.parse(toQuery.initialInfo.databaseInfo.databaseUri),
468+
);
469+
if (!database) {
470+
throw new Error(
471+
"Could not find database the queries. Please check that the database still exists.",
472+
);
473+
}
474+
475+
const { uniquePath1, uniquePath2, path, cleanup } =
476+
await this.cliServer.bqrsDiff(
477+
fromQuery.completedQuery.query.resultsPath,
478+
toQuery.completedQuery.query.resultsPath,
479+
{ retainResultSets: ["nodes", "edges", "subpaths"] },
480+
);
481+
try {
482+
const sarifOutput1 = join(path, "from.sarif");
483+
const sarifOutput2 = join(path, "to.sarif");
484+
485+
const sourceLocationPrefix = await database.getSourceLocationPrefix(
486+
this.cliServer,
487+
);
488+
const sourceArchiveUri = database.sourceArchive;
489+
const sourceInfo =
490+
sourceArchiveUri === undefined
491+
? undefined
492+
: {
493+
sourceArchive: sourceArchiveUri.fsPath,
494+
sourceLocationPrefix,
495+
};
496+
497+
const fromResultSet = await this.cliServer.interpretBqrsSarif(
498+
fromQuery.completedQuery.query.metadata!,
499+
uniquePath1,
500+
sarifOutput1,
501+
sourceInfo,
502+
);
503+
const toResultSet = await this.cliServer.interpretBqrsSarif(
504+
toQuery.completedQuery.query.metadata!,
505+
uniquePath2,
506+
sarifOutput2,
507+
sourceInfo,
508+
);
509+
510+
return {
511+
kind: "interpreted",
512+
sourceLocationPrefix,
513+
from: fromResultSet.runs[0].results!,
514+
to: toResultSet.runs[0].results!,
515+
};
516+
} finally {
517+
await cleanup();
518+
}
519+
}
520+
427521
private async openQuery(kind: "from" | "to") {
428522
const toOpen =
429523
kind === "from" ? this.comparePair?.from : this.comparePair?.to;
@@ -432,28 +526,3 @@ export class CompareView extends AbstractWebview<
432526
}
433527
}
434528
}
435-
436-
/**
437-
* Check that `fromInfo` and `toInfo` have comparable schemas for the given
438-
* result set names and get them if so.
439-
*/
440-
export function getComparableSchemas(
441-
fromInfo: CompareQueryInfo,
442-
toInfo: CompareQueryInfo,
443-
fromResultSetName: string,
444-
toResultSetName: string,
445-
): { fromSchema: BqrsResultSetSchema; toSchema: BqrsResultSetSchema } {
446-
const fromSchema = findSchema(fromInfo.schemas, fromResultSetName);
447-
const toSchema = findSchema(toInfo.schemas, toResultSetName);
448-
449-
if (fromSchema.columns.length !== toSchema.columns.length) {
450-
throw new Error("CodeQL Compare: Columns do not match.");
451-
}
452-
if (fromSchema.rows === 0) {
453-
throw new Error("CodeQL Compare: Source query has no results.");
454-
}
455-
if (toSchema.rows === 0) {
456-
throw new Error("CodeQL Compare: Target query has no results.");
457-
}
458-
return { fromSchema, toSchema };
459-
}

extensions/ql-vscode/src/compare/interpreted-results.ts

Lines changed: 0 additions & 80 deletions
This file was deleted.

0 commit comments

Comments
 (0)