where절을 만드는 함수를 하드코딩 없이 개선해보자
하드코딩이 확장성을 저해한다는 리뷰를 받아서 다시 생각해보기로 했다..
컬럼명을 하드코딩하는 것을 가리키는 것 같은데 컬러명을 변수명 그대로 받아내는 방법이 필요할 것 같다
let gender = ["male", "female"]
let scent = ["citrus", "fruity"]
// value값이 존재하면 "column IN (value)"를 반환하는 함수
const query = (column, value) => {
if(!value){
return "";
}
return `${column} IN ("${value.join("\", \"")}")`;
}
let queryCondition = [query("sc.name", scent), query("g.name", gender)].filter(el => el !== "");
// 배열queryCondition의 요소가 존재하면 "WHERE 요소 AND 요소"를 반환하는 함수
const where = (queryCondition) => {
if(queryCondition.length === 0){
return "";
}
let query = "WHERE "
for(let i=0; i<queryCondition.length; i++){
query += `${queryCondition[i]}`
if(i === queryCondition.length-1 ){
return query;
}
query += ` AND `
}
}
console.log( where(queryCondition) )
const where = (gender, scent) => {
if(!gender && !scent){
return "";
}else if(!gender){
return `WHERE sc.name IN ("${scent.join("\", \"")}")`
}else if(!scent){
return `WHERE g.name IN ("${gender.join("\", \"")}")`
}else{
return `WHERE sc.name IN ("${scent.join("\",\"")}") AND g.name IN ("${gender.join("\", \"")}")`
}
}
let whereQuery = where(gender, scent)
console.log(whereQuery)
const where = (gender, scent) => {
if(!gender && !scent) return "";
if(!gender)return `WHERE sc.name IN ('${scent.join("\', \'")}')`
if(!scent) return `WHERE g.name IN ('${gender.join("\', \'")}')`
return `WHERE sc.name IN ('${scent.join("\', \'")}') AND g.name IN ('${gender.join("\', \'")}')`
}
const getProducts = async (gender, scent, orderBy, offset, limitNum) => {
const params ={gender, scent};
const scentFilterBuilder = (value) => {
if(!value)return "";
return `sc.name IN ('${ value.join("\', \'") }')`;
};
const genderFilterBuilder = (value) => {
if(!value)return "";
return `g.name IN ('${ value.join("\', \'") }')`;
};
const makeProductQueryBuilders = (params) => {
const builderSet = {
"gender": genderFilterBuilder,
"scent": scentFilterBuilder,
};
let whereClauses = Object.entries(params).map( ([key, value]) => builderSet[key](value) );
whereClauses = whereClauses.filter(el => el !== '')
return `WHERE ${whereClauses.join(' AND ')}`;
};
const orderByQuery = (orderBySelected) => {
if(!orderBySelected){ return "";}
return `ORDER BY ${orderBySelected}`;
}
const limitQuery = (limitNumSelected, offsetSelected) => {
if(!limitNumSelected){ return "";}
return `LIMIT ${limitNumSelected} ${offsetQuery(offsetSelected)}`;
}
const offsetQuery = (offsetSelected) => {
if(!offsetSelected){ return "";}
return `OFFSET ${offsetSelected}`;
}
let whereClause = makeProductQueryBuilders(params)
let orderByClause = orderByQuery(orderBy);
let limitClause = limitQuery(limitNum, offset);
return await productDao.getProducts(whereClause, orderByClause, limitClause);
};