Turn Source into a protocol. Allow source->from to switch on attribute.
This commit is contained in:
parent
8a77dcd8f0
commit
d5e3716eba
3 changed files with 61 additions and 28 deletions
|
@ -143,11 +143,14 @@
|
||||||
Constant
|
Constant
|
||||||
(constrain-column-to-constant cc col position (:value pattern-part))
|
(constrain-column-to-constant cc col position (:value pattern-part))
|
||||||
|
|
||||||
(raise-str "Unknown pattern part " pattern-part))))
|
(raise "Unknown pattern part." {:part pattern-part :clause pattern}))))
|
||||||
|
|
||||||
cc
|
cc
|
||||||
places)))
|
places)))
|
||||||
|
|
||||||
|
(defn pattern->attribute [pattern]
|
||||||
|
(second (:pattern pattern)))
|
||||||
|
|
||||||
;; Accumulates a pattern into the CC. Returns a new CC.
|
;; Accumulates a pattern into the CC. Returns a new CC.
|
||||||
(defn apply-pattern-clause
|
(defn apply-pattern-clause
|
||||||
"Transform a DataScript Pattern instance into the parts needed
|
"Transform a DataScript Pattern instance into the parts needed
|
||||||
|
@ -162,7 +165,11 @@
|
||||||
(when-not (instance? DefaultSrc (:source pattern))
|
(when-not (instance? DefaultSrc (:source pattern))
|
||||||
(raise-str "Non-default sources are not supported in patterns. Pattern: " pattern))
|
(raise-str "Non-default sources are not supported in patterns. Pattern: " pattern))
|
||||||
|
|
||||||
(let [[table alias] (source->from (:source cc))] ; e.g., [:datoms :datoms123]
|
;; TODO: look up the attribute in external bindings if it's a var. Perhaps we
|
||||||
|
;; already know what it is…
|
||||||
|
(let [[table alias] (source->from
|
||||||
|
(:source cc) ; e.g., [:datoms :datoms123]
|
||||||
|
(pattern->attribute pattern))]
|
||||||
(apply-pattern-clause-for-alias
|
(apply-pattern-clause-for-alias
|
||||||
|
|
||||||
;; Record the new table mapping.
|
;; Record the new table mapping.
|
||||||
|
|
|
@ -4,7 +4,15 @@
|
||||||
|
|
||||||
(ns datomish.query.source
|
(ns datomish.query.source
|
||||||
(:require
|
(:require
|
||||||
[datomish.query.transforms :as transforms]))
|
[datomish.query.transforms :as transforms]
|
||||||
|
[datascript.parser
|
||||||
|
#?@(:cljs
|
||||||
|
[:refer [Variable Constant Placeholder]])])
|
||||||
|
#?(:clj
|
||||||
|
(:import [datascript.parser Variable Constant Placeholder])))
|
||||||
|
|
||||||
|
(defn- gensym-table-alias [table]
|
||||||
|
(gensym (name table)))
|
||||||
|
|
||||||
;;;
|
;;;
|
||||||
;;; A source is something that can match patterns. For example:
|
;;; A source is something that can match patterns. For example:
|
||||||
|
@ -24,9 +32,17 @@
|
||||||
;;; * Transform constants and attributes into something usable
|
;;; * Transform constants and attributes into something usable
|
||||||
;;; by the source.
|
;;; by the source.
|
||||||
|
|
||||||
|
(defprotocol Source
|
||||||
|
(source->from [source attribute]
|
||||||
|
"Returns a pair, `[table alias]` for a pattern with the provided attribute.")
|
||||||
|
(source->constraints [source alias])
|
||||||
|
(attribute-in-source [source attribute])
|
||||||
|
(constant-in-source [source constant]))
|
||||||
|
|
||||||
(defrecord
|
(defrecord
|
||||||
Source
|
DatomsSource
|
||||||
[table ; e.g., :datoms
|
[table ; Typically :datoms.
|
||||||
|
fts-view ; Typically :fulltext_datoms.
|
||||||
columns ; e.g., [:e :a :v :tx]
|
columns ; e.g., [:e :a :v :tx]
|
||||||
|
|
||||||
;; `attribute-transform` is a function from attribute to constant value. Used to
|
;; `attribute-transform` is a function from attribute to constant value. Used to
|
||||||
|
@ -41,29 +57,38 @@
|
||||||
|
|
||||||
;; Not currently used.
|
;; Not currently used.
|
||||||
make-constraints ; ?fn [source alias] => [where-clauses]
|
make-constraints ; ?fn [source alias] => [where-clauses]
|
||||||
])
|
]
|
||||||
|
Source
|
||||||
|
|
||||||
(defn gensym-table-alias [table]
|
(source->from [source attribute]
|
||||||
(gensym (name table)))
|
(let [table
|
||||||
|
(if (and (instance? Constant attribute)
|
||||||
|
;; TODO: look in the DB schema to see if `attribute` is known to not be
|
||||||
|
;; a fulltext attribute.
|
||||||
|
true)
|
||||||
|
(:table source)
|
||||||
|
|
||||||
|
;; It's variable. We must act as if it could be a fulltext datom.
|
||||||
|
(:fts-view source))]
|
||||||
|
[table ((:table-alias source) table)]))
|
||||||
|
|
||||||
|
(source->constraints [source alias]
|
||||||
|
(when-let [f (:make-constraints source)]
|
||||||
|
(f alias)))
|
||||||
|
|
||||||
|
(attribute-in-source [source attribute]
|
||||||
|
((:attribute-transform source) attribute))
|
||||||
|
|
||||||
|
(constant-in-source [source constant]
|
||||||
|
((:constant-transform source) constant)))
|
||||||
|
|
||||||
(defn datoms-source [db]
|
(defn datoms-source [db]
|
||||||
(->Source :datoms
|
(map->DatomsSource
|
||||||
[:e :a :v :tx :added]
|
{:table :datoms
|
||||||
transforms/attribute-transform-string
|
:fts-view :fulltext_datoms
|
||||||
transforms/constant-transform-default
|
:columns [:e :a :v :tx :added]
|
||||||
gensym-table-alias
|
:attribute-transform transforms/attribute-transform-string
|
||||||
nil))
|
:constant-transform transforms/constant-transform-default
|
||||||
|
:table-alias gensym-table-alias
|
||||||
|
:make-constraints nil}))
|
||||||
|
|
||||||
(defn source->from [source]
|
|
||||||
(let [table (:table source)]
|
|
||||||
[table ((:table-alias source) table)]))
|
|
||||||
|
|
||||||
(defn source->constraints [source alias]
|
|
||||||
(when-let [f (:make-constraints source)]
|
|
||||||
(f alias)))
|
|
||||||
|
|
||||||
(defn attribute-in-source [source attribute]
|
|
||||||
((:attribute-transform source) attribute))
|
|
||||||
|
|
||||||
(defn constant-in-source [source constant]
|
|
||||||
((:constant-transform source) constant))
|
|
||||||
|
|
|
@ -26,8 +26,9 @@
|
||||||
(fgensym s (dec (swap! counter inc)))))))
|
(fgensym s (dec (swap! counter inc)))))))
|
||||||
|
|
||||||
(defn mock-source [db]
|
(defn mock-source [db]
|
||||||
(source/map->Source
|
(source/map->DatomsSource
|
||||||
{:table :datoms
|
{:table :datoms
|
||||||
|
:fts-view :fulltext_datoms
|
||||||
:columns [:e :a :v :tx :added]
|
:columns [:e :a :v :tx :added]
|
||||||
:attribute-transform transforms/attribute-transform-string
|
:attribute-transform transforms/attribute-transform-string
|
||||||
:constant-transform transforms/constant-transform-default
|
:constant-transform transforms/constant-transform-default
|
||||||
|
|
Loading…
Reference in a new issue