Как создать функцию динамического запроса в модуле nodejs pg?
Например:
const update = ({title, price, imageUrl, description, whereId, whereTitle }) => {
return db.query(
`UPDATE products
SET title=$1,
price=$2,
"imageUrl"=$3,
description=$4
WHERE
id=$5,
title ILIKE '%$6%'
`,
[title, price, imageUrl, description, whereId, whereTitle],
)
}
update({
whereId: 1,
title: 'Aliens 2: Electric Boogaloo',
description: 'Best sequel ever',
})
// shall execute this query:
// UPDATE products SET title='Aliens 2: Electric Boogaloo', description'Best sequel ever' WHERE id=1
// and keeping the price, "imageUrl" untouched / previous value
update({
whereTitle: 'godfather',
price: 20,
})
// shall execute this query:
// UPDATE products SET price=20 WHERE title ILIKE '%godfather%'
// or set the price of every products that contain the word 'godfather' as $20
// and keeping the title, "imageUrl", description, id untouched / previous value
Прямо сейчас мне нужно создать запрос для каждого возможного запроса
УСТАНОВИТЬ заголовок ГДЕ id
УСТАНОВИТЬ название, цену ГДЕ id
УСТАНОВИТЕ цену, "imageUrl" ГДЕ название
...
Это не очень сухой, поэтому я думаю, что должен быть лучший способ сделать это
Изменить 1:
Вот так, я предполагаю, будет выглядеть код.
db.query(
`UPDATE products
SET
title !== null? "title=$1," : skipToNextLine()
price !== null? "price=$2," : skipToNextLine()
"imageUrl" !== null? "\"imageUrl\"=$3," : skipToNextLine()
description !== null? "description=$4" : skipToNextLine()
whereId !== null && whereTitle !== null? "WHERE" : skipToNextLine()
whereId !== null? "id=$5," : skipToNextLine()
whereTitle !== null? "title ILIKE '%$6%'" : skipToNextLine()
`,
[title, price, imageUrl, description, whereId, whereTitle],
)
Я делаю это в стиле троичного выражения, но есть много других стилей. Я думаю, что идея похожа на язык шаблонов html, такой как pug.js, ejs, handlebars и т. Д. Должен быть другой способ, кроме написания десятков статических html-файлов для вашего html.
Изменить 2:
Я использовал конкатенацию строк для быстрого и грязного решения, но мне интересно, уязвимо ли оно для SQL-инъекции. Код также становится очень длинным, а надежность / простота понимания кода значительно снижается.
Вот мое текущее решение:
const update = ({
title,
price,
imageUrl,
description,
whereId,
whereTitle,
}) => {
let queryText = 'UPDATE products SET'
let queryValue = []
let dollarCounter = 1
if (!!title) {
queryText = queryText.concat(` title=$${dollarCounter},`)
queryValue.push(title)
dollarCounter++
}
if (!!price) {
queryText = queryText.concat(` price=$${dollarCounter},`)
queryValue.push(price)
dollarCounter++
}
if (!!imageUrl) {
queryText = queryText.concat(` "imageUrl"=$${dollarCounter},`)
queryValue.push(imageUrl)
dollarCounter++
}
if (!!description) {
queryText = queryText.concat(` description=$${dollarCounter},`)
queryValue.push(description)
dollarCounter++
}
queryText = queryText.slice(0, -1)
if (!!whereId || !!whereTitle) queryText = queryText.concat(' WHERE')
if (!!whereId) {
queryText = queryText.concat(` id=$${dollarCounter},`)
queryValue.push(whereId)
dollarCounter++
}
if (!!whereTitle) {
queryText = queryText.concat(` title ILIKE '%$${dollarCounter}%',`)
queryValue.push(whereTitle)
dollarCounter++
}
queryText = queryText.slice(0, -1)
const query = {
name: 'update',
text: queryText,
values: queryValue,
}
return db.query(query)
}