Заставить функции запроса hugsql выдавать ошибку, когда они возвращают неверное количество результатов

Использование Clojure и hugsql. Я определяю свои запросы как таковые.

-- :name query-should-return-one-but-returns-multiple
-- :result one
-- :command :query
SELECT v.id FROM some_table v;

После использования def-db-fns, это создаст функцию query-should-return-one-but-returns-multiple в моем пространстве имен.

Тем не менее, если у меня есть несколько строк в some_table, эта функция просто вернет произвольную строку и не сообщит об ошибке.

Как я могу заставить функции запроса, определенные для возврата :one бросить исключение, если база данных вернула более одного результата?

1 ответ

Решение

-- :result :one просто берет первую строку возвращенного набора результатов вашего запроса, поэтому нет подтверждения, что ваш запрос возвращает ровно 1 запись (hashmap).

Однако HugSQL использует мультиметоды Clojure для определения типов результатов, так что вы можете создавать свои собственные или переопределять существующие методы в соответствии с вашими потребностями.

Мы определяем функцию result-exactly-one это вызовет исключение, когда счетчик результата не один. Затем мы определяем hugsql-result-fn мультиметод с :exactly-one ключевое слово. Обратите внимание на цитируемое пространство имен (user в данном случае) символ, относящийся к функции, которую мы создали.

(require '[hugsql.core :as hugsql]
         '[hugsql.adapter])

(defn result-exactly-one
  [this result options]
  (let [rs (hugsql.adapter/result-many this result options)]
    (if (= 1 (count rs)) 
        rs 
        (throw (ex-info "Oops!" {})))))

(defmethod hugsql/hugsql-result-fn :exactly-one [sym] 'user/result-exactly-one)
-- :name return-exactly-one
-- :result :exactly-one
-- :command :query
SELECT v.id FROM t1 v;

И результат, когда возвращается 0 или более записей:

user=> (return-exactly-one db)

ExceptionInfo Oops!  clojure.core/ex-info (core.clj:4617)
Другие вопросы по тегам