CourseInsights / src / queryProcessor / QueryValidatorTransformations.ts
QueryValidatorTransformations.ts
Raw
import { InsightError } from "../controller/IInsightFacade";
import { ValidatorInfo } from "./QueryProcessor";
import QueryValidator from "./QueryValidator";

export default class QueryValidatorTransformations {
	private static tokens: string[] = ["SUM", "AVG", "MAX", "MIN", "COUNT"];

	public static validateTransformations(transformations: any, validateInfo: ValidatorInfo): boolean {
		if (transformations === null) {
			throw new InsightError("Transformations is null!");
		}
		if ("GROUP" in transformations && "APPLY" in transformations && Object.keys(transformations).length === 2) {
			this.validateGroup(transformations.GROUP, validateInfo);
			this.validateApply(transformations.APPLY, validateInfo);
			return true;
		}
		throw new InsightError("Transformations is not an object or has extra/missing keys");
	}

	public static validateGroup(group: any, validateInfo: ValidatorInfo): boolean {
		if (Array.isArray(group) && group.length > 0) {
			group.forEach((key: any) => {
				QueryValidator.validateKey(key, validateInfo);
				validateInfo.applyOrGroup.push(key);
			});
			return true;
		}
		throw new InsightError("Groups is not array or is empty");
	}

	public static validateApply(apply: any, validateInfo: ValidatorInfo): boolean {
		if (Array.isArray(apply)) {
			apply.forEach((applyrule) => {
				this.validateApplyRule(applyrule, validateInfo);
			});
			return true;
		}
		throw new InsightError("Apply is not an array");
	}

	public static validateApplyRule(applyrule: any, validateInfo: ValidatorInfo): boolean {
		if (applyrule === null) {
			throw new InsightError("Apply rule is null");
		}
		if (Object.keys(applyrule).length === 1) {
			const applykey: string = Object.keys(applyrule)[0];
			if (applykey.includes("_") || applykey.length === 0) {
				throw new InsightError("Invalid apply key");
			}
			if (validateInfo.applyOrGroup.includes(applykey)) {
				throw new InsightError("Duplicate apply key");
			}
			const obj = applyrule[applykey];
			if (Object.keys(obj).length === 1) {
				const token: string = Object.keys(obj)[0];
				if (this.tokens.includes(token)) {
					if (token === "COUNT") {
						QueryValidator.validateKey(obj[token], validateInfo);
					} else {
						QueryValidator.validateMKey(obj[token], validateInfo);
					}
					validateInfo.applyOrGroup.push(applykey);
					return true;
				}
				throw new InsightError("Invalid token in apply rule");
			}
			throw new InsightError("Object in apply rule doesnt have 1 key");
		}
		throw new InsightError("Apply rule is not an object with 1 key");
	}
}