这几个函数能增加一点数据库结构的可读性,简单地省掉一些键盘时间:
;; ==============================================
;; 方便性的处理函数。对于每个 datomic 程序都有用!
(defn assoc-when [m k v]
(if v (assoc m k v) m))
(defn attr
"用缩略形式创建 schema 中的属性:
每个属性必须有 ident 名称, type 类型和 doc 文档.
可选用 :cardinality 指定数量以及 :unique 指定唯一性"
[ident type doc
& {:keys [cardinality unique]
:or {cardinality :db.cardinality/one
unique nil}}]
(-> {:db/ident ident
:db/valueType type
:db/doc doc
:db/cardinality cardinality
:db.install/_attribute :db.part/db}
(assoc-when :db/unique unique)))
(defn entities
"给一组实体 ents 在 part 这个数据库分区中顺序生成临时 id"
[part ents]
(map #(assoc %1 :db/id (d/tempid part %2)) ents (iterate dec -1)))
(defn ensure-db
"在 uri 上建立一个数据库, 它的结构为 schema, 如果有种子数据 seed-data,
也记入数据库."
[uri schema & [seed-data]]
(d/create-database uri)
(when-let [conn (d/connect uri)]
(d/transact conn db-schema)
(when seed-data
(d/transact conn seed-data))))
下面这个数据库函数是传统的数据库上必不可少的:
(def seq-id
"Transaction 函数. 给 eid 实体构造的 id-field 设置一个顺序的 id. 相当于传统数据库的
sequence 或者自动增长功能.
要求在数据的种子数据中建立一个实体有 :db/ident (函数中用 next-id 指定),
这个实体有属性 next-value 来存储当前的最后 id 值."
(d/function {:lang "clojure"
:params '[db next-id next-value eid id-field]
:code '(let [val (inc (get (d/entity db next-id) next-value 0))]
[{:db/id next-id next-value val}
{:db/id eid id-field val}])}))
使用例子
(def db-schema
"数据库结构"
(entities
:db.part/db
[(attr :user/name :db.type/string "用户名" :unique :db.unique/identity)
(attr :product/id :db.type/string "产品号" :unique :db.unique/identity)
(attr :product/cashValue :db.type/long "产品的人民币价值(分)")
(attr :order/id :db.type/long "订单号" :unique :db.unique/identity)
(attr :order/user :db.type/ref "下订单的用户")
(attr :order/product :db.type/ref "订单所关联的产品")
(attr :order/quantity :db.type/long "产品数量")
(attr :orderId/value :db.type/long "顺序中下一个订单")]))
(def seed-data
"种子数据"
(entities
:db.part/user
[{:db/ident :orderId/next :orderId/value 10000}
{:db/ident :nextId
:db/doc (-> #'seq-id meta :doc)
:db/fn seq-id}]))
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。