Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
frinj unit conversion running inside a Datomic datalog query
;; lein settings
(defproject foo "1.0.0-SNAPSHOT"
:description "Test App"
:dependencies [[com.datomic/datomic "0.1.2678"]
[frinj "0.1.2" :exclusions [org.clojure/clojure]]])
;; load libs
(use 'frinj.core 'frinj.calc)
(frinj-init!)
(use '[datomic.api :only (q db) :as d])
;; get an in-memory db
(def uri "datomic:mem://roster")
(d/create-database uri)
(def conn (d/connect uri))
;; teach Datomic that attributes can have units
(d/transact conn [{:db/id (d/tempid :db.part/db)
:db/ident :units
:db/valueType :db.type/keyword
:db/cardinality :db.cardinality/one
:db.install/_attribute :db.part/db}])
;; add schema types, some bearing units
(d/transact conn [{:db/id (d/tempid :db.part/db)
:db/ident :name
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one
:db.install/_attribute :db.part/db}
{:db/id (d/tempid :db.part/db)
:db/ident :weight
:db/valueType :db.type/long
:units :pounds
:db/cardinality :db.cardinality/one
:db.install/_attribute :db.part/db}
{:db/id (d/tempid :db.part/db)
:db/ident :height
:units :inches
:db/valueType :db.type/long
:db/cardinality :db.cardinality/one
:db.install/_attribute :db.part/db}])
;; add a few values
(d/transact conn [{:db/id (d/tempid :db.part/user)
:name "Cole Aldrich"
:height 83
:weight 245}
{:db/id (d/tempid :db.part/user)
:name "Kevin Durant"
:height 81
:weight 215}])
;; adapter between frinj and query
(defn convert
[& items]
(-> (apply fj items) :v double))
;; Find players, converting height/weight from database rep
;; to units requested.
(defn roster
[height-units weight-units]
(q '[:find ?name ?m ?kg
:in $ ?to-h ?to-w
:where
[?e :name ?name]
[?e :height ?height]
[:height :units ?from-h]
[?e :weight ?weight]
[:weight :units ?from-w]
[(user/convert ?height ?from-h :to ?to-h) ?m]
[(user/convert ?weight ?from-w :to ?to-w) ?kg]]
(db conn)
height-units
weight-units))
;; get roster with some different units
(roster :meters :kilograms)
(roster :yards :stone)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment