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) {
let txResult = await db.transact([{"db/id": 55,
"page/title": title,
"page/url": url
// "page/starred": true
}]);
let datom = {"db/id": 55, "page/url": url};
if (title) {
datom["page/title"] = title;
}
if (content) {
datom["page/content"] = content;
}
let txResult = await db.transact([datom]);
return txResult;
}
async function handleClick(state) {
let db = await datomish.open("/tmp/testing.db");
await db.ensureSchema(schema);
let txResult = await savePage(db, tabs.activeTab.url, tabs.activeTab.title, "Content goes here");
console.log("Transaction returned " + JSON.stringify(txResult));
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]);
console.log("Query results: " + JSON.stringify(results));
let pages = await findPagesMatching(db, "goes");
console.log("Pages: " + JSON.stringify(pages));
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({
id: "datomish-save",
label: "Save Page",

View file

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

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))