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