Pass a Context into query.
This commit is contained in:
parent
f4b9b867a4
commit
9ae9a0572b
2 changed files with 41 additions and 32 deletions
|
@ -9,29 +9,30 @@
|
|||
[datomish.pair-chan :refer [go-pair <?]]
|
||||
[cljs.core.async.macros :refer [go]]))
|
||||
(:require
|
||||
[datomish.sqlite :as s]
|
||||
[datomish.sqlite-schema :as ss]
|
||||
[datomish.query :as dq]
|
||||
#?@(:clj
|
||||
[[datomish.jdbc-sqlite]
|
||||
[datomish.pair-chan :refer [go-pair <?]]
|
||||
[datomish.util :refer [while-let]]
|
||||
[clojure.core.async :refer
|
||||
[go ; macro in cljs.
|
||||
<! >! chan close! take!]]])
|
||||
#?@(:cljs
|
||||
[[datomish.promise-sqlite]
|
||||
[datomish.pair-chan]
|
||||
[datomish.util]
|
||||
[cljs.core.async :as a :refer
|
||||
[<! >! chan close! take!]]])))
|
||||
[datomish.sqlite :as s]
|
||||
[datomish.sqlite-schema :as ss]
|
||||
[datomish.query :as dq]
|
||||
#?@(:clj
|
||||
[[datomish.jdbc-sqlite]
|
||||
[datomish.pair-chan :refer [go-pair <?]]
|
||||
[datomish.util :refer [while-let]]
|
||||
[clojure.core.async :refer
|
||||
[go ; macro in cljs.
|
||||
<! >! chan close! take!]]])
|
||||
#?@(:cljs
|
||||
[[datomish.promise-sqlite]
|
||||
[datomish.pair-chan]
|
||||
[datomish.util]
|
||||
[cljs.core.async :as a :refer
|
||||
[<! >! chan close! take!]]])))
|
||||
|
||||
(defn <?run
|
||||
"Execute the provided query on the provided DB.
|
||||
Returns a transduced channel of [result err] pairs.
|
||||
Closes the channel when fully consumed."
|
||||
[db find]
|
||||
(let [context (dq/find->prepared-context (dq/parse find))
|
||||
(let [initial-context (dq/make-context)
|
||||
context (dq/expand-find-into-context initial-context (dq/parse find))
|
||||
row-pair-transducer (dq/row-pair-transducer context (dq/sql-projection context))
|
||||
chan (chan 50 row-pair-transducer)]
|
||||
|
||||
|
|
|
@ -52,10 +52,16 @@
|
|||
(or (-> context :bindings variable first)
|
||||
(raise (str "Couldn't find variable " variable))))
|
||||
|
||||
(defn make-context []
|
||||
(->Context [] {} [] []
|
||||
transforms/attribute-transform-string
|
||||
transforms/constant-transform-default))
|
||||
(defn make-context
|
||||
([]
|
||||
(make-context transforms/attribute-transform-string transforms/constant-transform-default))
|
||||
([attribute-transform constant-transform]
|
||||
(map->Context {:from []
|
||||
:bindings {}
|
||||
:wheres []
|
||||
:elements []
|
||||
:attribute-transform attribute-transform
|
||||
:constant-transform constant-transform})))
|
||||
|
||||
(defn apply-pattern-to-context
|
||||
"Transform a DataScript Pattern instance into the parts needed
|
||||
|
@ -127,10 +133,10 @@
|
|||
(defn apply-elements-to-context [context elements]
|
||||
(assoc context :elements elements))
|
||||
|
||||
(defn patterns->context
|
||||
"Turn a sequence of patterns into a Context."
|
||||
[patterns]
|
||||
(reduce apply-pattern-to-context (make-context) patterns))
|
||||
(defn expand-patterns-into-context
|
||||
"Reduce a sequence of patterns into a Context."
|
||||
[context patterns]
|
||||
(reduce apply-pattern-to-context context patterns))
|
||||
|
||||
(defn sql-projection
|
||||
"Take a `find` clause's `:elements` list and turn it into a SQL
|
||||
|
@ -192,7 +198,7 @@
|
|||
(= "$" (name (-> in first :variable :symbol))))
|
||||
(raise (str "Complex `in` not supported: " (print-str in)))))
|
||||
|
||||
(defn find->prepared-context [find]
|
||||
(defn expand-find-into-context [context find]
|
||||
;; There's some confusing use of 'where' and friends here. That's because
|
||||
;; the parsed Datalog includes :where, and it's also input to honeysql's
|
||||
;; SQL formatter.
|
||||
|
@ -201,24 +207,26 @@
|
|||
(validate-in in)
|
||||
(apply-elements-to-context
|
||||
(expand-where-from-bindings
|
||||
(patterns->context where)) ; 'where' here is the Datalog :where clause.
|
||||
(expand-patterns-into-context context where)) ; 'where' here is the Datalog :where clause.
|
||||
(:elements find))))
|
||||
|
||||
(defn find->sql-clause
|
||||
"Take a parsed `find` expression and turn it into a structured SQL
|
||||
expression that can be formatted by honeysql."
|
||||
[find]
|
||||
[context find]
|
||||
;; There's some confusing use of 'where' and friends here. That's because
|
||||
;; the parsed Datalog includes :where, and it's also input to honeysql's
|
||||
;; SQL formatter.
|
||||
(-> find find->prepared-context context->sql-clause))
|
||||
(->> find
|
||||
(expand-find-into-context context)
|
||||
context->sql-clause))
|
||||
|
||||
(defn find->sql-string
|
||||
"Take a parsed `find` expression and turn it into SQL."
|
||||
[find]
|
||||
(->
|
||||
[context find]
|
||||
(->>
|
||||
find
|
||||
find->sql-clause
|
||||
(find->sql-clause context)
|
||||
(sql/format :quoting sql-quoting-style)))
|
||||
|
||||
(defn parse
|
||||
|
|
Loading…
Reference in a new issue