Review comment: extracted shared go-promise.

This commit is contained in:
Richard Newman 2016-09-21 18:07:34 -07:00
parent 03d8d178fb
commit d0a04a5e56
3 changed files with 72 additions and 73 deletions

View file

@ -53,49 +53,37 @@ async function findPagesMatching(db, string) {
} }
async function savePage(db, url, title, content) { async function savePage(db, url, title, content) {
let txResult = await db.transact([{"db/id": 55, let datom = {"db/id": 55, "page/url": url};
"page/title": title, if (title) {
"page/url": url datom["page/title"] = title;
// "page/starred": true }
}]); if (content) {
datom["page/content"] = content;
}
let txResult = await db.transact([datom]);
return txResult; return txResult;
} }
async function handleClick(state) { async function handleClick(state) {
let db = await datomish.open("/tmp/testing.db"); let db = await datomish.open("/tmp/testing.db");
await db.ensureSchema(schema); await db.ensureSchema(schema);
let txResult = await savePage(db, tabs.activeTab.url, tabs.activeTab.title, "Content goes here"); let txResult = await savePage(db, tabs.activeTab.url, tabs.activeTab.title, "Content goes here");
console.log("Transaction returned " + JSON.stringify(txResult)); console.log("Transaction returned " + JSON.stringify(txResult));
console.log("Transaction instant: " + txResult.txInstant); console.log("Transaction instant: " + txResult.txInstant);
let results = await findURLs(db); //datomish.q(db.db(), "[:find ?url :in $ :where [?e :page/url ?url]]");
let results = await findURLs(db);
results = results.map(r => r[1]); results = results.map(r => r[1]);
console.log("Query results: " + JSON.stringify(results)); console.log("Query results: " + JSON.stringify(results));
let pages = await findPagesMatching(db, "goes"); let pages = await findPagesMatching(db, "goes");
console.log("Pages: " + JSON.stringify(pages)); console.log("Pages: " + JSON.stringify(pages));
await db.close(); await db.close();
} }
/*
async function handleClick(state) {
console.log("Handling click: " + state);
let tab = tabs.activeTab;
console.log("Active tab: " + tab);
console.log("Active tab: " + tab.url);
console.log("Active tab: " + tab.title);
let db = await initDB("/tmp/datomish.db");
console.log("Opened DB: " + db);
await savePage(db, tab.url, tab.title, "Content goes here.");
console.log("Saved page.");
let urls = await findURLs(db);
console.log("URLs: " + JSON.stringify(urls));
let results = await findPagesMatching(db, "goes");
console.log("Pages: " + JSON.stringify(results));
await db.close();
}
*/
var button = buttons.ActionButton({ var button = buttons.ActionButton({
id: "datomish-save", id: "datomish-save",
label: "Save Page", label: "Save Page",

View file

@ -5,7 +5,8 @@
(ns datomish.js (ns datomish.js
(:refer-clojure :exclude []) (:refer-clojure :exclude [])
(:require-macros (:require-macros
[datomish.pair-chan :refer [go-pair <?]]) [datomish.pair-chan :refer [go-pair <?]]
[datomish.promises :refer [go-promise]])
(:require (:require
[cljs.core.async :as a :refer [take! <! >!]] [cljs.core.async :as a :refer [take! <! >!]]
[cljs.reader] [cljs.reader]
@ -14,23 +15,12 @@
[datomish.db :as db] [datomish.db :as db]
[datomish.db-factory :as db-factory] [datomish.db-factory :as db-factory]
[datomish.pair-chan] [datomish.pair-chan]
[datomish.promises :refer [take-pair-as-promise!]]
[datomish.sqlite :as sqlite] [datomish.sqlite :as sqlite]
[datomish.simple-schema :as simple-schema] [datomish.simple-schema :as simple-schema]
[datomish.js-sqlite :as js-sqlite] [datomish.js-sqlite :as js-sqlite]
[datomish.transact :as transact])) [datomish.transact :as transact]))
(defn- take-pair-as-promise! [ch f]
;; Just like take-as-promise!, but aware that it's handling a pair channel.
;; Also converts values, if desired.
(promise
(fn [resolve reject]
(letfn [(split-pair [[v e]]
(if e
(do
(println "Got error:" e)
(reject e))
(resolve (f v))))]
(cljs.core.async/take! ch split-pair)))))
;; Public API. ;; Public API.
@ -40,13 +30,9 @@
(defn ^:export q [db find options] (defn ^:export q [db find options]
(let [find (cljs.reader/read-string find) (let [find (cljs.reader/read-string find)
opts (cljify options)] opts (cljify options)]
(println "Running query " (pr-str find) (pr-str {:foo find}) (pr-str opts))
(take-pair-as-promise! (take-pair-as-promise!
(go-pair (db/<?q db find opts)
(let [res (<? (db/<?q db find opts))] clj->js)))
(println "Got results: " (pr-str res))
(clj->js res)))
identity)))
(defn ^:export ensure-schema [conn simple-schema] (defn ^:export ensure-schema [conn simple-schema]
(let [simple-schema (cljify simple-schema) (let [simple-schema (cljify simple-schema)
@ -67,35 +53,30 @@
(try (try
(let [tx-data (js->tx-data tx-data)] (let [tx-data (js->tx-data tx-data)]
(println "Transacting:" (pr-str tx-data)) (println "Transacting:" (pr-str tx-data))
(take-pair-as-promise! (go-promise clj->js
(go-pair (let [tx-result (<? (transact/<transact! conn tx-data))]
(let [tx-result (<? (transact/<transact! conn tx-data))] (select-keys tx-result
(select-keys tx-result [:tempids
[:tempids :added-idents
:added-idents :added-attributes
:added-attributes :tx
:tx :txInstant]))))
:txInstant])))
clj->js))
(catch js/Error e (catch js/Error e
(println "Error in transact:" e)))) (println "Error in transact:" e))))
(defn ^:export open [path] (defn ^:export open [path]
;; Eventually, URI. For now, just a plain path (no file://). ;; Eventually, URI. For now, just a plain path (no file://).
(take-pair-as-promise! (go-promise clj->js
(go-pair (let [conn (<? (sqlite/<sqlite-connection path))
(let [conn (<? (sqlite/<sqlite-connection path)) db (<? (db-factory/<db-with-sqlite-connection conn))]
db (<? (db-factory/<db-with-sqlite-connection conn))] (let [c (transact/connection-with-db db)]
(let [c (transact/connection-with-db db)] ;; We pickle the connection as a thunk here so it roundtrips through JS
(clj->js ;; without incident.
;; We pickle the connection as a thunk here so it roundtrips through JS {:conn (fn [] c)
;; without incident. :roundtrip (fn [x] (clj->js (cljify x)))
{:conn (fn [] c) :db (fn [] (transact/db c))
:roundtrip (fn [x] (clj->js (cljify x))) :ensureSchema (fn [simple-schema] (ensure-schema c simple-schema))
:db (fn [] (transact/db c)) :transact (fn [tx-data] (transact c tx-data))
:ensureSchema (fn [simple-schema] (ensure-schema c simple-schema)) :close (fn [] (db/close-db db))
:transact (fn [tx-data] (transact c tx-data)) :toString (fn [] (str "#<DB " path ">"))
:close (fn [] (db/close-db db)) :path path}))))
:toString (fn [] (str "#<DB " path ">"))
:path path}))))
identity))

View file

@ -0,0 +1,30 @@
(ns datomish.promises
#?(:cljs
(:require-macros
[datomish.pair-chan :refer [go-pair <?]]))
(:require
#?@(:clj [[datomish.pair-chan :refer [go-pair]]
[clojure.core.async :as a :refer [take!]]])
#?@(:cljs [[cljs-promises.core :refer [promise]]
[cljs.core.async :as a :refer [take!]]])))
(defn take-pair-as-promise!
"Just like take-as-promise!, but aware that it's handling a pair channel.
Also converts values, if desired."
([ch]
(take-pair-as-promise! ch identity))
([ch f]
(promise
(fn [resolve reject]
(take!
ch
(fn [[v e]]
(if e
(reject e)
(resolve (f v)))))))))
(defmacro go-promise [f & body]
`(datomish.promises/take-pair-as-promise!
(datomish.pair-chan/go-pair
~@body)
~f))