Improve semantics; add search-index function
This commit is contained in:
parent
c4c50565b6
commit
210a91b17a
@ -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))
|
||||||
|
Loading…
Reference in New Issue
Block a user