File tree Expand file tree Collapse file tree 4 files changed +64
-15
lines changed
Expand file tree Collapse file tree 4 files changed +64
-15
lines changed Original file line number Diff line number Diff line change 1+ # WIP
2+
3+ - Transactor functions via : db .fn/call
4+
15# 0.1.3
26
37- ` entity ` added
Original file line number Diff line number Diff line change @@ -119,10 +119,13 @@ Interface differences:
119119* Custom query functions and aggregates should be passed as source instead of being referenced by symbol (due to lack of ` resolve ` in CLJS)
120120* Conn is just an atom storing last DB value, use ` @conn ` instead of ` (d/db conn) `
121121* Instead of ` #db/id[:db.part/user -100] ` just use ` -100 ` in place of ` :db/id ` or entity id
122+ * Transactor functions can be called as ` [:db.fn/call f args] ` where ` f ` is a function reference and will take db as first argument
123+ * Additional ` :db.fn/retractAttribute ` shortcut
122124
123125Expected soon:
124126
125127* Better error reporting
128+ * Support for components in schema
126129* Direct access to indexes
127130* Passing DB to rule
128131* Moar speed
@@ -136,7 +139,6 @@ Expected soon:
136139* Any value can be used as entity id, attribute or value. It’s better if they are immutable and fast to compare
137140* No ` db/ident ` attributes, keywords are _ literally_ attribute values, no integer id behind them
138141* AV index for all datoms
139- * No transactor functions besides ` :db.fn/retractEntity ` and ` :db.fn/retractAttribute `
140142* No schema migrations
141143* No history support, though history can be implemented on top of immutable DB values
142144* No cache segments management, no laziness. Entire DB must reside in memory
Original file line number Diff line number Diff line change 8181 vs
8282 [vs])]
8383 [:db/add eid a v]))
84- [entity]))
84+ (if (= (first entity) :db.fn/call )
85+ (let [[_ f & args] entity]
86+ (mapcat #(entity->ops db %) (apply f db args)))
87+ [entity])))
8588
8689(defn- op->tx-data [db [op e a v]]
8790 (let [tx (inc (.-max-tx db))]
372375 db-before (atom nil )
373376 tx-data (atom nil )
374377 tempids (atom nil )
378+ error (atom nil )
375379 db-after (swap! conn (fn [db]
376- (let [raw-datoms (mapcat #(entity->tx-data db %) entities)
377- datoms (map #(resolve-eid db %) raw-datoms)]
378- (reset! db-before db)
379- (reset! tx-data datoms)
380- (reset! tempids (->> raw-datoms
381- (filter #(neg? (.-e %)))
382- (map #(vector (.-e %) (-resolve-eid (.-e %) db)))
383- (into {})))
384- (-with db datoms))))
385- report (TxReport. @db-before db-after @tx-data)]
386- (doseq [[_ l] @(:listeners meta)]
387- (l report))
388- (assoc report :tempids @tempids)))
380+ (let [raw-datoms (try (mapcat #(entity->tx-data db %) entities)
381+ (catch js/Object e
382+ (reset! error e)))
383+ ]
384+ (if @error
385+ db
386+ (let [datoms (map #(resolve-eid db %) raw-datoms)]
387+ (reset! db-before db)
388+ (reset! tx-data datoms)
389+ (reset! tempids (->> raw-datoms
390+ (filter #(neg? (.-e %)))
391+ (map #(vector (.-e %) (-resolve-eid (.-e %) db)))
392+ (into {})))
393+ (-with db datoms)))
394+ )))]
395+ (if-let [e @error]
396+ (throw e)
397+ (let [report (TxReport. @db-before db-after @tx-data)]
398+ (doseq [[_ l] @(:listeners meta)]
399+ (l report))
400+ (assoc report :tempids @tempids)))))
389401
390402(defn listen!
391403 ([conn callback] (listen! conn (rand ) callback))
Original file line number Diff line number Diff line change 8484 :where [1 :aka ?v]] @conn)
8585 #{[" Devil" ] [" Tupen" ]}))))
8686
87+ (deftest test-db-fn
88+ (let [conn (d/create-conn {:aka { :cardinality :many }})
89+ inc-age (fn [db name]
90+ (if-let [[eid age] (first (d/q '{:find [?e ?age]
91+ :in [$ ?name]
92+ :where [[?e :name ?name]
93+ [?e :age ?age]]}
94+ db name))]
95+ [{:db/id eid :age (inc age)} [:db/add eid :had-birthday true ]]
96+ (throw (js/Error. (str " No entity with name: " name)))
97+ ))]
98+ (d/transact! conn [{:db/id 1 :name " Ivan" :age 31 }])
99+ (d/transact! conn [[:db/add 1 :name " Petr" ]])
100+ (d/transact! conn [[:db/add 1 :aka " Devil" ]])
101+ (d/transact! conn [[:db/add 1 :aka " Tupen" ]])
102+ (is (= (d/q '[:find ?v ?a
103+ :where [?e :name ?v]
104+ [?e :age ?a]] @conn)
105+ #{[" Petr" 31 ]}))
106+ (is (= (d/q '[:find ?v
107+ :where [?e :aka ?v]] @conn)
108+ #{[" Devil" ] [" Tupen" ]}))
109+ (is (thrown-with-msg? js/Error #"No entity with name: Bob"
110+ (d/transact! conn [[:db.fn/call inc-age " Bob" ]])))
111+ (let [{:keys [db-after]} (d/transact! conn [[:db.fn/call inc-age " Petr" ]])
112+ e (d/entity db-after 1 )]
113+ (is (= (:age e) 32 ))
114+ (is (:had-birthday e)))))
115+
87116
88117(deftest test-resolve-eid
89118 (let [conn (d/create-conn )
457486 #(reverse (sort %))))
458487 #{[:red [5 4 3 2 1 ]] [:blue [8 7 ]]})))))
459488
489+
490+
460491; ; (t/test-ns 'test.datomicscript)
461492
462493; ; Performance
You can’t perform that action at this time.
0 commit comments