浏览代码

Merge branch 'feat/db' into feat/capacitor-new

charlie 5 月之前
父节点
当前提交
47d4fe55d9
共有 66 个文件被更改,包括 681 次插入554 次删除
  1. 6 5
      .clj-kondo/config.edn
  2. 12 5
      clj-e2e/dev/user.clj
  3. 6 0
      clj-e2e/src/logseq/e2e/assert.clj
  4. 21 18
      clj-e2e/src/logseq/e2e/block.clj
  5. 1 0
      clj-e2e/src/logseq/e2e/keyboard.clj
  6. 8 0
      clj-e2e/src/logseq/e2e/util.clj
  7. 122 0
      clj-e2e/test/logseq/e2e/commands_test.clj
  8. 0 44
      clj-e2e/test/logseq/e2e/editor_test.clj
  9. 12 5
      clj-e2e/test/logseq/e2e/fixtures.clj
  10. 4 7
      clj-e2e/test/logseq/e2e/outliner_test.clj
  11. 1 1
      deps/db/.carve/config.edn
  12. 6 0
      deps/db/.carve/ignore
  13. 4 3
      deps/db/.clj-kondo/config.edn
  14. 1 1
      deps/db/script/diff_graphs.cljs
  15. 1 1
      deps/db/script/dump_datoms.cljs
  16. 1 1
      deps/db/script/export_graph.cljs
  17. 1 1
      deps/db/script/query.cljs
  18. 1 1
      deps/db/script/validate_db.cljs
  19. 17 8
      deps/db/src/logseq/db.cljs
  20. 1 1
      deps/db/src/logseq/db/common/delete_blocks.cljs
  21. 2 2
      deps/db/src/logseq/db/common/entity_plus.cljc
  22. 321 0
      deps/db/src/logseq/db/common/initial_data.cljs
  23. 1 1
      deps/db/src/logseq/db/common/property_util.cljs
  24. 9 334
      deps/db/src/logseq/db/common/sqlite.cljs
  25. 6 6
      deps/db/src/logseq/db/common/sqlite_cli.cljs
  26. 1 1
      deps/db/src/logseq/db/common/view.cljs
  27. 2 3
      deps/db/src/logseq/db/file_based/schema.cljs
  28. 1 1
      deps/db/src/logseq/db/frontend/malli_schema.cljs
  29. 1 1
      deps/db/src/logseq/db/frontend/schema.cljs
  30. 1 1
      deps/db/src/logseq/db/sqlite/create_graph.cljs
  31. 1 1
      deps/db/src/logseq/db/sqlite/export.cljs
  32. 1 16
      deps/db/src/logseq/db/sqlite/util.cljs
  33. 1 1
      deps/db/src/logseq/db/test/helper.cljs
  34. 7 7
      deps/db/test/logseq/db/common/initial_data_test.cljs
  35. 1 1
      deps/graph-parser/test/logseq/graph_parser/exporter_test.cljs
  36. 1 1
      deps/outliner/script/transact.cljs
  37. 1 1
      deps/outliner/src/logseq/outliner/cli.cljs
  38. 1 1
      deps/outliner/src/logseq/outliner/pipeline.cljs
  39. 1 1
      deps/outliner/src/logseq/outliner/property.cljs
  40. 1 1
      deps/outliner/test/logseq/outliner/validate_test.cljs
  41. 1 1
      deps/publishing/script/publishing.cljs
  42. 1 1
      deps/publishing/src/logseq/publishing/db.cljs
  43. 8 4
      scripts/src/logseq/tasks/dev/db_and_file_graphs.clj
  44. 5 5
      src/electron/electron/db.cljs
  45. 3 3
      src/electron/electron/handler.cljs
  46. 2 2
      src/main/frontend/background_tasks.cljs
  47. 14 4
      src/main/frontend/commands.cljs
  48. 1 1
      src/main/frontend/common/file/core.cljs
  49. 1 1
      src/main/frontend/common/graph_view.cljs
  50. 1 1
      src/main/frontend/components/block.cljs
  51. 11 10
      src/main/frontend/components/cmdk/core.cljs
  52. 1 1
      src/main/frontend/components/editor.cljs
  53. 2 2
      src/main/frontend/components/server.cljs
  54. 3 2
      src/main/frontend/db/restore.cljs
  55. 1 1
      src/main/frontend/db/utils.cljs
  56. 1 1
      src/main/frontend/extensions/fsrs.cljs
  57. 2 2
      src/main/frontend/handler/db_based/rtc.cljs
  58. 1 1
      src/main/frontend/handler/editor.cljs
  59. 3 3
      src/main/frontend/handler/export.cljs
  60. 1 1
      src/main/frontend/state.cljs
  61. 2 2
      src/main/frontend/worker/db/fix.cljs
  62. 22 17
      src/main/frontend/worker/db_worker.cljs
  63. 1 1
      src/main/frontend/worker/handler/page/db_based/page.cljs
  64. 2 1
      src/main/frontend/worker/pipeline.cljs
  65. 2 1
      src/main/frontend/worker/shared_service.cljs
  66. 2 2
      src/main/frontend/worker/util.cljc

+ 6 - 5
.clj-kondo/config.edn

@@ -9,7 +9,7 @@
 
 
   all-frontend
   all-frontend
   {:linters {:discouraged-namespace
   {:linters {:discouraged-namespace
-             {logseq.db.sqlite.cli {:message "frontend should not depend on CLI namespace with sqlite3 dependency"}
+             {logseq.db.common.sqlite-cli {:message "frontend should not depend on CLI namespace with sqlite3 dependency"}
               logseq.outliner.cli {:message "frontend should not depend on CLI namespace with sqlite3 dependency"}}}}
               logseq.outliner.cli {:message "frontend should not depend on CLI namespace with sqlite3 dependency"}}}}
 
 
   ;; false positive with match/match and _
   ;; false positive with match/match and _
@@ -45,7 +45,7 @@
    rum.core/use-layout-effect! {:message "Use frontend.hooks/use-layout-effect! instead" :level :info}
    rum.core/use-layout-effect! {:message "Use frontend.hooks/use-layout-effect! instead" :level :info}
    rum.core/use-callback {:message "Use frontend.hooks/use-callback instead" :level :info}}
    rum.core/use-callback {:message "Use frontend.hooks/use-callback instead" :level :info}}
   :unused-namespace {:level :warning
   :unused-namespace {:level :warning
-                     :exclude [logseq.db.frontend.entity-plus]}
+                     :exclude [logseq.db.common.entity-plus]}
 
 
   ;; TODO:lint: Remove node-path excludes once we have a cleaner api
   ;; TODO:lint: Remove node-path excludes once we have a cleaner api
   :unresolved-var {:exclude [frontend.util/node-path.basename
   :unresolved-var {:exclude [frontend.util/node-path.basename
@@ -173,10 +173,12 @@
              logseq.common.util.namespace ns-util
              logseq.common.util.namespace ns-util
              logseq.common.util.page-ref page-ref
              logseq.common.util.page-ref page-ref
              logseq.db ldb
              logseq.db ldb
+             logseq.db.common.entity-plus entity-plus
              logseq.db.common.entity-util common-entity-util
              logseq.db.common.entity-util common-entity-util
+             logseq.db.common.initial-data common-initial-data
              logseq.db.common.order db-order
              logseq.db.common.order db-order
              logseq.db.common.property-util db-property-util
              logseq.db.common.property-util db-property-util
-             logseq.db.common.sqlite sqlite-common-db
+             logseq.db.common.sqlite common-sqlite
              logseq.db.common.view db-view
              logseq.db.common.view db-view
              logseq.db.file-based.rules file-rules
              logseq.db.file-based.rules file-rules
              logseq.db.file-based.schema file-schema
              logseq.db.file-based.schema file-schema
@@ -185,7 +187,6 @@
              logseq.db.frontend.content db-content
              logseq.db.frontend.content db-content
              logseq.db.frontend.db db-db
              logseq.db.frontend.db db-db
              logseq.db.frontend.db-ident db-ident
              logseq.db.frontend.db-ident db-ident
-             logseq.db.frontend.entity-plus entity-plus
              logseq.db.frontend.entity-util entity-util
              logseq.db.frontend.entity-util entity-util
              logseq.db.frontend.inputs db-inputs
              logseq.db.frontend.inputs db-inputs
              logseq.db.frontend.property db-property
              logseq.db.frontend.property db-property
@@ -195,7 +196,7 @@
              logseq.db.frontend.schema db-schema
              logseq.db.frontend.schema db-schema
              logseq.db.frontend.validate db-validate
              logseq.db.frontend.validate db-validate
              logseq.db.sqlite.build sqlite-build
              logseq.db.sqlite.build sqlite-build
-             logseq.db.sqlite.cli sqlite-cli
+             logseq.db.common.sqlite-cli sqlite-cli
              logseq.db.sqlite.create-graph sqlite-create-graph
              logseq.db.sqlite.create-graph sqlite-create-graph
              logseq.db.sqlite.export sqlite-export
              logseq.db.sqlite.export sqlite-export
              logseq.db.sqlite.util sqlite-util
              logseq.db.sqlite.util sqlite-util

+ 12 - 5
clj-e2e/dev/user.clj

@@ -1,9 +1,11 @@
 (ns user
 (ns user
   "fns used on repl"
   "fns used on repl"
   (:require [clojure.test :refer [run-tests run-test]]
   (:require [clojure.test :refer [run-tests run-test]]
+            [logseq.e2e.block :as b]
+            [logseq.e2e.commands-test]
             [logseq.e2e.config :as config]
             [logseq.e2e.config :as config]
-            [logseq.e2e.editor-test]
             [logseq.e2e.fixtures :as fixtures]
             [logseq.e2e.fixtures :as fixtures]
+            [logseq.e2e.keyboard :as k]
             [logseq.e2e.multi-tabs-test]
             [logseq.e2e.multi-tabs-test]
             [logseq.e2e.outliner-test]
             [logseq.e2e.outliner-test]
             [logseq.e2e.rtc-basic-test]
             [logseq.e2e.rtc-basic-test]
@@ -23,10 +25,10 @@
   (some-> (get @*futures test-name) future-cancel)
   (some-> (get @*futures test-name) future-cancel)
   (swap! *futures dissoc test-name))
   (swap! *futures dissoc test-name))
 
 
-(defn run-editor-test
+(defn run-commands-test
   []
   []
-  (->> (future (run-tests 'logseq.e2e.editor-test))
-       (swap! *futures assoc :editor-test)))
+  (->> (future (run-tests 'logseq.e2e.commands-test))
+       (swap! *futures assoc :commands-test)))
 
 
 (defn run-outliner-test
 (defn run-outliner-test
   []
   []
@@ -65,9 +67,14 @@
     (w/wait-for (first (util/get-edit-block-container))
     (w/wait-for (first (util/get-edit-block-container))
                 {:state :detached}))
                 {:state :detached}))
 
 
-  (run-tests 'logseq.e2e.editor-test
+  (run-tests 'logseq.e2e.commands-test
              'logseq.e2e.multi-tabs-test
              'logseq.e2e.multi-tabs-test
              'logseq.e2e.outliner-test
              'logseq.e2e.outliner-test
              'logseq.e2e.rtc-basic-test)
              'logseq.e2e.rtc-basic-test)
+
+  (do
+    (reset! config/*headless true)
+    (dotimes [i 10]
+      (run-outliner-test)))
   ;;
   ;;
   )
   )

+ 6 - 0
clj-e2e/src/logseq/e2e/assert.clj

@@ -29,3 +29,9 @@
   []
   []
   ;; there's some blocks visible now
   ;; there's some blocks visible now
   (assert-is-visible "span.block-title-wrap"))
   (assert-is-visible "span.block-title-wrap"))
+
+(defn assert-editor-mode
+  []
+  (let [klass ".editor-wrapper textarea"
+        editor (w/-query klass)]
+    (w/wait-for editor)))

+ 21 - 18
clj-e2e/src/logseq/e2e/block.clj

@@ -11,14 +11,30 @@
   (assert/assert-in-normal-mode?)
   (assert/assert-in-normal-mode?)
   (w/click (last (w/query ".ls-page-blocks .ls-block .block-content"))))
   (w/click (last (w/query ".ls-page-blocks .ls-block .block-content"))))
 
 
+(defn save-block
+  [text]
+  (w/fill ".editor-wrapper textarea" text))
+
 (defn new-block
 (defn new-block
   [title]
   [title]
-  (k/enter)
-  (util/input title))
+  (let [editor? (util/get-editor)]
+    (when-not editor? (open-last-block))
+    (assert/assert-editor-mode)
+    (k/enter)
+    (save-block title)))
 
 
-(defn save-block
-  [text]
-  (util/input text))
+;; TODO: support tree
+(defn new-blocks
+  [titles]
+  (let [editor? (util/get-editor)]
+    (when-not editor? (open-last-block))
+    (assert/assert-editor-mode)
+    (let [value (util/get-edit-content)]
+      (if (string/blank? value)           ; empty block
+        (save-block (first titles))
+        (new-block (first titles))))
+    (doseq [title (rest titles)]
+      (new-block title))))
 
 
 (defn delete-blocks
 (defn delete-blocks
   "Delete the current block if in editing mode, otherwise, delete all the selected blocks."
   "Delete the current block if in editing mode, otherwise, delete all the selected blocks."
@@ -27,19 +43,6 @@
     (when editor (util/exit-edit))
     (when editor (util/exit-edit))
     (k/backspace)))
     (k/backspace)))
 
 
-;; TODO: support tree
-(defn new-blocks
-  [titles]
-  (open-last-block)
-  (let [value (util/get-edit-content)]
-    (if (string/blank? value)           ; empty block
-      (do
-        (save-block (first titles))
-        (doseq [title (rest titles)]
-          (new-block title)))
-      (doseq [title titles]
-        (new-block title)))))
-
 (defn assert-blocks-visible
 (defn assert-blocks-visible
   "blocks - coll of :block/title"
   "blocks - coll of :block/title"
   [blocks]
   [blocks]

+ 1 - 0
clj-e2e/src/logseq/e2e/keyboard.clj

@@ -8,5 +8,6 @@
 (def backspace #(press "Backspace"))
 (def backspace #(press "Backspace"))
 (def tab #(press "Tab"))
 (def tab #(press "Tab"))
 (def shift+tab #(press "Shift+Tab"))
 (def shift+tab #(press "Shift+Tab"))
+(def shift+enter #(press "Shift+Enter"))
 (def arrow-up #(press "ArrowUp"))
 (def arrow-up #(press "ArrowUp"))
 (def arrow-down #(press "ArrowDown"))
 (def arrow-down #(press "ArrowDown"))

+ 8 - 0
clj-e2e/src/logseq/e2e/util.clj

@@ -161,3 +161,11 @@
   []
   []
   (w/refresh)
   (w/refresh)
   (assert/assert-graph-loaded?))
   (assert/assert-graph-loaded?))
+
+(defn move-cursor-to-end
+  []
+  (k/press "ControlOrMeta+a" "ArrowRight"))
+
+(defn move-cursor-to-start
+  []
+  (k/press "ControlOrMeta+a" "ArrowLeft"))

+ 122 - 0
clj-e2e/test/logseq/e2e/commands_test.clj

@@ -0,0 +1,122 @@
+(ns logseq.e2e.commands-test
+  (:require
+   [clojure.string :as string]
+   [clojure.test :refer [deftest testing is use-fixtures]]
+   [logseq.e2e.block :as b]
+   [logseq.e2e.fixtures :as fixtures]
+   [logseq.e2e.keyboard :as k]
+   [logseq.e2e.util :as util]
+   [wally.main :as w]))
+
+(use-fixtures :once fixtures/open-page)
+
+(use-fixtures :each fixtures/new-logseq-page)
+
+(deftest command-trigger-test
+  (testing "/command trigger popup"
+    (b/new-block "b2")
+    (util/type " /")
+    (w/wait-for ".ui__popover-content")
+    (is (some? (w/find-one-by-text "span" "Node reference")))
+    (k/backspace)
+    (w/wait-for-not-visible ".ui__popover-content")))
+
+(defn- input-command
+  [command-match]
+  (util/type "/")
+  (util/type command-match)
+  (w/wait-for ".ui__popover-content")
+  (k/enter))
+
+(deftest node-reference-test
+  (testing "Node reference"
+    (testing "Page reference"
+      (b/new-blocks ["b1" ""])
+      (input-command "Node eferen")
+      (util/type "Another page")
+      (k/enter)
+      (is (= "[[Another page]]" (util/get-edit-content)))
+      (util/exit-edit)
+      (is (= "Another page" (util/get-text "a.page-ref"))))
+    (testing "Block reference"
+      (b/new-block "")
+      (input-command "Node eferen")
+      (util/type "b1")
+      (util/wait-timeout 300)
+      (k/enter)
+      (is (string/includes? (util/get-edit-content) "[["))
+      (util/exit-edit)
+      (is (= "b1" (util/get-text ".block-ref"))))))
+
+(deftest link-test
+  (testing "/link"
+    (let [add-logseq-link (fn []
+                            (util/type "https://logseq.com")
+                            (k/tab)
+                            (util/type "Logseq")
+                            (k/tab)
+                            (k/enter))]
+      (b/new-block "")
+      (input-command "link")
+      (add-logseq-link)
+      (is (= "[Logseq](https://logseq.com)" (util/get-edit-content)))
+      (util/type " some content ")
+      (input-command "link")
+      (add-logseq-link)
+      (is (= (str "[Logseq](https://logseq.com)"
+                  " some content "
+                  "[Logseq](https://logseq.com)") (util/get-edit-content))))))
+
+(deftest link-image-test
+  (testing "/image link"
+    (b/new-block "")
+    (input-command "image link")
+    (util/type "https://logseq.com/test.png")
+    (k/tab)
+    (util/type "Logseq")
+    (k/tab)
+    (k/enter)
+    (is (= "![Logseq](https://logseq.com/test.png)" (util/get-edit-content)))))
+
+(deftest underline-test
+  (testing "/underline"
+    (b/new-block "")
+    (input-command "underline")
+    (is (= "<ins></ins>" (util/get-edit-content)))
+    (util/type "test")
+    (is (= "<ins>test</ins>" (util/get-edit-content)))
+    (util/move-cursor-to-end)))
+
+(deftest code-block-test
+  (testing "/code block"
+    (b/new-block "")
+    (input-command "code block")
+    (w/wait-for ".CodeMirror")
+    (util/wait-timeout 100)
+    ;; create another block
+    (k/shift+enter)))
+
+(deftest math-block-test
+  (testing "/math block"
+    (b/new-block "")
+    (input-command "math block")
+    (util/type "1 + 2 = 3")
+    (util/exit-edit)
+    (w/wait-for ".katex")))
+
+(deftest quote-test
+  (testing "/quote"
+    (b/new-block "")
+    (input-command "quote")
+    (w/wait-for "div[data-node-type='quote']")))
+
+(deftest headings-test
+  (testing "/heading"
+    (dotimes [i 6]
+      (let [heading (str "h" (inc i))
+            text (str heading " test ")]
+        (b/new-block text)
+        (input-command heading)
+        (is (= text (util/get-edit-content)))
+        (util/exit-edit)
+        (w/wait-for heading)))))

+ 0 - 44
clj-e2e/test/logseq/e2e/editor_test.clj

@@ -1,44 +0,0 @@
-(ns logseq.e2e.editor-test
-  (:require
-   [clojure.string :as string]
-   [clojure.test :refer [deftest testing is use-fixtures]]
-   [logseq.e2e.block :as b]
-   [logseq.e2e.fixtures :as fixtures]
-   [logseq.e2e.keyboard :as k]
-   [logseq.e2e.util :as util]
-   [wally.main :as w]))
-
-(use-fixtures :once fixtures/open-page)
-
-(deftest commands-test
-  (testing "/command trigger popup"
-    (util/new-page "Test")
-    (b/save-block "b1")
-    (util/type " /")
-    (w/wait-for ".ui__popover-content")
-    (is (some? (w/find-one-by-text "span" "Node reference")))
-    (k/backspace)
-    (w/wait-for-not-visible ".ui__popover-content"))
-
-  (testing "Node reference"
-    (testing "Page reference"
-      (b/new-block "/")
-      (util/type "Node eferen")
-      (w/wait-for ".ui__popover-content")
-      (k/enter)
-      (util/type "Another page")
-      (k/enter)
-      (is (= "[[Another page]]" (util/get-edit-content)))
-      (util/exit-edit)
-      (is (= "Another page" (util/get-text "a.page-ref"))))
-    (testing "Block reference"
-      (b/new-block "/")
-      (util/type "Node eferen")
-      (w/wait-for ".ui__popover-content")
-      (k/enter)
-      (util/type "b1")
-      (util/wait-timeout 300)
-      (k/enter)
-      (is (string/includes? (util/get-edit-content) "[["))
-      (util/exit-edit)
-      (is (= "b1" (util/get-text ".block-ref"))))))

+ 12 - 5
clj-e2e/test/logseq/e2e/fixtures.clj

@@ -1,7 +1,8 @@
 (ns logseq.e2e.fixtures
 (ns logseq.e2e.fixtures
-  (:require [wally.main :as w]
-            [logseq.e2e.config :as config]
-            [logseq.e2e.playwright-page :as pw-page]))
+  (:require [logseq.e2e.config :as config]
+            [logseq.e2e.playwright-page :as pw-page]
+            [logseq.e2e.util :as util]
+            [wally.main :as w]))
 
 
 ;; TODO: save trace
 ;; TODO: save trace
 ;; TODO: parallel support
 ;; TODO: parallel support
@@ -10,8 +11,7 @@
   (w/with-page-open
   (w/with-page-open
     (w/make-page {:headless (or headless @config/*headless)
     (w/make-page {:headless (or headless @config/*headless)
                   :persistent false
                   :persistent false
-                  :slow-mo @config/*slow-mo
-                  })
+                  :slow-mo @config/*slow-mo})
     (w/navigate (str "http://localhost:" (or port @config/*port)))
     (w/navigate (str "http://localhost:" (or port @config/*port)))
     (f)))
     (f)))
 
 
@@ -55,3 +55,10 @@
     (binding [*pw-ctx* ctx]
     (binding [*pw-ctx* ctx]
       (f)
       (f)
       (.close (.browser *pw-ctx*)))))
       (.close (.browser *pw-ctx*)))))
+
+(defonce *page-number (atom 0))
+
+(defn new-logseq-page
+  [f]
+  (util/new-page (str "page " (swap! *page-number inc)))
+  (f))

+ 4 - 7
clj-e2e/test/logseq/e2e/outliner_test.clj

@@ -1,16 +1,16 @@
 (ns logseq.e2e.outliner-test
 (ns logseq.e2e.outliner-test
   (:require
   (:require
    [clojure.test :refer [deftest testing is use-fixtures]]
    [clojure.test :refer [deftest testing is use-fixtures]]
+   [logseq.e2e.block :as b]
    [logseq.e2e.fixtures :as fixtures]
    [logseq.e2e.fixtures :as fixtures]
    [logseq.e2e.keyboard :as k]
    [logseq.e2e.keyboard :as k]
-   [logseq.e2e.block :as b]
    [logseq.e2e.util :as util]
    [logseq.e2e.util :as util]
    [wally.main :as w]))
    [wally.main :as w]))
 
 
 (use-fixtures :once fixtures/open-page)
 (use-fixtures :once fixtures/open-page)
+(use-fixtures :each fixtures/new-logseq-page)
 
 
 (deftest create-test-page-and-insert-blocks
 (deftest create-test-page-and-insert-blocks
-  (util/new-page "p1")
   ;; a page block and a child block
   ;; a page block and a child block
   (is (= 2 (util/blocks-count)))
   (is (= 2 (util/blocks-count)))
   (b/new-blocks ["first block" "second block"])
   (b/new-blocks ["first block" "second block"])
@@ -18,7 +18,6 @@
   (is (= 3 (util/blocks-count))))
   (is (= 3 (util/blocks-count))))
 
 
 (deftest indent-and-outdent-test
 (deftest indent-and-outdent-test
-  (util/new-page "p2")
   (b/new-blocks ["b1" "b2"])
   (b/new-blocks ["b1" "b2"])
   (testing "simple indent and outdent"
   (testing "simple indent and outdent"
     (util/indent)
     (util/indent)
@@ -44,7 +43,6 @@
       (is (and (= x2 x4) (= x3 x5) (< x2 x3))))))
       (is (and (= x2 x4) (= x3 x5) (< x2 x3))))))
 
 
 (deftest move-up-down-test
 (deftest move-up-down-test
-  (util/new-page "p3")
   (b/new-blocks ["b1" "b2" "b3" "b4"])
   (b/new-blocks ["b1" "b2" "b3" "b4"])
   (util/repeat-keyboard 2 "Shift+ArrowUp")
   (util/repeat-keyboard 2 "Shift+ArrowUp")
   (let [contents (util/get-page-blocks-contents)]
   (let [contents (util/get-page-blocks-contents)]
@@ -58,16 +56,15 @@
 
 
 (deftest delete-test
 (deftest delete-test
   (testing "Delete blocks case 1"
   (testing "Delete blocks case 1"
-    (util/new-page "p4")
     (b/new-blocks ["b1" "b2" "b3" "b4"])
     (b/new-blocks ["b1" "b2" "b3" "b4"])
     (b/delete-blocks)                   ; delete b4
     (b/delete-blocks)                   ; delete b4
     (util/repeat-keyboard 2 "Shift+ArrowUp") ; select b3 and b2
     (util/repeat-keyboard 2 "Shift+ArrowUp") ; select b3 and b2
     (b/delete-blocks)
     (b/delete-blocks)
     (is (= "b1" (util/get-edit-content)))
     (is (= "b1" (util/get-edit-content)))
-    (is (= 1 (util/page-blocks-count))))
+    (is (= 1 (util/page-blocks-count)))))
 
 
+(deftest delete-test-with-children
   (testing "Delete block with its children"
   (testing "Delete block with its children"
-    (util/new-page "p5")
     (b/new-blocks ["b1" "b2" "b3" "b4"])
     (b/new-blocks ["b1" "b2" "b3" "b4"])
     (util/indent)
     (util/indent)
     (k/arrow-up)
     (k/arrow-up)

+ 1 - 1
deps/db/.carve/config.edn

@@ -1,7 +1,7 @@
 {:paths ["src"]
 {:paths ["src"]
  :api-namespaces [logseq.db.common.sqlite
  :api-namespaces [logseq.db.common.sqlite
                   logseq.db.sqlite.util
                   logseq.db.sqlite.util
-                  logseq.db.sqlite.cli
+                  logseq.db.common.sqlite-cli
                   logseq.db.frontend.property
                   logseq.db.frontend.property
                   logseq.db.frontend.property.build
                   logseq.db.frontend.property.build
                   logseq.db.common.property-util
                   logseq.db.common.property-util

+ 6 - 0
deps/db/.carve/ignore

@@ -28,3 +28,9 @@ logseq.db.sqlite.export/build-import
 logseq.db.common.view/get-property-values
 logseq.db.common.view/get-property-values
 ;; API
 ;; API
 logseq.db.common.view/get-view-data
 logseq.db.common.view/get-view-data
+;; API
+logseq.db.common.initial-data/with-parent
+;; API
+logseq.db.common.initial-data/get-block-and-children
+;; API
+logseq.db.common.initial-data/get-initial-data

+ 4 - 3
deps/db/.clj-kondo/config.edn

@@ -9,10 +9,11 @@
   :consistent-alias
   :consistent-alias
   {:aliases {clojure.string string
   {:aliases {clojure.string string
              logseq.db ldb
              logseq.db ldb
+             logseq.db.common.entity-plus entity-plus
              logseq.db.common.entity-util common-entity-util
              logseq.db.common.entity-util common-entity-util
              logseq.db.common.order db-order
              logseq.db.common.order db-order
              logseq.db.common.property-util db-property-util
              logseq.db.common.property-util db-property-util
-             logseq.db.common.sqlite sqlite-common-db
+             logseq.db.common.sqlite common-sqlite
              logseq.db.common.view db-view
              logseq.db.common.view db-view
              logseq.db.frontend.content db-content
              logseq.db.frontend.content db-content
              logseq.db.frontend.class db-class
              logseq.db.frontend.class db-class
@@ -25,12 +26,12 @@
              logseq.db.file-based.rules file-rules
              logseq.db.file-based.rules file-rules
              logseq.db.file-based.schema file-schema
              logseq.db.file-based.schema file-schema
              logseq.db.file-based.entity-util file-entity-util
              logseq.db.file-based.entity-util file-entity-util
-             logseq.db.frontend.entity-plus entity-plus
              logseq.db.frontend.rules rules
              logseq.db.frontend.rules rules
              logseq.db.frontend.schema db-schema
              logseq.db.frontend.schema db-schema
              logseq.db.frontend.validate db-validate
              logseq.db.frontend.validate db-validate
              logseq.db.sqlite.build sqlite-build
              logseq.db.sqlite.build sqlite-build
-             logseq.db.sqlite.cli sqlite-cli
+             logseq.db.common.initial-data common-initial-data
+             logseq.db.common.sqlite-cli sqlite-cli
              logseq.db.sqlite.create-graph sqlite-create-graph
              logseq.db.sqlite.create-graph sqlite-create-graph
              logseq.db.sqlite.export sqlite-export
              logseq.db.sqlite.export sqlite-export
              logseq.db.sqlite.util sqlite-util}}}
              logseq.db.sqlite.util sqlite-util}}}

+ 1 - 1
deps/db/script/diff_graphs.cljs

@@ -7,7 +7,7 @@
             [clojure.pprint :as pprint]
             [clojure.pprint :as pprint]
             [clojure.string :as string]
             [clojure.string :as string]
             [logseq.common.config :as common-config]
             [logseq.common.config :as common-config]
-            [logseq.db.sqlite.cli :as sqlite-cli]
+            [logseq.db.common.sqlite-cli :as sqlite-cli]
             [logseq.db.sqlite.export :as sqlite-export]
             [logseq.db.sqlite.export :as sqlite-export]
             [nbb.core :as nbb]))
             [nbb.core :as nbb]))
 
 

+ 1 - 1
deps/db/script/dump_datoms.cljs

@@ -7,7 +7,7 @@
               ["path" :as path]
               ["path" :as path]
               [clojure.pprint :as pprint]
               [clojure.pprint :as pprint]
               [datascript.core :as d]
               [datascript.core :as d]
-              [logseq.db.sqlite.cli :as sqlite-cli]
+              [logseq.db.common.sqlite-cli :as sqlite-cli]
               [nbb.core :as nbb]))
               [nbb.core :as nbb]))
 
 
 (defn read-graph
 (defn read-graph

+ 1 - 1
deps/db/script/export_graph.cljs

@@ -7,7 +7,7 @@
             [clojure.edn :as edn]
             [clojure.edn :as edn]
             [clojure.pprint :as pprint]
             [clojure.pprint :as pprint]
             [clojure.string :as string]
             [clojure.string :as string]
-            [logseq.db.sqlite.cli :as sqlite-cli]
+            [logseq.db.common.sqlite-cli :as sqlite-cli]
             [logseq.db.sqlite.export :as sqlite-export]
             [logseq.db.sqlite.export :as sqlite-export]
             [nbb.core :as nbb]))
             [nbb.core :as nbb]))
 
 

+ 1 - 1
deps/db/script/query.cljs

@@ -11,7 +11,7 @@
             [clojure.string :as string]
             [clojure.string :as string]
             [datascript.core :as d]
             [datascript.core :as d]
             [logseq.db.frontend.rules :as rules]
             [logseq.db.frontend.rules :as rules]
-            [logseq.db.sqlite.cli :as sqlite-cli]
+            [logseq.db.common.sqlite-cli :as sqlite-cli]
             [nbb.core :as nbb]))
             [nbb.core :as nbb]))
 
 
 (defn- sh
 (defn- sh

+ 1 - 1
deps/db/script/validate_db.cljs

@@ -9,7 +9,7 @@
             [datascript.core :as d]
             [datascript.core :as d]
             [logseq.db.frontend.malli-schema :as db-malli-schema]
             [logseq.db.frontend.malli-schema :as db-malli-schema]
             [logseq.db.frontend.validate :as db-validate]
             [logseq.db.frontend.validate :as db-validate]
-            [logseq.db.sqlite.cli :as sqlite-cli]
+            [logseq.db.common.sqlite-cli :as sqlite-cli]
             [malli.core :as m]
             [malli.core :as m]
             [malli.error :as me]
             [malli.error :as me]
             [nbb.core :as nbb]))
             [nbb.core :as nbb]))

+ 17 - 8
deps/db/src/logseq/db.cljs

@@ -10,14 +10,16 @@
             [logseq.common.util :as common-util]
             [logseq.common.util :as common-util]
             [logseq.common.uuid :as common-uuid]
             [logseq.common.uuid :as common-uuid]
             [logseq.db.common.delete-blocks :as delete-blocks] ;; Load entity extensions
             [logseq.db.common.delete-blocks :as delete-blocks] ;; Load entity extensions
+            [logseq.db.common.entity-plus :as entity-plus]
             [logseq.db.common.entity-util :as common-entity-util]
             [logseq.db.common.entity-util :as common-entity-util]
-            [logseq.db.common.sqlite :as sqlite-common-db]
+            [logseq.db.common.initial-data :as common-initial-data]
+            [logseq.db.file-based.schema :as file-schema]
             [logseq.db.frontend.class :as db-class]
             [logseq.db.frontend.class :as db-class]
             [logseq.db.frontend.db :as db-db]
             [logseq.db.frontend.db :as db-db]
-            [logseq.db.frontend.entity-plus :as entity-plus]
             [logseq.db.frontend.entity-util :as entity-util]
             [logseq.db.frontend.entity-util :as entity-util]
             [logseq.db.frontend.property :as db-property]
             [logseq.db.frontend.property :as db-property]
             [logseq.db.frontend.rules :as rules]
             [logseq.db.frontend.rules :as rules]
+            [logseq.db.frontend.schema :as db-schema]
             [logseq.db.sqlite.util :as sqlite-util])
             [logseq.db.sqlite.util :as sqlite-util])
   (:refer-clojure :exclude [object?]))
   (:refer-clojure :exclude [object?]))
 
 
@@ -190,7 +192,7 @@
        (map first)
        (map first)
        (remove hidden?)))
        (remove hidden?)))
 
 
-(def get-first-page-by-name sqlite-common-db/get-first-page-by-name)
+(def get-first-page-by-name common-initial-data/get-first-page-by-name)
 
 
 (def db-based-graph? entity-plus/db-based-graph?)
 (def db-based-graph? entity-plus/db-based-graph?)
 
 
@@ -248,7 +250,7 @@
     (if-let [id (if (uuid? page-name-or-uuid) page-name-or-uuid
     (if-let [id (if (uuid? page-name-or-uuid) page-name-or-uuid
                     (parse-uuid page-name-or-uuid))]
                     (parse-uuid page-name-or-uuid))]
       (d/entity db [:block/uuid id])
       (d/entity db [:block/uuid id])
-      (d/entity db (sqlite-common-db/get-first-page-by-title db page-name-or-uuid)))))
+      (d/entity db (common-initial-data/get-first-page-by-title db page-name-or-uuid)))))
 
 
 (defn page-empty?
 (defn page-empty?
   "Whether a page is empty. Does it has a non-page block?
   "Whether a page is empty. Does it has a non-page block?
@@ -347,8 +349,8 @@
         (recur (:block/uuid parent) (conj parents' parent) (inc d))
         (recur (:block/uuid parent) (conj parents' parent) (inc d))
         parents'))))
         parents'))))
 
 
-(def get-block-children-ids sqlite-common-db/get-block-children-ids)
-(def get-block-children sqlite-common-db/get-block-children)
+(def get-block-children-ids common-initial-data/get-block-children-ids)
+(def get-block-children common-initial-data/get-block-children)
 
 
 (defn- get-sorted-page-block-ids
 (defn- get-sorted-page-block-ids
   [db page-id]
   [db page-id]
@@ -541,9 +543,9 @@
 (def get-class-ident-by-display-type db-db/get-class-ident-by-display-type)
 (def get-class-ident-by-display-type db-db/get-class-ident-by-display-type)
 (def get-display-type-by-class-ident db-db/get-display-type-by-class-ident)
 (def get-display-type-by-class-ident db-db/get-display-type-by-class-ident)
 
 
-(def get-recent-updated-pages sqlite-common-db/get-recent-updated-pages)
+(def get-recent-updated-pages common-initial-data/get-recent-updated-pages)
 
 
-(def get-latest-journals sqlite-common-db/get-latest-journals)
+(def get-latest-journals common-initial-data/get-latest-journals)
 
 
 (defn get-pages-relation
 (defn get-pages-relation
   [db with-journal?]
   [db with-journal?]
@@ -578,3 +580,10 @@
          :where
          :where
          [?page :block/tags ?tag]]
          [?page :block/tags ?tag]]
        db))
        db))
+
+(defn get-schema
+  "Returns schema for given repo"
+  [repo]
+  (if (sqlite-util/db-based-graph? repo)
+    db-schema/schema
+    file-schema/schema))

+ 1 - 1
deps/db/src/logseq/db/common/delete_blocks.cljs

@@ -6,7 +6,7 @@
             [logseq.common.util.block-ref :as block-ref]
             [logseq.common.util.block-ref :as block-ref]
             [logseq.common.util.page-ref :as page-ref]
             [logseq.common.util.page-ref :as page-ref]
             [logseq.db.common.entity-util :as common-entity-util]
             [logseq.db.common.entity-util :as common-entity-util]
-            [logseq.db.frontend.entity-plus :as entity-plus]
+            [logseq.db.common.entity-plus :as entity-plus]
             [logseq.db.frontend.entity-util :as entity-util]))
             [logseq.db.frontend.entity-util :as entity-util]))
 
 
 (defn- replace-ref-with-deleted-block-title
 (defn- replace-ref-with-deleted-block-title

+ 2 - 2
deps/db/src/logseq/db/frontend/entity_plus.cljc → deps/db/src/logseq/db/common/entity_plus.cljc

@@ -1,4 +1,4 @@
-(ns logseq.db.frontend.entity-plus
+(ns logseq.db.common.entity-plus
   "Add map ops such as assoc/dissoc to datascript Entity.
   "Add map ops such as assoc/dissoc to datascript Entity.
 
 
    NOTE: This doesn't work for nbb/sci yet because of https://github.com/babashka/sci/issues/639"
    NOTE: This doesn't work for nbb/sci yet because of https://github.com/babashka/sci/issues/639"
@@ -58,7 +58,7 @@
     ;; FIXME: Correct dependency ordering instead of resolve workaround
     ;; FIXME: Correct dependency ordering instead of resolve workaround
     #?(:org.babashka/nbb false
     #?(:org.babashka/nbb false
        :cljs (when-let [f (resolve 'frontend.common.missionary/background-task-running?)]
        :cljs (when-let [f (resolve 'frontend.common.missionary/background-task-running?)]
-               (f :logseq.db.frontend.entity-plus/reset-immutable-entities-cache!)))))
+               (f :logseq.db.common.entity-plus/reset-immutable-entities-cache!)))))
 
 
 (defn entity-memoized
 (defn entity-memoized
   [db eid]
   [db eid]

+ 321 - 0
deps/db/src/logseq/db/common/initial_data.cljs

@@ -0,0 +1,321 @@
+(ns logseq.db.common.initial-data
+  "Provides db helper fns for graph initialization and lazy loading entities"
+  (:require [clojure.set :as set]
+            [datascript.core :as d]
+            [datascript.impl.entity :as de]
+            [logseq.common.config :as common-config]
+            [logseq.common.util :as common-util]
+            [logseq.common.util.date-time :as date-time-util]
+            [logseq.db.common.entity-util :as common-entity-util]
+            [logseq.db.common.order :as db-order]
+            [logseq.db.common.entity-plus :as entity-plus]
+            [logseq.db.frontend.entity-util :as entity-util]))
+
+(defn- get-pages-by-name
+  [db page-name]
+  (d/datoms db :avet :block/name (common-util/page-name-sanity-lc page-name)))
+
+(defn get-first-page-by-name
+  "Return the oldest page's db id for :block/name"
+  [db page-name]
+  (when (and db (string? page-name))
+    (first (sort (map :e (get-pages-by-name db page-name))))))
+
+(defn get-first-page-by-title
+  "Return the oldest page's db id for :block/title"
+  [db page-name]
+  {:pre [(string? page-name)]}
+  (->> (d/datoms db :avet :block/title page-name)
+       (filter (fn [d]
+                 (let [e (d/entity db (:e d))]
+                   (common-entity-util/page? e))))
+       (map :e)
+       sort
+       first))
+
+(comment
+  (defn- get-built-in-files
+    [db]
+    (let [files ["logseq/config.edn"
+                 "logseq/custom.css"
+                 "logseq/custom.js"]]
+      (map #(d/pull db '[*] [:file/path %]) files))))
+
+(defn- get-all-files
+  [db]
+  (->> (d/datoms db :avet :file/path)
+       (mapcat (fn [e] (d/datoms db :eavt (:e e))))))
+
+(defn- with-block-refs
+  [db block]
+  (update block :block/refs (fn [refs] (map (fn [ref] (d/pull db '[*] (:db/id ref))) refs))))
+
+(defn with-parent
+  [db block]
+  (cond
+    (:block/page block)
+    (let [parent (when-let [e (d/entity db (:db/id (:block/parent block)))]
+                   (select-keys e [:db/id :block/uuid]))]
+      (->>
+       (assoc block :block/parent parent)
+       (common-util/remove-nils-non-nested)
+       (with-block-refs db)))
+
+    :else
+    block))
+
+(comment
+  (defn- with-block-link
+    [db block]
+    (if (:block/link block)
+      (update block :block/link (fn [link] (d/pull db '[*] (:db/id link))))
+      block)))
+
+(defn- mark-block-fully-loaded
+  [b]
+  (assoc b :block.temp/fully-loaded? true))
+
+(comment
+  (defn- property-without-db-attrs
+    [property]
+    (dissoc property :db/index :db/valueType :db/cardinality))
+
+  (defn- property-with-values
+    [db block properties]
+    (when (entity-plus/db-based-graph? db)
+      (let [block (d/entity db (:db/id block))
+            property-vals (if properties
+                            (map block properties)
+                            (vals (:block/properties block)))]
+        (->> property-vals
+             (mapcat
+              (fn [property-values]
+                (let [values (->>
+                              (if (and (coll? property-values)
+                                       (map? (first property-values)))
+                                property-values
+                                #{property-values}))
+                      value-ids (when (every? map? values)
+                                  (->> (map :db/id values)
+                                       (filter (fn [id] (or (int? id) (keyword? id))))))
+                      value-blocks (->>
+                                    (when (seq value-ids)
+                                      (map
+                                       (fn [id] (d/pull db '[:db/id :block/uuid
+                                                             :block/name :block/title
+                                                             :logseq.property/value
+                                                             :block/tags :block/page
+                                                             :logseq.property/created-from-property] id))
+                                       value-ids))
+                                  ;; FIXME: why d/pull returns {:db/id db-ident} instead of {:db/id number-eid}?
+                                    (keep (fn [block]
+                                            (let [from-property-id (get-in block [:logseq.property/created-from-property :db/id])]
+                                              (if (keyword? from-property-id)
+                                                (assoc-in block [:logseq.property/created-from-property :db/id] (:db/id (d/entity db from-property-id)))
+                                                block)))))]
+                  value-blocks))))))))
+
+(defn get-block-children-ids
+  "Returns children UUIDs"
+  [db block-uuid]
+  (when-let [eid (:db/id (d/entity db [:block/uuid block-uuid]))]
+    (let [seen   (volatile! [])]
+      (loop [steps          100      ;check result every 100 steps
+             eids-to-expand [eid]]
+        (when (seq eids-to-expand)
+          (let [eids-to-expand*
+                (mapcat (fn [eid] (map first (d/datoms db :avet :block/parent eid))) eids-to-expand)
+                uuids-to-add (remove nil? (map #(:block/uuid (d/entity db %)) eids-to-expand*))]
+            (when (and (zero? steps)
+                       (seq (set/intersection (set @seen) (set uuids-to-add))))
+              (throw (ex-info "bad outliner data, need to re-index to fix"
+                              {:seen @seen :eids-to-expand eids-to-expand})))
+            (vswap! seen (partial apply conj) uuids-to-add)
+            (recur (if (zero? steps) 100 (dec steps)) eids-to-expand*))))
+      @seen)))
+
+(defn get-block-children
+  "Including nested children."
+  [db block-uuid]
+  (let [ids (get-block-children-ids db block-uuid)]
+    (when (seq ids)
+      (let [ids' (map (fn [id] [:block/uuid id]) ids)]
+        (d/pull-many db '[*] ids')))))
+
+(defn- with-raw-title
+  [m entity]
+  (if-let [raw-title (:block/raw-title entity)]
+    (assoc m :block/title raw-title)
+    m))
+
+(defn- entity->map
+  [entity]
+  (-> (into {} entity)
+      (with-raw-title entity)
+      (assoc :db/id (:db/id entity))))
+
+(defn ^:large-vars/cleanup-todo get-block-and-children
+  [db id {:keys [children? children-only? nested-children? properties children-props]}]
+  (let [block (d/entity db (if (uuid? id)
+                             [:block/uuid id]
+                             id))
+        block-refs-count? (some #{:block.temp/refs-count} properties)
+        whiteboard? (common-entity-util/whiteboard? block)]
+    (when block
+      (let [children (when (or children? children-only?)
+                       (let [page? (common-entity-util/page? block)
+                             children (->>
+                                       (cond
+                                         (and nested-children? (not page?))
+                                         (get-block-children db (:block/uuid block))
+                                         nested-children?
+                                         (:block/_page block)
+                                         :else
+                                         (let [short-page? (when page?
+                                                             (<= (count (:block/_page block)) 100))]
+                                           (if short-page?
+                                             (:block/_page block)
+                                             (:block/_parent block))))
+                                       (remove (fn [e] (or (:logseq.property/created-from-property e)
+                                                           (:block/closed-value-property e)))))
+                             children-props (if whiteboard?
+                                              '[*]
+                                              (or children-props
+                                                  [:db/id :block/uuid :block/parent :block/order :block/collapsed? :block/title
+                                                   ;; pre-loading feature-related properties to avoid UI refreshing
+                                                   :logseq.task/status :logseq.property.node/display-type]))]
+                         (map
+                          (fn [block]
+                            (if (= children-props '[*])
+                              (entity->map block)
+                              (-> (select-keys block children-props)
+                                  (with-raw-title block))))
+                          children)))]
+        (if children-only?
+          {:children children}
+          (let [block' (if (seq properties)
+                         (-> (select-keys block properties)
+                             (with-raw-title block)
+                             (assoc :db/id (:db/id block)))
+                         (entity->map block))
+                block' (cond->
+                        (mark-block-fully-loaded block')
+                         true
+                         (update-vals (fn [v]
+                                        (cond
+                                          (de/entity? v)
+                                          (entity->map v)
+                                          (and (coll? v) (every? de/entity? v))
+                                          (map entity->map v)
+
+                                          :else
+                                          v)))
+                         block-refs-count?
+                         (assoc :block.temp/refs-count (count (:block/_refs block))))]
+            (cond->
+             {:block block'}
+              children?
+              (assoc :children children))))))))
+
+(defn get-latest-journals
+  [db]
+  (let [today (date-time-util/date->int (js/Date.))]
+    (->> (d/datoms db :avet :block/journal-day)
+         vec
+         rseq
+         (keep (fn [d]
+                 (and (<= (:v d) today)
+                      (let [e (d/entity db (:e d))]
+                        (when (and (common-entity-util/journal? e) (:db/id e))
+                          e))))))))
+
+(defn- get-structured-datoms
+  [db]
+  (let [class-property-id (:db/id (d/entity db :logseq.class/Property))]
+    (->> (concat
+          (d/datoms db :avet :block/tags :logseq.class/Tag)
+          (d/datoms db :avet :block/tags :logseq.class/Property)
+          (d/datoms db :avet :block/closed-value-property))
+         (mapcat (fn [d]
+                   (let [block-datoms (d/datoms db :eavt (:e d))
+                         property-desc-datoms (when (= (:v d) class-property-id)
+                                                (when-let [desc (:logseq.property/description (d/entity db (:e d)))]
+                                                  (d/datoms db :eavt (:db/id desc))))]
+                     (if property-desc-datoms
+                       (concat block-datoms property-desc-datoms)
+                       block-datoms)))))))
+
+(defn- get-favorites
+  "Favorites page and its blocks"
+  [db]
+  (let [page-id (get-first-page-by-name db common-config/favorites-page-name)
+        block (d/entity db page-id)
+        children (:block/_page block)]
+    (when block
+      (concat (d/datoms db :eavt (:db/id block))
+              (->> (keep :block/link children)
+                   (mapcat (fn [l]
+                             (d/datoms db :eavt (:db/id l)))))
+              (mapcat (fn [child]
+                        (d/datoms db :eavt (:db/id child)))
+                      children)))))
+
+(defn- get-views-data
+  [db]
+  (let [page-id (get-first-page-by-name db common-config/views-page-name)
+        children (when page-id (:block/_parent (d/entity db page-id)))]
+    (when (seq children)
+      (into
+       (mapcat (fn [b] (d/datoms db :eavt (:db/id b)))
+               children)
+       (d/datoms db :eavt page-id)))))
+
+(defn get-recent-updated-pages
+  [db]
+  (some->>
+   (d/datoms db :avet :block/updated-at)
+   rseq
+   (keep (fn [datom]
+           (let [e (d/entity db (:e datom))]
+             (when (and (common-entity-util/page? e) (not (entity-util/hidden? e)))
+               e))))
+   (take 30)))
+
+(defn get-initial-data
+  "Returns current database schema and initial data.
+   NOTE: This fn is called by DB and file graphs"
+  [db]
+  (let [db-graph? (entity-plus/db-based-graph? db)
+        _ (when db-graph?
+            (reset! db-order/*max-key (db-order/get-max-order db)))
+        schema (:schema db)
+        idents (mapcat (fn [id]
+                         (when-let [e (d/entity db id)]
+                           (d/datoms db :eavt (:db/id e))))
+                       [:logseq.kv/db-type
+                        :logseq.kv/schema-version
+                        :logseq.kv/graph-uuid
+                        :logseq.kv/latest-code-lang
+                        :logseq.kv/graph-backup-folder
+                        :logseq.property/empty-placeholder])
+        favorites (when db-graph? (get-favorites db))
+        views (when db-graph? (get-views-data db))
+        all-files (get-all-files db)
+        structured-datoms (when db-graph?
+                            (get-structured-datoms db))
+        recent-updated-pages (let [pages (get-recent-updated-pages db)]
+                               (mapcat (fn [p] (d/datoms db :eavt (:db/id p))) pages))
+        pages-datoms (let [contents-id (get-first-page-by-title db "Contents")
+                           views-id (get-first-page-by-title db common-config/views-page-name)]
+                       (mapcat #(d/datoms db :eavt %)
+                               (remove nil? [contents-id views-id])))
+        data (distinct
+              (concat idents
+                      structured-datoms
+                      favorites
+                      recent-updated-pages
+                      views
+                      all-files
+                      pages-datoms))]
+    {:schema schema
+     :initial-data data}))

+ 1 - 1
deps/db/src/logseq/db/common/property_util.cljs

@@ -1,7 +1,7 @@
 (ns logseq.db.common.property-util
 (ns logseq.db.common.property-util
   "Property related util fns. Fns used in both DB and file graphs should go here"
   "Property related util fns. Fns used in both DB and file graphs should go here"
   (:require [datascript.core :as d]
   (:require [datascript.core :as d]
-            [logseq.db.frontend.entity-plus :as entity-plus]
+            [logseq.db.common.entity-plus :as entity-plus]
             [logseq.db.frontend.property :as db-property]
             [logseq.db.frontend.property :as db-property]
             [logseq.db.frontend.property.type :as db-property-type]
             [logseq.db.frontend.property.type :as db-property-type]
             [logseq.db.sqlite.util :as sqlite-util]))
             [logseq.db.sqlite.util :as sqlite-util]))

+ 9 - 334
deps/db/src/logseq/db/common/sqlite.cljs

@@ -1,343 +1,11 @@
 (ns logseq.db.common.sqlite
 (ns logseq.db.common.sqlite
-  "Provides common sqlite db fns for file and DB graphs. These fns work on
+  "Provides common sqlite util fns for file and DB graphs. These fns work on
   browser and node"
   browser and node"
   (:require ["path" :as node-path]
   (:require ["path" :as node-path]
-            [clojure.set :as set]
             [clojure.string :as string]
             [clojure.string :as string]
             [datascript.core :as d]
             [datascript.core :as d]
-            [datascript.impl.entity :as de]
-            [logseq.common.config :as common-config]
-            [logseq.common.util :as common-util]
-            [logseq.common.util.date-time :as date-time-util]
-            [logseq.db.common.entity-util :as common-entity-util]
-            [logseq.db.common.order :as db-order]
-            [logseq.db.frontend.entity-plus :as entity-plus]
-            [logseq.db.frontend.entity-util :as entity-util]
             [logseq.db.sqlite.util :as sqlite-util]))
             [logseq.db.sqlite.util :as sqlite-util]))
 
 
-(defn- get-pages-by-name
-  [db page-name]
-  (d/datoms db :avet :block/name (common-util/page-name-sanity-lc page-name)))
-
-(defn get-first-page-by-name
-  "Return the oldest page's db id for :block/name"
-  [db page-name]
-  (when (and db (string? page-name))
-    (first (sort (map :e (get-pages-by-name db page-name))))))
-
-(defn get-first-page-by-title
-  "Return the oldest page's db id for :block/title"
-  [db page-name]
-  {:pre [(string? page-name)]}
-  (->> (d/datoms db :avet :block/title page-name)
-       (filter (fn [d]
-                 (let [e (d/entity db (:e d))]
-                   (common-entity-util/page? e))))
-       (map :e)
-       sort
-       first))
-
-(comment
-  (defn- get-built-in-files
-    [db]
-    (let [files ["logseq/config.edn"
-                 "logseq/custom.css"
-                 "logseq/custom.js"]]
-      (map #(d/pull db '[*] [:file/path %]) files))))
-
-(defn get-all-files
-  [db]
-  (->> (d/datoms db :avet :file/path)
-       (mapcat (fn [e] (d/datoms db :eavt (:e e))))))
-
-(defn- with-block-refs
-  [db block]
-  (update block :block/refs (fn [refs] (map (fn [ref] (d/pull db '[*] (:db/id ref))) refs))))
-
-(defn with-parent
-  [db block]
-  (cond
-    (:block/page block)
-    (let [parent (when-let [e (d/entity db (:db/id (:block/parent block)))]
-                   (select-keys e [:db/id :block/uuid]))]
-      (->>
-       (assoc block :block/parent parent)
-       (common-util/remove-nils-non-nested)
-       (with-block-refs db)))
-
-    :else
-    block))
-
-(comment
-  (defn- with-block-link
-    [db block]
-    (if (:block/link block)
-      (update block :block/link (fn [link] (d/pull db '[*] (:db/id link))))
-      block)))
-
-(defn- mark-block-fully-loaded
-  [b]
-  (assoc b :block.temp/fully-loaded? true))
-
-(comment
-  (defn- property-without-db-attrs
-    [property]
-    (dissoc property :db/index :db/valueType :db/cardinality))
-
-  (defn- property-with-values
-    [db block properties]
-    (when (entity-plus/db-based-graph? db)
-      (let [block (d/entity db (:db/id block))
-            property-vals (if properties
-                            (map block properties)
-                            (vals (:block/properties block)))]
-        (->> property-vals
-             (mapcat
-              (fn [property-values]
-                (let [values (->>
-                              (if (and (coll? property-values)
-                                       (map? (first property-values)))
-                                property-values
-                                #{property-values}))
-                      value-ids (when (every? map? values)
-                                  (->> (map :db/id values)
-                                       (filter (fn [id] (or (int? id) (keyword? id))))))
-                      value-blocks (->>
-                                    (when (seq value-ids)
-                                      (map
-                                       (fn [id] (d/pull db '[:db/id :block/uuid
-                                                             :block/name :block/title
-                                                             :logseq.property/value
-                                                             :block/tags :block/page
-                                                             :logseq.property/created-from-property] id))
-                                       value-ids))
-                                  ;; FIXME: why d/pull returns {:db/id db-ident} instead of {:db/id number-eid}?
-                                    (keep (fn [block]
-                                            (let [from-property-id (get-in block [:logseq.property/created-from-property :db/id])]
-                                              (if (keyword? from-property-id)
-                                                (assoc-in block [:logseq.property/created-from-property :db/id] (:db/id (d/entity db from-property-id)))
-                                                block)))))]
-                  value-blocks))))))))
-
-(defn get-block-children-ids
-  "Returns children UUIDs"
-  [db block-uuid]
-  (when-let [eid (:db/id (d/entity db [:block/uuid block-uuid]))]
-    (let [seen   (volatile! [])]
-      (loop [steps          100      ;check result every 100 steps
-             eids-to-expand [eid]]
-        (when (seq eids-to-expand)
-          (let [eids-to-expand*
-                (mapcat (fn [eid] (map first (d/datoms db :avet :block/parent eid))) eids-to-expand)
-                uuids-to-add (remove nil? (map #(:block/uuid (d/entity db %)) eids-to-expand*))]
-            (when (and (zero? steps)
-                       (seq (set/intersection (set @seen) (set uuids-to-add))))
-              (throw (ex-info "bad outliner data, need to re-index to fix"
-                              {:seen @seen :eids-to-expand eids-to-expand})))
-            (vswap! seen (partial apply conj) uuids-to-add)
-            (recur (if (zero? steps) 100 (dec steps)) eids-to-expand*))))
-      @seen)))
-
-(defn get-block-children
-  "Including nested children."
-  [db block-uuid]
-  (let [ids (get-block-children-ids db block-uuid)]
-    (when (seq ids)
-      (let [ids' (map (fn [id] [:block/uuid id]) ids)]
-        (d/pull-many db '[*] ids')))))
-
-(defn- with-raw-title
-  [m entity]
-  (if-let [raw-title (:block/raw-title entity)]
-    (assoc m :block/title raw-title)
-    m))
-
-(defn- entity->map
-  [entity]
-  (-> (into {} entity)
-      (with-raw-title entity)
-      (assoc :db/id (:db/id entity))))
-
-(defn ^:large-vars/cleanup-todo get-block-and-children
-  [db id {:keys [children? children-only? nested-children? properties children-props]}]
-  (let [block (d/entity db (if (uuid? id)
-                             [:block/uuid id]
-                             id))
-        block-refs-count? (some #{:block.temp/refs-count} properties)
-        whiteboard? (common-entity-util/whiteboard? block)]
-    (when block
-      (let [children (when (or children? children-only?)
-                       (let [page? (common-entity-util/page? block)
-                             children (->>
-                                       (cond
-                                         (and nested-children? (not page?))
-                                         (get-block-children db (:block/uuid block))
-                                         nested-children?
-                                         (:block/_page block)
-                                         :else
-                                         (let [short-page? (when page?
-                                                             (<= (count (:block/_page block)) 100))]
-                                           (if short-page?
-                                             (:block/_page block)
-                                             (:block/_parent block))))
-                                       (remove (fn [e] (or (:logseq.property/created-from-property e)
-                                                           (:block/closed-value-property e)))))
-                             children-props (if whiteboard?
-                                              '[*]
-                                              (or children-props
-                                                  [:db/id :block/uuid :block/parent :block/order :block/collapsed? :block/title
-                                                   ;; pre-loading feature-related properties to avoid UI refreshing
-                                                   :logseq.task/status :logseq.property.node/display-type]))]
-                         (map
-                          (fn [block]
-                            (if (= children-props '[*])
-                              (entity->map block)
-                              (-> (select-keys block children-props)
-                                  (with-raw-title block))))
-                          children)))]
-        (if children-only?
-          {:children children}
-          (let [block' (if (seq properties)
-                         (-> (select-keys block properties)
-                             (with-raw-title block)
-                             (assoc :db/id (:db/id block)))
-                         (entity->map block))
-                block' (cond->
-                        (mark-block-fully-loaded block')
-                         true
-                         (update-vals (fn [v]
-                                        (cond
-                                          (de/entity? v)
-                                          (entity->map v)
-                                          (and (coll? v) (every? de/entity? v))
-                                          (map entity->map v)
-
-                                          :else
-                                          v)))
-                         block-refs-count?
-                         (assoc :block.temp/refs-count (count (:block/_refs block))))]
-            (cond->
-             {:block block'}
-              children?
-              (assoc :children children))))))))
-
-(defn get-latest-journals
-  [db]
-  (let [today (date-time-util/date->int (js/Date.))]
-    (->> (d/datoms db :avet :block/journal-day)
-         vec
-         rseq
-         (keep (fn [d]
-                 (and (<= (:v d) today)
-                      (let [e (d/entity db (:e d))]
-                        (when (and (common-entity-util/journal? e) (:db/id e))
-                          e))))))))
-
-(defn get-page->refs-count
-  [db]
-  (let [datoms (d/datoms db :avet :block/name)]
-    (->>
-     (map (fn [d]
-            [(:e d)
-             (count (:block/_refs (d/entity db (:e d))))]) datoms)
-     (into {}))))
-
-(defn get-structured-datoms
-  [db]
-  (let [class-property-id (:db/id (d/entity db :logseq.class/Property))]
-    (->> (concat
-          (d/datoms db :avet :block/tags :logseq.class/Tag)
-          (d/datoms db :avet :block/tags :logseq.class/Property)
-          (d/datoms db :avet :block/closed-value-property))
-         (mapcat (fn [d]
-                   (let [block-datoms (d/datoms db :eavt (:e d))
-                         property-desc-datoms (when (= (:v d) class-property-id)
-                                                (when-let [desc (:logseq.property/description (d/entity db (:e d)))]
-                                                  (d/datoms db :eavt (:db/id desc))))]
-                     (if property-desc-datoms
-                       (concat block-datoms property-desc-datoms)
-                       block-datoms)))))))
-
-(defn get-favorites
-  "Favorites page and its blocks"
-  [db]
-  (let [page-id (get-first-page-by-name db common-config/favorites-page-name)
-        block (d/entity db page-id)
-        children (:block/_page block)]
-    (when block
-      (concat (d/datoms db :eavt (:db/id block))
-              (->> (keep :block/link children)
-                   (mapcat (fn [l]
-                             (d/datoms db :eavt (:db/id l)))))
-              (mapcat (fn [child]
-                        (d/datoms db :eavt (:db/id child)))
-                      children)))))
-
-(defn get-views-data
-  [db]
-  (let [page-id (get-first-page-by-name db common-config/views-page-name)
-        children (when page-id (:block/_parent (d/entity db page-id)))]
-    (when (seq children)
-      (into
-       (mapcat (fn [b] (d/datoms db :eavt (:db/id b)))
-               children)
-       (d/datoms db :eavt page-id)))))
-
-(defn get-recent-updated-pages
-  [db]
-  (some->>
-   (d/datoms db :avet :block/updated-at)
-   rseq
-   (keep (fn [datom]
-           (let [e (d/entity db (:e datom))]
-             (when (and (common-entity-util/page? e) (not (entity-util/hidden? e)))
-               e))))
-   (take 30)))
-
-(defn get-initial-data
-  "Returns current database schema and initial data.
-   NOTE: This fn is called by DB and file graphs"
-  [db]
-  (let [db-graph? (entity-plus/db-based-graph? db)
-        _ (when db-graph?
-            (reset! db-order/*max-key (db-order/get-max-order db)))
-        schema (:schema db)
-        idents (mapcat (fn [id]
-                         (when-let [e (d/entity db id)]
-                           (d/datoms db :eavt (:db/id e))))
-                       [:logseq.kv/db-type
-                        :logseq.kv/schema-version
-                        :logseq.kv/graph-uuid
-                        :logseq.kv/latest-code-lang
-                        :logseq.kv/graph-backup-folder
-                        :logseq.property/empty-placeholder])
-        favorites (when db-graph? (get-favorites db))
-        views (when db-graph? (get-views-data db))
-        all-files (get-all-files db)
-        structured-datoms (when db-graph?
-                            (get-structured-datoms db))
-        recent-updated-pages (let [pages (get-recent-updated-pages db)]
-                               (mapcat (fn [p] (d/datoms db :eavt (:db/id p))) pages))
-        pages-datoms (let [contents-id (get-first-page-by-title db "Contents")
-                           views-id (get-first-page-by-title db common-config/views-page-name)]
-                       (mapcat #(d/datoms db :eavt %)
-                               (remove nil? [contents-id views-id])))
-        data (distinct
-              (concat idents
-                      structured-datoms
-                      favorites
-                      recent-updated-pages
-                      views
-                      all-files
-                      pages-datoms))]
-    {:schema schema
-     :initial-data data}))
-
-(defn restore-initial-data
-  "Given initial Datascript datoms and schema, returns a datascript connection"
-  [data schema]
-  (d/conn-from-datoms data schema))
-
 (defn create-kvs-table!
 (defn create-kvs-table!
   "Creates a sqlite table for use with datascript.storage if one doesn't exist"
   "Creates a sqlite table for use with datascript.storage if one doesn't exist"
   [sqlite-db]
   [sqlite-db]
@@ -349,9 +17,16 @@
   (or (d/restore-conn storage)
   (or (d/restore-conn storage)
       (d/create-conn schema {:storage storage})))
       (d/create-conn schema {:storage storage})))
 
 
+(defonce file-version-prefix "logseq_local_")
+
+(defn local-file-based-graph?
+  [s]
+  (and (string? s)
+       (string/starts-with? s file-version-prefix)))
+
 (defn sanitize-db-name
 (defn sanitize-db-name
   [db-name]
   [db-name]
-  (if (string/starts-with? db-name sqlite-util/file-version-prefix)
+  (if (string/starts-with? db-name file-version-prefix)
     (-> db-name
     (-> db-name
         (string/replace ":" "+3A+")
         (string/replace ":" "+3A+")
         (string/replace "/" "++"))
         (string/replace "/" "++"))

+ 6 - 6
deps/db/src/logseq/db/sqlite/cli.cljs → deps/db/src/logseq/db/common/sqlite_cli.cljs

@@ -1,4 +1,4 @@
-(ns ^:node-only logseq.db.sqlite.cli
+(ns ^:node-only logseq.db.common.sqlite-cli
   "Primary ns to interact with DB files for DB and file graphs with node.js based CLIs"
   "Primary ns to interact with DB files for DB and file graphs with node.js based CLIs"
   (:require ["better-sqlite3" :as sqlite3]
   (:require ["better-sqlite3" :as sqlite3]
             ["fs" :as fs]
             ["fs" :as fs]
@@ -7,7 +7,7 @@
             ;; FIXME: datascript.core has to come before datascript.storage or else nbb fails
             ;; FIXME: datascript.core has to come before datascript.storage or else nbb fails
             [datascript.core]
             [datascript.core]
             [datascript.storage :refer [IStorage]]
             [datascript.storage :refer [IStorage]]
-            [logseq.db.common.sqlite :as sqlite-common-db]
+            [logseq.db.common.sqlite :as common-sqlite]
             [logseq.db.file-based.schema :as file-schema]
             [logseq.db.file-based.schema :as file-schema]
             [logseq.db.frontend.schema :as db-schema]
             [logseq.db.frontend.schema :as db-schema]
             [logseq.db.sqlite.util :as sqlite-util]))
             [logseq.db.sqlite.util :as sqlite-util]))
@@ -87,13 +87,13 @@
   needed sqlite tables if not created and returns a datascript connection that's
   needed sqlite tables if not created and returns a datascript connection that's
   connected to the sqlite db"
   connected to the sqlite db"
   [graphs-dir db-name]
   [graphs-dir db-name]
-  (let [[_db-sanitized-name db-full-path] (sqlite-common-db/get-db-full-path graphs-dir db-name)
+  (let [[_db-sanitized-name db-full-path] (common-sqlite/get-db-full-path graphs-dir db-name)
         db (new sqlite db-full-path nil)
         db (new sqlite db-full-path nil)
         ;; For both desktop and CLI, only file graphs have db-name that indicate their db type
         ;; For both desktop and CLI, only file graphs have db-name that indicate their db type
-        schema (if (sqlite-util/local-file-based-graph? db-name)
+        schema (if (common-sqlite/local-file-based-graph? db-name)
                  file-schema/schema
                  file-schema/schema
                  db-schema/schema)]
                  db-schema/schema)]
-    (sqlite-common-db/create-kvs-table! db)
+    (common-sqlite/create-kvs-table! db)
     (let [storage (new-sqlite-storage db)
     (let [storage (new-sqlite-storage db)
-          conn (sqlite-common-db/get-storage-conn storage schema)]
+          conn (common-sqlite/get-storage-conn storage schema)]
       conn)))
       conn)))

+ 1 - 1
deps/db/src/logseq/db/common/view.cljs

@@ -9,7 +9,7 @@
             [logseq.common.util :as common-util]
             [logseq.common.util :as common-util]
             [logseq.db :as ldb]
             [logseq.db :as ldb]
             [logseq.db.frontend.class :as db-class]
             [logseq.db.frontend.class :as db-class]
-            [logseq.db.frontend.entity-plus :as entity-plus]
+            [logseq.db.common.entity-plus :as entity-plus]
             [logseq.db.frontend.entity-util :as entity-util]
             [logseq.db.frontend.entity-util :as entity-util]
             [logseq.db.frontend.property :as db-property]
             [logseq.db.frontend.property :as db-property]
             [logseq.db.frontend.property.type :as db-property-type]
             [logseq.db.frontend.property.type :as db-property-type]

+ 2 - 3
deps/db/src/logseq/db/file_based/schema.cljs

@@ -32,9 +32,8 @@
    :block/path-refs {:db/valueType   :db.type/ref
    :block/path-refs {:db/valueType   :db.type/ref
                      :db/cardinality :db.cardinality/many}
                      :db/cardinality :db.cardinality/many}
 
 
-   ;; tags are structured classes
-   :block/tags {:db/valueType :db.type/ref
-                :db/cardinality :db.cardinality/many}
+  :block/tags {:db/valueType :db.type/ref
+               :db/cardinality :db.cardinality/many}
 
 
    ;; which block this block links to, used for tag, embeds
    ;; which block this block links to, used for tag, embeds
    :block/link {:db/valueType :db.type/ref
    :block/link {:db/valueType :db.type/ref

+ 1 - 1
deps/db/src/logseq/db/frontend/malli_schema.cljs

@@ -5,7 +5,7 @@
             [datascript.core :as d]
             [datascript.core :as d]
             [logseq.db.common.order :as db-order]
             [logseq.db.common.order :as db-order]
             [logseq.db.frontend.class :as db-class]
             [logseq.db.frontend.class :as db-class]
-            [logseq.db.frontend.entity-plus :as entity-plus]
+            [logseq.db.common.entity-plus :as entity-plus]
             [logseq.db.frontend.entity-util :as entity-util]
             [logseq.db.frontend.entity-util :as entity-util]
             [logseq.db.frontend.property :as db-property]
             [logseq.db.frontend.property :as db-property]
             [logseq.db.frontend.property.type :as db-property-type]
             [logseq.db.frontend.property.type :as db-property-type]

+ 1 - 1
deps/db/src/logseq/db/frontend/schema.cljs

@@ -61,7 +61,7 @@
     :else (throw (ex-info "Not a schema-version" {:data schema-version}))))
     :else (throw (ex-info "Not a schema-version" {:data schema-version}))))
 
 
 (def schema
 (def schema
-  "Schema for DB graphs"
+  "Schema for DB graphs. :block/tags are classes in this schema"
   (merge
   (merge
    (apply dissoc file-schema/schema file-schema/file-only-attributes)
    (apply dissoc file-schema/schema file-schema/file-only-attributes)
    {:block/name {:db/index true}        ; remove db/unique for :block/name
    {:block/name {:db/index true}        ; remove db/unique for :block/name

+ 1 - 1
deps/db/src/logseq/db/sqlite/create_graph.cljs

@@ -170,7 +170,7 @@
   (build-initial-classes* db-class/built-in-classes db-ident->properties))
   (build-initial-classes* db-class/built-in-classes db-ident->properties))
 
 
 (defn build-initial-views
 (defn build-initial-views
-  "Builds initial blocks used for storing views. Used by db and file graphs"
+  "Builds initial blocks used for storing views"
   []
   []
   (let [page-id (common-uuid/gen-uuid :builtin-block-uuid common-config/views-page-name)]
   (let [page-id (common-uuid/gen-uuid :builtin-block-uuid common-config/views-page-name)]
     [(sqlite-util/block-with-timestamps
     [(sqlite-util/block-with-timestamps

+ 1 - 1
deps/db/src/logseq/db/sqlite/export.cljs

@@ -10,7 +10,7 @@
             [logseq.db.frontend.class :as db-class]
             [logseq.db.frontend.class :as db-class]
             [logseq.db.frontend.content :as db-content]
             [logseq.db.frontend.content :as db-content]
             [logseq.db.frontend.db :as db-db]
             [logseq.db.frontend.db :as db-db]
-            [logseq.db.frontend.entity-plus :as entity-plus]
+            [logseq.db.common.entity-plus :as entity-plus]
             [logseq.db.frontend.entity-util :as entity-util]
             [logseq.db.frontend.entity-util :as entity-util]
             [logseq.db.frontend.property :as db-property]
             [logseq.db.frontend.property :as db-property]
             [logseq.db.sqlite.build :as sqlite-build]
             [logseq.db.sqlite.build :as sqlite-build]

+ 1 - 16
deps/db/src/logseq/db/sqlite/util.cljs

@@ -9,13 +9,10 @@
             [logseq.common.util :as common-util]
             [logseq.common.util :as common-util]
             [logseq.common.uuid :as common-uuid]
             [logseq.common.uuid :as common-uuid]
             [logseq.db.common.order :as db-order]
             [logseq.db.common.order :as db-order]
-            [logseq.db.file-based.schema :as file-schema]
             [logseq.db.frontend.property :as db-property]
             [logseq.db.frontend.property :as db-property]
-            [logseq.db.frontend.property.type :as db-property-type]
-            [logseq.db.frontend.schema :as db-schema]))
+            [logseq.db.frontend.property.type :as db-property-type]))
 
 
 (defonce db-version-prefix "logseq_db_")
 (defonce db-version-prefix "logseq_db_")
-(defonce file-version-prefix "logseq_local_")
 
 
 (def ^:private write-handlers (cljs-bean.transit/writer-handlers))
 (def ^:private write-handlers (cljs-bean.transit/writer-handlers))
 (def ^:private read-handlers {})
 (def ^:private read-handlers {})
@@ -59,18 +56,6 @@
   (when graph-name
   (when graph-name
     (string/starts-with? graph-name db-version-prefix)))
     (string/starts-with? graph-name db-version-prefix)))
 
 
-(defn local-file-based-graph?
-  [s]
-  (and (string? s)
-       (string/starts-with? s file-version-prefix)))
-
-(defn get-schema
-  "Returns schema for given repo"
-  [repo]
-  (if (db-based-graph? repo)
-    db-schema/schema
-    file-schema/schema))
-
 (def block-with-timestamps common-util/block-with-timestamps)
 (def block-with-timestamps common-util/block-with-timestamps)
 
 
 (defn build-new-property
 (defn build-new-property

+ 1 - 1
deps/db/src/logseq/db/test/helper.cljs

@@ -2,7 +2,7 @@
   "Main ns for providing test fns for DB graphs"
   "Main ns for providing test fns for DB graphs"
   (:require [datascript.core :as d]
   (:require [datascript.core :as d]
             [datascript.impl.entity :as de]
             [datascript.impl.entity :as de]
-            [logseq.db.frontend.entity-plus :as entity-plus]
+            [logseq.db.common.entity-plus :as entity-plus]
             [logseq.db.frontend.property :as db-property]
             [logseq.db.frontend.property :as db-property]
             [logseq.db.frontend.schema :as db-schema]
             [logseq.db.frontend.schema :as db-schema]
             [logseq.db.sqlite.build :as sqlite-build]
             [logseq.db.sqlite.build :as sqlite-build]

+ 7 - 7
deps/db/test/logseq/db/common/sqlite_test.cljs → deps/db/test/logseq/db/common/initial_data_test.cljs

@@ -1,13 +1,13 @@
-(ns logseq.db.common.sqlite-test
+(ns logseq.db.common.initial-data-test
   "This ns is the only one to test against file based datascript connections.
   "This ns is the only one to test against file based datascript connections.
    These are useful integration tests"
    These are useful integration tests"
   (:require ["fs" :as fs]
   (:require ["fs" :as fs]
             ["path" :as node-path]
             ["path" :as node-path]
             [cljs.test :refer [deftest async use-fixtures is testing]]
             [cljs.test :refer [deftest async use-fixtures is testing]]
             [datascript.core :as d]
             [datascript.core :as d]
-            [logseq.db.common.sqlite :as sqlite-common-db]
+            [logseq.db.common.initial-data :as common-initial-data]
             [logseq.db.sqlite.build :as sqlite-build]
             [logseq.db.sqlite.build :as sqlite-build]
-            [logseq.db.sqlite.cli :as sqlite-cli]
+            [logseq.db.common.sqlite-cli :as sqlite-cli]
             [logseq.db.sqlite.create-graph :as sqlite-create-graph]
             [logseq.db.sqlite.create-graph :as sqlite-create-graph]
             [logseq.db.test.helper :as db-test]))
             [logseq.db.test.helper :as db-test]))
 
 
@@ -35,8 +35,8 @@
                    :file/content "{:foo :bar}"}]
                    :file/content "{:foo :bar}"}]
           _ (d/transact! conn* blocks)
           _ (d/transact! conn* blocks)
           ;; Simulate getting data from sqlite and restoring it for frontend
           ;; Simulate getting data from sqlite and restoring it for frontend
-          {:keys [schema initial-data]} (sqlite-common-db/get-initial-data @conn*)
-          conn (sqlite-common-db/restore-initial-data initial-data schema)]
+          {:keys [schema initial-data]} (common-initial-data/get-initial-data @conn*)
+          conn (d/conn-from-datoms initial-data schema)]
       (is (= blocks
       (is (= blocks
              (->> @conn
              (->> @conn
                   (d/q '[:find (pull ?b [:block/uuid :file/path :file/content]) :where [?b :file/content]])
                   (d/q '[:find (pull ?b [:block/uuid :file/path :file/content]) :where [?b :file/content]])
@@ -54,7 +54,7 @@
             :blocks [{:block/title "b1"}]}]})
             :blocks [{:block/title "b1"}]}]})
         _ (d/transact! conn* init-tx)
         _ (d/transact! conn* init-tx)
           ;; Simulate getting data from sqlite and restoring it for frontend
           ;; Simulate getting data from sqlite and restoring it for frontend
-        {:keys [schema initial-data]} (sqlite-common-db/get-initial-data @conn*)
-        conn (sqlite-common-db/restore-initial-data initial-data schema)]
+        {:keys [schema initial-data]} (common-initial-data/get-initial-data @conn*)
+        conn (d/conn-from-datoms initial-data schema)]
     (is (some? (db-test/find-page-by-title @conn "page1"))
     (is (some? (db-test/find-page-by-title @conn "page1"))
         "Restores recently updated page")))
         "Restores recently updated page")))

+ 1 - 1
deps/graph-parser/test/logseq/graph_parser/exporter_test.cljs

@@ -10,7 +10,7 @@
             [logseq.common.util.date-time :as date-time-util]
             [logseq.common.util.date-time :as date-time-util]
             [logseq.db :as ldb]
             [logseq.db :as ldb]
             [logseq.db.frontend.content :as db-content]
             [logseq.db.frontend.content :as db-content]
-            [logseq.db.frontend.entity-plus :as entity-plus]
+            [logseq.db.common.entity-plus :as entity-plus]
             [logseq.db.frontend.malli-schema :as db-malli-schema]
             [logseq.db.frontend.malli-schema :as db-malli-schema]
             [logseq.db.frontend.rules :as rules]
             [logseq.db.frontend.rules :as rules]
             [logseq.db.frontend.validate :as db-validate]
             [logseq.db.frontend.validate :as db-validate]

+ 1 - 1
deps/outliner/script/transact.cljs

@@ -6,7 +6,7 @@
             [clojure.string :as string]
             [clojure.string :as string]
             [datascript.core :as d]
             [datascript.core :as d]
             [logseq.db.frontend.rules :as rules]
             [logseq.db.frontend.rules :as rules]
-            [logseq.db.sqlite.cli :as sqlite-cli]
+            [logseq.db.common.sqlite-cli :as sqlite-cli]
             [logseq.outliner.db-pipeline :as db-pipeline]
             [logseq.outliner.db-pipeline :as db-pipeline]
             [nbb.core :as nbb]))
             [nbb.core :as nbb]))
 
 

+ 1 - 1
deps/outliner/src/logseq/outliner/cli.cljs

@@ -4,7 +4,7 @@
             [datascript.core :as d]
             [datascript.core :as d]
             [logseq.db.sqlite.create-graph :as sqlite-create-graph]
             [logseq.db.sqlite.create-graph :as sqlite-create-graph]
             [logseq.db.sqlite.build :as sqlite-build]
             [logseq.db.sqlite.build :as sqlite-build]
-            [logseq.db.sqlite.cli :as sqlite-cli]
+            [logseq.db.common.sqlite-cli :as sqlite-cli]
             [logseq.outliner.db-pipeline :as db-pipeline]
             [logseq.outliner.db-pipeline :as db-pipeline]
             ["fs" :as fs]
             ["fs" :as fs]
             ["path" :as node-path]))
             ["path" :as node-path]))

+ 1 - 1
deps/outliner/src/logseq/outliner/pipeline.cljs

@@ -6,7 +6,7 @@
             [logseq.common.util.date-time :as date-time-util]
             [logseq.common.util.date-time :as date-time-util]
             [logseq.db :as ldb]
             [logseq.db :as ldb]
             [logseq.db.frontend.content :as db-content]
             [logseq.db.frontend.content :as db-content]
-            [logseq.db.frontend.entity-plus :as entity-plus]
+            [logseq.db.common.entity-plus :as entity-plus]
             [logseq.db.frontend.property :as db-property]
             [logseq.db.frontend.property :as db-property]
             [logseq.outliner.datascript-report :as ds-report]))
             [logseq.outliner.datascript-report :as ds-report]))
 
 

+ 1 - 1
deps/outliner/src/logseq/outliner/property.cljs

@@ -8,7 +8,7 @@
             [logseq.db :as ldb]
             [logseq.db :as ldb]
             [logseq.db.common.order :as db-order]
             [logseq.db.common.order :as db-order]
             [logseq.db.frontend.db-ident :as db-ident]
             [logseq.db.frontend.db-ident :as db-ident]
-            [logseq.db.frontend.entity-plus :as entity-plus]
+            [logseq.db.common.entity-plus :as entity-plus]
             [logseq.db.frontend.entity-util :as entity-util]
             [logseq.db.frontend.entity-util :as entity-util]
             [logseq.db.frontend.malli-schema :as db-malli-schema]
             [logseq.db.frontend.malli-schema :as db-malli-schema]
             [logseq.db.frontend.property :as db-property]
             [logseq.db.frontend.property :as db-property]

+ 1 - 1
deps/outliner/test/logseq/outliner/validate_test.cljs

@@ -1,7 +1,7 @@
 (ns logseq.outliner.validate-test
 (ns logseq.outliner.validate-test
   (:require [cljs.test :refer [are deftest is testing]]
   (:require [cljs.test :refer [are deftest is testing]]
             [datascript.core :as d]
             [datascript.core :as d]
-            [logseq.db.frontend.entity-plus :as entity-plus]
+            [logseq.db.common.entity-plus :as entity-plus]
             [logseq.db.test.helper :as db-test]
             [logseq.db.test.helper :as db-test]
             [logseq.outliner.validate :as outliner-validate]))
             [logseq.outliner.validate :as outliner-validate]))
 
 

+ 1 - 1
deps/publishing/script/publishing.cljs

@@ -4,7 +4,7 @@
             ["path" :as node-path]
             ["path" :as node-path]
             [clojure.edn :as edn]
             [clojure.edn :as edn]
             [datascript.core :as d]
             [datascript.core :as d]
-            [logseq.db.sqlite.cli :as sqlite-cli]
+            [logseq.db.common.sqlite-cli :as sqlite-cli]
             [logseq.db.sqlite.util :as sqlite-util]
             [logseq.db.sqlite.util :as sqlite-util]
             [logseq.graph-parser.cli :as gp-cli]
             [logseq.graph-parser.cli :as gp-cli]
             [logseq.publishing :as publishing]
             [logseq.publishing :as publishing]

+ 1 - 1
deps/publishing/src/logseq/publishing/db.cljs

@@ -3,7 +3,7 @@
   (:require [clojure.set :as set]
   (:require [clojure.set :as set]
             [clojure.string :as string]
             [clojure.string :as string]
             [datascript.core :as d]
             [datascript.core :as d]
-            [logseq.db.frontend.entity-plus :as entity-plus]
+            [logseq.db.common.entity-plus :as entity-plus]
             [logseq.db.frontend.malli-schema :as db-malli-schema]
             [logseq.db.frontend.malli-schema :as db-malli-schema]
             [logseq.db.frontend.rules :as rules]))
             [logseq.db.frontend.rules :as rules]))
 
 

+ 8 - 4
scripts/src/logseq/tasks/dev/db_and_file_graphs.clj

@@ -61,7 +61,8 @@
 
 
 (def file-graph-paths
 (def file-graph-paths
   "Paths _only_ for file graphs"
   "Paths _only_ for file graphs"
-  ["deps/graph-parser/src/logseq/graph_parser/db.cljs"
+  ["deps/db/src/logseq/db/file_based"
+   "deps/graph-parser/src/logseq/graph_parser/db.cljs"
    "deps/graph-parser/src/logseq/graph_parser/extract.cljc"
    "deps/graph-parser/src/logseq/graph_parser/extract.cljc"
    "deps/graph-parser/src/logseq/graph_parser/property.cljs"
    "deps/graph-parser/src/logseq/graph_parser/property.cljs"
    "deps/graph-parser/src/logseq/graph_parser.cljs"
    "deps/graph-parser/src/logseq/graph_parser.cljs"
@@ -98,8 +99,7 @@
 
 
 (defn- validate-multi-graph-fns-not-in-file-or-db
 (defn- validate-multi-graph-fns-not-in-file-or-db
   []
   []
-  ;; TODO: Lint `(db-based-graph?` when db.frontend.entity-plus is split into separate graph contexts
-  (let [multi-graph-fns ["/db-based-graph\\?"
+  (let [multi-graph-fns ["/db-based-graph\\?" "\\(db-based-graph\\?"
                          ;; Use file-entity-util and entity-util when in a single graph context
                          ;; Use file-entity-util and entity-util when in a single graph context
                          "ldb/whiteboard\\?" "ldb/journal\\?" "ldb/page\\?"]
                          "ldb/whiteboard\\?" "ldb/journal\\?" "ldb/page\\?"]
         res (grep-many multi-graph-fns (into file-graph-paths db-graph-paths))]
         res (grep-many multi-graph-fns (into file-graph-paths db-graph-paths))]
@@ -120,12 +120,16 @@
                               "block/properties :"
                               "block/properties :"
                               ;; anything org mode except for org.babashka or urls like schema.org
                               ;; anything org mode except for org.babashka or urls like schema.org
                               "[^\\.]org[^\\.]"
                               "[^\\.]org[^\\.]"
+                              "file-based"
                               "#+BEGIN_"
                               "#+BEGIN_"
                               "#+END_"
                               "#+END_"
                               "pre-block"]))
                               "pre-block"]))
         ;; For now use the whole code line. If this is too brittle can make this smaller
         ;; For now use the whole code line. If this is too brittle can make this smaller
         allowed-exceptions #{":block/pre-block? :block/scheduled :block/deadline :block/type :block/name :block/marker"
         allowed-exceptions #{":block/pre-block? :block/scheduled :block/deadline :block/type :block/name :block/marker"
                              "(dissoc :block/format))]"
                              "(dissoc :block/format))]"
+                             ;; TODO: Mv these 2 file-based ns out of db files
+                             "(:require [logseq.db.file-based.rules :as file-rules]))"
+                             "[logseq.db.file-based.schema :as file-schema]))"
                              ;; The next 3 are from components.property.value
                              ;; The next 3 are from components.property.value
                              "{:block/name page-title})"
                              "{:block/name page-title})"
                              "(when-not (db/get-page journal)"
                              "(when-not (db/get-page journal)"
@@ -159,7 +163,7 @@
   (let [db-concepts
   (let [db-concepts
         ;; from logseq.db.frontend.schema
         ;; from logseq.db.frontend.schema
         ["closed-value" "class/properties" "classes" "property/parent"
         ["closed-value" "class/properties" "classes" "property/parent"
-         "logseq.property" "logseq.class"]
+         "logseq.property" "logseq.class" "db-based"]
         res (grep-many db-concepts file-graph-paths)]
         res (grep-many db-concepts file-graph-paths)]
     (when-not (and (= 1 (:exit res)) (= "" (:out res)))
     (when-not (and (= 1 (:exit res)) (= "" (:out res)))
       (println "The following files should not have contained db specific concepts:")
       (println "The following files should not have contained db specific concepts:")

+ 5 - 5
src/electron/electron/db.cljs

@@ -3,7 +3,7 @@
   (:require ["electron" :refer [app]]
   (:require ["electron" :refer [app]]
             ["fs-extra" :as fs]
             ["fs-extra" :as fs]
             ["path" :as node-path]
             ["path" :as node-path]
-            [logseq.db.common.sqlite :as sqlite-common-db]))
+            [logseq.db.common.sqlite :as common-sqlite]))
 
 
 (defn get-graphs-dir
 (defn get-graphs-dir
   []
   []
@@ -17,19 +17,19 @@
 (defn ensure-graph-dir!
 (defn ensure-graph-dir!
   [db-name]
   [db-name]
   (ensure-graphs-dir!)
   (ensure-graphs-dir!)
-  (let [graph-dir (node-path/join (get-graphs-dir) (sqlite-common-db/sanitize-db-name db-name))]
+  (let [graph-dir (node-path/join (get-graphs-dir) (common-sqlite/sanitize-db-name db-name))]
     (fs/ensureDirSync graph-dir)
     (fs/ensureDirSync graph-dir)
     graph-dir))
     graph-dir))
 
 
 (defn save-db!
 (defn save-db!
   [db-name data]
   [db-name data]
-  (let [[_db-name db-path] (sqlite-common-db/get-db-full-path (get-graphs-dir) db-name)]
+  (let [[_db-name db-path] (common-sqlite/get-db-full-path (get-graphs-dir) db-name)]
     (fs/writeFileSync db-path data)))
     (fs/writeFileSync db-path data)))
 
 
 (defn get-db
 (defn get-db
   [db-name]
   [db-name]
   (let [_ (ensure-graph-dir! db-name)
   (let [_ (ensure-graph-dir! db-name)
-        [_db-name db-path] (sqlite-common-db/get-db-full-path (get-graphs-dir) db-name)]
+        [_db-name db-path] (common-sqlite/get-db-full-path (get-graphs-dir) db-name)]
     (when (fs/existsSync db-path)
     (when (fs/existsSync db-path)
       (fs/readFileSync db-path))))
       (fs/readFileSync db-path))))
 
 
@@ -37,7 +37,7 @@
 
 
 (defn unlink-graph!
 (defn unlink-graph!
   [repo]
   [repo]
-  (let [db-name (sqlite-common-db/sanitize-db-name repo)
+  (let [db-name (common-sqlite/sanitize-db-name repo)
         path (node-path/join (get-graphs-dir) db-name)
         path (node-path/join (get-graphs-dir) db-name)
         unlinked (node-path/join (get-graphs-dir) unlinked-graphs-dir)
         unlinked (node-path/join (get-graphs-dir) unlinked-graphs-dir)
         new-path (node-path/join unlinked db-name)
         new-path (node-path/join unlinked db-name)

+ 3 - 3
src/electron/electron/handler.cljs

@@ -31,7 +31,7 @@
             [electron.window :as win]
             [electron.window :as win]
             [goog.functions :refer [debounce]]
             [goog.functions :refer [debounce]]
             [logseq.common.graph :as common-graph]
             [logseq.common.graph :as common-graph]
-            [logseq.db.common.sqlite :as sqlite-common-db]
+            [logseq.db.common.sqlite :as common-sqlite]
             [logseq.db.sqlite.util :as sqlite-util]
             [logseq.db.sqlite.util :as sqlite-util]
             [promesa.core :as p]))
             [promesa.core :as p]))
 
 
@@ -240,7 +240,7 @@
          (remove (fn [s] (= s db/unlinked-graphs-dir)))
          (remove (fn [s] (= s db/unlinked-graphs-dir)))
          (map graph-name->path)
          (map graph-name->path)
          (map (fn [s]
          (map (fn [s]
-                (if (string/starts-with? s sqlite-util/file-version-prefix)
+                (if (string/starts-with? s common-sqlite/file-version-prefix)
                   s
                   s
                   (str sqlite-util/db-version-prefix s)))))))
                   (str sqlite-util/db-version-prefix s)))))))
 
 
@@ -294,7 +294,7 @@
 (defmethod handle :deleteGraph [_window [_ graph graph-name _db-based?]]
 (defmethod handle :deleteGraph [_window [_ graph graph-name _db-based?]]
   (when graph-name
   (when graph-name
     (db/unlink-graph! graph)
     (db/unlink-graph! graph)
-    (let [old-transit-path (node-path/join (get-graphs-dir) (str (sqlite-common-db/sanitize-db-name graph) ".transit"))]
+    (let [old-transit-path (node-path/join (get-graphs-dir) (str (common-sqlite/sanitize-db-name graph) ".transit"))]
       (when (fs/existsSync old-transit-path)
       (when (fs/existsSync old-transit-path)
         (fs/unlinkSync old-transit-path)))))
         (fs/unlinkSync old-transit-path)))))
 
 

+ 2 - 2
src/main/frontend/background_tasks.cljs

@@ -2,11 +2,11 @@
   "Some background tasks"
   "Some background tasks"
   (:require [frontend.common.missionary :as c.m]
   (:require [frontend.common.missionary :as c.m]
             [frontend.flows :as flows]
             [frontend.flows :as flows]
-            [logseq.db.frontend.entity-plus :as entity-plus]
+            [logseq.db.common.entity-plus :as entity-plus]
             [missionary.core :as m]))
             [missionary.core :as m]))
 
 
 (c.m/run-background-task
 (c.m/run-background-task
- :logseq.db.frontend.entity-plus/reset-immutable-entities-cache!
+ :logseq.db.common.entity-plus/reset-immutable-entities-cache!
  (m/reduce
  (m/reduce
   (fn [_ repo]
   (fn [_ repo]
     (when (some? repo)
     (when (some? repo)

+ 14 - 4
src/main/frontend/commands.cljs

@@ -357,10 +357,20 @@
 
 
       ;; task management
       ;; task management
       (get-statuses)
       (get-statuses)
-      [["Deadline" [[:editor/clear-current-slash]
-                    [:editor/set-deadline]] "" :icon/calendar-stats]
-       ["Scheduled" [[:editor/clear-current-slash]
-                     [:editor/set-scheduled]] "" :icon/calendar-month]]
+
+      ;; task date
+      [["Deadline"
+        [[:editor/clear-current-slash]
+         [:editor/set-deadline]]
+        ""
+        :icon/calendar-stats
+        "TASK DATE"]
+       ["Scheduled"
+        [[:editor/clear-current-slash]
+         [:editor/set-scheduled]]
+        ""
+        :icon/calendar-month
+        "TASK DATE"]]
 
 
       ;; priority
       ;; priority
       (get-priorities)
       (get-priorities)

+ 1 - 1
src/main/frontend/common/file/core.cljs

@@ -5,7 +5,7 @@
             [datascript.core :as d]
             [datascript.core :as d]
             [logseq.db :as ldb]
             [logseq.db :as ldb]
             [logseq.db.frontend.content :as db-content]
             [logseq.db.frontend.content :as db-content]
-            [logseq.db.frontend.entity-plus :as entity-plus]
+            [logseq.db.common.entity-plus :as entity-plus]
             [logseq.db.sqlite.util :as sqlite-util]
             [logseq.db.sqlite.util :as sqlite-util]
             [logseq.graph-parser.property :as gp-property]
             [logseq.graph-parser.property :as gp-property]
             [logseq.outliner.tree :as otree]))
             [logseq.outliner.tree :as otree]))

+ 1 - 1
src/main/frontend/common/graph_view.cljs

@@ -6,7 +6,7 @@
             [logseq.common.util :as common-util]
             [logseq.common.util :as common-util]
             [logseq.db :as ldb]
             [logseq.db :as ldb]
             [logseq.db.common.property-util :as db-property-util]
             [logseq.db.common.property-util :as db-property-util]
-            [logseq.db.frontend.entity-plus :as entity-plus]
+            [logseq.db.common.entity-plus :as entity-plus]
             [logseq.db.sqlite.create-graph :as sqlite-create-graph]
             [logseq.db.sqlite.create-graph :as sqlite-create-graph]
             [logseq.graph-parser.db :as gp-db]))
             [logseq.graph-parser.db :as gp-db]))
 
 

+ 1 - 1
src/main/frontend/components/block.cljs

@@ -80,7 +80,7 @@
             [logseq.common.util.page-ref :as page-ref]
             [logseq.common.util.page-ref :as page-ref]
             [logseq.db :as ldb]
             [logseq.db :as ldb]
             [logseq.db.frontend.content :as db-content]
             [logseq.db.frontend.content :as db-content]
-            [logseq.db.frontend.entity-plus :as entity-plus]
+            [logseq.db.common.entity-plus :as entity-plus]
             [logseq.graph-parser.block :as gp-block]
             [logseq.graph-parser.block :as gp-block]
             [logseq.graph-parser.mldoc :as gp-mldoc]
             [logseq.graph-parser.mldoc :as gp-mldoc]
             [logseq.graph-parser.text :as text]
             [logseq.graph-parser.text :as text]

+ 11 - 10
src/main/frontend/components/cmdk/core.cljs

@@ -197,16 +197,17 @@
     "page"))
     "page"))
 
 
 (defmethod load-results :initial [_ state]
 (defmethod load-results :initial [_ state]
-  (let [!results (::results state)
-        recent-pages (map (fn [block]
-                            (let [text (block-handler/block-unique-title block)
-                                  icon (get-page-icon block)]
-                              {:icon icon
-                               :icon-theme :gray
-                               :text text
-                               :source-block block}))
-                          (ldb/get-recent-updated-pages (db/get-db)))]
-    (reset! !results (assoc-in default-results [:recently-updated-pages :items] recent-pages))))
+  (when-let [db (db/get-db)]
+    (let [!results (::results state)
+          recent-pages (map (fn [block]
+                              (let [text (block-handler/block-unique-title block)
+                                    icon (get-page-icon block)]
+                                {:icon icon
+                                 :icon-theme :gray
+                                 :text text
+                                 :source-block block}))
+                            (ldb/get-recent-updated-pages db))]
+      (reset! !results (assoc-in default-results [:recently-updated-pages :items] recent-pages)))))
 
 
 ;; The commands search uses the command-palette handler
 ;; The commands search uses the command-palette handler
 (defmethod load-results :commands [group state]
 (defmethod load-results :commands [group state]

+ 1 - 1
src/main/frontend/components/editor.cljs

@@ -47,7 +47,7 @@
               (or
               (or
                (= "Add new property" (first item))
                (= "Add new property" (first item))
                (when (= (count item) 5)
                (when (= (count item) 5)
-                 (contains? #{"TASK STATUS" "PRIORITY"} (last item))))) commands)
+                 (contains? #{"TASK STATUS" "TASK DATE" "PRIORITY"} (last item))))) commands)
     commands))
     commands))
 
 
 (rum/defcs commands < rum/reactive
 (rum/defcs commands < rum/reactive

+ 2 - 2
src/main/frontend/components/server.cljs

@@ -74,7 +74,7 @@
                          (not= (util/safe-parse-int (or port 0))
                          (not= (util/safe-parse-int (or port 0))
                                (util/safe-parse-int (or (:port server-state) 0))))
                                (util/safe-parse-int (or (:port server-state) 0))))
         changed?     (or hp-changed? (->> [autostart (:autostart server-state)]
         changed?     (or hp-changed? (->> [autostart (:autostart server-state)]
-                                          (mapv #(cond-> % (nil? %) not))
+                                          (mapv #(cond-> % (nil? %) boolean))
                                           (apply not=)))]
                                           (apply not=)))]
 
 
     [:div.cp__server-configs-panel.pt-5
     [:div.cp__server-configs-panel.pt-5
@@ -104,7 +104,7 @@
        (ui/checkbox
        (ui/checkbox
         {:on-change #(let [checked (.-checked (.-target %))]
         {:on-change #(let [checked (.-checked (.-target %))]
                        (swap! *configs assoc :autostart checked))
                        (swap! *configs assoc :autostart checked))
-         :value     (not (false? autostart))})
+         :checked   (not (false? autostart))})
 
 
        [:strong.select-none "Auto start server with the app launched"]]]
        [:strong.select-none "Auto start server with the app launched"]]]
 
 

+ 3 - 2
src/main/frontend/db/restore.cljs

@@ -1,12 +1,12 @@
 (ns frontend.db.restore
 (ns frontend.db.restore
   "Fns for DB restore(from text or sqlite)"
   "Fns for DB restore(from text or sqlite)"
   (:require [cljs-time.core :as t]
   (:require [cljs-time.core :as t]
+            [datascript.core :as d]
             [frontend.db.conn :as db-conn]
             [frontend.db.conn :as db-conn]
             [frontend.persist-db :as persist-db]
             [frontend.persist-db :as persist-db]
             [frontend.state :as state]
             [frontend.state :as state]
             [frontend.undo-redo :as undo-redo]
             [frontend.undo-redo :as undo-redo]
             [logseq.db :as ldb]
             [logseq.db :as ldb]
-            [logseq.db.common.sqlite :as sqlite-common-db]
             [promesa.core :as p]))
             [promesa.core :as p]))
 
 
 (defn restore-graph!
 (defn restore-graph!
@@ -15,11 +15,12 @@
   (state/set-state! :graph/loading? true)
   (state/set-state! :graph/loading? true)
   (p/let [start-time (t/now)
   (p/let [start-time (t/now)
           {:keys [schema initial-data]} (persist-db/<fetch-init-data repo opts)
           {:keys [schema initial-data]} (persist-db/<fetch-init-data repo opts)
+          _ (state/set-current-repo! repo)
           ;; Without valid schema app fails hard downstream
           ;; Without valid schema app fails hard downstream
           _ (when (nil? schema)
           _ (when (nil? schema)
               (throw (ex-info "No valid schema found when reloading db" {:repo repo})))
               (throw (ex-info "No valid schema found when reloading db" {:repo repo})))
           conn (try
           conn (try
-                 (sqlite-common-db/restore-initial-data initial-data schema)
+                 (d/conn-from-datoms initial-data schema)
                  (catch :default e
                  (catch :default e
                    (prn :error :restore-initial-data-failed
                    (prn :error :restore-initial-data-failed
                         (ldb/write-transit-str {:schema schema
                         (ldb/write-transit-str {:schema schema

+ 1 - 1
src/main/frontend/db/utils.cljs

@@ -4,7 +4,7 @@
             [frontend.db.conn :as conn]
             [frontend.db.conn :as conn]
             [frontend.state :as state]
             [frontend.state :as state]
             [logseq.db.frontend.content :as db-content]
             [logseq.db.frontend.content :as db-content]
-            [logseq.db.frontend.entity-plus :as entity-plus]))
+            [logseq.db.common.entity-plus :as entity-plus]))
 
 
 ;; transit serialization
 ;; transit serialization
 
 

+ 1 - 1
src/main/frontend/extensions/fsrs.cljs

@@ -18,7 +18,7 @@
             [frontend.ui :as ui]
             [frontend.ui :as ui]
             [frontend.util :as util]
             [frontend.util :as util]
             [logseq.db :as ldb]
             [logseq.db :as ldb]
-            [logseq.db.frontend.entity-plus :as entity-plus]
+            [logseq.db.common.entity-plus :as entity-plus]
             [logseq.shui.ui :as shui]
             [logseq.shui.ui :as shui]
             [missionary.core :as m]
             [missionary.core :as m]
             [open-spaced-repetition.cljc-fsrs.core :as fsrs.core]
             [open-spaced-repetition.cljc-fsrs.core :as fsrs.core]

+ 2 - 2
src/main/frontend/handler/db_based/rtc.cljs

@@ -10,7 +10,7 @@
             [frontend.util :as util]
             [frontend.util :as util]
             [lambdaisland.glogi :as log]
             [lambdaisland.glogi :as log]
             [logseq.db :as ldb]
             [logseq.db :as ldb]
-            [logseq.db.common.sqlite :as sqlite-common-db]
+            [logseq.db.common.sqlite :as common-sqlite]
             [logseq.shui.ui :as shui]
             [logseq.shui.ui :as shui]
             [promesa.core :as p]))
             [promesa.core :as p]))
 
 
@@ -19,7 +19,7 @@
   (p/do!
   (p/do!
    (js/Promise. user-handler/task--ensure-id&access-token)
    (js/Promise. user-handler/task--ensure-id&access-token)
    (let [token (state/get-auth-id-token)
    (let [token (state/get-auth-id-token)
-         repo-name (sqlite-common-db/sanitize-db-name repo)]
+         repo-name (common-sqlite/sanitize-db-name repo)]
      (state/<invoke-db-worker :thread-api/rtc-async-upload-graph repo token repo-name))))
      (state/<invoke-db-worker :thread-api/rtc-async-upload-graph repo token repo-name))))
 
 
 (defn <rtc-delete-graph!
 (defn <rtc-delete-graph!

+ 1 - 1
src/main/frontend/handler/editor.cljs

@@ -55,7 +55,7 @@
             [logseq.common.util.page-ref :as page-ref]
             [logseq.common.util.page-ref :as page-ref]
             [logseq.db :as ldb]
             [logseq.db :as ldb]
             [logseq.db.file-based.schema :as file-schema]
             [logseq.db.file-based.schema :as file-schema]
-            [logseq.db.frontend.entity-plus :as entity-plus]
+            [logseq.db.common.entity-plus :as entity-plus]
             [logseq.db.frontend.property :as db-property]
             [logseq.db.frontend.property :as db-property]
             [logseq.graph-parser.block :as gp-block]
             [logseq.graph-parser.block :as gp-block]
             [logseq.graph-parser.mldoc :as gp-mldoc]
             [logseq.graph-parser.mldoc :as gp-mldoc]

+ 3 - 3
src/main/frontend/handler/export.cljs

@@ -22,7 +22,7 @@
    [goog.dom :as gdom]
    [goog.dom :as gdom]
    [lambdaisland.glogi :as log]
    [lambdaisland.glogi :as log]
    [logseq.db :as ldb]
    [logseq.db :as ldb]
-   [logseq.db.common.sqlite :as sqlite-common-db]
+   [logseq.db.common.sqlite :as common-sqlite]
    [logseq.publishing.html :as publish-html]
    [logseq.publishing.html :as publish-html]
    [promesa.core :as p])
    [promesa.core :as p])
   (:import
   (:import
@@ -58,7 +58,7 @@
   [repo]
   [repo]
   (p/let [db-data (persist-db/<export-db repo {:return-data? true})
   (p/let [db-data (persist-db/<export-db repo {:return-data? true})
           filename "db.sqlite"
           filename "db.sqlite"
-          repo-name (sqlite-common-db/sanitize-db-name repo)
+          repo-name (common-sqlite/sanitize-db-name repo)
           assets (assets-handler/<get-all-assets)
           assets (assets-handler/<get-all-assets)
           files (cons [filename db-data] assets)
           files (cons [filename db-data] assets)
           zipfile (zip/make-zip repo-name files repo)]
           zipfile (zip/make-zip repo-name files repo)]
@@ -255,7 +255,7 @@
   (when (and repo (= repo (state/get-current-repo)))
   (when (and repo (= repo (state/get-current-repo)))
     (when-let [backup-folder (ldb/get-key-value (db/get-db repo) :logseq.kv/graph-backup-folder)]
     (when-let [backup-folder (ldb/get-key-value (db/get-db repo) :logseq.kv/graph-backup-folder)]
       (p/let [handle (idb/get-item (str "handle/" (js/btoa repo) "/" backup-folder))
       (p/let [handle (idb/get-item (str "handle/" (js/btoa repo) "/" backup-folder))
-              repo-name (sqlite-common-db/sanitize-db-name repo)]
+              repo-name (common-sqlite/sanitize-db-name repo)]
         (if handle
         (if handle
           (->
           (->
            (p/let [graph-dir-handle (.getDirectoryHandle handle repo-name #js {:create true})
            (p/let [graph-dir-handle (.getDirectoryHandle handle repo-name #js {:create true})

+ 1 - 1
src/main/frontend/state.cljs

@@ -21,7 +21,7 @@
             [goog.object :as gobj]
             [goog.object :as gobj]
             [logseq.common.config :as common-config]
             [logseq.common.config :as common-config]
             [logseq.db :as ldb]
             [logseq.db :as ldb]
-            [logseq.db.frontend.entity-plus :as entity-plus]
+            [logseq.db.common.entity-plus :as entity-plus]
             [logseq.db.sqlite.util :as sqlite-util]
             [logseq.db.sqlite.util :as sqlite-util]
             [logseq.shui.dialog.core :as shui-dialog]
             [logseq.shui.dialog.core :as shui-dialog]
             [logseq.shui.hooks :as hooks]
             [logseq.shui.hooks :as hooks]

+ 2 - 2
src/main/frontend/worker/db/fix.cljs

@@ -1,11 +1,11 @@
 (ns frontend.worker.db.fix
 (ns frontend.worker.db.fix
   "fix db"
   "fix db"
   (:require [datascript.core :as d]
   (:require [datascript.core :as d]
-            [logseq.db.sqlite.util :as sqlite-util]))
+            [logseq.db :as ldb]))
 
 
 (defn check-and-fix-schema!
 (defn check-and-fix-schema!
   [repo conn]
   [repo conn]
-  (let [schema (sqlite-util/get-schema repo)
+  (let [schema (ldb/get-schema repo)
         db-schema (:schema @conn)
         db-schema (:schema @conn)
         diffs (->> (keep (fn [[k v]]
         diffs (->> (keep (fn [[k v]]
                            (let [schema-v (-> (get db-schema k)
                            (let [schema-v (-> (get db-schema k)

+ 22 - 17
src/main/frontend/worker/db_worker.cljs

@@ -31,12 +31,14 @@
             [frontend.worker.util :as worker-util]
             [frontend.worker.util :as worker-util]
             [goog.object :as gobj]
             [goog.object :as gobj]
             [lambdaisland.glogi.console :as glogi-console]
             [lambdaisland.glogi.console :as glogi-console]
+            [logseq.common.log :as log]
             [logseq.common.util :as common-util]
             [logseq.common.util :as common-util]
             [logseq.db :as ldb]
             [logseq.db :as ldb]
+            [logseq.db.common.entity-plus :as entity-plus]
+            [logseq.db.common.initial-data :as common-initial-data]
             [logseq.db.common.order :as db-order]
             [logseq.db.common.order :as db-order]
-            [logseq.db.common.sqlite :as sqlite-common-db]
+            [logseq.db.common.sqlite :as common-sqlite]
             [logseq.db.common.view :as db-view]
             [logseq.db.common.view :as db-view]
-            [logseq.db.frontend.entity-plus :as entity-plus]
             [logseq.db.frontend.schema :as db-schema]
             [logseq.db.frontend.schema :as db-schema]
             [logseq.db.sqlite.create-graph :as sqlite-create-graph]
             [logseq.db.sqlite.create-graph :as sqlite-create-graph]
             [logseq.db.sqlite.export :as sqlite-export]
             [logseq.db.sqlite.export :as sqlite-export]
@@ -328,19 +330,19 @@
                                        :client-ops client-ops-db})
                                        :client-ops client-ops-db})
       (doseq [db' dbs]
       (doseq [db' dbs]
         (enable-sqlite-wal-mode! db'))
         (enable-sqlite-wal-mode! db'))
-      (sqlite-common-db/create-kvs-table! db)
-      (when-not @*publishing? (sqlite-common-db/create-kvs-table! client-ops-db))
+      (common-sqlite/create-kvs-table! db)
+      (when-not @*publishing? (common-sqlite/create-kvs-table! client-ops-db))
       (db-migrate/migrate-sqlite-db db)
       (db-migrate/migrate-sqlite-db db)
       (when-not @*publishing? (db-migrate/migrate-sqlite-db client-ops-db))
       (when-not @*publishing? (db-migrate/migrate-sqlite-db client-ops-db))
       (search/create-tables-and-triggers! search-db)
       (search/create-tables-and-triggers! search-db)
-      (let [schema (sqlite-util/get-schema repo)
-            conn (sqlite-common-db/get-storage-conn storage schema)
+      (let [schema (ldb/get-schema repo)
+            conn (common-sqlite/get-storage-conn storage schema)
             _ (db-fix/check-and-fix-schema! repo conn)
             _ (db-fix/check-and-fix-schema! repo conn)
             _ (when datoms
             _ (when datoms
                 (let [data (map (fn [datom]
                 (let [data (map (fn [datom]
                                   [:db/add (:e datom) (:a datom) (:v datom)]) datoms)]
                                   [:db/add (:e datom) (:a datom) (:v datom)]) datoms)]
                   (d/transact! conn data {:initial-db? true})))
                   (d/transact! conn data {:initial-db? true})))
-            client-ops-conn (when-not @*publishing? (sqlite-common-db/get-storage-conn
+            client-ops-conn (when-not @*publishing? (common-sqlite/get-storage-conn
                                                      client-ops-storage
                                                      client-ops-storage
                                                      client-op/schema-in-db))
                                                      client-op/schema-in-db))
             initial-data-exists? (when (nil? datoms)
             initial-data-exists? (when (nil? datoms)
@@ -357,12 +359,14 @@
             (d/transact! conn initial-data {:initial-db? true})))
             (d/transact! conn initial-data {:initial-db? true})))
 
 
         (try
         (try
-          (when-let [missing-addresses (seq (find-missing-addresses db))]
-            (throw (ex-info "DB missing addresses" {:missing-addresses missing-addresses})))
+          (when-not import-type
+            (when-let [missing-addresses (seq (find-missing-addresses db))]
+              (throw (ex-info "DB missing addresses" {:missing-addresses missing-addresses}))))
 
 
           (db-migrate/migrate conn search-db)
           (db-migrate/migrate conn search-db)
 
 
           (catch :default _e
           (catch :default _e
+            (log/error "DB migrate failed, retrying")
             (when db-based?
             (when db-based?
               (rebuild-db-from-datoms! conn db import-type)
               (rebuild-db-from-datoms! conn db import-type)
               (db-migrate/migrate conn search-db))))
               (db-migrate/migrate conn search-db))))
@@ -489,7 +493,7 @@
                 id)]
                 id)]
       (some->> eid
       (some->> eid
                (d/pull @conn selector)
                (d/pull @conn selector)
-               (sqlite-common-db/with-parent @conn)))))
+               (common-initial-data/with-parent @conn)))))
 
 
 (def ^:private *get-blocks-cache (volatile! (cache/lru-cache-factory {} :threshold 1000)))
 (def ^:private *get-blocks-cache (volatile! (cache/lru-cache-factory {} :threshold 1000)))
 (def ^:private get-blocks-with-cache
 (def ^:private get-blocks-with-cache
@@ -503,7 +507,7 @@
      (when db
      (when db
        (mapv (fn [{:keys [id opts]}]
        (mapv (fn [{:keys [id opts]}]
                (let [id' (if (and (string? id) (common-util/uuid-string? id)) (uuid id) id)]
                (let [id' (if (and (string? id) (common-util/uuid-string? id)) (uuid id) id)]
-                 (-> (sqlite-common-db/get-block-and-children db id' opts)
+                 (-> (common-initial-data/get-block-and-children db id' opts)
                      (assoc :id id)))) requests)))))
                      (assoc :id id)))) requests)))))
 
 
 (def-thread-api :thread-api/get-blocks
 (def-thread-api :thread-api/get-blocks
@@ -601,7 +605,7 @@
 (def-thread-api :thread-api/get-initial-data
 (def-thread-api :thread-api/get-initial-data
   [repo]
   [repo]
   (when-let [conn (worker-state/get-datascript-conn repo)]
   (when-let [conn (worker-state/get-datascript-conn repo)]
-    (sqlite-common-db/get-initial-data @conn)))
+    (common-initial-data/get-initial-data @conn)))
 
 
 (def-thread-api :thread-api/reset-db
 (def-thread-api :thread-api/reset-db
   [repo db-transit]
   [repo db-transit]
@@ -851,7 +855,7 @@
          :rtc-sync-state])))
          :rtc-sync-state])))
 
 
 (defn- <init-service!
 (defn- <init-service!
-  [graph]
+  [graph import?]
   (let [[prev-graph service] @*service]
   (let [[prev-graph service] @*service]
     (some-> prev-graph close-db!)
     (some-> prev-graph close-db!)
     (when graph
     (when graph
@@ -860,7 +864,8 @@
         (p/let [service (shared-service/<create-service graph
         (p/let [service (shared-service/<create-service graph
                                                         (bean/->js fns)
                                                         (bean/->js fns)
                                                         #(on-become-master graph)
                                                         #(on-become-master graph)
-                                                        broadcast-data-types)]
+                                                        broadcast-data-types
+                                                        {:import? import?})]
           (assert (p/promise? (get-in service [:status :ready])))
           (assert (p/promise? (get-in service [:status :ready])))
           (reset! *service [graph service])
           (reset! *service [graph service])
           service)))))
           service)))))
@@ -880,10 +885,10 @@
                                 (= :thread-api/create-or-open-db method-k)
                                 (= :thread-api/create-or-open-db method-k)
                                 ;; because shared-service operates at the graph level,
                                 ;; because shared-service operates at the graph level,
                                 ;; creating a new database or switching to another one requires re-initializing the service.
                                 ;; creating a new database or switching to another one requires re-initializing the service.
-                                (let [[graph _opts] (ldb/read-transit-str (last args))]
-                                  (p/let [service (<init-service! graph)]
+                                (let [[graph opts] (ldb/read-transit-str (last args))]
+                                  (p/let [service (<init-service! graph (some? (:import-type opts)))]
                                     (get-in service [:status :ready])
                                     (get-in service [:status :ready])
-                                      ;; wait for service ready
+                                    ;; wait for service ready
                                     (js-invoke (:proxy service) k args)))
                                     (js-invoke (:proxy service) k args)))
 
 
                                 (or (contains? #{:thread-api/sync-app-state} method-k)
                                 (or (contains? #{:thread-api/sync-app-state} method-k)

+ 1 - 1
src/main/frontend/worker/handler/page/db_based/page.cljs

@@ -9,7 +9,7 @@
             [logseq.db.common.order :as db-order]
             [logseq.db.common.order :as db-order]
             [logseq.db.common.property-util :as db-property-util]
             [logseq.db.common.property-util :as db-property-util]
             [logseq.db.frontend.class :as db-class]
             [logseq.db.frontend.class :as db-class]
-            [logseq.db.frontend.entity-plus :as entity-plus]
+            [logseq.db.common.entity-plus :as entity-plus]
             [logseq.db.frontend.entity-util :as entity-util]
             [logseq.db.frontend.entity-util :as entity-util]
             [logseq.db.frontend.malli-schema :as db-malli-schema]
             [logseq.db.frontend.malli-schema :as db-malli-schema]
             [logseq.db.frontend.property.build :as db-property-build]
             [logseq.db.frontend.property.build :as db-property-build]

+ 2 - 1
src/main/frontend/worker/pipeline.cljs

@@ -12,6 +12,7 @@
             [logseq.common.util :as common-util]
             [logseq.common.util :as common-util]
             [logseq.common.uuid :as common-uuid]
             [logseq.common.uuid :as common-uuid]
             [logseq.db :as ldb]
             [logseq.db :as ldb]
+            [logseq.db.common.sqlite :as common-sqlite]
             [logseq.db.frontend.validate :as db-validate]
             [logseq.db.frontend.validate :as db-validate]
             [logseq.db.sqlite.export :as sqlite-export]
             [logseq.db.sqlite.export :as sqlite-export]
             [logseq.db.sqlite.util :as sqlite-util]
             [logseq.db.sqlite.util :as sqlite-util]
@@ -232,7 +233,7 @@
                                 :db-after (:db-after result)))
                                 :db-after (:db-after result)))
                        tx-report)
                        tx-report)
           {:keys [pages blocks]} (ds-report/get-blocks-and-pages tx-report*)
           {:keys [pages blocks]} (ds-report/get-blocks-and-pages tx-report*)
-          _ (when (sqlite-util/local-file-based-graph? repo)
+          _ (when (common-sqlite/local-file-based-graph? repo)
               (let [page-ids (distinct (map :db/id pages))]
               (let [page-ids (distinct (map :db/id pages))]
                 (doseq [page-id page-ids]
                 (doseq [page-id page-ids]
                   (when (d/entity @conn page-id)
                   (when (d/entity @conn page-id)

+ 2 - 1
src/main/frontend/worker/shared_service.cljs

@@ -302,8 +302,9 @@
 (defn <create-service
 (defn <create-service
   "broadcast-data-types - For data matching these types,
   "broadcast-data-types - For data matching these types,
                           forward the data broadcast from the master client directly to the UI thread."
                           forward the data broadcast from the master client directly to the UI thread."
-  [service-name target on-become-master-handler broadcast-data-types]
+  [service-name target on-become-master-handler broadcast-data-types {:keys [import?]}]
   (clear-old-service!)
   (clear-old-service!)
+  (when import? (reset! *master-client? true))
   (p/let [broadcast-data-types (set broadcast-data-types)
   (p/let [broadcast-data-types (set broadcast-data-types)
           status {:ready (p/deferred)}
           status {:ready (p/deferred)}
           common-channel (ensure-common-channel service-name)
           common-channel (ensure-common-channel service-name)

+ 2 - 2
src/main/frontend/worker/util.cljc

@@ -6,7 +6,7 @@
                      [goog.crypt :as crypt]
                      [goog.crypt :as crypt]
                      [goog.crypt.Hmac]
                      [goog.crypt.Hmac]
                      [goog.crypt.Sha256]
                      [goog.crypt.Sha256]
-                     [logseq.db.common.sqlite :as sqlite-common-db]
+                     [logseq.db.common.sqlite :as common-sqlite]
                      [frontend.common.file.util :as wfu])))
                      [frontend.common.file.util :as wfu])))
 
 
 ;; Copied from https://github.com/tonsky/datascript-todo
 ;; Copied from https://github.com/tonsky/datascript-todo
@@ -27,7 +27,7 @@
 
 
      (defn get-pool-name
      (defn get-pool-name
        [graph-name]
        [graph-name]
-       (str "logseq-pool-" (sqlite-common-db/sanitize-db-name graph-name)))
+       (str "logseq-pool-" (common-sqlite/sanitize-db-name graph-name)))
 
 
      (defn- decode-username
      (defn- decode-username
        [username]
        [username]