Skip to content

Instantly share code, notes, and snippets.

@jacobobryant
Last active June 12, 2020 04:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jacobobryant/deeb5b69c3ad5093eff17e86c00b3518 to your computer and use it in GitHub Desktop.
Save jacobobryant/deeb5b69c3ad5093eff17e86c00b3518 to your computer and use it in GitHub Desktop.
Biff-style txes + rules with Datomic
; Code snippet from a previous version of Findka that used Datomic + Biff-style transactions & rules.
; See trident.datomic-cloud/tx: https://github.com/jacobobryant/trident/blob/9516dcd9ac8fb48f7438e6f5a9519bc832c57d48/src/trident/datomic_cloud.clj#L87
(s/def :user.integration/goodreads-id #(or (empty? %)
(->> %
(str "https://www.goodreads.com/review/list_rss/")
http/head
u/catchall
:status
(= 200))))
(s/def :user.integration/feed-url #(or (empty? %)
(some? (u/catchall (remus/parse-url %)))))
(s/def :user/site-config (u/only-keys :opt schema/site-config-keys))
(s/def :user.profile/id #(re-matches #"[a-zA-Z0-9]*" %))
(def rules
{:item {:spec (s/nilable (u/only-keys :req [:item/url-0] :opt schema/item-keys))
:id (fn [env [_ url]]
[:item/key-1 [url (:user-eid env)]])
:user-key :item/user-0}
:user {:spec (u/only-keys :opt [:user.profile/id
:user/site-config
:user/account-level
:user/tutorial-position
:user/algorithm-mode])
:id (fn [env _]
(:user-eid env))}
:integrations {:spec (u/only-keys :opt schema/integration-keys)
:id (fn [env _]
(:user-eid env))}})
(defmethod handle :save
[{:keys [db user-eid conn firebase-app opts] :as env}]
;(sc.api/spy)
(let [tx (u/forcat [[ident ent] opts
:let [table (first ident)
{:keys [spec id user-key]} (rules table)]]
(cond
(nil? spec) [^:error {}]
(not (s/valid? spec ent)) (-> (s/explain-data spec ent)
::s/problems
first
:path
(#(hash-map :error-path %))
(with-meta {::error true})
vector)
:default (let [ent (walk/postwalk
#(if (map? %) (util/save-blob firebase-app %) %)
ent)
ent (cond-> ent
(and ent user-key) (assoc user-key user-eid))
id (id env ident)]
(tcloud/tx db ent id))))
errors (filter #(or (empty? %) (::error (meta %))) tx)
tx-result (delay (d/transact conn {:tx-data tx}))]
(merge
(first errors)
{:success? (and (empty? errors) (some? (try @tx-result
(catch Exception e
(st/print-stack-trace e)
nil))))})))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment