diff --git a/src/computersandblues/lodestone/app.cljs b/src/computersandblues/lodestone/app.cljs index 3cc4915..8234e39 100644 --- a/src/computersandblues/lodestone/app.cljs +++ b/src/computersandblues/lodestone/app.cljs @@ -349,7 +349,7 @@ refresh-id (js/Date.now)] (swap! state update-in [:section/posts :loading] conj refresh-id) (-> (js/Promise.all #js [(db/count! ::db/posts) - (-> (db/open-cursor! ::db/posts db/all "prev") + (-> (db/open-cursor! ::db/posts "created_at" db/all "prev") (db/transduce-cursor xform))]) (.then (fn [[total displayed-posts]] (swap! state update :section/posts #(-> (assoc % :total total) @@ -407,12 +407,15 @@ ;; database -(def db-version 1) +(def db-version 2) (def migrations - {1 (fn migration-0001 [db] + {1 (fn migration-0001 [db _] (db/create-object-store! db ::db/application {:keyPath "id"}) - (db/create-object-store! db ::db/posts {:keyPath "id"}))}) + (db/create-object-store! db ::db/posts {:keyPath "id"})) + 2 (fn migration-0002 [_ txn] + (-> (db/open-store txn ::db/posts "readwrite") + (db/create-index! "created_at" "created_at" {:unique false})))}) ;; go go go diff --git a/src/computersandblues/lodestone/database.cljs b/src/computersandblues/lodestone/database.cljs index 74eb843..89faecc 100644 --- a/src/computersandblues/lodestone/database.cljs +++ b/src/computersandblues/lodestone/database.cljs @@ -21,25 +21,34 @@ (.addEventListener "upgradeneeded" (fn [ev] (let [db (.-result request) - old-version (.-oldVersion ev)] + old-version (.-oldVersion ev) + txn (-> ev .-target .-transaction)] (js/console.log ::upgradeneeded ev db) (doseq [version (range (inc old-version) (inc db-version)) :let [migration (migrations version)]] - (migration db))))) + (migration db txn))))) ; we don't add a listener for "blocked" events because we handle "versionchange" above (.addEventListener "error" (fn [ev] (reject (.-result request) ev)))))))) (defn open-store - ([db store-id] - (open-store db store-id "readonly")) - ([db store-id permissions] + ([db-or-txn store-id] + (open-store db-or-txn store-id "readonly")) + ([db-or-txn store-id permissions] (let [store-id (str store-id) ; simplifies using keywords as store identifiers - txn (.transaction db store-id permissions)] + txn (if (instance? js/IDBTransaction db-or-txn) + db-or-txn + (.transaction db-or-txn store-id permissions))] (.objectStore txn store-id)))) (defn create-object-store! [db store-id key-opts] (.createObjectStore db (str store-id) (clj->js key-opts))) +(defn create-index! + ([store idx-name fields] + (create-index! store idx-name fields {})) + ([store idx-name fields opts] + (.createIndex store (str idx-name) (clj->js fields) (clj->js opts)))) + (defn- promisify [request] (js/Promise. (fn [resolve reject] (doto request @@ -70,7 +79,10 @@ ([store-id key-range] (open-cursor! store-id key-range "next")) ([store-id key-range direction] (let [store (open-store @+db+ store-id)] - (.openCursor store key-range direction)))) + (.openCursor store key-range direction))) + ([store-id idx-name key-range direction] + (let [store (open-store @+db+ store-id)] + (.openCursor (.index store (str idx-name)) key-range direction)))) #_(defn logging [f] (let [n (volatile! 0)]