refactor: finish splitting file and db page create

db create had file specific assumptions and file create had db specific
assumptions like class?
This commit is contained in:
Gabriel Horner
2024-06-12 14:57:23 -04:00
parent 0b61bdea29
commit 9f89717a57
4 changed files with 224 additions and 174 deletions

View File

@@ -3,185 +3,18 @@
(:require [logseq.db :as ldb]
[logseq.graph-parser.db :as gp-db]
[logseq.graph-parser.block :as gp-block]
[logseq.graph-parser.property :as gp-property]
[logseq.db.sqlite.util :as sqlite-util]
[datascript.core :as d]
[clojure.string :as string]
[logseq.graph-parser.text :as text]
[logseq.common.util :as common-util]
[logseq.common.config :as common-config]
[logseq.db.frontend.content :as db-content]
[frontend.worker.date :as date]
[logseq.db.frontend.order :as db-order]
[logseq.db.frontend.property.util :as db-property-util]
[logseq.db.frontend.property.build :as db-property-build]
[logseq.db.frontend.class :as db-class]))
(defn file-based-properties-block
[repo conn config date-formatter properties format page]
(let [content (gp-property/insert-properties repo format "" properties)
refs (gp-block/get-page-refs-from-properties properties @conn date-formatter config)]
{:block/pre-block? true
:block/uuid (ldb/new-block-id)
:block/properties properties
:block/properties-order (keys properties)
:block/refs refs
:block/order (db-order/gen-key nil nil)
:block/format format
:block/content content
:block/parent page
:block/page page}))
(defn- build-page-tx [repo conn config date-formatter format properties page {:keys [whiteboard? class? tags]}]
(when (:block/uuid page)
(let [page-entity [:block/uuid (:block/uuid page)]
page' (merge page
(when whiteboard? {:block/type "whiteboard"})
(when tags {:block/tags (mapv #(hash-map :db/id
(:db/id (d/entity @conn [:block/uuid %])))
tags)}))]
(if (sqlite-util/db-based-graph? repo)
(let [property-vals-tx-m
;; Builds property values for built-in properties like logseq.property.pdf/file
(db-property-build/build-property-values-tx-m
page'
(->> properties
(keep (fn [[k v]]
(when (db-property-util/built-in-has-ref-value? k)
[k v])))
(into {})))]
(cond-> [(if class? (db-class/build-new-class @conn page') page')]
(seq property-vals-tx-m)
(into (vals property-vals-tx-m))
true
(conj (merge {:block/uuid (:block/uuid page)}
properties
(db-property-build/build-properties-with-ref-values property-vals-tx-m)))))
(let [file-page (merge page'
(when (seq properties) {:block/properties properties}))]
(if (and (seq properties)
(not whiteboard?)
(ldb/page-empty? @conn (:block/name page)))
[file-page (file-based-properties-block repo conn config date-formatter properties format page-entity)]
[file-page]))))))
(defn get-title-and-pagename
[title]
(let [title (-> (string/trim title)
(text/page-ref-un-brackets!)
;; remove `#` from tags
(string/replace #"^#+" ""))
title (common-util/remove-boundary-slashes title)
page-name (common-util/page-name-sanity-lc title)]
[title page-name]))
(defn build-first-block-tx
[page-uuid format]
(let [page-id [:block/uuid page-uuid]]
[(sqlite-util/block-with-timestamps
{:block/uuid (ldb/new-block-id)
:block/page page-id
:block/parent page-id
:block/order (db-order/gen-key nil nil)
:block/content ""
:block/format format})]))
(defn- file-based-create!
[repo conn config title {:keys [create-first-block? format properties uuid persist-op? whiteboard? class? today-journal?]
:or {create-first-block? true
format nil
properties nil
uuid nil
persist-op? true}
:as options}]
(let [date-formatter (common-config/get-date-formatter config)
split-namespace? (not (or (string/starts-with? title "hls__")
(date/valid-journal-title? date-formatter title)))
[title page-name] (get-title-and-pagename title)
with-uuid? (if (uuid? uuid) uuid true)]
(when-not (ldb/get-page @conn page-name)
(let [pages (if split-namespace?
(common-util/split-namespace-pages title)
[title])
format (or format (common-config/get-preferred-format config))
pages (map (fn [page]
;; only apply uuid to the deepest hierarchy of page to create if provided.
(-> (gp-block/page-name->map page (if (= page title) with-uuid? true) @conn true date-formatter :class? class?)
(assoc :block/format format)))
pages)
txs (->> pages
;; for namespace pages, only last page need properties
drop-last
(mapcat #(build-page-tx repo conn config date-formatter format nil % {}))
(remove nil?))
txs (map-indexed (fn [i page]
(if (zero? i)
page
(assoc page :block/namespace
[:block/uuid (:block/uuid (nth txs (dec i)))])))
txs)
page-uuid (:block/uuid (last pages))
page-txs (build-page-tx repo conn config date-formatter format properties (last pages) (select-keys options [:whiteboard? :class? :tags]))
page-txs (if (seq txs)
(update page-txs 0
(fn [p]
(assoc p :block/namespace [:block/uuid (:block/uuid (last txs))])))
page-txs)
first-block-tx (when (and
create-first-block?
(not (or whiteboard? class?))
page-txs)
(build-first-block-tx (:block/uuid (first page-txs)) format))
txs (concat
txs
page-txs
first-block-tx)
[page-uuid result] (when (seq txs)
[page-uuid (ldb/transact! conn txs (cond-> {:persist-op? persist-op?
:outliner-op :create-page}
today-journal?
(assoc :create-today-journal? true
:today-journal-name page-name)))])]
[result page-name page-uuid]))))
(defn db-based-create!
[repo conn config title
{:keys [create-first-block? properties uuid persist-op? whiteboard? class? today-journal?]
:or {create-first-block? true
properties nil
uuid nil
persist-op? true}
:as options}]
(let [date-formatter (common-config/get-date-formatter config)
[title page-name] (get-title-and-pagename title)
with-uuid? (if (uuid? uuid) uuid true)]
(when-not (ldb/get-page @conn page-name)
(let [format :markdown
page (-> (gp-block/page-name->map title with-uuid? @conn true date-formatter :class? class?)
(assoc :block/format format))
page-uuid (:block/uuid page)
page-txs (build-page-tx repo conn config date-formatter format properties page (select-keys options [:whiteboard? :class? :tags]))
first-block-tx (when (and
create-first-block?
(not (or whiteboard? class?))
page-txs)
(build-first-block-tx (:block/uuid (first page-txs)) format))
txs (concat
page-txs
first-block-tx)
[page-uuid result] (when (seq txs)
[page-uuid (ldb/transact! conn txs (cond-> {:persist-op? persist-op?
:outliner-op :create-page}
today-journal?
(assoc :create-today-journal? true
:today-journal-name page-name)))])]
[result page-name page-uuid]))))
[frontend.worker.handler.page.db-based.page :as db-worker-page]
[frontend.worker.handler.page.file-based.page :as file-worker-page]))
(defn rtc-create-page!
[conn config title {:keys [uuid]}]
(assert (uuid? uuid) (str "rtc-create-page! `uuid` is not a uuid " uuid))
(let [date-formatter (common-config/get-date-formatter config)
[title page-name] (get-title-and-pagename title)
[title page-name] (db-worker-page/get-title-and-pagename title)
page (-> (gp-block/page-name->map title uuid @conn true date-formatter
{:skip-existing-page-check? true})
(assoc :block/format :markdown))
@@ -202,8 +35,8 @@
TODO: Add other options"
[repo conn config title & options]
(if (ldb/db-based-graph? @conn)
(db-based-create! repo conn config title options)
(file-based-create! repo conn config title options)))
(db-worker-page/create! conn config title options)
(file-worker-page/create! repo conn config title options)))
(defn db-refs->page
"Replace [[page name]] with page name"

View File

@@ -0,0 +1,93 @@
(ns frontend.worker.handler.page.db-based.page
"Page operations for DB graphs"
(:require [logseq.db :as ldb]
[logseq.graph-parser.block :as gp-block]
[logseq.db.sqlite.util :as sqlite-util]
[datascript.core :as d]
[clojure.string :as string]
[logseq.graph-parser.text :as text]
[logseq.common.util :as common-util]
[logseq.common.config :as common-config]
[logseq.db.frontend.order :as db-order]
[logseq.db.frontend.property.util :as db-property-util]
[logseq.db.frontend.property.build :as db-property-build]
[logseq.db.frontend.class :as db-class]))
(defn- build-page-tx [conn properties page {:keys [whiteboard? class? tags]}]
(when (:block/uuid page)
(let [page' (merge page
(when whiteboard? {:block/type "whiteboard"})
(when tags {:block/tags (mapv #(hash-map :db/id
(:db/id (d/entity @conn [:block/uuid %])))
tags)}))
property-vals-tx-m
;; Builds property values for built-in properties like logseq.property.pdf/file
(db-property-build/build-property-values-tx-m
page'
(->> properties
(keep (fn [[k v]]
(when (db-property-util/built-in-has-ref-value? k)
[k v])))
(into {})))]
(cond-> [(if class? (db-class/build-new-class @conn page') page')]
(seq property-vals-tx-m)
(into (vals property-vals-tx-m))
true
(conj (merge {:block/uuid (:block/uuid page)}
properties
(db-property-build/build-properties-with-ref-values property-vals-tx-m)))))))
;; TODO: Revisit title cleanup as this was copied from file implementation
(defn get-title-and-pagename
[title]
(let [title (-> (string/trim title)
(text/page-ref-un-brackets!)
;; remove `#` from tags
(string/replace #"^#+" ""))
title (common-util/remove-boundary-slashes title)
page-name (common-util/page-name-sanity-lc title)]
[title page-name]))
(defn build-first-block-tx
[page-uuid format]
(let [page-id [:block/uuid page-uuid]]
[(sqlite-util/block-with-timestamps
{:block/uuid (ldb/new-block-id)
:block/page page-id
:block/parent page-id
:block/order (db-order/gen-key nil nil)
:block/content ""
:block/format format})]))
(defn create!
[conn config title
{:keys [create-first-block? properties uuid persist-op? whiteboard? class? today-journal?]
:or {create-first-block? true
properties nil
uuid nil
persist-op? true}
:as options}]
(let [date-formatter (common-config/get-date-formatter config)
[title page-name] (get-title-and-pagename title)
with-uuid? (if (uuid? uuid) uuid true)]
(when-not (ldb/get-case-page @conn page-name)
(let [format :markdown
page (-> (gp-block/page-name->map title with-uuid? @conn true date-formatter :class? class?)
(assoc :block/format format))
page-uuid (:block/uuid page)
page-txs (build-page-tx conn properties page (select-keys options [:whiteboard? :class? :tags]))
first-block-tx (when (and
create-first-block?
(not (or whiteboard? class?))
page-txs)
(build-first-block-tx (:block/uuid (first page-txs)) format))
txs (concat
page-txs
first-block-tx)
[page-uuid result] (when (seq txs)
[page-uuid (ldb/transact! conn txs (cond-> {:persist-op? persist-op?
:outliner-op :create-page}
today-journal?
(assoc :create-today-journal? true
:today-journal-name page-name)))])]
[result page-name page-uuid]))))

View File

@@ -0,0 +1,123 @@
(ns frontend.worker.handler.page.file-based.page
"Page operations for file graphs"
(:require [logseq.db :as ldb]
[logseq.graph-parser.block :as gp-block]
[logseq.graph-parser.property :as gp-property]
[logseq.outliner.core :as outliner-core]
[datascript.core :as d]
[clojure.string :as string]
[logseq.graph-parser.text :as text]
[logseq.common.util :as common-util]
[logseq.common.config :as common-config]
[frontend.worker.date :as date]
[logseq.db.frontend.order :as db-order]))
(defn- file-based-properties-block
[repo conn config date-formatter properties format page]
(let [content (gp-property/insert-properties repo format "" properties)
refs (gp-block/get-page-refs-from-properties properties @conn date-formatter config)]
{:block/pre-block? true
:block/uuid (ldb/new-block-id)
:block/properties properties
:block/properties-order (keys properties)
:block/refs refs
:block/order (db-order/gen-key nil nil)
:block/format format
:block/content content
:block/parent page
:block/page page}))
(defn- build-page-tx [repo conn config date-formatter format properties page {:keys [whiteboard? tags]}]
(when (:block/uuid page)
(let [page-entity [:block/uuid (:block/uuid page)]
page' (merge page
(when whiteboard? {:block/type "whiteboard"})
(when tags {:block/tags (mapv #(hash-map :db/id
(:db/id (d/entity @conn [:block/uuid %])))
tags)}))
file-page (merge page'
(when (seq properties) {:block/properties properties}))]
(if (and (seq properties)
(not whiteboard?)
(ldb/page-empty? @conn (:block/name page)))
[file-page (file-based-properties-block repo conn config date-formatter properties format page-entity)]
[file-page]))))
(defn get-title-and-pagename
[title]
(let [title (-> (string/trim title)
(text/page-ref-un-brackets!)
;; remove `#` from tags
(string/replace #"^#+" ""))
title (common-util/remove-boundary-slashes title)
page-name (common-util/page-name-sanity-lc title)]
[title page-name]))
(defn- build-first-block-tx
[page-uuid format]
(let [page-id [:block/uuid page-uuid]]
[(outliner-core/block-with-timestamps
{:block/uuid (ldb/new-block-id)
:block/page page-id
:block/parent page-id
:block/order (db-order/gen-key nil nil)
:block/content ""
:block/format format})]))
(defn create!
[repo conn config title {:keys [create-first-block? format properties uuid persist-op? whiteboard? today-journal?]
:or {create-first-block? true
format nil
properties nil
uuid nil
persist-op? true}
:as options}]
(let [date-formatter (common-config/get-date-formatter config)
split-namespace? (not (or (string/starts-with? title "hls__")
(date/valid-journal-title? date-formatter title)))
[title page-name] (get-title-and-pagename title)
with-uuid? (if (uuid? uuid) uuid true)]
(when-not (ldb/get-page @conn page-name)
(let [pages (if split-namespace?
(common-util/split-namespace-pages title)
[title])
format (or format (common-config/get-preferred-format config))
pages (map (fn [page]
;; only apply uuid to the deepest hierarchy of page to create if provided.
(-> (gp-block/page-name->map page (if (= page title) with-uuid? true) @conn true date-formatter)
(assoc :block/format format)))
pages)
txs (->> pages
;; for namespace pages, only last page need properties
drop-last
(mapcat #(build-page-tx repo conn config date-formatter format nil % {}))
(remove nil?))
txs (map-indexed (fn [i page]
(if (zero? i)
page
(assoc page :block/namespace
[:block/uuid (:block/uuid (nth txs (dec i)))])))
txs)
page-uuid (:block/uuid (last pages))
page-txs (build-page-tx repo conn config date-formatter format properties (last pages) (select-keys options [:whiteboard? :tags]))
page-txs (if (seq txs)
(update page-txs 0
(fn [p]
(assoc p :block/namespace [:block/uuid (:block/uuid (last txs))])))
page-txs)
first-block-tx (when (and
create-first-block?
(not whiteboard?)
page-txs)
(build-first-block-tx (:block/uuid (first page-txs)) format))
txs (concat
txs
page-txs
first-block-tx)
[page-uuid result] (when (seq txs)
[page-uuid (ldb/transact! conn txs (cond-> {:persist-op? persist-op?
:outliner-op :create-page}
today-journal?
(assoc :create-today-journal? true
:today-journal-name page-name)))])]
[result page-name page-uuid]))))