Last active
March 16, 2018 06:53
-
-
Save wvdlaan/5772825 to your computer and use it in GitHub Desktop.
Datomic multiple attribute key example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns myupsert.core | |
(require [datomic.api :as d])) | |
(def schema | |
[ | |
{:db/id #db/id [:db.part/db] | |
:db/ident :product/name | |
:db/valueType :db.type/string | |
:db/cardinality :db.cardinality/one | |
:db.install/_attribute :db.part/db} | |
{:db/id #db/id [:db.part/db] | |
:db/ident :product/version | |
:db/valueType :db.type/string | |
:db/cardinality :db.cardinality/one | |
:db.install/_attribute :db.part/db} | |
{:db/id #db/id [:db.part/db] | |
:db/ident :product/price | |
:db/valueType :db.type/double | |
:db/cardinality :db.cardinality/one | |
:db.install/_attribute :db.part/db} | |
{:db/id #db/id [:db.part/user] | |
:db/ident :upsertProduct | |
:db/fn #db/fn | |
{:lang :clojure | |
:params [db m] | |
:code (if-let [id (ffirst | |
(d/q '[:find ?e | |
:in $ ?n ?v | |
:where | |
[?e :product/name ?n] | |
[?e :product/version ?v]] | |
db (:product/name m) (:product/version m)))] | |
[(-> (dissoc m :product/name :product/version) | |
(assoc :db/id id))] | |
[m])}} | |
]) | |
(defn init-db [] | |
(let [uri "datomic:mem://test" | |
_ (d/create-database uri) | |
conn (d/connect uri) | |
_ (d/transact conn schema)] | |
conn)) | |
(defn get-product [name version conn] | |
(->> (d/q '[:find ?e | |
:in $ ?n ?v | |
:where [?e :product/name ?n] [?e :product/version ?v]] | |
(d/db conn) name version) | |
(map first) | |
(map #(d/entity (d/db conn) %)) | |
(map d/touch))) | |
(comment | |
(def conn (init-db)) | |
(d/transact conn [[:upsertProduct {:db/id #db/id [:db.part/user] | |
:product/name "Foo" | |
:product/version "1.1" | |
:product/price 12.34}]]) | |
(get-product "Foo" "1.1" conn) | |
(d/transact conn [[:upsertProduct {:db/id #db/id [:db.part/user] | |
:product/name "Foo" | |
:product/version "1.1" | |
:product/price 56.78}]]) | |
(get-product "Foo" "1.1" conn) | |
) |
Yes, you are right. And AFAIK this can not be solve using a transaction function.
But I can live with that. I think it's more of a logical limitation on what a transaction is supposed to be than on Datomic's feature set. I'd love to see a Gist for a utility method for breaking up transactions into multiple ones based on compound keys before I have to work it out myself, lol.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Yes, you are right. And AFAIK this can not be solve using a transaction function. This topic is discussed here: https://groups.google.com/d/msg/datomic/dhzwweFSiso/lqET7Isa6XcJ