Browse Source

fix: don't record local txs for remote graph

Tienson Qin 4 weeks ago
parent
commit
de1c58b02a

+ 2 - 1
deps/db/src/logseq/db/frontend/kv_entity.cljs

@@ -40,4 +40,5 @@ RTC won't start when major-schema-versions don't match"
      :logseq.kv/graph-text-embedding-model-name   {:doc "Graph's text-embedding model name"
                                                    :rtc {:rtc/ignore-entity-when-init-upload true
                                                          :rtc/ignore-entity-when-init-download true}}
-     :logseq.kv/graph-rtc-e2ee?              {:doc "true if it's a rtc graph with E2EE enabled"})))
+     :logseq.kv/graph-rtc-e2ee?              {:doc "true if it's a rtc graph with E2EE enabled"}
+     :logseq.kv/graph-remote?                {:doc "true if it's a remote graph"})))

+ 4 - 2
deps/db/src/logseq/db/sqlite/create_graph.cljs

@@ -222,7 +222,7 @@
 (defn build-db-initial-data
   "Builds tx of initial data for a new graph including key values, initial files,
    built-in properties and built-in classes"
-  [config-content & {:keys [import-type graph-git-sha]}]
+  [config-content & {:keys [import-type graph-git-sha remote-graph?]}]
   (assert (string? config-content))
   (let [initial-data (cond->
                       [(sqlite-util/kv :logseq.kv/db-type "db")
@@ -236,9 +236,11 @@
                        (into (sqlite-util/import-tx import-type))
                        graph-git-sha
                        (conj (sqlite-util/kv :logseq.kv/graph-git-sha graph-git-sha))
+                       remote-graph?
+                       (conj (sqlite-util/kv :logseq.kv/graph-remote? remote-graph?))
                        true
                        (conj (sqlite-util/kv :logseq.kv/local-graph-uuid
-                                             (uuid (str "loc" (subs (str (common-uuid/gen-uuid)) 3))))))
+                                             (uuid (str "00000000" (subs (str (common-uuid/gen-uuid)) 8))))))
         initial-files (build-initial-files config-content)
         {properties-tx :tx :keys [properties]} (build-initial-properties)
         db-ident->properties (zipmap (map :db/ident properties) properties)

+ 2 - 1
src/main/frontend/components/repo.cljs

@@ -454,7 +454,8 @@
                        (invalid-graph-name-warning)
                        (do
                          (set-creating-db? true)
-                         (p/let [repo (repo-handler/new-db! graph-name)]
+                         (p/let [repo (repo-handler/new-db! graph-name
+                                                            {:remote-graph? cloud?})]
                            (when cloud?
                              (->
                               (p/do

+ 3 - 2
src/main/frontend/handler/repo.cljs

@@ -134,12 +134,13 @@
   (let [full-graph-name (string/lower-case (str config/db-version-prefix graph-name))]
     (some #(= (some-> (:url %) string/lower-case) full-graph-name) (state/get-repos))))
 
-(defn- create-db [full-graph-name {:keys [file-graph-import?]}]
+(defn- create-db [full-graph-name {:keys [file-graph-import? remote-graph?]}]
   (->
    (p/let [config config/config-default-content
            _ (persist-db/<new full-graph-name
                               (cond-> {:config config
-                                       :graph-git-sha config/revision}
+                                       :graph-git-sha config/revision
+                                       :remote-graph? remote-graph?}
                                 file-graph-import? (assoc :import-type :file-graph)))
            _ (start-repo-db-if-not-exists! full-graph-name)
            _ (state/add-repo! {:url full-graph-name :root (config/get-local-dir full-graph-name)})

+ 3 - 2
src/main/frontend/worker/db_worker.cljs

@@ -289,8 +289,9 @@
         (let [initial-tx-report (when (and (not initial-data-exists?) (not datoms))
                                   (let [config (or config "")
                                         initial-data (sqlite-create-graph/build-db-initial-data
-                                                      config (select-keys opts [:import-type :graph-git-sha]))]
-                                    (ldb/transact! conn initial-data {:initial-db? true})))]
+                                                      config (select-keys opts [:import-type :graph-git-sha :remote-graph?]))]
+                                    (ldb/transact! conn initial-data
+                                                   {:initial-db? true})))]
           (db-migrate/migrate conn)
 
           (gc-sqlite-dbs! db client-ops-db conn {})

+ 13 - 4
src/main/frontend/worker/sync.cljs

@@ -426,6 +426,15 @@
       (when-let [client (current-client repo)]
         (broadcast-rtc-state! client)))))
 
+(comment
+  (defn- clear-pending-txs!
+    [repo]
+    (when-let [conn (client-ops-conn repo)]
+      (let [tx-data (->> (d/datoms @conn :avet :db-sync/created-at)
+                         (map (fn [d]
+                                [:db/retractEntity (:e d)])))]
+        (d/transact! conn tx-data)))))
+
 (defn get-lookup-id
   [x]
   (when (and (vector? x)
@@ -1030,12 +1039,11 @@
                                              (flush-pending! repo current))))))))))))))))))
 
 (defn handle-local-tx!
-  [repo {:keys [tx-data tx-meta] :as tx-report}]
+  [repo {:keys [tx-data tx-meta db-after] :as tx-report}]
   (when (and (enabled?) (seq tx-data)
              (not (:rtc-tx? tx-meta))
              (:persist-op? tx-meta true)
-             ;; (ldb/get-graph-rtc-uuid (:db-after tx-report))
-             )
+             (:kv/value (d/entity db-after :logseq.kv/graph-remote?)))
     (enqueue-local-tx! repo tx-report)
     (when-let [client @worker-state/*db-sync-client]
       (when (= repo (:repo client))
@@ -1096,7 +1104,8 @@
 (defn- set-graph-e2ee-enabled!
   [repo]
   (when-let [conn (worker-state/get-datascript-conn repo)]
-    (ldb/transact! conn [(ldb/kv :logseq.kv/graph-rtc-e2ee? true)])))
+    (ldb/transact! conn [(ldb/kv :logseq.kv/graph-remote? true)
+                         (ldb/kv :logseq.kv/graph-rtc-e2ee? true)])))
 
 (defn upload-graph!
   [repo]

+ 39 - 70
src/main/frontend/worker/undo_redo.cljs

@@ -32,6 +32,40 @@
   [tx-data]
   (boolean (some structural-tx-item? tx-data)))
 
+(defn- resolve-entity-id
+  [db value]
+  (cond
+    (int? value) value
+    (vector? value) (d/entid db value)
+    :else nil))
+
+(defn- tx-entity-ids
+  [db tx-data]
+  (->> tx-data
+       (keep (fn [item]
+               (cond
+                 (vector? item)
+                 (let [e (second item)]
+                   (resolve-entity-id db e))
+
+                 (d/datom? item)
+                 (resolve-entity-id db (:e item))
+
+                 (map? item)
+                 (or (resolve-entity-id db (:db/id item))
+                     (resolve-entity-id db [:block/uuid (:block/uuid item)]))
+
+                 :else nil)))
+       (remove nil?)
+       set))
+
+(defn- entities-exist?
+  [db tx-data]
+  (every? (fn [id]
+            (when id
+              (d/entity db id)))
+          (tx-entity-ids db tx-data)))
+
 (defn- parent-cycle?
   [ent]
   (let [start (:block/uuid ent)]
@@ -47,75 +81,6 @@
                   true
                   (recur next-ent (conj seen next-uuid) (inc steps))))))))
 
-(defn- db-issues
-  [db]
-  (let [ents (->> (d/q '[:find [?e ...]
-                         :where
-                         [?e :block/uuid]]
-                       db)
-                  (map (fn [e] (d/entity db e))))
-        uuid-required-ids (->> (concat
-                                (d/q '[:find [?e ...]
-                                       :where
-                                       [?e :block/title]]
-                                     db)
-                                (d/q '[:find [?e ...]
-                                       :where
-                                       [?e :block/page]]
-                                     db)
-                                (d/q '[:find [?e ...]
-                                       :where
-                                       [?e :block/parent]]
-                                     db))
-                               distinct)]
-    (concat
-     (for [e uuid-required-ids
-           :let [ent (d/entity db e)]
-           :when (nil? (:block/uuid ent))]
-       {:type :missing-uuid :e e})
-     (for [ent ents
-           :let [uuid (:block/uuid ent)
-                 parent (:block/parent ent)]
-           :when (and (not (ldb/page? ent)) (nil? parent))]
-       {:type :missing-parent :uuid uuid})
-     (for [ent ents
-           :let [uuid (:block/uuid ent)
-                 parent (:block/parent ent)]
-           :when (and (not (ldb/page? ent)) parent (nil? (:block/uuid parent)))]
-       {:type :missing-parent-ref :uuid uuid})
-     (for [ent ents
-           :let [uuid (:block/uuid ent)
-                 page (:block/page ent)]
-           :when (and (not (ldb/page? ent)) (nil? page))]
-       {:type :missing-page :uuid uuid})
-     (for [ent ents
-           :let [uuid (:block/uuid ent)
-                 page (:block/page ent)]
-           :when (and (not (ldb/page? ent)) page (not (ldb/page? page)))]
-       {:type :page-not-page :uuid uuid})
-     (for [ent ents
-           :let [uuid (:block/uuid ent)
-                 parent (:block/parent ent)
-                 page (:block/page ent)
-                 expected-page (when parent
-                                 (if (ldb/page? parent) parent (:block/page parent)))]
-           :when (and (not (ldb/page? ent))
-                      parent
-                      page
-                      expected-page
-                      (not= (:block/uuid expected-page) (:block/uuid page)))]
-       {:type :page-mismatch :uuid uuid})
-     (for [ent ents
-           :let [uuid (:block/uuid ent)
-                 parent (:block/parent ent)]
-           :when (and parent (= uuid (:block/uuid parent)))]
-       {:type :self-parent :uuid uuid})
-     (for [ent ents
-           :let [uuid (:block/uuid ent)]
-           :when (and (not (ldb/page? ent))
-                      (parent-cycle? ent))]
-       {:type :cycle :uuid uuid}))))
-
 (defn- issues-for-entity-ids
   [db ids]
   (let [id->ent (->> ids
@@ -211,7 +176,11 @@
   [conn tx-data]
   (try
     (if-not (structural-tx? tx-data)
-      true
+      (if (entities-exist? @conn tx-data)
+        true
+        (do
+          (log/warn ::undo-redo-invalid {:reason :missing-entities})
+          false))
       (let [db-before @conn
             tx-report (d/with db-before tx-data)
             db-after (:db-after tx-report)

+ 5 - 5
src/test/frontend/undo_redo_test.cljs

@@ -320,8 +320,8 @@
   (testing "undo validation skips db-issues for non-structural tx-data"
     (let [conn (db/get-db test-db false)
           {:keys [child-uuid]} (seed-page-parent-child!)]
-      (with-redefs [frontend.worker.undo-redo/db-issues (fn [_]
-                                                          (throw (js/Error. "db-issues called")))]
+      (with-redefs [undo-validate/issues-for-entity-ids (fn [_ _]
+                                                          (throw (js/Error. "issues-for-entity-ids called")))]
         (is (true? (undo-validate/valid-undo-redo-tx?
                     conn
                     [[:db/add [:block/uuid child-uuid] :block/title "child-updated"]])))))))
@@ -331,9 +331,9 @@
     (let [conn (db/get-db test-db false)
           {:keys [page-uuid child-uuid]} (seed-page-parent-child!)
           calls (atom 0)]
-      (with-redefs [frontend.worker.undo-redo/issues-for-entity-ids (fn [_ _]
-                                                                      (swap! calls inc)
-                                                                      [])]
+      (with-redefs [undo-validate/issues-for-entity-ids (fn [_ _]
+                                                          (swap! calls inc)
+                                                          [])]
         (is (true? (undo-validate/valid-undo-redo-tx?
                     conn
                     [[:db/add [:block/uuid child-uuid] :block/parent [:block/uuid page-uuid]]])))