Add d/q; make query minimally schema aware.

This commit is contained in:
Nick Alexander 2016-08-05 17:58:46 -07:00 committed by Richard Newman
parent 65ed0976dd
commit b4e5c88d6a
6 changed files with 160 additions and 93 deletions

View file

@ -144,13 +144,35 @@
] ]
rowid))) rowid)))
(defn datoms-attribute-transform
[db x]
{:pre [(db? db)]}
(entid db x))
(defn datoms-constant-transform
[db x]
{:pre [(db? db)]}
(sqlite-schema/->SQLite x))
(defn datoms-source [db]
(source/map->DatomsSource
{:table :datoms
:fulltext-table :fulltext_values
:fulltext-view :all_datoms
:columns [:e :a :v :tx :added]
:attribute-transform (partial datoms-attribute-transform db)
:constant-transform (partial datoms-constant-transform db)
:table-alias source/gensym-table-alias
:make-constraints nil}))
(defrecord DB [sqlite-connection schema entids ident-map current-tx] (defrecord DB [sqlite-connection schema entids ident-map current-tx]
;; ident-map maps between keyword idents and integer entids. The set of idents and entids is ;; ident-map maps between keyword idents and integer entids. The set of idents and entids is
;; disjoint, so we represent both directions of the mapping in the same map for simplicity. Also ;; disjoint, so we represent both directions of the mapping in the same map for simplicity. Also
;; for simplicity, we assume that an entid has at most one associated ident, and vice-versa. See ;; for simplicity, we assume that an entid has at most one associated ident, and vice-versa. See
;; http://docs.datomic.com/identity.html#idents. ;; http://docs.datomic.com/identity.html#idents.
IDB IDB
(query-context [db] (context/->Context (source/datoms-source db) nil nil)) (query-context [db] (context/->Context (datoms-source db) nil nil))
(schema [db] (.-schema db)) (schema [db] (.-schema db))

View file

@ -116,8 +116,10 @@
[q] [q]
(dp/parse-query q)) (dp/parse-query q))
(comment #_
(def sql-quoting-style nil) (def sql-quoting-style nil)
#_
(datomish.query/find->sql-string (datomish.query/find->sql-string
(datomish.query.context/->Context (datomish.query.source/datoms-source nil) nil nil) (datomish.query.context/->Context (datomish.query.source/datoms-source nil) nil nil)
(datomish.query/parse (datomish.query/parse
@ -126,7 +128,6 @@
[?t :db/txInstant ?timestampMicros] [?t :db/txInstant ?timestampMicros]
(not [(> ?t ?latest)]) ]) (not [(> ?t ?latest)]) ])
{:latest 5}) {:latest 5})
)
#_ #_
(datomish.query/find->sql-string (datomish.query/find->sql-string

View file

@ -114,7 +114,7 @@
(defn- plain-symbol->sql-predicate-symbol [fn] (defn- plain-symbol->sql-predicate-symbol [fn]
(when-not (instance? PlainSymbol fn) (when-not (instance? PlainSymbol fn)
(raise-str "Predicate functions must be named by plain symbols." fn)) (raise-str "Predicate functions must be named by plain symbols." fn))
(#{:> :< :=} (keyword (name (:symbol fn))))) (#{:> :>= :< :<= := :!=} (keyword (name (:symbol fn)))))
(defn apply-predicate-clause [cc predicate] (defn apply-predicate-clause [cc predicate]
(when-not (instance? Predicate predicate) (when-not (instance? Predicate predicate)

View file

@ -11,7 +11,7 @@
#?(:clj #?(:clj
(:import [datascript.parser Variable Constant Placeholder]))) (:import [datascript.parser Variable Constant Placeholder])))
(defn- gensym-table-alias [table] (defn gensym-table-alias [table]
(gensym (name table))) (gensym (name table)))
;;; ;;;
@ -93,15 +93,3 @@
(constant-in-source [source constant] (constant-in-source [source constant]
((:constant-transform source) constant))) ((:constant-transform source) constant)))
(defn datoms-source [db]
(map->DatomsSource
{:table :datoms
:fulltext-table :fulltext_values
:fulltext-view :all_datoms
:columns [:e :a :v :tx :added]
:attribute-transform transforms/attribute-transform-string
:constant-transform transforms/constant-transform-default
:table-alias gensym-table-alias
:make-constraints nil}))

View file

@ -37,3 +37,5 @@
(def entid db/entid) (def entid db/entid)
(def ident db/ident) (def ident db/ident)
(def <q db/<?q)

View file

@ -0,0 +1,54 @@
;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
(ns datomish.query-test
#?(:cljs
(:require-macros
[datomish.pair-chan :refer [go-pair <?]]
[datomish.node-tempfile-macros :refer [with-tempfile]]
[cljs.core.async.macros :as a :refer [go]]))
(:require
[datomish.api :as d]
#?@(:clj [[datomish.pair-chan :refer [go-pair <?]]
[tempfile.core :refer [tempfile with-tempfile]]
[datomish.test-macros :refer [deftest-async]]
[clojure.test :as t :refer [is are deftest testing]]
[clojure.core.async :refer [go <! >!]]])
#?@(:cljs [[datomish.pair-chan]
[datomish.test-macros :refer-macros [deftest-async]]
[datomish.node-tempfile :refer [tempfile]]
[cljs.test :as t :refer-macros [is are deftest testing async]]
[cljs.core.async :as a :refer [<! >!]]]))
#?(:clj
(:import [clojure.lang ExceptionInfo]))
#?(:clj
(:import [datascript.db DB])))
#?(:cljs
(def Throwable js/Error))
(def test-schema
[{:db/id (d/id-literal :test -1)
:db/ident :x
:db/unique :db.unique/identity
:db/valueType :db.type/integer
:db.install/_attribute :db.part/db}
])
(deftest-async test-q
(with-tempfile [t (tempfile)]
(let [conn (<? (d/<connect t))
{tx0 :tx} (<? (d/<transact! conn test-schema))]
(try
(let [{tx1 :tx} (<? (d/<transact! conn [{:db/id 101 :x 505}]))]
(is (= (<? (d/<q (d/db conn)
`[:find ?e ?a ?v ?tx :in $ :where
[?e ?a ?v ?tx]
[(> ?tx ~tx0)]
[(!= ?a ~(d/entid (d/db conn) :db/txInstant))] ;; TODO: map ident->entid for values.
] {}))
[[101 (d/entid (d/db conn) :x) 505 tx1]]))) ;; TODO: map entid->ident on egress.
(finally
(<? (d/<close conn)))))))