Created
March 5, 2012 18:56
-
-
Save stuarthalloway/1980351 to your computer and use it in GitHub Desktop.
frinj unit conversion running inside a Datomic datalog query
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; 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