Merge pull request #2308 from github/charisk/query-history-store-naming

Query history store renaming
This commit is contained in:
Charis Kyriakou
2023-04-13 12:30:25 +01:00
committed by GitHub
12 changed files with 453 additions and 344 deletions

View File

@@ -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";

View File

@@ -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,
);
}

View File

@@ -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,
};
}

View File

@@ -0,0 +1 @@
export * from "./query-history-store";

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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,
};
}

View File

@@ -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),
};
}

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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(
{ {

View File

@@ -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;