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