beherbergung/backend/src/beherbergung/db/validate.clj

47 lines
1.8 KiB
Clojure

(ns beherbergung.db.validate
(:require [clojure.spec.alpha :as s]
[beherbergung.db.export :refer [all_docs write-edn]]
[clojure.pprint :refer [pprint]]
[clojure.tools.logging :refer [error]]))
(defn validate
"Validate a xtdb-document or a collection of documents.
When not conforming to the spec, an explaination is associated."
[doc]
(if (map? doc)
(when-not (:xt/fn doc)
(let [spec (:xt/spec doc)]
(when-not spec
(error ":xt/spec must not be empty!" doc))
(if (s/valid? spec doc)
doc
(assoc doc :explain (s/explain-data spec doc)))))
(map validate doc)))
(defn validate-db
"Validate the database.
The db_ctx is only returned, when all documents have been confirmed."
[db_ctx]
(let [validated-docs (validate (all_docs db_ctx))
errors (filter :explain validated-docs)
file "/tmp/validation-errors"]
(if (not-empty errors)
(do
(println "There have been validation errors in" (count errors) "database documents.")
(println "It seems that the latest update changed this specs:" (into [] (keys (group-by :xt/spec errors))))
(write-edn file errors)
(println "Details have been written to:" file))
db_ctx)))
(defn validate-tx
"Validate docs before they are written to the database."
[tx-ops]
(let [docs (->> tx-ops
(filter #(= :xtdb.api/put (first %)))
(map second))
errors (filter :explain (validate docs))]
(if (not-empty errors)
(do (println "Transaction canceled due to validiation errors:")
(pprint errors))
tx-ops)))