Обработка нулевых параметров с помощью 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! Функция имеет аналогичную функциональность.

Другие вопросы по тегам