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

export default class QueryValidatorWhere {
	constructor() {}

	public static validateQueryWhere(where: any, validateInfo: ValidatorInfo): boolean {
		if (where === null) {
			throw new InsightError("WHERE is null!");
		}
		if (!Array.isArray(where) && Object.keys(where).length === 0 && typeof where === "object") {
			return true;
		}
		if (Object.keys(where).length === 1) {
			this.validateFilter(where, validateInfo);
			return true;
		}
		throw new InsightError("WHERE is wrong!");
	}

	public static validateFilter(filter: any, validateInfo: ValidatorInfo): boolean {
		if (filter !== null && Object.keys(filter).length === 1) {
			if ("AND" in filter || "OR" in filter) {
				const logic = "AND" in filter ? filter.AND : filter.OR;
				this.validateLogicComparator(logic, validateInfo);
				return true;
			} else if ("GT" in filter || "LT" in filter || "EQ" in filter) {
				const mcomp = "GT" in filter ? filter.GT : "LT" in filter ? filter.LT : filter.EQ;
				this.validateMComparison(mcomp, validateInfo);
				return true;
			} else if ("NOT" in filter) {
				this.validateNegation(filter.NOT, validateInfo);
				return true;
			} else if ("IS" in filter) {
				this.validateSComparison(filter.IS, validateInfo);
				return true;
			}
		}
		throw new InsightError("A filter is wrong!");
	}

	public static validateLogicComparator(logic: any, validateInfo: ValidatorInfo): boolean {
		if (Array.isArray(logic) && logic.length > 0) {
			logic.forEach((filter) => {
				this.validateFilter(filter, validateInfo);
			});
			return true;
		}
		throw new InsightError("empty and or empty or!");
	}

	public static validateNegation(not: any, validateInfo: ValidatorInfo): boolean {
		this.validateFilter(not, validateInfo);
		return true;
	}

	public static validateMComparison(mcomp: any, validateInfo: ValidatorInfo): boolean {
		if (Object.keys(mcomp).length === 1) {
			const mkey: string = Object.keys(mcomp)[0];
			QueryValidator.validateMKey(mkey, validateInfo);
			const value = mcomp[mkey];
			if (typeof value === "number") {
				return true;
			}
		}
		throw new InsightError("MComparison has extra fields!");
	}

	public static validateSComparison(scomp: any, validateInfo: ValidatorInfo): boolean {
		if (Object.keys(scomp).length === 1) {
			const skey = Object.keys(scomp)[0];
			QueryValidator.validateSKey(skey, validateInfo);
			const input = scomp[skey];
			if (typeof input !== "string" || (input.length > 2 && input.substring(1, input.length - 1).includes("*"))) {
				throw new InsightError("Wrong input string!");
			}
			return true;
		}
		throw new InsightError("MComparison has extra fields!");
	}
}