mirror of
https://github.com/logseq/logseq.git
synced 2026-02-01 22:47:36 +00:00
fix: parent cycle
This commit is contained in:
@@ -9,10 +9,8 @@
|
||||
(defn- ref->eid [db ref]
|
||||
(cond
|
||||
(nil? ref) nil
|
||||
(number? ref) ref
|
||||
(number? ref) (when (pos? ref) ref)
|
||||
(vector? ref) (d/entid db ref)
|
||||
(instance? Entity ref) (.-eid ^Entity ref)
|
||||
(uuid? ref) (d/entid db [:block/uuid ref])
|
||||
(keyword? ref) (d/entid db [:db/ident ref])
|
||||
:else nil))
|
||||
|
||||
@@ -64,8 +62,6 @@
|
||||
"Returns a map with cycle details when applying tx-data would introduce a cycle.
|
||||
Otherwise returns nil."
|
||||
[db tx-data]
|
||||
(prn :debug :detect-cycle
|
||||
tx-data)
|
||||
(reduce
|
||||
(fn [_ attr]
|
||||
(let [updates (attr-updates-from-tx tx-data attr)
|
||||
@@ -109,6 +105,6 @@
|
||||
(when parent-uuid
|
||||
[:block/uuid parent-uuid]))
|
||||
:else current-raw)]
|
||||
(assoc acc (pr-str entity-ref) current)))
|
||||
(assoc acc [:block/uuid (:block/uuid (d/entity db eid))] current)))
|
||||
{}
|
||||
updates)))
|
||||
|
||||
@@ -106,8 +106,9 @@
|
||||
(defn- cycle-reject-response [db tx-data {:keys [attr]}]
|
||||
{:type "tx/reject"
|
||||
:reason "cycle"
|
||||
:attr (name attr)
|
||||
:server_values (common/write-transit (cycle/server-values-for db tx-data attr))})
|
||||
:data (common/write-transit
|
||||
{:attr attr
|
||||
:server_values (cycle/server-values-for db tx-data attr)})})
|
||||
|
||||
(defn- journal-page-info []
|
||||
(let [now (common/now-ms)
|
||||
@@ -171,9 +172,7 @@
|
||||
tx-data))
|
||||
|
||||
(defn- fix-missing-parent [db tx-data]
|
||||
(let [_ (prn :debug 1)
|
||||
updates (attr-updates-from-tx tx-data :block/parent)
|
||||
_ (prn :debug 2)
|
||||
(let [updates (attr-updates-from-tx tx-data :block/parent)
|
||||
journal (journal-page-info)
|
||||
journal-ref [:block/uuid (:uuid journal)]
|
||||
journal-tx (build-journal-page-tx db journal)
|
||||
@@ -301,6 +300,16 @@
|
||||
[op e' a v'])))
|
||||
tx-data))
|
||||
|
||||
(defn- fix-tx-data
|
||||
[db tx-data]
|
||||
(if (some (fn [[op _e a v]]
|
||||
(= [op a v] [:db/add :db/ident :logseq.class/Root]))
|
||||
tx-data) ; initial data
|
||||
tx-data
|
||||
(->> tx-data
|
||||
(fix-missing-parent db)
|
||||
(fix-duplicate-orders db))))
|
||||
|
||||
(defn- apply-tx! [^js self sender tx-data]
|
||||
(let [sql (.-sql self)
|
||||
conn (.-conn self)
|
||||
@@ -308,8 +317,7 @@
|
||||
resolved (de-normalize-tx-data db tx-data)
|
||||
tx-report (d/with db resolved)
|
||||
db' (:db-after tx-report)
|
||||
parent-fixed (fix-missing-parent db' resolved)
|
||||
order-fixed (fix-duplicate-orders db' parent-fixed)
|
||||
order-fixed (fix-tx-data db' resolved)
|
||||
cycle-info (cycle/detect-cycle db' order-fixed)]
|
||||
(if cycle-info
|
||||
(do
|
||||
|
||||
@@ -42,3 +42,29 @@
|
||||
(let [tx [{:block/uuid b :block/parent [:block/uuid b]}]
|
||||
values (cycle/server-values-for @conn tx :block/parent)]
|
||||
(is (= {(pr-str [:block/uuid b]) [:block/uuid a]} values)))))
|
||||
|
||||
(deftest numeric-entity-cycle-test
|
||||
(let [conn (new-conn)
|
||||
a (random-uuid)
|
||||
b (random-uuid)]
|
||||
(d/transact! conn [{:block/uuid a}
|
||||
{:block/uuid b :block/parent [:block/uuid a]}])
|
||||
(let [a-eid (d/entid @conn [:block/uuid a])
|
||||
tx [[:db/add a-eid :block/parent [:block/uuid b]]]
|
||||
result (cycle/detect-cycle @conn tx)]
|
||||
(is (= :block/parent (:attr result)))
|
||||
(is (= [:block/uuid a] (:entity result))))))
|
||||
|
||||
(deftest three-block-cycle-test
|
||||
(let [conn (new-conn)
|
||||
a (random-uuid)
|
||||
b (random-uuid)
|
||||
c (random-uuid)]
|
||||
(d/transact! conn [{:block/uuid a}
|
||||
{:block/uuid b :block/parent [:block/uuid a]}
|
||||
{:block/uuid c :block/parent [:block/uuid b]}])
|
||||
(let [a-eid (d/entid @conn [:block/uuid a])
|
||||
tx [[:db/add a-eid :block/parent [:block/uuid c]]]
|
||||
result (cycle/detect-cycle @conn tx)]
|
||||
(is (= :block/parent (:attr result)))
|
||||
(is (= [:block/uuid a] (:entity result))))))
|
||||
|
||||
@@ -130,37 +130,23 @@
|
||||
(catch :default e
|
||||
(log/error :worker-sync/apply-remote-tx-failed {:error e})))))
|
||||
|
||||
(defn- reconcile-cycle! [repo attr server-values]
|
||||
(defn- reconcile-cycle! [repo attr server_values]
|
||||
(when-let [conn (worker-state/get-datascript-conn repo)]
|
||||
(let [db @conn
|
||||
tx-data (reduce
|
||||
(fn [acc [entity-str value]]
|
||||
(let [entity (reader/read-string entity-str)
|
||||
eid (d/entid db entity)
|
||||
current-raw (when eid (get (d/entity db eid) attr))
|
||||
current (cond
|
||||
(and (= attr :block/parent) (instance? Entity current-raw))
|
||||
(when-let [parent-uuid (:block/uuid current-raw)]
|
||||
[:block/uuid parent-uuid])
|
||||
(and (= attr :logseq.property.class/extends) (instance? Entity current-raw))
|
||||
(:db/ident current-raw)
|
||||
:else current-raw)]
|
||||
(fn [acc [eid value]]
|
||||
(let [entity (d/entity db eid)
|
||||
current (:db/id (get entity attr))]
|
||||
(cond
|
||||
(nil? eid) acc
|
||||
(nil? entity) acc
|
||||
(nil? value)
|
||||
(cond
|
||||
(and current (sequential? current))
|
||||
(if current
|
||||
(conj acc [:db/retract eid attr current])
|
||||
|
||||
(some? current)
|
||||
(conj acc [:db/retract eid attr current])
|
||||
|
||||
:else acc)
|
||||
|
||||
acc)
|
||||
:else
|
||||
(conj acc [:db/add eid attr value]))))
|
||||
[]
|
||||
server-values)]
|
||||
server_values)]
|
||||
(when (seq tx-data)
|
||||
(d/transact! conn tx-data {:worker-sync/remote? true})))))
|
||||
|
||||
@@ -200,9 +186,8 @@
|
||||
(remove-pending-txs! repo @(:inflight client))))
|
||||
(reset! (:inflight client) [])
|
||||
(when (= "cycle" (:reason message))
|
||||
(let [attr (keyword (:attr message))
|
||||
server-values (sqlite-util/read-transit-str (:server_values message))]
|
||||
(reconcile-cycle! repo attr server-values)))
|
||||
(let [{:keys [attr server_values]} (sqlite-util/read-transit-str (:data message))]
|
||||
(reconcile-cycle! repo attr server_values)))
|
||||
(flush-pending! repo client))
|
||||
"pull/ok" (do
|
||||
(update-server-t! client (:t message))
|
||||
|
||||
Reference in New Issue
Block a user