Поля ОБНОВЛЕНИЯ по условию с интерполяцией Slick String
У меня два Option
s:
val name: Option[String] = ...
val shared: Option[Boolean] = ...
Я хотел бы построить UPDATE
запросить это SET
s эти поля, если вышеуказанные значения Some
, но оставляет их без изменений, если они None
,
Мне удалось добиться этого примерно так, но я не очень заинтересован в проверке запятой, которая не будет масштабироваться, если мне нужно будет добавить дополнительные столбцы. Я также не очень хочу использовать var
,
var query = Q.u + "UPDATE wishlist SET"
if(name.isDefined) query = query + " name = " +? name + (if (share.isDefined) ", " else "")
if(shared.isDefined) query = query + " shared = " +? share
Если бы я не занимался внедрением SQL, я мог бы сделать что-то вроде:
val fields = List(
name.map(n => s"name = '$n'"),
shared.map(e => s"shared = $e")
).flatten
s"UPDATE wishlist SET ${fields.mkString(", ")}"
Вопрос: есть ли лучший способ сделать это с простой интерполяцией SQL/String в Slick, или я могу только перейти к встроенному встраиваемому?
1 ответ
Это не супер элегантно, но я думаю, что по крайней мере оно гибкое в том смысле, что оно будет расширяться для поддержки множества входных данных без изменения базовой логики:
val name:Option[String] = Some("foo")
val share:Option[String] = Some("bar")
val sets = List(
name.map(n => (" name = ", n)),
share.map(s => (" shared = ", s))
).flatten
val query2 = sets.zipWithIndex.foldLeft(Q.u + "UPDATE wishlist SET"){
case (q,(p,0)) => q + p._1 +? p._2
case (q,(p,i)) => q + "," + p._1 +? p._2
}
Я помещаю пары полей и значений в список в качестве параметров для Tuple
S, а затем выравнивание, чтобы удалить None
s. Затем я сворачиваюсь, чтобы получить окончательное утверждение, принимая во внимание, что любой фрагмент запроса после первого будет нуждаться в запятой.