Skip to content

Commit 016e63c

Browse files
committed
fix: ensure using :rename-db-idents to rename properties in migrate
1 parent 2b80c5a commit 016e63c

3 files changed

Lines changed: 27 additions & 406 deletions

File tree

src/main/frontend/worker/db/migrate.cljs

Lines changed: 26 additions & 277 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,7 @@
99
[logseq.common.config :as common-config]
1010
[logseq.common.util :as common-util]
1111
[logseq.db :as ldb]
12-
[logseq.db.common.order :as db-order]
1312
[logseq.db.frontend.class :as db-class]
14-
[logseq.db.frontend.db-ident :as db-ident]
1513
[logseq.db.frontend.property :as db-property]
1614
[logseq.db.frontend.schema :as db-schema]
1715
[logseq.db.sqlite.create-graph :as sqlite-create-graph]
@@ -20,20 +18,16 @@
2018
;; Frontend migrations
2119
;; ===================
2220

23-
(defn- rename-properties-aux
21+
(defn- rename-properties-fix
2422
[db props-to-rename]
25-
(let [property-tx (map
23+
(let [;; update property title/name
24+
;; don't update :db/ident since it's addressed by `:rename-db-idents`
25+
property-tx (map
2626
(fn [[old new]]
27-
(let [e-new (d/entity db new)
28-
e-old (d/entity db old)]
29-
(if e-new
30-
(when e-old
31-
[:db/retractEntity (:db/id e-old)])
32-
(merge {:db/id (:db/id (d/entity db old))
33-
:db/ident new}
34-
(when-let [new-title (get-in db-property/built-in-properties [new :title])]
35-
{:block/title new-title
36-
:block/name (common-util/page-name-sanity-lc new-title)})))))
27+
(merge {:db/id (:db/id (d/entity db old))}
28+
(when-let [new-title (get-in db-property/built-in-properties [new :title])]
29+
{:block/title new-title
30+
:block/name (common-util/page-name-sanity-lc new-title)})))
3731
props-to-rename)
3832
titles-tx (->> (d/datoms db :avet :block/title)
3933
(keep (fn [d]
@@ -118,21 +112,20 @@
118112
ordered-columns-tx
119113
filters-tx)))
120114

121-
(defn rename-properties
122-
[props-to-rename & {:keys [replace-fn]}]
123-
(fn [db]
124-
(when (ldb/db-based-graph? db)
125-
(let [props-tx (rename-properties-aux db props-to-rename)
126-
fix-tx (mapcat (fn [[old new]]
127-
;; can't use datoms b/c user properties aren't indexed
128-
(->> (d/q '[:find ?b ?prop-v :in $ ?prop :where [?b ?prop ?prop-v]] db old)
129-
(mapcat (fn [[id prop-value]]
130-
(if (fn? replace-fn)
131-
(replace-fn id prop-value)
132-
[[:db/retract id old]
133-
[:db/add id new prop-value]])))))
134-
props-to-rename)]
135-
(concat props-tx fix-tx)))))
115+
(defn- rename-properties
116+
[props-to-rename {:keys [fix]}]
117+
{:rename-db-idents (mapv
118+
(fn [[old-ident new-ident]]
119+
{:db-ident-or-block-uuid old-ident
120+
:new-db-ident new-ident})
121+
props-to-rename)
122+
:fix (fn [db]
123+
(let [common-fix (rename-properties-fix db
124+
{:logseq.property.asset/external-src
125+
:logseq.property.asset/external-url})
126+
additional-fix (when (fn? fix)
127+
(fix db))]
128+
(concat common-fix additional-fix)))})
136129

137130
(comment
138131
(defn- rename-classes
@@ -147,238 +140,6 @@
147140
:block/name (common-util/page-name-sanity-lc new-title)})))
148141
classes-to-rename)))))
149142

150-
(defn fix-rename-parent-to-extends
151-
[db]
152-
(let [parent-entity (d/entity db :logseq.property/parent)]
153-
(when parent-entity
154-
(let [old-p :logseq.property/parent
155-
new-p :logseq.property.class/extends
156-
f (rename-properties
157-
{old-p new-p}
158-
{:replace-fn (fn [id prop-value]
159-
(let [page (d/entity db id)
160-
;; bad impl, it's not just simple db/ident renaming
161-
new-p' (if (ldb/class? page) new-p :block/parent)]
162-
[[:db/retract id old-p]
163-
[:db/add id new-p' prop-value]]))})
164-
rename-property-tx (f db)
165-
library-page (if-let [page (ldb/get-built-in-page db common-config/library-page-name)]
166-
page
167-
(-> (sqlite-util/build-new-page common-config/library-page-name)
168-
sqlite-create-graph/mark-block-as-built-in))
169-
library-id (:block/uuid library-page)
170-
library-page-tx (when-not (de/entity? library-page)
171-
[library-page])
172-
pages-with-parent (->> (d/datoms db :avet :logseq.property/parent)
173-
(keep (fn [d]
174-
(let [e (d/entity db (:e d))]
175-
(when-not (ldb/class? e)
176-
e)))))
177-
parents (->> pages-with-parent
178-
(map :logseq.property/parent)
179-
(common-util/distinct-by :db/id))
180-
top-parents (remove :logseq.property/parent parents)
181-
top-parent-ids (set (map :db/id top-parents))
182-
move-top-parents-to-library (map (fn [parent]
183-
{:db/id (:db/id parent)
184-
:block/parent [:block/uuid library-id]
185-
:block/order (db-order/gen-key)}) top-parents)
186-
update-children-parent-and-order (->> pages-with-parent
187-
(remove (fn [page] (top-parent-ids (:db/id page))))
188-
(map (fn [page]
189-
{:db/id (:db/id page)
190-
:block/order (db-order/gen-key)})))]
191-
(concat
192-
rename-property-tx
193-
library-page-tx
194-
move-top-parents-to-library
195-
update-children-parent-and-order)))))
196-
197-
(defn- retract-property-attributes
198-
[id]
199-
[[:db/retract id :block/tags :logseq.class/Property]
200-
[:db/retract id :logseq.property/type]
201-
[:db/retract id :db/cardinality]
202-
[:db/retract id :db/valueType]
203-
[:db/retract id :db/index]
204-
[:db/retract id :logseq.property/classes]
205-
[:db/retract id :logseq.property/hide?]
206-
[:db/retract id :logseq.property/public?]
207-
[:db/retract id :logseq.property/view-context]
208-
[:db/retract id :logseq.property/ui-position]
209-
[:db/retract id :logseq.property/default-value]
210-
[:db/retract id :logseq.property/hide-empty-value]
211-
[:db/retract id :logseq.property/enable-history?]])
212-
213-
(defn separate-classes-and-properties
214-
[db]
215-
;; find all properties that're classes, create new properties to separate them
216-
;; from classes.
217-
(let [class-ids (d/q
218-
'[:find [?b ...]
219-
:where
220-
[?b :block/tags :logseq.class/Property]
221-
[?b :block/tags :logseq.class/Tag]]
222-
db)]
223-
(mapcat
224-
(fn [id]
225-
(let [class (d/entity db id)
226-
ident (:db/ident class)
227-
new-property (sqlite-util/build-new-property
228-
(:block/title class)
229-
(select-keys class [:logseq.property/type :db/cardinality])
230-
{:title (:block/title class)
231-
:ref-type? true
232-
:properties (merge
233-
(select-keys class [:logseq.property/hide? :logseq.property/public?
234-
:logseq.property/view-context :logseq.property/ui-position
235-
:logseq.property/default-value :logseq.property/hide-empty-value :logseq.property/enable-history?])
236-
{:logseq.property/classes id})})
237-
retract-property-attrs (retract-property-attributes id)
238-
datoms (if (:db/index class)
239-
(d/datoms db :avet ident)
240-
(filter (fn [d] (= ident (:a d))) (d/datoms db :eavt)))
241-
tag-properties (->> (d/datoms db :avet :logseq.property.class/properties id)
242-
(mapcat (fn [d]
243-
[[:db/retract (:e d) (:a d) (:v d)]
244-
[:db/add (:e d) (:a d) [:block/uuid (:block/uuid new-property)]]])))
245-
other-properties-tx (mapcat
246-
(fn [ident]
247-
(->> (d/datoms db :avet ident id)
248-
(mapcat (fn [d]
249-
[[:db/retract (:e d) (:a d) (:v d)]
250-
[:db/add (:e d) (:a d) [:block/uuid (:block/uuid new-property)]]]))))
251-
[:logseq.property.view/group-by-property :logseq.property.table/pinned-columns])]
252-
(concat [new-property]
253-
tag-properties
254-
other-properties-tx
255-
retract-property-attrs
256-
(mapcat
257-
(fn [d]
258-
[[:db/retract (:e d) ident (:v d)]
259-
[:db/add (:e d) (:db/ident new-property) (:v d)]])
260-
datoms))))
261-
class-ids)))
262-
263-
(defn fix-tag-properties
264-
[db]
265-
;; find all classes that're still used as properties
266-
(let [class-ids (d/q
267-
'[:find [?b ...]
268-
:where
269-
[?b :block/tags :logseq.class/Tag]
270-
[?b1 :logseq.property.class/properties ?b]]
271-
db)]
272-
(mapcat
273-
(fn [id]
274-
(let [class (d/entity db id)
275-
property-id (first (ldb/page-exists? db (:block/title class) :logseq.class/Property))
276-
tag-properties (when property-id
277-
(->> (d/datoms db :avet :logseq.property.class/properties id)
278-
(mapcat (fn [d]
279-
[[:db/retract (:e d) (:a d) (:v d)]
280-
[:db/add (:e d) (:a d) property-id]]))))]
281-
tag-properties))
282-
class-ids)))
283-
284-
(defn add-missing-db-ident-for-tags
285-
[db _sqlite-db]
286-
(let [class-ids (d/q
287-
'[:find [?b ...]
288-
:where
289-
[?b :block/tags :logseq.class/Tag]
290-
[(missing? $ ?b :db/ident)]]
291-
db)]
292-
(mapcat
293-
(fn [id]
294-
[[:db/add id :logseq.property.class/extends :logseq.class/Root]
295-
[:db/retract id :block/tags :logseq.class/Page]
296-
[:db/retract id :block/refs :logseq.class/Page]
297-
[:db/retract id :block/path-refs :logseq.class/Page]])
298-
class-ids)))
299-
300-
(defn add-missing-db-ident-for-tags2
301-
[db]
302-
(let [class-ids
303-
(d/q
304-
'[:find [?b ...]
305-
:where
306-
[?b :block/tags :logseq.class/Tag]
307-
[(missing? $ ?b :db/ident)]]
308-
db)]
309-
(keep
310-
(fn [id]
311-
(let [ent (d/entity db id)
312-
title (:block/title ent)
313-
block-uuid (:block/uuid ent)]
314-
(when block-uuid
315-
{:db-ident-or-block-uuid block-uuid
316-
:new-db-ident (db-ident/replace-db-ident-random-suffix
317-
(db-class/create-user-class-ident-from-name db title)
318-
(subs (str block-uuid) 28))})))
319-
class-ids)))
320-
321-
(defn fix-using-properties-as-tags
322-
[db]
323-
;; find all properties that're tags
324-
(let [property-ids (->>
325-
(d/q
326-
'[:find ?b ?i
327-
:where
328-
[?b :block/tags :logseq.class/Tag]
329-
[?b :db/ident ?i]]
330-
db)
331-
(filter (fn [[_ ident]] (= "user.property" (namespace ident))))
332-
(map first))]
333-
(mapcat
334-
(fn [id]
335-
(into (retract-property-attributes id)
336-
[[:db/retract id :logseq.property/parent]]))
337-
property-ids)))
338-
339-
(defn fix-using-properties-as-tags2
340-
[db]
341-
(let [property-ids
342-
(->>
343-
(d/q
344-
'[:find ?b ?i
345-
:where
346-
[?b :block/tags :logseq.class/Tag]
347-
[?b :db/ident ?i]]
348-
db)
349-
(filter (fn [[_ ident]] (= "user.property" (namespace ident))))
350-
(map first))]
351-
(keep
352-
(fn [id]
353-
(let [ent (d/entity db id)
354-
title (:block/title ent)
355-
block-uuid (:block/uuid ent)]
356-
(when block-uuid
357-
{:db-ident-or-block-uuid block-uuid
358-
:new-db-ident (db-ident/replace-db-ident-random-suffix
359-
(db-class/create-user-class-ident-from-name db title)
360-
(subs (str block-uuid) 28))})))
361-
property-ids)))
362-
363-
(defn remove-block-order-for-tags
364-
[db]
365-
;; find all properties that're tags
366-
(let [tag-ids (d/q
367-
'[:find [?b ...]
368-
:where
369-
[?b :block/tags :logseq.class/Tag]
370-
[?b :block/order]]
371-
db)]
372-
(map
373-
(fn [id]
374-
[:db/retract id :block/order])
375-
tag-ids)))
376-
377-
(defn- update-extends-to-cardinality-many
378-
[db]
379-
(let [extends (d/entity db :logseq.property.class/extends)]
380-
[[:db/add (:db/id extends) :db/cardinality :db.cardinality/many]]))
381-
382143
(defn- add-quick-add-page
383144
[_db]
384145
(let [page (-> (-> (sqlite-util/build-new-page common-config/quick-add-page-name)
@@ -414,25 +175,11 @@
414175
(when (:logseq.property/ui-position e)
415176
[:db/retract (:e d) :logseq.property/ui-position]))))))
416177

417-
(defn- rename-external-src-to-external-url
418-
[db]
419-
(let [f (rename-properties
420-
{:logseq.property.asset/external-src :logseq.property.asset/external-url}
421-
{})]
422-
(f db)))
423-
424178
(def schema-version->updates
425179
"A vec of tuples defining datascript migrations. Each tuple consists of the
426180
schema version integer and a migration map. A migration map can have keys of :properties, :classes
427181
:rename-db-idents and :fix."
428-
[["65.0" {:fix separate-classes-and-properties}]
429-
["65.1" {:fix fix-rename-parent-to-extends}]
430-
["65.2" {:fix fix-tag-properties}]
431-
["65.3" {:rename-db-idents add-missing-db-ident-for-tags2 :fix add-missing-db-ident-for-tags}]
432-
["65.4" {:rename-db-idents fix-using-properties-as-tags2 :fix fix-using-properties-as-tags}]
433-
["65.5" {:fix remove-block-order-for-tags}]
434-
["65.6" {:fix update-extends-to-cardinality-many}]
435-
["65.7" {:fix add-quick-add-page}]
182+
[["65.7" {:fix add-quick-add-page}]
436183
["65.8" {:fix add-missing-page-name}]
437184
["65.9" {:properties [:logseq.property.embedding/hnsw-label-updated-at]}]
438185
["65.10" {:properties [:block/journal-day :logseq.property.view/sort-groups-by-property :logseq.property.view/sort-groups-desc?]}]
@@ -441,7 +188,9 @@
441188
["65.13" {:properties [:logseq.property.asset/width
442189
:logseq.property.asset/height]}]
443190
["65.14" {:properties [:logseq.property.asset/external-src]}]
444-
["65.15" {:fix rename-external-src-to-external-url}]])
191+
["65.15" (rename-properties {:logseq.property.asset/external-src
192+
:logseq.property.asset/external-url}
193+
{})]])
445194

446195
(let [[major minor] (last (sort (map (comp (juxt :major :minor) db-schema/parse-schema-version first)
447196
schema-version->updates)))]

0 commit comments

Comments
 (0)