From e8de3cc104dca45f6620e8b758961fddc1d7dcad Mon Sep 17 00:00:00 2001 From: Tienson Qin Date: Sun, 3 May 2026 23:16:37 +0800 Subject: [PATCH] fix: sqlite import --- src/main/frontend/utils.js | 15 +++++++-- src/main/frontend/worker/db_core.cljs | 4 +-- src/test/frontend/persist_db_test.cljs | 22 +++++++++++++ src/test/frontend/worker/db_core_test.cljs | 38 ++++++++++++++++++++++ 4 files changed, 75 insertions(+), 4 deletions(-) diff --git a/src/main/frontend/utils.js b/src/main/frontend/utils.js index 248ed36c57..ea4becd7f5 100644 --- a/src/main/frontend/utils.js +++ b/src/main/frontend/utils.js @@ -517,10 +517,21 @@ export function base64ToUint8Array (base64String) { export function uint8ArrayToBase64 (uint8Array) { try { + let bytes = null + if (uint8Array instanceof Uint8Array) { + bytes = uint8Array + } else if (ArrayBuffer.isView(uint8Array)) { + bytes = new Uint8Array(uint8Array.buffer, uint8Array.byteOffset, uint8Array.byteLength) + } else if (uint8Array instanceof ArrayBuffer) { + bytes = new Uint8Array(uint8Array) + } else { + throw new TypeError('Expected Uint8Array, TypedArray, or ArrayBuffer') + } + let binary = '' - const len = uint8Array.byteLength + const len = bytes.byteLength for (let i = 0; i < len; i++) { - binary += String.fromCharCode(uint8Array[i]) + binary += String.fromCharCode(bytes[i]) } return btoa(binary) } catch (e) { diff --git a/src/main/frontend/worker/db_core.cljs b/src/main/frontend/worker/db_core.cljs index ee8810c14d..a89693fd39 100644 --- a/src/main/frontend/worker/db_core.cljs +++ b/src/main/frontend/worker/db_core.cljs @@ -918,9 +918,9 @@ (def-thread-api :thread-api/import-db-base64 [repo base64] (when-not (string/blank? repo) - (p/let [pool ( (protocol/InBrowser) "logseq_db_graph_a" payload) + (p/then (fn [_] + (is (= [[:thread-api/import-db-base64 ["logseq_db_graph_a" "c3FsaXRlLWJ5dGVz"]]] + @worker-import-calls)))) + (p/catch (fn [e] + (is false (str "unexpected error: " e)))) + (p/finally + (fn [] + (set! state/ + (restoring-worker-state + (fn [] + (let [import-db! (get @thread-api/*thread-apis :thread-api/import-db-base64) + imported-pool-ids (atom []) + pool-seq (atom 0) + make-pool (fn [id] + (let [pool #js {:id id + :paused false}] + (set! (.-pauseVfs pool) (fn [] (set! (.-paused pool) true))) + (set! (.-unpauseVfs pool) (fn [] (set! (.-paused pool) false))) + pool)) + existing-pool (make-pool "existing-pool") + sqlite-data (.encode (js/TextEncoder.) "SQLite format 3") + sqlite-base64 (.toString (js/Buffer.from sqlite-data) "base64")] + (reset! worker-state/*opfs-pools {test-repo existing-pool}) + (let [platform' (build-test-platform + {:import-db (fn [pool _path _data] + (swap! imported-pool-ids conj (.-id pool)) + (if (.-paused pool) + (p/rejected (js/Error. "No available handles to import to.")) + (p/resolved nil)))})] + (platform/set-platform! + (assoc platform' + :storage + (assoc (:storage platform') + :install-opfs-pool (fn [_sqlite _pool-name] + (let [id (str "new-pool-" (swap! pool-seq inc))] + (p/resolved (make-pool id)))))))) + (-> (import-db! test-repo sqlite-base64) + (p/then (fn [_] + (is (= ["new-pool-1"] @imported-pool-ids)))) + (p/catch (fn [error] + (is false (str "expected import to succeed with active pool, got " error)))))))) + (p/finally done)))) + (deftest set-db-sync-config-keeps-only-non-auth-fields-test (let [set-config! (get @thread-api/*thread-apis :thread-api/set-db-sync-config) get-config (get @thread-api/*thread-apis :thread-api/get-db-sync-config)