如何跟踪刚刚添加到数据库中的内容的实体ID?

时间:2015-03-05 01:06:14

标签: clojure datomic

在html-post页面上,用户可以输入各种字段并点击提交,

我的router.clj代码看起来像

 (POST "/postGO" [ post-title post-input post-tags :as request ]
    (def email (get-in request [:session :ze-auth-email]))
      ;; connect to datomic and write in the request
    (dbm/add-ze-post post-title post-input post-tags email) ;; db insert

    {:status 200, 
     :body "successfully added the post to the database", 
     :headers {"Content-Type" "text/plain"}}) ;;generic return page

效果很好,但我希望之后将用户重定向到可以向他们显示上传帖子的页面。要做到这一点,让实体的eid进行交易会非常有帮助。

;; code from my dbm file for playing directly with the database
;; id est: the db transact code
(defn add-ze-blurb [title, content, tags, useremail]
  (d/transact conn [{:db/id (d/tempid :db.part/user),
                     :post/title title,
                     :post/content content,
                     :post/tag tags,
                     :author/email useremail}]))

一旦成功地将某些内容添加到数据库中,有没有办法让datomic返回eid,或者我应该在之后使用另一个查询来确保它在那里?

1 个答案:

答案 0 :(得分:3)

对于简单的情况,只需解释d/transact返回的未来并使用:tx-data。完整的例子:

(require '[datomic.api :refer [db q] :as d])
(def uri "datomic:mem://test")
(d/create-database uri)

(def conn (d/connect uri))
(def schema [{:db/id (d/tempid :db.part/db)
              :db/ident :foo
              :db/valueType :db.type/string
              :db/cardinality :db.cardinality/one
              :db.install/_attribute :db.part/db}])
@(d/transact conn schema)

(def tempid (d/tempid :db.part/user))
(def tx [{:db/id tempid :foo "bar"}])
(def result @(d/transact conn tx)) ;; 
(def eid (:e (second (:tx-data result))))
(assert (= "bar" (:foo (d/entity (db conn) eid))))

您也可以使用d/resolve-tempid

(def eid (d/resolve-tempid (db conn) (:tempids result) tempid))
(assert (= "bar" (:foo (d/entity (db conn) eid))))

Datomic documentation中所述,在deref之后,事务将由交易者应用,并且返回的数据反映了数据库的新值。