Обработка нулевых параметров с помощью Clojure/Hugsql
Я использую Hugsql с Clojure для доступа к базе данных Postgresql. Некоторые из моих таблиц базы данных имеют необязательные столбцы - для простого примера рассмотрим таблицу "пользователи" с различными столбцами адресов - адрес1, адрес2, город и т. Д.
Когда я пишу спецификацию запроса Hugsql для "обновления", я не знаю, какие значения будут присутствовать в карте, которую я передаю. Поэтому, если я напишу запрос:
-- :name update-user! :! :n
UPDATE users set firstname = :firstname, address1 = :address1 where id = :id
но передать в пользовательскую карту
(update-user! {:id "testuser" :firstname "Bartholamew"})
тогда исключение выдается. Я ожидаю, что это создаст что-то вроде
UPDATE users SET firstname='Bartholamew', address1=NULL where id='testuser'
Я посмотрел на исходный код Hugsql - он вызывает функцию (validate-parameters), которая выдает исключение, которое я не вижу в обходной ситуации. Я уверен, что упускаю что-то очевидное: это не кажется необычным требованием, и я уверен, что не хочу писать отдельную спецификацию SQL-запроса для каждой возможной комбинации необязательных столбцов.
Есть ли способ обработать пропущенные параметры, которые я пропускаю? Я злоупотребляю базой данных, имея дополнительные столбцы?
1 ответ
Вы можете использовать выражения HugSQL Clojure для условной поддержки, включая ваш желаемый SQL, на основе параметров, предоставленных во время выполнения. Итак, вы можете написать что-то вроде этого:
-- :name update-user! :! :n
UPDATE users SET
id = id
--~ (when (contains? params :firstname) ",firstname = :firstname")
--~ (when (contains? params :address1) ",address1 = :address1")
WHERE id = :id
Обратите внимание id=id
здесь немного глупо иметь дело с запятыми. Конечно, вы можете сделать что-то более надежное и универсальное в этом примере из документации по HugSQL:
SQL:
-- :name clj-expr-generic-update :! :n
/* :require [clojure.string :as string]
[hugsql.parameters :refer [identifier-param-quote]] */
update :i:table set
/*~
(string/join ","
(for [[field _] (:updates params)]
(str (identifier-param-quote (name field) options)
" = :v:updates." (name field))))
~*/
where id = :id
Clojure:
(clj-expr-generic-update db {:table "test"
:updates {:name "X"}
:id 3})
Я также рекомендую вам посмотреть и узнать, что доступно в базовой библиотеке jdbc. Адаптер HugSQL по умолчанию - clojure.java.jdbc, и его update!
Функция имеет аналогичную функциональность.