Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ pom.xml.asc
.hg/
figwheel_server.log
/resources/public/js
/out/
20 changes: 18 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ even after the component using that query is un-rendered. (Thanks, [metasoarous]
they sort-of worked in the older version. If you need to use those,
just keep using the older version until those expressions are
supported.

## Overview

Posh gives you two functions to retrieve data from the database from
Expand Down Expand Up @@ -307,7 +307,7 @@ one day explain further.
### Editable Label

This component will show the text value
for any entity and attrib combo. There is an "edit" button that, when clicked,
for any entity and attrib combo. There is an "edit" button that, when clicked,
creates an `:edit` entity that keeps track of the
temporary text typed in the edit box. The "done" button resets the original
value of the entity and attrib and deletes the `:edit` entity. The
Expand Down Expand Up @@ -369,6 +369,22 @@ Datomic db over to DataScript.

See our Gitter room for updates: https://gitter.im/mpdairy/posh

## Developing this library

Start a Clojure REPL via your normal way -- `M-x cider-jack-in` for Emacs users.

Start a CLJS REPL via `lein trampoline cljsbuild repl-listen`

Files of interest:

* posh.clj.datomic.clj - Clojure Datomic API
* posh.clj.datascript.clj - Clojure Datascript API
* posh.reagent - CLJS Datascript API

### Running tests

Run `lein test` from project root

## License

Copyright © 2015 Matt Parker
Expand Down
17 changes: 8 additions & 9 deletions project.clj
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
(defproject posh "0.5.6"
(defproject posh "0.5.7"
:description "Luxuriously easy and powerful Reagent / Datascript front-end framework"
:url "http://github.com/mpdairy/posh/"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/clojure "1.7.0"]
[org.clojure/clojurescript "1.7.228"]
#_[datascript "0.15.0"]
:dependencies [[org.clojure/clojure "1.10.1"]
[org.clojure/clojurescript "1.10.520"]
#_[datascript "0.18.6"]
#_[com.datomic/datomic-free "0.9.5407"]
[org.clojure/core.match "0.3.0-alpha4"]]
[org.clojure/core.match "0.3.0"]]
:plugins [[lein-cljsbuild "1.1.3"]]
:cljsbuild {
:builds [ {:id "posh"
:profiles {:test {:dependencies [[datascript "0.18.6"]]}}
:cljsbuild {:builds [ {:id "posh"
:source-paths ["src/"]
:figwheel false
:compiler {:main "posh.core"
:asset-path "js"
:output-to "resources/public/js/main.js"
:output-dir "resources/public/js"} } ]
}
:output-dir "resources/public/js"} } ]}
:scm {:name "git"
:url "https://github.com/mpdairy/posh"})
3 changes: 2 additions & 1 deletion src/posh/clj/datascript.clj
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
(def dcfg
(let [dcfg {:db d/db
:pull* d/pull
:pull-many d/pull-many
:q d/q
:filter d/filter
:with d/with
Expand All @@ -15,6 +16,6 @@
:conn? d/conn?
:ratom rx/atom
:make-reaction rx/make-reaction}]
(assoc dcfg :pull (partial base/safe-pull dcfg))))
(assoc dcfg :pull (partial base/safe-pull dcfg))))

(base/add-plugin dcfg)
3 changes: 2 additions & 1 deletion src/posh/clj/datomic.clj
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
(def dcfg
(let [dcfg {:db d/db
:pull* d/pull
:pull-many d/pull-many
:q d/q
:filter d/filter
:with d/with
Expand All @@ -29,6 +30,6 @@
:conn? conn?
:ratom rx/atom
:make-reaction rx/make-reaction}]
(assoc dcfg :pull (partial base/safe-pull dcfg))))
(assoc dcfg :pull (partial base/safe-pull dcfg))))

(base/add-plugin dcfg)
65 changes: 39 additions & 26 deletions src/posh/core.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -90,15 +90,15 @@
(let [storage-key [:filter-q query args]
cached (get cache storage-key)]
(assoc
(if cached
(if cached
posh-tree
(let [{:keys [analysis dbvarmap]} (u/update-q-with-dbvarmap posh-tree storage-key)]
(merge
posh-tree
(let [{:keys [analysis dbvarmap]} (u/update-q-with-dbvarmap posh-tree storage-key)]
(merge
posh-tree
{:graph (graph/add-item-connect graph storage-key (vals dbvarmap))
:cache (assoc cache storage-key
(u/filter-q-transform-analysis analysis))})))
:return storage-key)))
{:graph (graph/add-item-connect graph storage-key (vals dbvarmap))
:cache (assoc cache storage-key
(u/filter-q-transform-analysis analysis))})))
:return storage-key)))


;; ================== queries ====================
Expand All @@ -107,28 +107,43 @@
(let [storage-key [:pull poshdb pull-pattern eid]
cached (get cache storage-key)]
(assoc
(if cached
(if cached
posh-tree
(let [analysis (merge
{:tx-t 0}
(u/update-pull posh-tree storage-key))]
(merge
posh-tree
(let [analysis (merge
{:tx-t 0}
(u/update-pull posh-tree storage-key))]
(merge
posh-tree
{:graph (graph/add-item-connect graph storage-key [poshdb])
:cache (assoc cache storage-key analysis)})))
:return storage-key)))
{:graph (graph/add-item-connect graph storage-key [poshdb])
:cache (assoc cache storage-key analysis)})))
:return storage-key)))

(defn add-pull-many [{:keys [graph cache dcfg conns conns-by-id retrieve] :as posh-tree} poshdb pull-pattern eids]
(let [storage-key [:pull-many poshdb pull-pattern eids]
cached (get cache storage-key)]
(assoc
(if cached
posh-tree
(let [analysis (merge
{:tx-t 0}
(u/update-pull-many posh-tree storage-key))]
(merge
posh-tree
{:graph (graph/add-item-connect graph storage-key [poshdb])
:cache (assoc cache storage-key analysis)})))
:return storage-key)))

(defn add-q [{:keys [cache graph dcfg conns retrieve] :as posh-tree} query & args]
(let [storage-key [:q query args]
cached (get cache storage-key)]
(assoc
(or cached
(let [{:keys [analysis dbvarmap]} (u/update-q-with-dbvarmap posh-tree storage-key)]
(merge
posh-tree
{:graph (graph/add-item-connect graph storage-key (vals dbvarmap))
:cache (assoc cache storage-key analysis)})))
:return storage-key)))
(or cached
(let [{:keys [analysis dbvarmap]} (u/update-q-with-dbvarmap posh-tree storage-key)]
(merge
posh-tree
{:graph (graph/add-item-connect graph storage-key (vals dbvarmap))
:cache (assoc cache storage-key analysis)})))
:return storage-key)))

;; ======================= remove items ===================

Expand Down Expand Up @@ -229,5 +244,3 @@
{}
txs)]
(after-transact (assoc posh-tree :txs {}) conns-results)))


26 changes: 11 additions & 15 deletions src/posh/lib/pull_analyze.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -184,14 +184,14 @@
{:patterns
{db-id
(dm/reduce-patterns
(concat
(when (vector? ent-id)
[['_ (first ent-id) (second ent-id)]])
(tx-pattern-for-pull
schema
prepped-pull-pattern
affected-datoms
false)))}})
(concat
(when (vector? ent-id)
[['_ (first ent-id) (second ent-id)]])
(tx-pattern-for-pull
schema
prepped-pull-pattern
affected-datoms
false)))}})
(when (some #{:ref-patterns} retrieve)
{:ref-patterns
{db-id
Expand All @@ -201,19 +201,17 @@
prepped-pull-pattern
affected-datoms
true))}}))))))))

(defn pull-many-analyze [dcfg retrieve {:keys [db schema db-id]} pull-pattern ent-ids]
(when-not (empty? retrieve)
(let [resolved-ent-ids (map #((:entid dcfg) db %) ent-ids)
affected-datoms
(map (fn [ent-id] (pull-affected-datoms (:pull dcfg) db pull-pattern ent-id))
resolved-ent-ids)]
affected-datoms (pull-affected-datoms (:pull-many dcfg) db pull-pattern ent-ids)]
(merge
(when (some #{:results} retrieve)
{:results affected-datoms})
(when (some #{:datoms :datoms-t} retrieve)
(let [datoms (mapcat #(generate-affected-tx-datoms-for-pull schema %)
affected-datoms)]
affected-datoms)]
(merge
(when (some #{:datoms} retrieve)
{:datoms {db-id datoms}})
Expand All @@ -233,5 +231,3 @@
(vec (cons (set resolved-ent-ids) (rest (ffirst patterns))))
(mapcat rest patterns))
(dm/reduce-patterns (apply concat patterns)))}})))))


87 changes: 68 additions & 19 deletions src/posh/lib/q_analyze.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@

(defn eav? [v]
(and (vector? v)
(not (some coll? v))))
(not (or (coll? (first v))
(coll? (second v))))))

(defn wildcard? [s] (= s '_))

Expand Down Expand Up @@ -374,15 +375,58 @@
(apply merge))))

(defn split-datoms [datoms]
(->> (group-by first datoms)
(map (fn [[db-sym db-datoms]]
{db-sym
(map (comp vec rest) db-datoms)}))
(apply merge)))
(->> (group-by first datoms)
(map (fn [[db-sym db-datoms]]
{db-sym
(map (comp vec rest) db-datoms)}))
(apply merge)))

(defn resolve-any-idents [entid-fn db input-set]
(set (for [x input-set]
(if (coll? x) (entid-fn db x) x))))
(defn- schema-ref?
"Returns whether attribute identified by k is of :db/valueType :db.type/ref"
[schema k]
(= :db.type/ref (:db/valueType (get schema k))))

(defn- indexes-of [e coll] (keep-indexed #(if (= e %2) %1) coll))

(defn- lookup-ref?
"Returns whether var-name is used as lookup-ref inside of query's :where clauses.
var-name - the symbolic variable name
where - coll of where clauses
schema - map of schemas with attribute names as keys
Returns boolean true or false"
[schema where var-name var-value]
(if-not (coll? var-value)
false
(loop [clause (first where)
remaining (rest where)]
(condp = (first (indexes-of var-name clause))
1 true

;; If datascript supported :db/valueTuple :db.type/tuple, could check that here
;; instead of needing to scan every :where clause to ensure it's not a schema-ref
3 (if (schema-ref? schema (nth clause 2))
true
(if (seq remaining)
(recur (first remaining) (rest remaining))
false))

(if (seq remaining)
(recur (first remaining) (rest remaining))
false)))))

(defn resolve-any-idents
"Given input-set from query, resolves any lookup-refs
Inputs:
entid-fn - Datomic/DS function to take lookup-ref & returns entid
db - value of DB
schemas - map with keys matching known schema attributes
where - where clauses of query
input-set - value from query :in"
[entid-fn db schema where var-name input-set]
(set (for [var-value input-set]
(if (lookup-ref? schema where var-name var-value)
(entid-fn db var-value)
var-value))))

;;;;;;;; q function that gives pattern, datoms, and results all in one
;;;;;;;; query. db should be first of args (for now. later, finding
Expand Down Expand Up @@ -457,17 +501,17 @@
vars (vec (get-all-vars eavs))
newqm (merge qm {:find vars :where where})
;; This doesn't seem to be getting used anymore
;newq (qm-to-query newqm)
;;newq (qm-to-query newqm)
dbvarmap (make-dbarg-map (:in qm) args)
fixed-args (->> (zipmap (:in qm) args)
(map (fn [[sym arg]]
(or (:db (get dbvarmap sym)) arg))))
r (apply (partial (:q dcfg) newqm) fixed-args)
lookup-ref-patterns
(->> args
;; Would be nice to check by the schema as well, to make sure this is actually a identity attribute
(filter (every-pred vector? (comp keyword? first) (comp (partial = 2) count)))
(map (fn [[a v]] ['$ '_ a v])))]
;; Would be nice to check by the schema as well, to make sure this is actually a identity attribute
(filter (every-pred vector? (comp keyword? first) (comp (partial = 2) count)))
(map (fn [[a v]] ['$ '_ a v])))]
(merge
(when (some #{:datoms :datoms-t} retrieve)
(let [datoms (split-datoms (create-q-datoms r eavs vars))]
Expand All @@ -491,19 +535,24 @@
{:results
((:q dcfg) {:find (vec (:find qm))
:in [[vars '...]]}
(vec r))})
(vec r))})
(when (some #{:patterns :filter-patterns :simple-patterns} retrieve)
(let
[in-vars (get-input-sets (:q dcfg) (:in qm) args)
eavs-ins (map (fn [[db & eav]]
(vec
(cons db
(map
#(if-let [v (in-vars %)]
(resolve-any-idents (:entid dcfg)
(:db (get dbvarmap db))
v)
%) eav))))
(fn [var-name]
(if-let [var-value (in-vars var-name)]
(resolve-any-idents (:entid dcfg)
(:db (get dbvarmap db))
(:schema (get dbvarmap db))
where
var-name
var-value)
var-name))
eav))))
(concat lookup-ref-patterns eavs))
qvar-count (count-qvars eavs-ins)
linked-qvars (set (remove nil? (map (fn [[k v]] (if (> v 1) k)) qvar-count)))
Expand Down
Loading