CourseInsights / src / queryProcessor / QueryProcessor.ts
QueryProcessor.ts
Raw
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;
	}
}