Merge pull request #2308 from github/charisk/query-history-store-naming
Query history store renaming
This commit is contained in:
@@ -39,10 +39,7 @@ import {
|
|||||||
QueryStatus,
|
QueryStatus,
|
||||||
variantAnalysisStatusToQueryStatus,
|
variantAnalysisStatusToQueryStatus,
|
||||||
} from "../query-status";
|
} from "../query-status";
|
||||||
import {
|
import { readQueryHistoryFromFile, writeQueryHistoryToFile } from "./store";
|
||||||
readQueryHistoryFromFile,
|
|
||||||
writeQueryHistoryToFile,
|
|
||||||
} from "./store/query-history-store";
|
|
||||||
import { pathExists } from "fs-extra";
|
import { pathExists } from "fs-extra";
|
||||||
import { CliVersionConstraint } from "../cli";
|
import { CliVersionConstraint } from "../cli";
|
||||||
import { HistoryItemLabelProvider } from "./history-item-label-provider";
|
import { HistoryItemLabelProvider } from "./history-item-label-provider";
|
||||||
|
|||||||
@@ -1,105 +0,0 @@
|
|||||||
import {
|
|
||||||
LocalQueryInfo,
|
|
||||||
CompletedQueryInfo,
|
|
||||||
InitialQueryInfo,
|
|
||||||
} from "../../query-results";
|
|
||||||
import { QueryEvaluationInfo } from "../../run-queries-shared";
|
|
||||||
import { QueryHistoryInfo } from "../query-history-info";
|
|
||||||
import { VariantAnalysisHistoryItem } from "../variant-analysis-history-item";
|
|
||||||
import {
|
|
||||||
CompletedQueryInfoData,
|
|
||||||
QueryEvaluationInfoData,
|
|
||||||
InitialQueryInfoData,
|
|
||||||
LocalQueryDataItem,
|
|
||||||
} from "./local-query-data-item";
|
|
||||||
import { QueryHistoryDataItem } from "./query-history-data";
|
|
||||||
|
|
||||||
// Maps Query History Data Models to Domain Models
|
|
||||||
|
|
||||||
export function mapQueryHistoryToDomainModels(
|
|
||||||
queries: QueryHistoryDataItem[],
|
|
||||||
): QueryHistoryInfo[] {
|
|
||||||
return queries.map((d) => {
|
|
||||||
if (d.t === "variant-analysis") {
|
|
||||||
const query: VariantAnalysisHistoryItem = d;
|
|
||||||
return query;
|
|
||||||
} else if (d.t === "local") {
|
|
||||||
return mapLocalQueryDataItemToDomainModel(d);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw Error(
|
|
||||||
`Unexpected or corrupted query history file. Unknown query history item: ${JSON.stringify(
|
|
||||||
d,
|
|
||||||
)}`,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function mapLocalQueryDataItemToDomainModel(
|
|
||||||
localQuery: LocalQueryDataItem,
|
|
||||||
): LocalQueryInfo {
|
|
||||||
return new LocalQueryInfo(
|
|
||||||
mapInitialQueryInfoDataToDomainModel(localQuery.initialInfo),
|
|
||||||
undefined,
|
|
||||||
localQuery.failureReason,
|
|
||||||
localQuery.completedQuery &&
|
|
||||||
mapCompletedQueryInfoDataToDomainModel(localQuery.completedQuery),
|
|
||||||
localQuery.evalLogLocation,
|
|
||||||
localQuery.evalLogSummaryLocation,
|
|
||||||
localQuery.jsonEvalLogSummaryLocation,
|
|
||||||
localQuery.evalLogSummarySymbolsLocation,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function mapCompletedQueryInfoDataToDomainModel(
|
|
||||||
completedQuery: CompletedQueryInfoData,
|
|
||||||
): CompletedQueryInfo {
|
|
||||||
return new CompletedQueryInfo(
|
|
||||||
mapQueryEvaluationInfoDataToDomainModel(completedQuery.query),
|
|
||||||
{
|
|
||||||
runId: completedQuery.result.runId,
|
|
||||||
queryId: completedQuery.result.queryId,
|
|
||||||
resultType: completedQuery.result.resultType,
|
|
||||||
evaluationTime: completedQuery.result.evaluationTime,
|
|
||||||
message: completedQuery.result.message,
|
|
||||||
logFileLocation: completedQuery.result.logFileLocation,
|
|
||||||
},
|
|
||||||
completedQuery.logFileLocation,
|
|
||||||
completedQuery.successful ?? completedQuery.sucessful,
|
|
||||||
completedQuery.message,
|
|
||||||
completedQuery.interpretedResultsSortState,
|
|
||||||
completedQuery.resultCount,
|
|
||||||
completedQuery.sortedResultsInfo,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function mapInitialQueryInfoDataToDomainModel(
|
|
||||||
initialInfo: InitialQueryInfoData,
|
|
||||||
): InitialQueryInfo {
|
|
||||||
return {
|
|
||||||
userSpecifiedLabel: initialInfo.userSpecifiedLabel,
|
|
||||||
queryText: initialInfo.queryText,
|
|
||||||
isQuickQuery: initialInfo.isQuickQuery,
|
|
||||||
isQuickEval: initialInfo.isQuickEval,
|
|
||||||
quickEvalPosition: initialInfo.quickEvalPosition,
|
|
||||||
queryPath: initialInfo.queryPath,
|
|
||||||
databaseInfo: {
|
|
||||||
databaseUri: initialInfo.databaseInfo.databaseUri,
|
|
||||||
name: initialInfo.databaseInfo.name,
|
|
||||||
},
|
|
||||||
start: new Date(initialInfo.start),
|
|
||||||
id: initialInfo.id,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function mapQueryEvaluationInfoDataToDomainModel(
|
|
||||||
evaluationInfo: QueryEvaluationInfoData,
|
|
||||||
): QueryEvaluationInfo {
|
|
||||||
return new QueryEvaluationInfo(
|
|
||||||
evaluationInfo.querySaveDir,
|
|
||||||
evaluationInfo.dbItemPath,
|
|
||||||
evaluationInfo.databaseHasMetadataFile,
|
|
||||||
evaluationInfo.quickEvalPosition,
|
|
||||||
evaluationInfo.metadata,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
import { assertNever } from "../../pure/helpers-pure";
|
|
||||||
import { LocalQueryInfo, InitialQueryInfo } from "../../query-results";
|
|
||||||
import { QueryEvaluationInfo } from "../../run-queries-shared";
|
|
||||||
import { QueryHistoryInfo } from "../query-history-info";
|
|
||||||
import {
|
|
||||||
LocalQueryDataItem,
|
|
||||||
InitialQueryInfoData,
|
|
||||||
QueryEvaluationInfoData,
|
|
||||||
} from "./local-query-data-item";
|
|
||||||
import { QueryHistoryDataItem } from "./query-history-data";
|
|
||||||
import { VariantAnalysisDataItem } from "./variant-analysis-data-item";
|
|
||||||
|
|
||||||
// Maps Query History Domain Models to Data Models
|
|
||||||
|
|
||||||
export function mapQueryHistoryToDataModels(
|
|
||||||
queries: QueryHistoryInfo[],
|
|
||||||
): QueryHistoryDataItem[] {
|
|
||||||
return queries.map((q) => {
|
|
||||||
if (q.t === "variant-analysis") {
|
|
||||||
const query: VariantAnalysisDataItem = q;
|
|
||||||
return query;
|
|
||||||
} else if (q.t === "local") {
|
|
||||||
return mapLocalQueryInfoToDataModel(q);
|
|
||||||
} else {
|
|
||||||
assertNever(q);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function mapLocalQueryInfoToDataModel(
|
|
||||||
query: LocalQueryInfo,
|
|
||||||
): LocalQueryDataItem {
|
|
||||||
return {
|
|
||||||
initialInfo: mapInitialQueryInfoToDataModel(query.initialInfo),
|
|
||||||
t: "local",
|
|
||||||
evalLogLocation: query.evalLogLocation,
|
|
||||||
evalLogSummaryLocation: query.evalLogSummaryLocation,
|
|
||||||
jsonEvalLogSummaryLocation: query.jsonEvalLogSummaryLocation,
|
|
||||||
evalLogSummarySymbolsLocation: query.evalLogSummarySymbolsLocation,
|
|
||||||
failureReason: query.failureReason,
|
|
||||||
completedQuery: query.completedQuery && {
|
|
||||||
query: mapQueryEvaluationInfoToDataModel(query.completedQuery.query),
|
|
||||||
result: {
|
|
||||||
runId: query.completedQuery.result.runId,
|
|
||||||
queryId: query.completedQuery.result.queryId,
|
|
||||||
resultType: query.completedQuery.result.resultType,
|
|
||||||
evaluationTime: query.completedQuery.result.evaluationTime,
|
|
||||||
message: query.completedQuery.result.message,
|
|
||||||
logFileLocation: query.completedQuery.result.logFileLocation,
|
|
||||||
},
|
|
||||||
logFileLocation: query.completedQuery.logFileLocation,
|
|
||||||
successful: query.completedQuery.successful,
|
|
||||||
message: query.completedQuery.message,
|
|
||||||
resultCount: query.completedQuery.resultCount,
|
|
||||||
sortedResultsInfo: query.completedQuery.sortedResultsInfo,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function mapInitialQueryInfoToDataModel(
|
|
||||||
localQueryInitialInfo: InitialQueryInfo,
|
|
||||||
): InitialQueryInfoData {
|
|
||||||
return {
|
|
||||||
userSpecifiedLabel: localQueryInitialInfo.userSpecifiedLabel,
|
|
||||||
queryText: localQueryInitialInfo.queryText,
|
|
||||||
isQuickQuery: localQueryInitialInfo.isQuickQuery,
|
|
||||||
isQuickEval: localQueryInitialInfo.isQuickEval,
|
|
||||||
quickEvalPosition: localQueryInitialInfo.quickEvalPosition,
|
|
||||||
queryPath: localQueryInitialInfo.queryPath,
|
|
||||||
databaseInfo: {
|
|
||||||
databaseUri: localQueryInitialInfo.databaseInfo.databaseUri,
|
|
||||||
name: localQueryInitialInfo.databaseInfo.name,
|
|
||||||
},
|
|
||||||
start: localQueryInitialInfo.start,
|
|
||||||
id: localQueryInitialInfo.id,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function mapQueryEvaluationInfoToDataModel(
|
|
||||||
queryEvaluationInfo: QueryEvaluationInfo,
|
|
||||||
): QueryEvaluationInfoData {
|
|
||||||
return {
|
|
||||||
querySaveDir: queryEvaluationInfo.querySaveDir,
|
|
||||||
dbItemPath: queryEvaluationInfo.dbItemPath,
|
|
||||||
databaseHasMetadataFile: queryEvaluationInfo.databaseHasMetadataFile,
|
|
||||||
quickEvalPosition: queryEvaluationInfo.quickEvalPosition,
|
|
||||||
metadata: queryEvaluationInfo.metadata,
|
|
||||||
resultsPaths: queryEvaluationInfo.resultsPaths,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
1
extensions/ql-vscode/src/query-history/store/index.ts
Normal file
1
extensions/ql-vscode/src/query-history/store/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export * from "./query-history-store";
|
||||||
@@ -1,100 +0,0 @@
|
|||||||
export interface LocalQueryDataItem {
|
|
||||||
initialInfo: InitialQueryInfoData;
|
|
||||||
t: "local";
|
|
||||||
evalLogLocation?: string;
|
|
||||||
evalLogSummaryLocation?: string;
|
|
||||||
jsonEvalLogSummaryLocation?: string;
|
|
||||||
evalLogSummarySymbolsLocation?: string;
|
|
||||||
completedQuery?: CompletedQueryInfoData;
|
|
||||||
failureReason?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface InitialQueryInfoData {
|
|
||||||
userSpecifiedLabel?: string;
|
|
||||||
queryText: string;
|
|
||||||
isQuickQuery: boolean;
|
|
||||||
isQuickEval: boolean;
|
|
||||||
quickEvalPosition?: PositionData;
|
|
||||||
queryPath: string;
|
|
||||||
databaseInfo: DatabaseInfoData;
|
|
||||||
start: Date;
|
|
||||||
id: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface DatabaseInfoData {
|
|
||||||
name: string;
|
|
||||||
databaseUri: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface PositionData {
|
|
||||||
line: number;
|
|
||||||
column: number;
|
|
||||||
endLine: number;
|
|
||||||
endColumn: number;
|
|
||||||
fileName: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface CompletedQueryInfoData {
|
|
||||||
query: QueryEvaluationInfoData;
|
|
||||||
message?: string;
|
|
||||||
successful?: boolean;
|
|
||||||
|
|
||||||
// There once was a typo in the data model, which is why we need to support both
|
|
||||||
sucessful?: boolean;
|
|
||||||
result: EvaluationResultData;
|
|
||||||
logFileLocation?: string;
|
|
||||||
resultCount: number;
|
|
||||||
sortedResultsInfo: Record<string, SortedResultSetInfo>;
|
|
||||||
interpretedResultsSortState?: InterpretedResultsSortState;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface InterpretedResultsSortState {
|
|
||||||
sortBy: InterpretedResultsSortColumn;
|
|
||||||
sortDirection: SortDirection;
|
|
||||||
}
|
|
||||||
|
|
||||||
type InterpretedResultsSortColumn = "alert-message";
|
|
||||||
|
|
||||||
interface SortedResultSetInfo {
|
|
||||||
resultsPath: string;
|
|
||||||
sortState: RawResultsSortState;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface RawResultsSortState {
|
|
||||||
columnIndex: number;
|
|
||||||
sortDirection: SortDirection;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum SortDirection {
|
|
||||||
asc,
|
|
||||||
desc,
|
|
||||||
}
|
|
||||||
|
|
||||||
interface EvaluationResultData {
|
|
||||||
runId: number;
|
|
||||||
queryId: number;
|
|
||||||
resultType: number;
|
|
||||||
evaluationTime: number;
|
|
||||||
message?: string;
|
|
||||||
logFileLocation?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface QueryEvaluationInfoData {
|
|
||||||
querySaveDir: string;
|
|
||||||
dbItemPath: string;
|
|
||||||
databaseHasMetadataFile: boolean;
|
|
||||||
quickEvalPosition?: PositionData;
|
|
||||||
metadata?: QueryMetadataData;
|
|
||||||
resultsPaths: {
|
|
||||||
resultsPath: string;
|
|
||||||
interpretedResultsPath: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
interface QueryMetadataData {
|
|
||||||
name?: string;
|
|
||||||
description?: string;
|
|
||||||
id?: string;
|
|
||||||
kind?: string;
|
|
||||||
scored?: string;
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
// Contains models and consts for the data we want to store in the query history store.
|
|
||||||
// Changes to these models should be done carefully and account for backwards compatibility of data.
|
|
||||||
|
|
||||||
import { LocalQueryDataItem } from "./local-query-data-item";
|
|
||||||
import { VariantAnalysisDataItem } from "./variant-analysis-data-item";
|
|
||||||
|
|
||||||
export const ALLOWED_QUERY_HISTORY_VERSIONS = [1, 2];
|
|
||||||
|
|
||||||
export interface QueryHistoryData {
|
|
||||||
version: number;
|
|
||||||
queries: QueryHistoryDataItem[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export type QueryHistoryDataItem = LocalQueryDataItem | VariantAnalysisDataItem;
|
|
||||||
@@ -0,0 +1,140 @@
|
|||||||
|
import { assertNever } from "../../pure/helpers-pure";
|
||||||
|
import {
|
||||||
|
LocalQueryInfo,
|
||||||
|
InitialQueryInfo,
|
||||||
|
CompletedQueryInfo,
|
||||||
|
} from "../../query-results";
|
||||||
|
import { QueryEvaluationInfo } from "../../run-queries-shared";
|
||||||
|
import { QueryHistoryInfo } from "../query-history-info";
|
||||||
|
import {
|
||||||
|
QueryHistoryLocalQueryDto,
|
||||||
|
InitialQueryInfoDto,
|
||||||
|
QueryEvaluationInfoDto,
|
||||||
|
CompletedQueryInfoDto,
|
||||||
|
SortedResultSetInfoDto,
|
||||||
|
SortDirectionDto,
|
||||||
|
} from "./query-history-local-query-dto";
|
||||||
|
import { QueryHistoryItemDto } from "./query-history-dto";
|
||||||
|
import { QueryHistoryVariantAnalysisDto } from "./query-history-variant-analysis-dto";
|
||||||
|
import {
|
||||||
|
RawResultsSortState,
|
||||||
|
SortDirection,
|
||||||
|
SortedResultSetInfo,
|
||||||
|
} from "../../pure/interface-types";
|
||||||
|
|
||||||
|
export function mapQueryHistoryToDto(
|
||||||
|
queries: QueryHistoryInfo[],
|
||||||
|
): QueryHistoryItemDto[] {
|
||||||
|
return queries.map((q) => {
|
||||||
|
if (q.t === "variant-analysis") {
|
||||||
|
const query: QueryHistoryVariantAnalysisDto = q;
|
||||||
|
return query;
|
||||||
|
} else if (q.t === "local") {
|
||||||
|
return mapLocalQueryInfoToDto(q);
|
||||||
|
} else {
|
||||||
|
assertNever(q);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapLocalQueryInfoToDto(
|
||||||
|
query: LocalQueryInfo,
|
||||||
|
): QueryHistoryLocalQueryDto {
|
||||||
|
return {
|
||||||
|
initialInfo: mapInitialQueryInfoToDto(query.initialInfo),
|
||||||
|
t: "local",
|
||||||
|
evalLogLocation: query.evalLogLocation,
|
||||||
|
evalLogSummaryLocation: query.evalLogSummaryLocation,
|
||||||
|
jsonEvalLogSummaryLocation: query.jsonEvalLogSummaryLocation,
|
||||||
|
evalLogSummarySymbolsLocation: query.evalLogSummarySymbolsLocation,
|
||||||
|
failureReason: query.failureReason,
|
||||||
|
completedQuery:
|
||||||
|
query.completedQuery && mapCompletedQueryToDto(query.completedQuery),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapCompletedQueryToDto(
|
||||||
|
query: CompletedQueryInfo,
|
||||||
|
): CompletedQueryInfoDto {
|
||||||
|
const sortedResults = Object.fromEntries(
|
||||||
|
Object.entries(query.sortedResultsInfo).map(([key, value]) => {
|
||||||
|
return [key, mapSortedResultSetInfoToDto(value)];
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
query: mapQueryEvaluationInfoToDto(query.query),
|
||||||
|
result: {
|
||||||
|
runId: query.result.runId,
|
||||||
|
queryId: query.result.queryId,
|
||||||
|
resultType: query.result.resultType,
|
||||||
|
evaluationTime: query.result.evaluationTime,
|
||||||
|
message: query.result.message,
|
||||||
|
logFileLocation: query.result.logFileLocation,
|
||||||
|
},
|
||||||
|
logFileLocation: query.logFileLocation,
|
||||||
|
successful: query.successful,
|
||||||
|
message: query.message,
|
||||||
|
resultCount: query.resultCount,
|
||||||
|
sortedResultsInfo: sortedResults,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapSortDirectionToDto(sortDirection: SortDirection): SortDirectionDto {
|
||||||
|
switch (sortDirection) {
|
||||||
|
case SortDirection.asc:
|
||||||
|
return SortDirectionDto.asc;
|
||||||
|
case SortDirection.desc:
|
||||||
|
return SortDirectionDto.desc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapRawResultsSortStateToDto(
|
||||||
|
sortState: RawResultsSortState,
|
||||||
|
): SortedResultSetInfoDto["sortState"] {
|
||||||
|
return {
|
||||||
|
columnIndex: sortState.columnIndex,
|
||||||
|
sortDirection: mapSortDirectionToDto(sortState.sortDirection),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapSortedResultSetInfoToDto(
|
||||||
|
resultSet: SortedResultSetInfo,
|
||||||
|
): SortedResultSetInfoDto {
|
||||||
|
return {
|
||||||
|
resultsPath: resultSet.resultsPath,
|
||||||
|
sortState: mapRawResultsSortStateToDto(resultSet.sortState),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapInitialQueryInfoToDto(
|
||||||
|
localQueryInitialInfo: InitialQueryInfo,
|
||||||
|
): InitialQueryInfoDto {
|
||||||
|
return {
|
||||||
|
userSpecifiedLabel: localQueryInitialInfo.userSpecifiedLabel,
|
||||||
|
queryText: localQueryInitialInfo.queryText,
|
||||||
|
isQuickQuery: localQueryInitialInfo.isQuickQuery,
|
||||||
|
isQuickEval: localQueryInitialInfo.isQuickEval,
|
||||||
|
quickEvalPosition: localQueryInitialInfo.quickEvalPosition,
|
||||||
|
queryPath: localQueryInitialInfo.queryPath,
|
||||||
|
databaseInfo: {
|
||||||
|
databaseUri: localQueryInitialInfo.databaseInfo.databaseUri,
|
||||||
|
name: localQueryInitialInfo.databaseInfo.name,
|
||||||
|
},
|
||||||
|
start: localQueryInitialInfo.start,
|
||||||
|
id: localQueryInitialInfo.id,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapQueryEvaluationInfoToDto(
|
||||||
|
queryEvaluationInfo: QueryEvaluationInfo,
|
||||||
|
): QueryEvaluationInfoDto {
|
||||||
|
return {
|
||||||
|
querySaveDir: queryEvaluationInfo.querySaveDir,
|
||||||
|
dbItemPath: queryEvaluationInfo.dbItemPath,
|
||||||
|
databaseHasMetadataFile: queryEvaluationInfo.databaseHasMetadataFile,
|
||||||
|
quickEvalPosition: queryEvaluationInfo.quickEvalPosition,
|
||||||
|
metadata: queryEvaluationInfo.metadata,
|
||||||
|
resultsPaths: queryEvaluationInfo.resultsPaths,
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,163 @@
|
|||||||
|
import {
|
||||||
|
LocalQueryInfo,
|
||||||
|
CompletedQueryInfo,
|
||||||
|
InitialQueryInfo,
|
||||||
|
} from "../../query-results";
|
||||||
|
import { QueryEvaluationInfo } from "../../run-queries-shared";
|
||||||
|
import { QueryHistoryInfo } from "../query-history-info";
|
||||||
|
import { VariantAnalysisHistoryItem } from "../variant-analysis-history-item";
|
||||||
|
import {
|
||||||
|
CompletedQueryInfoDto,
|
||||||
|
QueryEvaluationInfoDto,
|
||||||
|
InitialQueryInfoDto,
|
||||||
|
QueryHistoryLocalQueryDto,
|
||||||
|
SortDirectionDto,
|
||||||
|
InterpretedResultsSortStateDto,
|
||||||
|
SortedResultSetInfoDto,
|
||||||
|
RawResultsSortStateDto,
|
||||||
|
} from "./query-history-local-query-dto";
|
||||||
|
import { QueryHistoryItemDto } from "./query-history-dto";
|
||||||
|
import {
|
||||||
|
InterpretedResultsSortState,
|
||||||
|
RawResultsSortState,
|
||||||
|
SortDirection,
|
||||||
|
SortedResultSetInfo,
|
||||||
|
} from "../../pure/interface-types";
|
||||||
|
|
||||||
|
export function mapQueryHistoryToDomainModel(
|
||||||
|
queries: QueryHistoryItemDto[],
|
||||||
|
): QueryHistoryInfo[] {
|
||||||
|
return queries.map((d) => {
|
||||||
|
if (d.t === "variant-analysis") {
|
||||||
|
const query: VariantAnalysisHistoryItem = d;
|
||||||
|
return query;
|
||||||
|
} else if (d.t === "local") {
|
||||||
|
return mapLocalQueryItemToDomainModel(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw Error(
|
||||||
|
`Unexpected or corrupted query history file. Unknown query history item: ${JSON.stringify(
|
||||||
|
d,
|
||||||
|
)}`,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapLocalQueryItemToDomainModel(
|
||||||
|
localQuery: QueryHistoryLocalQueryDto,
|
||||||
|
): LocalQueryInfo {
|
||||||
|
return new LocalQueryInfo(
|
||||||
|
mapInitialQueryInfoToDomainModel(localQuery.initialInfo),
|
||||||
|
undefined,
|
||||||
|
localQuery.failureReason,
|
||||||
|
localQuery.completedQuery &&
|
||||||
|
mapCompletedQueryInfoToDomainModel(localQuery.completedQuery),
|
||||||
|
localQuery.evalLogLocation,
|
||||||
|
localQuery.evalLogSummaryLocation,
|
||||||
|
localQuery.jsonEvalLogSummaryLocation,
|
||||||
|
localQuery.evalLogSummarySymbolsLocation,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapCompletedQueryInfoToDomainModel(
|
||||||
|
completedQuery: CompletedQueryInfoDto,
|
||||||
|
): CompletedQueryInfo {
|
||||||
|
const sortState =
|
||||||
|
completedQuery.interpretedResultsSortState &&
|
||||||
|
mapSortStateToDomainModel(completedQuery.interpretedResultsSortState);
|
||||||
|
|
||||||
|
const sortedResults = Object.fromEntries(
|
||||||
|
Object.entries(completedQuery.sortedResultsInfo).map(([key, value]) => {
|
||||||
|
return [key, mapSortedResultSetInfoToDomainModel(value)];
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
return new CompletedQueryInfo(
|
||||||
|
mapQueryEvaluationInfoToDomainModel(completedQuery.query),
|
||||||
|
{
|
||||||
|
runId: completedQuery.result.runId,
|
||||||
|
queryId: completedQuery.result.queryId,
|
||||||
|
resultType: completedQuery.result.resultType,
|
||||||
|
evaluationTime: completedQuery.result.evaluationTime,
|
||||||
|
message: completedQuery.result.message,
|
||||||
|
logFileLocation: completedQuery.result.logFileLocation,
|
||||||
|
},
|
||||||
|
completedQuery.logFileLocation,
|
||||||
|
completedQuery.successful ?? completedQuery.sucessful,
|
||||||
|
completedQuery.message,
|
||||||
|
sortState,
|
||||||
|
completedQuery.resultCount,
|
||||||
|
sortedResults,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapInitialQueryInfoToDomainModel(
|
||||||
|
initialInfo: InitialQueryInfoDto,
|
||||||
|
): InitialQueryInfo {
|
||||||
|
return {
|
||||||
|
userSpecifiedLabel: initialInfo.userSpecifiedLabel,
|
||||||
|
queryText: initialInfo.queryText,
|
||||||
|
isQuickQuery: initialInfo.isQuickQuery,
|
||||||
|
isQuickEval: initialInfo.isQuickEval,
|
||||||
|
quickEvalPosition: initialInfo.quickEvalPosition,
|
||||||
|
queryPath: initialInfo.queryPath,
|
||||||
|
databaseInfo: {
|
||||||
|
databaseUri: initialInfo.databaseInfo.databaseUri,
|
||||||
|
name: initialInfo.databaseInfo.name,
|
||||||
|
},
|
||||||
|
start: new Date(initialInfo.start),
|
||||||
|
id: initialInfo.id,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapQueryEvaluationInfoToDomainModel(
|
||||||
|
evaluationInfo: QueryEvaluationInfoDto,
|
||||||
|
): QueryEvaluationInfo {
|
||||||
|
return new QueryEvaluationInfo(
|
||||||
|
evaluationInfo.querySaveDir,
|
||||||
|
evaluationInfo.dbItemPath,
|
||||||
|
evaluationInfo.databaseHasMetadataFile,
|
||||||
|
evaluationInfo.quickEvalPosition,
|
||||||
|
evaluationInfo.metadata,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapSortDirectionToDomainModel(
|
||||||
|
sortDirection: SortDirectionDto,
|
||||||
|
): SortDirection {
|
||||||
|
switch (sortDirection) {
|
||||||
|
case SortDirectionDto.asc:
|
||||||
|
return SortDirection.asc;
|
||||||
|
case SortDirectionDto.desc:
|
||||||
|
return SortDirection.desc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapSortStateToDomainModel(
|
||||||
|
sortState: InterpretedResultsSortStateDto,
|
||||||
|
): InterpretedResultsSortState {
|
||||||
|
return {
|
||||||
|
sortBy: sortState.sortBy,
|
||||||
|
sortDirection: mapSortDirectionToDomainModel(sortState.sortDirection),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapSortedResultSetInfoToDomainModel(
|
||||||
|
sortedResultSetInfo: SortedResultSetInfoDto,
|
||||||
|
): SortedResultSetInfo {
|
||||||
|
return {
|
||||||
|
resultsPath: sortedResultSetInfo.resultsPath,
|
||||||
|
sortState: mapRawResultsSortStateToDomainModel(
|
||||||
|
sortedResultSetInfo.sortState,
|
||||||
|
),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapRawResultsSortStateToDomainModel(
|
||||||
|
sortState: RawResultsSortStateDto,
|
||||||
|
): RawResultsSortState {
|
||||||
|
return {
|
||||||
|
columnIndex: sortState.columnIndex,
|
||||||
|
sortDirection: mapSortDirectionToDomainModel(sortState.sortDirection),
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
// Contains models and consts for the data we want to store in the query history store.
|
||||||
|
// Changes to these models should be done carefully and account for backwards compatibility of data.
|
||||||
|
|
||||||
|
import { QueryHistoryLocalQueryDto } from "./query-history-local-query-dto";
|
||||||
|
import { QueryHistoryVariantAnalysisDto } from "./query-history-variant-analysis-dto";
|
||||||
|
|
||||||
|
export interface QueryHistoryDto {
|
||||||
|
version: number;
|
||||||
|
queries: QueryHistoryItemDto[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export type QueryHistoryItemDto =
|
||||||
|
| QueryHistoryLocalQueryDto
|
||||||
|
| QueryHistoryVariantAnalysisDto;
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
// Contains models and consts for the data we want to store in the query history store.
|
||||||
|
// Changes to these models should be done carefully and account for backwards compatibility of data.
|
||||||
|
|
||||||
|
export interface QueryHistoryLocalQueryDto {
|
||||||
|
initialInfo: InitialQueryInfoDto;
|
||||||
|
t: "local";
|
||||||
|
evalLogLocation?: string;
|
||||||
|
evalLogSummaryLocation?: string;
|
||||||
|
jsonEvalLogSummaryLocation?: string;
|
||||||
|
evalLogSummarySymbolsLocation?: string;
|
||||||
|
completedQuery?: CompletedQueryInfoDto;
|
||||||
|
failureReason?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface InitialQueryInfoDto {
|
||||||
|
userSpecifiedLabel?: string;
|
||||||
|
queryText: string;
|
||||||
|
isQuickQuery: boolean;
|
||||||
|
isQuickEval: boolean;
|
||||||
|
quickEvalPosition?: PositionDto;
|
||||||
|
queryPath: string;
|
||||||
|
databaseInfo: DatabaseInfoDto;
|
||||||
|
start: Date;
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface DatabaseInfoDto {
|
||||||
|
name: string;
|
||||||
|
databaseUri: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PositionDto {
|
||||||
|
line: number;
|
||||||
|
column: number;
|
||||||
|
endLine: number;
|
||||||
|
endColumn: number;
|
||||||
|
fileName: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CompletedQueryInfoDto {
|
||||||
|
query: QueryEvaluationInfoDto;
|
||||||
|
message?: string;
|
||||||
|
successful?: boolean;
|
||||||
|
|
||||||
|
// There once was a typo in the data model, which is why we need to support both
|
||||||
|
sucessful?: boolean;
|
||||||
|
result: EvaluationResultDto;
|
||||||
|
logFileLocation?: string;
|
||||||
|
resultCount: number;
|
||||||
|
sortedResultsInfo: Record<string, SortedResultSetInfoDto>;
|
||||||
|
interpretedResultsSortState?: InterpretedResultsSortStateDto;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface InterpretedResultsSortStateDto {
|
||||||
|
sortBy: InterpretedResultsSortColumnDto;
|
||||||
|
sortDirection: SortDirectionDto;
|
||||||
|
}
|
||||||
|
|
||||||
|
type InterpretedResultsSortColumnDto = "alert-message";
|
||||||
|
|
||||||
|
export interface SortedResultSetInfoDto {
|
||||||
|
resultsPath: string;
|
||||||
|
sortState: RawResultsSortStateDto;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RawResultsSortStateDto {
|
||||||
|
columnIndex: number;
|
||||||
|
sortDirection: SortDirectionDto;
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum SortDirectionDto {
|
||||||
|
asc,
|
||||||
|
desc,
|
||||||
|
}
|
||||||
|
|
||||||
|
interface EvaluationResultDto {
|
||||||
|
runId: number;
|
||||||
|
queryId: number;
|
||||||
|
resultType: number;
|
||||||
|
evaluationTime: number;
|
||||||
|
message?: string;
|
||||||
|
logFileLocation?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface QueryEvaluationInfoDto {
|
||||||
|
querySaveDir: string;
|
||||||
|
dbItemPath: string;
|
||||||
|
databaseHasMetadataFile: boolean;
|
||||||
|
quickEvalPosition?: PositionDto;
|
||||||
|
metadata?: QueryMetadataDto;
|
||||||
|
resultsPaths: {
|
||||||
|
resultsPath: string;
|
||||||
|
interpretedResultsPath: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
interface QueryMetadataDto {
|
||||||
|
name?: string;
|
||||||
|
description?: string;
|
||||||
|
id?: string;
|
||||||
|
kind?: string;
|
||||||
|
scored?: string;
|
||||||
|
}
|
||||||
@@ -10,13 +10,11 @@ import {
|
|||||||
} from "../../pure/helpers-pure";
|
} from "../../pure/helpers-pure";
|
||||||
import { QueryHistoryInfo } from "../query-history-info";
|
import { QueryHistoryInfo } from "../query-history-info";
|
||||||
import { redactableError } from "../../pure/errors";
|
import { redactableError } from "../../pure/errors";
|
||||||
import {
|
import { QueryHistoryDto, QueryHistoryItemDto } from "./query-history-dto";
|
||||||
ALLOWED_QUERY_HISTORY_VERSIONS,
|
import { mapQueryHistoryToDomainModel } from "./query-history-dto-mapper";
|
||||||
QueryHistoryData,
|
import { mapQueryHistoryToDto } from "./query-history-domain-mapper";
|
||||||
QueryHistoryDataItem,
|
|
||||||
} from "./query-history-data";
|
const ALLOWED_QUERY_HISTORY_VERSIONS = [1, 2];
|
||||||
import { mapQueryHistoryToDomainModels } from "./data-mapper";
|
|
||||||
import { mapQueryHistoryToDataModels } from "./domain-mapper";
|
|
||||||
|
|
||||||
export async function readQueryHistoryFromFile(
|
export async function readQueryHistoryFromFile(
|
||||||
fsPath: string,
|
fsPath: string,
|
||||||
@@ -26,7 +24,7 @@ export async function readQueryHistoryFromFile(
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const obj: QueryHistoryData = await readJson(fsPath, {
|
const obj: QueryHistoryDto = await readJson(fsPath, {
|
||||||
encoding: "utf8",
|
encoding: "utf8",
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -40,21 +38,21 @@ export async function readQueryHistoryFromFile(
|
|||||||
const queries = obj.queries;
|
const queries = obj.queries;
|
||||||
// Remove remote queries, which are not supported anymore.
|
// Remove remote queries, which are not supported anymore.
|
||||||
const parsedQueries = queries.filter(
|
const parsedQueries = queries.filter(
|
||||||
(q: QueryHistoryDataItem | { t: "remote" }) => q.t !== "remote",
|
(q: QueryHistoryItemDto | { t: "remote" }) => q.t !== "remote",
|
||||||
);
|
);
|
||||||
|
|
||||||
// Map the data models to the domain models.
|
// Map the data models to the domain models.
|
||||||
const domainModels: QueryHistoryInfo[] =
|
const domainModels: QueryHistoryInfo[] =
|
||||||
mapQueryHistoryToDomainModels(parsedQueries);
|
mapQueryHistoryToDomainModel(parsedQueries);
|
||||||
|
|
||||||
// filter out queries that have been deleted on disk
|
// Filter out queries that have been deleted on disk
|
||||||
// most likely another workspace has deleted them because the
|
// most likely another workspace has deleted them because the
|
||||||
// queries aged out.
|
// queries aged out.
|
||||||
const filteredDomainModels: Promise<QueryHistoryInfo[]> = asyncFilter(
|
const filteredDomainModels: Promise<QueryHistoryInfo[]> = asyncFilter(
|
||||||
domainModels,
|
domainModels,
|
||||||
async (q) => {
|
async (q) => {
|
||||||
if (q.t === "variant-analysis") {
|
if (q.t === "variant-analysis") {
|
||||||
// the query history store doesn't know where variant analysises are
|
// The query history store doesn't know where variant analysises are
|
||||||
// stored so we need to assume here that they exist. We check later
|
// stored so we need to assume here that they exist. We check later
|
||||||
// to see if they exist on disk.
|
// to see if they exist on disk.
|
||||||
return true;
|
return true;
|
||||||
@@ -72,7 +70,7 @@ export async function readQueryHistoryFromFile(
|
|||||||
fullMessage: `Error loading query history.\n${getErrorStack(e)}`,
|
fullMessage: `Error loading query history.\n${getErrorStack(e)}`,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
// since the query history is invalid, it should be deleted so this error does not happen on next startup.
|
// Since the query history is invalid, it should be deleted so this error does not happen on next startup.
|
||||||
await remove(fsPath);
|
await remove(fsPath);
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
@@ -95,13 +93,13 @@ export async function writeQueryHistoryToFile(
|
|||||||
if (!(await pathExists(fsPath))) {
|
if (!(await pathExists(fsPath))) {
|
||||||
await mkdir(dirname(fsPath), { recursive: true });
|
await mkdir(dirname(fsPath), { recursive: true });
|
||||||
}
|
}
|
||||||
// remove incomplete local queries since they cannot be recreated on restart
|
// Remove incomplete local queries since they cannot be recreated on restart
|
||||||
const filteredQueries = queries.filter((q) =>
|
const filteredQueries = queries.filter((q) =>
|
||||||
q.t === "local" ? q.completedQuery !== undefined : true,
|
q.t === "local" ? q.completedQuery !== undefined : true,
|
||||||
);
|
);
|
||||||
|
|
||||||
// map domain model queries to data model
|
// Map domain model queries to data model
|
||||||
const queryHistoryData = mapQueryHistoryToDataModels(filteredQueries);
|
const queryHistoryData = mapQueryHistoryToDto(filteredQueries);
|
||||||
|
|
||||||
const data = JSON.stringify(
|
const data = JSON.stringify(
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// Contains models and consts for the data we want to store in the query history store.
|
||||||
|
// Changes to these models should be done carefully and account for backwards compatibility of data.
|
||||||
|
|
||||||
import { QueryLanguage } from "../../common/query-language";
|
import { QueryLanguage } from "../../common/query-language";
|
||||||
import { QueryStatus } from "../../query-status";
|
import { QueryStatus } from "../../query-status";
|
||||||
import {
|
import {
|
||||||
@@ -6,20 +9,19 @@ import {
|
|||||||
VariantAnalysisStatus,
|
VariantAnalysisStatus,
|
||||||
} from "../../variant-analysis/shared/variant-analysis";
|
} from "../../variant-analysis/shared/variant-analysis";
|
||||||
|
|
||||||
// Data Model for Variant Analysis Query History Items
|
|
||||||
// All data points are modelled, except enums.
|
// All data points are modelled, except enums.
|
||||||
|
|
||||||
export interface VariantAnalysisDataItem {
|
export interface QueryHistoryVariantAnalysisDto {
|
||||||
readonly t: "variant-analysis";
|
readonly t: "variant-analysis";
|
||||||
failureReason?: string;
|
failureReason?: string;
|
||||||
resultCount?: number;
|
resultCount?: number;
|
||||||
status: QueryStatus;
|
status: QueryStatus;
|
||||||
completed: boolean;
|
completed: boolean;
|
||||||
variantAnalysis: VariantAnalysisQueryHistoryData;
|
variantAnalysis: VariantAnalysisQueryHistoryDto;
|
||||||
userSpecifiedLabel?: string;
|
userSpecifiedLabel?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface VariantAnalysisQueryHistoryData {
|
export interface VariantAnalysisQueryHistoryDto {
|
||||||
id: number;
|
id: number;
|
||||||
controllerRepo: {
|
controllerRepo: {
|
||||||
id: number;
|
id: number;
|
||||||
@@ -44,11 +46,11 @@ export interface VariantAnalysisQueryHistoryData {
|
|||||||
completedAt?: string;
|
completedAt?: string;
|
||||||
actionsWorkflowRunId?: number;
|
actionsWorkflowRunId?: number;
|
||||||
failureReason?: VariantAnalysisFailureReason;
|
failureReason?: VariantAnalysisFailureReason;
|
||||||
scannedRepos?: VariantAnalysisScannedRepositoryData[];
|
scannedRepos?: VariantAnalysisScannedRepositoryDto[];
|
||||||
skippedRepos?: VariantAnalysisSkippedRepositoriesData;
|
skippedRepos?: VariantAnalysisSkippedRepositoriesDto;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface VariantAnalysisScannedRepositoryData {
|
export interface VariantAnalysisScannedRepositoryDto {
|
||||||
repository: {
|
repository: {
|
||||||
id: number;
|
id: number;
|
||||||
fullName: string;
|
fullName: string;
|
||||||
@@ -62,19 +64,19 @@ export interface VariantAnalysisScannedRepositoryData {
|
|||||||
failureMessage?: string;
|
failureMessage?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface VariantAnalysisSkippedRepositoriesData {
|
export interface VariantAnalysisSkippedRepositoriesDto {
|
||||||
accessMismatchRepos?: VariantAnalysisSkippedRepositoryGroupData;
|
accessMismatchRepos?: VariantAnalysisSkippedRepositoryGroupDto;
|
||||||
notFoundRepos?: VariantAnalysisSkippedRepositoryGroupData;
|
notFoundRepos?: VariantAnalysisSkippedRepositoryGroupDto;
|
||||||
noCodeqlDbRepos?: VariantAnalysisSkippedRepositoryGroupData;
|
noCodeqlDbRepos?: VariantAnalysisSkippedRepositoryGroupDto;
|
||||||
overLimitRepos?: VariantAnalysisSkippedRepositoryGroupData;
|
overLimitRepos?: VariantAnalysisSkippedRepositoryGroupDto;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface VariantAnalysisSkippedRepositoryGroupData {
|
export interface VariantAnalysisSkippedRepositoryGroupDto {
|
||||||
repositoryCount: number;
|
repositoryCount: number;
|
||||||
repositories: VariantAnalysisSkippedRepositoryData[];
|
repositories: VariantAnalysisSkippedRepositoryDto[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface VariantAnalysisSkippedRepositoryData {
|
export interface VariantAnalysisSkippedRepositoryDto {
|
||||||
id?: number;
|
id?: number;
|
||||||
fullName: string;
|
fullName: string;
|
||||||
private?: boolean;
|
private?: boolean;
|
||||||
Reference in New Issue
Block a user