Skip to content

Commit

Permalink
Add support for do/raw-txn (#22)
Browse files Browse the repository at this point in the history
* Add support for do/raw-txn

Enable users of the save and delete middlewares to add to the generated
transactions by adding a list of transaction data under the key do/raw-txn into Pathom env.

Also switched to the latest com.datomic/local and got rid of thus unnecessary `dev-local-tu`

(Updating to com.datomic/peer is blocked by datomock)
  • Loading branch information
holyjak authored Aug 21, 2023
1 parent 3b02be6 commit ba55ebd
Show file tree
Hide file tree
Showing 9 changed files with 79 additions and 35 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
tests:
@echo "This will fail if you have not installed Cloud dev-local and on-prem creds in your :mvn/repos and maven settings.xml manually. See Datomic Documentation."
@echo "This will fail if you have not installed on-prem creds in your :mvn/repos and maven settings.xml manually. See Datomic Documentation."
clojure -A:test -J-Dguardrails.config=guardrails-test.edn -J-Dguardrails.enabled

dev:
Expand Down
10 changes: 6 additions & 4 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ image:https://img.shields.io/clojars/v/com.fulcrologic/fulcro-rad-datomic.svg[li

This is a plugin for Fulcro RAD that adds support for using Datomic databases as the back-end technology.

NOTE: The current version supports on-prem Datomic Pro (PostgreSQL, MySQL, or Microsoft SQL Server backends), Datomic Free, or Mem stores, as well as Datomic Cloud. Make sure
NOTE: The current version supports on-prem Datomic Pro (PostgreSQL, MySQL, or Microsoft SQL Server backends), Datomic Cloud, and Datomic-Local, as well as the nowadays deprecated Datomic Free.

Make sure
you do not accidentally get Datomic Free and Datomic Pro BOTH on the CLASSPATH. If you're using deps you should make
sure you use something like:

Expand Down Expand Up @@ -115,7 +117,7 @@ TODO: Write the validator, and document it.
== Databases

It is up to you to configure, create, migrate, and manage your database infrastructure; however,
this plugin comes with various ustilities that can help you set up and manage the runtime
this plugin comes with various utilities that can help you set up and manage the runtime
environment. You *must* follow certain conventions for things to work at all, and *may choose* to
opt into various features that make it easy to get started and evolve your system.

Expand Down Expand Up @@ -149,7 +151,7 @@ in the context of the current request.
`::datomic/databases` - A map, keyed by schema, of the most recent database value that
should be used in the context of the current request (for consistent reads across multiple resolvers).

TODO: Supply helper funtions that can help with this
TODO: Supply helper functions that can help with this

== Indexed Access (Version 1.3.1+)

Expand Down Expand Up @@ -204,7 +206,7 @@ A typical test might look like the following:
NOTE: The connection is memoized based on the schema key (not any supplied migration data). You
can use `(datomic/reset-test-schema k)` to forget the current memoized version.

For Datomic Cloud, the current recommendation is to use the https://github.com/ComputeSoftware/dev-local-tu[dev-local-tu] library.
For Datomic Cloud, the current recommendation is to use the `com.datomic/local` with the `:mem` storage.
See the https://github.com/fulcrologic/fulcro-rad-demo[fulcrologic/fulcro-rad-demo] for an example.

== Resolver Generation
Expand Down
7 changes: 4 additions & 3 deletions deps.edn
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@
com.wsscode/pathom3 {:mvn/version "2022.04.20-alpha"}
org.clojure/test.check {:mvn/version "1.1.1"}
lambdaisland/kaocha {:mvn/version "1.69.1069"}
dev-local-tu/dev-local-tu {:mvn/version "0.2.2"}
com.datomic/dev-local {:mvn/version "1.0.243"}
com.datomic/client-cloud {:mvn/version "1.0.120"}
com.datomic/local {:mvn/version "1.0.267"}
com.datomic/client-cloud {:mvn/version "1.0.123"}
;; com.datomic/peer {:mvn/version "1.0.6735" ; TODO use when datamock > 0.2.2 is out
;; :exclusions [org.slf4j/slf4j-nop]}
com.datomic/datomic-pro {:mvn/version "1.0.6165"
:exclusions [org.slf4j/slf4j-nop]}}}

Expand Down
5 changes: 3 additions & 2 deletions src/main/com/fulcrologic/rad/database_adapters/datomic.clj
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,13 @@
"Delete the given entity, if possible."
[{:datomic/keys [transact]
::attr/keys [key->attribute] :as env} params]
(enc/if-let [pk (ffirst params)
(enc/if-let [raw-txn (or (do/raw-txn env) [])
pk (ffirst params)
id (get params pk)
ident [pk id]
{:keys [::attr/schema]} (key->attribute pk)
connection (-> env do/connections (get schema))
txn [[:db/retractEntity ident]]]
txn (into [[:db/retractEntity ident]] raw-txn)]
(do
(log/info "Deleting" ident)
(let [database-atom (get-in env [do/databases schema])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,13 @@
to transact datoms."
[{:datomic/keys [transact]
::attr/keys [key->attribute] :as env} params]
(enc/if-let [pk (ffirst params)
(enc/if-let [raw-txn (or (do/raw-txn env) [])
pk (ffirst params)
id (get params pk)
ident [pk id]
{:keys [::attr/schema]} (key->attribute pk)
connection (-> env do/connections (get schema))
txn [[:db/retractEntity ident]]]
txn (into [[:db/retractEntity ident]] raw-txn)]
(do
(log/info "Deleting" ident)
(let [database-atom (get-in env [do/databases schema])
Expand Down
12 changes: 10 additions & 2 deletions src/main/com/fulcrologic/rad/database_adapters/datomic_common.clj
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,8 @@
(>defn delta->txn
[{::attr/keys [key->attribute] :as env} target-schema delta]
[map? keyword? map? => map?]
(let [tempid->txid (tempid->intermediate-id env delta)
(let [raw-txn (do/raw-txn env)
tempid->txid (tempid->intermediate-id env delta)
tempid->generated-id (tempids->generated-ids env delta)
non-native-id-attributes-txn (keep
(fn [[k id :as ident]]
Expand All @@ -268,7 +269,8 @@
(concat
non-native-id-attributes-txn
(to-one-txn env target-schema delta)
(to-many-txn env target-schema delta)))}))
(to-many-txn env target-schema delta)
raw-txn))}))

(defn- attribute-schema [attributes]
(mapv
Expand Down Expand Up @@ -654,3 +656,9 @@
:components [qualified-key rad-id-value]})
first
:e))))

(defn append-to-raw-txn
"Append raw transaction forms `txn` to `do/raw-txn` in the middleware environment.
To be used by middlewares wrapping the default delete/save middleware."
[mw-env txn]
(update mw-env do/raw-txn (fnil into []) txn))
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
:com.fulcrologic.rad.database-adapters.datomic/connections)

(def databases
"If using the datomic pathom-plugin, the resulting pathm-env will contain
"If using the datomic pathom-plugin, the resulting pathom-env will contain
a map from schema->database at this key path"
:com.fulcrologic.rad.database-adapters.datomic/databases)

Expand All @@ -30,3 +30,22 @@
This only affects Datomic autogenerated resolvers."
:com.fulcrologic.rad.database-adapters.datomic/wrap-resolve)

(def raw-txn
"Middleware enviroment key. A sequence of Datomic transaction data in the list and/or map form, which will be added to the
transaction data produced by the currently active (save or delete) middleware.
You can use this to ensure pre- and post-condition, enrich the transactions, etc.
See also `datomic-common/append-to-raw-txn`.
Ex.:
```clj
(let [user ..., order ..., ident ...]
(cond-> middleware-env
(first-order-campaign? order)
(datomic-common/append-to-raw-txn
[(list 'my.txn.fns/ensure-no-prior-order user) ; check pre-condition
{:db/id \"datomic.tx\" :tx/user (:email user)} ; enrich transaction info
{:db/id (datomic-common/failsafe-id env ident) :db/ensure :order/valid-new-order}]))) ; check post-condition
```"
:com.fulcrologic.rad.database-adapters.datomic/raw-txn)
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
[com.fulcrologic.rad.test-schema.person :as person]
[com.fulcrologic.rad.test-schema.thing :as thing]
[datomic.client.api :as d]
[dev-local-tu.core :as dev-local-tu]
[fulcro-spec.core :refer [specification assertions component behavior when-mocking]]
[taoensso.timbre :as log]))

Expand All @@ -35,16 +34,22 @@
(def ^:dynamic *env* {})

(defn with-env [tests]
(with-open [db-env (dev-local-tu/test-env)]
(let [config {:datomic/env :test
:datomic/schema :production
:datomic/database (str (gensym "test-database"))
:datomic/test-client (:client db-env)}
conn (datomic/start-database! all-attributes config {})]
(binding [*conn* conn
*env* {::attr/key->attribute key->attribute
do/connections {:production conn}}]
(tests)))))
(let [dbname (str (gensym "test-database"))
client (d/client {:server-type :datomic-local
:system (str (ids/new-uuid))
:storage-dir :mem})]
(try
(let [config {:datomic/env :test
:datomic/schema :production
:datomic/database dbname
:datomic/test-client client}
conn (datomic/start-database! all-attributes config {})]
(binding [*conn* conn
*env* {::attr/key->attribute key->attribute
do/connections {:production conn}}]
(tests)))
(finally
(d/delete-database client {:db-name dbname})))))

(use-fixtures :each with-env)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
[com.fulcrologic.rad.database-adapters.datomic-cloud :as datomic]
[com.fulcrologic.rad.database-adapters.datomic-options :as do]
[com.fulcrologic.rad.database-adapters.indexed-access-checks :as checks :refer [run-checks]]
[com.fulcrologic.rad.ids :as ids]
[com.fulcrologic.rad.type-support.date-time :as dt]
[dev-local-tu.core :as dev-local-tu]
[datomic.client.api :as d]
[fulcro-spec.core :refer [specification]]))

(use-fixtures :once
Expand All @@ -24,12 +25,18 @@
(run-checks (assoc
datomic/datomic-api
:generate-resolvers datomic/generate-resolvers
:make-connection (fn [& args]
(with-open [db-env (dev-local-tu/test-env)]
(let [config {:datomic/env :test
:datomic/schema :main
:datomic/database (str (gensym "test-database"))
:datomic/test-client (:client db-env)}
conn (datomic/start-database! schema-attributes config {})]
conn))))))
:make-connection (fn [& _args]
(let [dbname (str (gensym "test-database"))
client (d/client {:server-type :datomic-local
:system (str (ids/new-uuid))
:storage-dir :mem})]
(try
(let [config {:datomic/env :test
:datomic/schema :main
:datomic/database dbname
:datomic/test-client client}
conn (datomic/start-database! schema-attributes config {})]
conn)
(finally
(d/delete-database client {:db-name dbname}))))))))

0 comments on commit ba55ebd

Please sign in to comment.