Add hacky <q to DB.

This commit is contained in:
Nick Alexander 2016-07-14 17:42:31 -07:00
parent f3e1f3ae20
commit 44411f0e94
2 changed files with 46 additions and 0 deletions

View file

@ -11,6 +11,9 @@
[honeysql.core :as sql]
[datomish.util :as util #?(:cljs :refer-macros :clj :refer) [raise cond-let]]
[datomish.sqlite :as s]
[datomish.exec :as de]
[datomish.query :as dq]
[datomish.transforms :as dt]
[datomish.sqlite-schema :as sqlite-schema]
#?@(:clj [[datomish.pair-chan :refer [go-pair <?]]
[clojure.core.async :as a :refer [go <! >!]]])
@ -36,6 +39,29 @@
(defn db? [x]
(and (satisfies? IDB x)))
(defn <q
"Execute the provided query on the provided DB.
Returns a transduced pair-chan of [[results] err]."
[db find]
{:pre [(db? db)]}
(let [attribute-transform (fn [a] (get (idents db) a a))
constant-transform dt/constant-transform-default
initial-context (dq/make-context attribute-transform constant-transform)
context (dq/find->into-context initial-context (dq/parse find))
row-pair-transducer (dq/row-pair-transducer context (dq/sql-projection context))
chan (a/chan 50 row-pair-transducer)]
(s/<?all-rows (:sqlite-connection db) (dq/context->sql-string context) chan)
;; TODO: extract this reducing function lifted to the Maybe monad.
(let [g (fn [f [rv re] [v e]]
(if re
[nil re]
(if e
[nil e]
[(f rv v) nil])))]
(go-pair
(<? (a/reduce (partial g conj) [[] nil] chan))))))
;; TODO: implement support for DB parts?
(def tx0 0x2000000)

View file

@ -101,3 +101,23 @@
[txb txInstant -1 txb 1]])))
(finally
(<? (db/close db)))))))
(deftest-async test-q
(with-tempfile [t (tempfile)]
(let [c (<? (s/<sqlite-connection t))
db (<? (db/<with-sqlite-connection c))]
(try
(let [now -1
txInstant (<? (db/<entid db :db/txInstant)) ;; TODO: convert entids to idents on egress.
x (<? (db/<entid db :x)) ;; TODO: convert entids to idents on egress.
report (<? (db/<transact! db [[:db/add 0 :x "valuex"]] nil now))
current-tx (:current-tx report)]
(is (= current-tx db/tx0))
(is (= (<? (<datoms db))
[[0 x "valuex" db/tx0 true]
[db/tx0 txInstant now db/tx0 true]]))
(is (= (<? (db/<q db '[:find ?e ?a ?v ?tx :in $ :where [?e ?a ?v ?tx]]))
[[1 x "valuex" db/tx0] ;; TODO: include added.
[db/tx0 txInstant now db/tx0]])))
(finally
(<? (db/close db)))))))