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!"); } }