Kaynağa Gözat

fix: unsafe cardinality from many to one

Tienson Qin 1 yıl önce
ebeveyn
işleme
18a9c4af55

+ 1 - 1
src/main/frontend/components/property/value.cljs

@@ -820,7 +820,7 @@
                       :parent-block block
                       :format :markdown}
          v (cond
-             (and multiple-values? (or (set? v) (empty? v)))
+             (and multiple-values? (or (set? v) (and (coll? v) (empty? v))))
              v
              multiple-values?
              #{v}

+ 10 - 4
src/main/frontend/db_worker.cljs

@@ -31,7 +31,8 @@
             [logseq.outliner.op :as outliner-op]
             [promesa.core :as p]
             [shadow.cljs.modern :refer [defclass]]
-            [logseq.common.util :as common-util]))
+            [logseq.common.util :as common-util]
+            [frontend.worker.db.fix :as db-fix]))
 
 (defonce *sqlite worker-state/*sqlite)
 (defonce *sqlite-conns worker-state/*sqlite-conns)
@@ -367,6 +368,11 @@
              tx-meta (if (string? tx-meta)
                        (ldb/read-transit-str tx-meta)
                        tx-meta)
+             tx-data' (if (and (= :update-property (:outliner-op tx-meta))
+                               (:many->one? tx-meta) (:property-id tx-meta))
+                        (concat tx-data
+                                (db-fix/fix-cardinality-many->one @conn (:property-id tx-meta)))
+                        tx-data)
              context (if (string? context)
                        (ldb/read-transit-str context)
                        context)
@@ -382,12 +388,12 @@
                           (dissoc :insert-blocks?)))]
          (when-not (and (:create-today-journal? tx-meta)
                         (:today-journal-name tx-meta)
-                        (seq tx-data)
+                        (seq tx-data')
                         (ldb/get-page @conn (:today-journal-name tx-meta))) ; today journal created already
 
-           ;; (prn :debug :transact :tx-data tx-data :tx-meta tx-meta')
+           ;; (prn :debug :transact :tx-data tx-data' :tx-meta tx-meta')
            (worker-util/profile "Worker db transact"
-                                (ldb/transact! conn tx-data tx-meta')))
+                                (ldb/transact! conn tx-data' tx-meta')))
          nil)
        (catch :default e
          (prn :debug :error)

+ 6 - 2
src/main/frontend/handler/db_based/property.cljs

@@ -122,8 +122,12 @@
                          property-name
                          (assoc :block/original-name property-name))]
                       (update-schema property schema))
-                     (remove nil?))]
-        (db/transact! repo tx-data {:outliner-op :save-block}))
+                     (remove nil?))
+            many->one? (and (= (:db/cardinality property) :db.cardinality/many)
+                            (= :one (:cardinality schema)))]
+        (db/transact! repo tx-data {:outliner-op :update-property
+                                    :property-id (:db/id property)
+                                    :many->one? many->one?}))
       (let [k-name (or (and property-name (name property-name))
                        (name property-id))]
         (assert (some? k-name)

+ 13 - 0
src/main/frontend/worker/db/fix.cljs

@@ -175,3 +175,16 @@
               (let [tx-data (:tx-data (ldb/transact! conn fix-broken-chain-tx transact-opts))]
                 (swap! *fix-tx-data (fn [old-data] (concat old-data tx-data)))))))
         @*fix-tx-data))))
+
+(defn fix-cardinality-many->one
+  [db property-id]
+  (when-let [attribute (:db/ident (d/entity db property-id))]
+    (let [deleting-datoms (->> (d/datoms db :avet attribute)
+                               (group-by :e)
+                               (mapcat (fn [[_e v-datoms]]
+                                         (let [recent-datom (last (sort-by :t v-datoms))]
+                                           (remove #{recent-datom} v-datoms)))))]
+      (map
+       (fn [d]
+         [:db/retract (:e d) (:a d) (:v d)])
+       deleting-datoms))))