Skip to content

Commit

Permalink
mutation: support running multiple queries
Browse files Browse the repository at this point in the history
  • Loading branch information
pyr committed Sep 14, 2023
1 parent 802e251 commit 54579ca
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 6 deletions.
18 changes: 12 additions & 6 deletions src/seql/mutation.clj
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@
:pre (dissoc pre :valid? :query)}))))))
pre)))

(defn- wrap-statements
"Transform returned statement value into a vector, allowing handlers to return
multiple statements"
[x]
(if (vector? x) x [x]))

(defn mutate!
"Perform a mutation. Since mutations are spec'd, parameters are
expected to conform it."
Expand All @@ -56,15 +62,15 @@
:code 400
:explain (s/explain-str spec params)})))
(let [cparams (c/write-map params)
statement (-> cparams
(assoc ::schema (env/schema env))
(assoc ::metadata metadata)
handler
sql/format)
statements (map sql/format (-> cparams
(assoc ::schema (env/schema env))
(assoc ::metadata metadata)
handler
wrap-statements))
result (jdbc/with-transaction [tx (env/jdbc env)]
;; if we have preconditions check these first
(run-preconditions! tx mutation (dissoc cparams ::schema ::metadata) pre)
(jdbc/execute! tx statement))]
(last (map #(jdbc/execute! tx %) statements)))]
(when-not (success-result? result)
(throw (ex-info (format "the mutation has failed: %s" mutation)
{:type :error/mutation-failed
Expand Down
52 changes: 52 additions & 0 deletions test/seql/multi_query_integration_test.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
(ns seql.multi-query-integration-test
(:require [seql.mutation :refer [mutate!]]
[clojure.spec.alpha :as s]
[seql.env :as env]
[seql.query :as q]
[seql.helpers :refer [make-schema entity-from-spec mutation-fn]]
[db.fixtures :refer [jdbc-config with-db-fixtures]]
[clojure.test :refer [use-fixtures testing deftest is]]))

(use-fixtures :each (with-db-fixtures :small))

(create-ns 'my.entities)
(create-ns 'my.entities.account)
(alias 'account 'my.entities.account)

(s/def ::account/name string?)
(s/def ::account/id nat-int?)
(s/def ::account/state #{:active :suspended :terminated})
(s/def ::account/account (s/keys :req [::account/name ::account/state]))
(s/def ::account/create ::account/account)

(def schema
"As gradually explained in the project's README"
(make-schema
(entity-from-spec ::account/account
(mutation-fn ::account/delete-two any?
(constantly
[{:delete-from :account :where [:= :id 1]}
{:delete-from :account :where [:= :id 2]}]))
(mutation-fn ::account/add-two any?
(constantly
[{:insert-into :account
:columns [:id :name :state]
:values [[1 "hello" "active"]]}
{:insert-into :account
:columns [:id :name :state]
:values [[2 "bye" "suspended"]]}])))))

(def env
(env/make-env jdbc-config schema))

(deftest multi-query-test
(testing "adding two new accounts via a multi query mutation"
(mutate! env ::account/add-two {}))

(testing "retrieving newly created account by name"
(let [{::account/keys [state]} (q/execute env [::account/name "hello"])]
(is (= state :active)))
(let [{::account/keys [state]} (q/execute env [::account/name "bye"])]
(is (= state :suspended))))

(mutate! env ::account/delete-two {}))

0 comments on commit 54579ca

Please sign in to comment.