Add d/q; make query minimally schema aware.
This commit is contained in:
parent
65ed0976dd
commit
b4e5c88d6a
6 changed files with 160 additions and 93 deletions
|
@ -144,13 +144,35 @@
|
|||
]
|
||||
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]
|
||||
;; 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
|
||||
;; for simplicity, we assume that an entid has at most one associated ident, and vice-versa. See
|
||||
;; http://docs.datomic.com/identity.html#idents.
|
||||
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))
|
||||
|
||||
|
|
|
@ -116,9 +116,11 @@
|
|||
[q]
|
||||
(dp/parse-query q))
|
||||
|
||||
(comment
|
||||
(def sql-quoting-style nil)
|
||||
(datomish.query/find->sql-string
|
||||
#_
|
||||
(def sql-quoting-style nil)
|
||||
|
||||
#_
|
||||
(datomish.query/find->sql-string
|
||||
(datomish.query.context/->Context (datomish.query.source/datoms-source nil) nil nil)
|
||||
(datomish.query/parse
|
||||
'[:find ?timestampMicros ?page :in $ ?latest :where
|
||||
|
@ -126,7 +128,6 @@
|
|||
[?t :db/txInstant ?timestampMicros]
|
||||
(not [(> ?t ?latest)]) ])
|
||||
{:latest 5})
|
||||
)
|
||||
|
||||
#_
|
||||
(datomish.query/find->sql-string
|
||||
|
|
|
@ -114,7 +114,7 @@
|
|||
(defn- plain-symbol->sql-predicate-symbol [fn]
|
||||
(when-not (instance? PlainSymbol 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]
|
||||
(when-not (instance? Predicate predicate)
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#?(:clj
|
||||
(:import [datascript.parser Variable Constant Placeholder])))
|
||||
|
||||
(defn- gensym-table-alias [table]
|
||||
(defn gensym-table-alias [table]
|
||||
(gensym (name table)))
|
||||
|
||||
;;;
|
||||
|
@ -93,15 +93,3 @@
|
|||
|
||||
(constant-in-source [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}))
|
||||
|
||||
|
|
|
@ -37,3 +37,5 @@
|
|||
(def entid db/entid)
|
||||
|
||||
(def ident db/ident)
|
||||
|
||||
(def <q db/<?q)
|
||||
|
|
54
test/datomish/query_test.cljc
Normal file
54
test/datomish/query_test.cljc
Normal 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)))))))
|
Loading…
Reference in a new issue