Improve semantics; add search-index function

This commit is contained in:
Jeremy Dormitzer 2018-02-18 18:26:49 -05:00
parent c4c50565b6
commit 210a91b17a
No known key found for this signature in database
GPG Key ID: 04F17C0F5A32C320

View File

@ -1,21 +1,21 @@
(ns looped-in.indexeddb (ns looped-in.indexeddb
(:require [cljs.core.async :refer [go chan >!]] (:require [cljs.core.async :refer [go chan >! close!]]
[looped-in.logging :as log])) [looped-in.logging :as log]))
(defn add-data (defn add-data
"Adds data to IndexedDB" "Adds data to IndexedDB"
[db object-store data] [db object-store data]
(let [channel (chan) (let [channel (chan)
transaction (.transaction db (clj->js [object-store]) "readwrite") transaction (.transaction db (array object-store) "readwrite")
store (.objectStore transaction object-store) store (.objectStore transaction object-store)
data-coll (if (coll? data) data [data])] data-coll (if (coll? data) data [data])]
(doseq [datum data-coll] (doseq [datum data-coll]
(.add store datum)) (.add store datum))
(set! (.-onerror transaction) (set! (.-onerror transaction)
(fn [event] (log/error "Error adding data to IndexedDB: " (fn [event] (log/error "Error adding data to IndexedDB: "
(.-errorCode (.-target event))))) (.-message (.-error (.-target event))))))
(set! (.-oncomplete transaction) (set! (.-oncomplete transaction)
(fn [event] (go (>! channel (.-result (.-target event)))))) (fn [event] (close! channel)))
channel)) channel))
(defn get-data (defn get-data
@ -23,14 +23,37 @@
[db object-store index] [db object-store index]
(let [channel (chan) (let [channel (chan)
request (-> db request (-> db
(.transaction (clj->js [object-store])) (.transaction (array object-store))
(.objectStore objectStore) (.objectStore object-store)
(.get index))] (.get index))]
(set! (.-onerror request) (set! (.-onerror request)
(fn [event] (log/error "Error getting data from IndexedDB: " (fn [event] (log/error "Error getting data from IndexedDB: "
(.-errorCode (.-target event))))) (.-message (.-error (.-target event))))))
(set! (.-onsuccess request) (set! (.-onsuccess request)
(fn [event] (go (>! channel (.-result (.-target event)))))) (fn [event] (let [res (.-result (.-target event))]
(if (nil? res) (close! channel) (go (>! channel res))))))
channel))
(defn search-index
"Returns a channel of all data objects matching the index query.
The channel will contain multiple values if there are multiple matches."
[db object-store index query]
(let [channel (chan)
request (-> db
(.transaction (array object-store))
(.objectStore object-store)
(.index index)
(.openCursor query))]
(set! (.-onerror request)
(fn [event] (log/error "Error opening cursor into IndexedDB: "
(.-message (.-error (.-target event))))))
(set! (.-onsuccess request)
(fn [event]
(let [cursor (.-result (.-target event))]
(if (nil? cursor)
(close! channel)
(do (go (>! channel (.-value cursor)))
(.continue cursor))))))
channel)) channel))
(defn update-data (defn update-data
@ -40,19 +63,19 @@
[db object-store index updated-values] [db object-store index updated-values]
(let [channel (chan) (let [channel (chan)
store (-> db store (-> db
(.transaction (clj->js [object-store]) "readwrite") (.transaction (array object-store) "readwrite")
(.objectStore object-store)) (.objectStore object-store))
get-request (.get store index)] get-request (.get store index)]
(set! (.-onerror get-request) (set! (.-onerror get-request)
(fn [event] (log/error "Error getting data from IndexedDB: " (fn [event] (log/error "Error getting data from IndexedDB: "
(.-errorCode (.-target event))))) (.-message (.-error (.-target event))))))
(set! (.-onsuccess get-request) (set! (.-onsuccess get-request)
(fn [event] (fn [event]
(let [data (js->clj (.-result (.-target event)) :keywordize-keys true) (let [data (js->clj (.-result (.-target event)) :keywordize-keys true)
update-request (.put store (clj->js (merge data updated-values)))] update-request (.put store (clj->js (merge data updated-values)))]
(set! (.-onerror update-request) (set! (.-onerror update-request)
(fn [event] (log/error "Error updating data in IndexedDB: " (fn [event] (log/error "Error updating data in IndexedDB: "
(.-errorCode (.-target event))))) (.-message (.-error (.-target event))))))
(set! (.-onsuccess update-request) (set! (.-onsuccess update-request)
(fn [event] (go (>! channel (.-result (.-target event))))))))) (fn [event] (go (>! channel (.-result (.-target event)))))))))
channel)) channel))
@ -62,14 +85,14 @@
[db object-store index] [db object-store index]
(let [channel (chan) (let [channel (chan)
request (-> db request (-> db
(.transaction (clj->js [object-store]) "readwrite") (.transaction (array object-store) "readwrite")
(.objectStore object-store) (.objectStore object-store)
(.delete index))] (.delete index))]
(set! (.onerror request) (set! (.-onerror request)
(fn [event] (log/error "Error deleting data from IndexedDB: " (fn [event] (log/error "Error deleting data from IndexedDB: "
(.-errorCode (.-target event))))) (.-message (.-error (.-target event))))))
(set! (.onsuccess request) (set! (.-onsuccess request)
(fn [event] (go (>! channel (.-result (.-target event)))))) (fn [event] (close! channel)))
channel)) channel))
(defn open-database (defn open-database
@ -81,11 +104,13 @@
request (.open js/window.indexedDB name version)] request (.open js/window.indexedDB name version)]
(set! (.-onerror request) (set! (.-onerror request)
(fn [event] (log/error "Error opening IndexedDB: " (fn [event] (log/error "Error opening IndexedDB: "
(.-errorCode (.-target event))))) (.-message (.-error (.-target event))))))
(set! (.-onsuccess request) (set! (.-onsuccess request)
(fn [event] (go (>! channel (.-result (.-target event)))))) (fn [event] (go (>! channel (.-result (.-target event))))))
channel))) channel)))
;; The problem is that clj->js is not camelCasing keys
(defn create-database (defn create-database
"Creates an IndexedDB database and returns a channel that resolves with a database instance. "Creates an IndexedDB database and returns a channel that resolves with a database instance.
If the database has already been created with the specified version, If the database has already been created with the specified version,
@ -99,7 +124,7 @@
(set! (.-onerror request) (set! (.-onerror request)
(fn [event] (fn [event]
(log/error "Error opening IndexedDB: " (log/error "Error opening IndexedDB: "
(.-errorCode (.-target event))))) (.-message (.-error (.-target event))))))
(set! (.-onupgradeneeded request) (set! (.-onupgradeneeded request)
(fn [event] (fn [event]
(let [db (.-result (.-target event))] (let [db (.-result (.-target event))]
@ -107,9 +132,9 @@
(let [store (.createObjectStore db (let [store (.createObjectStore db
(:name object-store) (:name object-store)
(clj->js (clj->js
{:key-path {:keyPath
(:key-path object-store) (:key-path object-store)
:auto-increment :autoIncrement
(:auto-increment? object-store)}))] (:auto-increment? object-store)}))]
(doseq [index (:indices object-store)] (doseq [index (:indices object-store)]
(.createIndex store (.createIndex store
@ -117,11 +142,12 @@
(:key-path index) (:key-path index)
(clj->js (:opts index))))))))) (clj->js (:opts index)))))))))
(set! (.-onsuccess request) (set! (.-onsuccess request)
(go (>! channel (.-result (.-target event))))) (fn [event]
(go (>! channel (.-result (.-target event))))))
channel))) channel)))
(defn create-object-store (defn create-object-store
"Creates an object store data structure. "Creates an object store data structure for use with `looped-in.indexeddb/create-database`.
`indices` is a sequence of index maps `indices` is a sequence of index maps
created via `looped-in.indexeddb/create-index`." created via `looped-in.indexeddb/create-index`."
([store-name key-path] ([store-name key-path]
@ -133,7 +159,7 @@
(defn create-index (defn create-index
"Creates an index for use with `looped-in.indexeddb/create-object-store`. "Creates an index for use with `looped-in.indexeddb/create-object-store`.
`opts` is a map of options. Valid keys are :unique and :multi-entry, as `opts` is a map of options. Valid keys are :unique and :multiEntry, as
documented at https://developer.mozilla.org/en-US/docs/Web/API/IDBObjectStore/createIndex." documented at https://developer.mozilla.org/en-US/docs/Web/API/IDBObjectStore/createIndex."
([name] ([name]
(create-index name name)) (create-index name name))