import { InsightDatasetKind, InsightResult } from "../controller/IInsightFacade";
import InsightFacade from "../controller/InsightFacade";
import { DatasetRoom, DatasetSection } from "../datasetProcessor/DatasetSection";
import QueryCollector from "./QueryCollector";
import QueryPersister from "./QueryPersister";
import { FILTER, Key, QUERY } from "./QueryTree";
import QueryValidator from "./QueryValidator";
export type ValidatorInfo = {
id: string;
applyOrGroup: string[];
type: string;
column: string[];
};
export default class QueryProcessor {
private insightFacade: InsightFacade;
constructor(insightFacade: InsightFacade) {
this.insightFacade = insightFacade;
}
public async processQuery(query: QUERY): Promise<InsightResult[]> {
const validateInfo: ValidatorInfo = { id: "", applyOrGroup: [], type: "", column: [] };
QueryValidator.validateQuery(query, validateInfo);
const id = validateInfo.id;
await QueryValidator.validateKind(id, validateInfo.type as InsightDatasetKind);
let dataset: InsightResult[] = [];
if (this.insightFacade.datasetIds.includes(id) && this.insightFacade.datasets.has(id)) {
dataset = this.insightFacade.datasets.get(id) as unknown as InsightResult[];
} else {
//can be triggered if file crashes or processQuery goes first
dataset = await new QueryPersister().persistQuery("data/" + id + ".json");
this.insightFacade.datasets.set(id, dataset as unknown as DatasetSection[] | DatasetRoom[]);
this.insightFacade.datasetIds.push(id);
}
const collector = new QueryCollector();
let resultWhere: InsightResult[] = [];
if (Object.keys(query.WHERE).length === 0) {
resultWhere = dataset;
} else {
// for (const section of dataset) {
// if (collector.collectFILTER(query.WHERE as FILTER, section)) {
// resultWhere.push(section);
// }
// }
resultWhere = dataset.filter((section) => {
return collector.collectFILTER(query.WHERE as FILTER, section);
});
}
if (query.TRANSFORMATIONS) {
resultWhere = collector.collectTRANSFORMATIONS(query.TRANSFORMATIONS, resultWhere);
}
QueryValidator.validateSize(resultWhere.length);
let resultOptions: InsightResult[] = resultWhere.map((res) =>
collector.collectCOLUMNS(query.OPTIONS.COLUMNS as Key[], res)
);
if (query.OPTIONS.ORDER) {
resultOptions = collector.collectORDER(query.OPTIONS.ORDER, resultOptions);
}
return resultOptions;
}
}