async.cljs 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. (ns frontend.db.async
  2. "Async queries"
  3. (:require [promesa.core :as p]
  4. [frontend.state :as state]
  5. [frontend.config :as config]
  6. [frontend.db.utils :as db-utils]
  7. [frontend.db.async.util :as db-async-util]
  8. [frontend.db.file-based.async :as file-async]
  9. [frontend.db :as db]
  10. [frontend.db.model :as db-model]
  11. [frontend.persist-db.browser :as db-browser]
  12. [datascript.core :as d]
  13. [frontend.db.react :as react]
  14. [frontend.date :as date]
  15. [cljs-time.core :as t]
  16. [cljs-time.format :as tf]
  17. [logseq.db :as ldb]
  18. [frontend.util :as util]
  19. [logseq.db.frontend.property :as db-property]))
  20. (def <q db-async-util/<q)
  21. (def <pull db-async-util/<pull)
  22. (comment
  23. (def <pull-many db-async-util/<pull-many))
  24. (defn <get-files
  25. [graph]
  26. (p/let [result (<q graph
  27. {:transact-db? false}
  28. '[:find [(pull ?file [:file/path :file/last-modified-at]) ...]
  29. :where
  30. [?file :file/path ?path]])]
  31. (->> result seq reverse (map #(vector (:file/path %) (or (:file/last-modified-at %) 0))))))
  32. (defn <get-all-templates
  33. [graph]
  34. (p/let [result (<q graph
  35. {:transact-db? true}
  36. '[:find ?t (pull ?b [*])
  37. :where
  38. [?b :block/properties ?p]
  39. [(get ?p :template) ?t]])]
  40. (into {} result)))
  41. (defn <get-template-by-name
  42. [name]
  43. (let [repo (state/get-current-repo)]
  44. (p/let [templates (<get-all-templates repo)]
  45. (get templates name))))
  46. (defn <db-based-get-all-properties
  47. "Return seq of all property names except for private built-in properties."
  48. [graph]
  49. (p/let [result (<q graph
  50. {:transact-db? false}
  51. '[:find [(pull ?e [:block/uuid :db/ident :block/original-name :block/schema]) ...]
  52. :where
  53. [?e :block/type "property"]
  54. [?e :block/original-name]])]
  55. (->> result
  56. ;; remove private built-in properties
  57. (remove #(and (:db/ident %)
  58. (db-property/logseq-property? (:db/ident %))
  59. (not (get-in % [:block/schema :public?])))))))
  60. (defn <get-all-property-names
  61. "Returns a seq of property name strings"
  62. []
  63. (when-let [graph (state/get-current-repo)]
  64. (if (config/db-based-graph? graph)
  65. (p/let [properties (<db-based-get-all-properties graph)]
  66. (map :block/original-name properties))
  67. (file-async/<file-based-get-all-properties graph))))
  68. (defn <get-property-values
  69. [graph property]
  70. (when-not (config/db-based-graph? graph)
  71. (file-async/<get-file-based-property-values graph property)))
  72. (defn <get-block-property-values
  73. [graph property-id]
  74. (<q graph {:transact-db? false}
  75. '[:find ?b ?v
  76. :in $ ?property-id
  77. :where
  78. [?b ?property-id ?v]
  79. [(not= ?v :logseq.property/empty-placeholder)]]
  80. property-id))
  81. ;; TODO: batch queries for better performance and UX
  82. (defn <get-block
  83. [graph name-or-uuid & {:keys [children?]
  84. :or {children? true}}]
  85. (let [name' (str name-or-uuid)
  86. e (cond
  87. (number? name-or-uuid)
  88. (db/entity name-or-uuid)
  89. (util/uuid-string? name')
  90. (db/entity [:block/uuid (uuid name')])
  91. :else
  92. (db/get-page name'))
  93. id (or (and (:block/uuid e) (str (:block/uuid e)))
  94. (and (util/uuid-string? name') name')
  95. name-or-uuid)]
  96. (if (:block.temp/fully-loaded? e)
  97. e
  98. (when-let [^Object sqlite @db-browser/*worker]
  99. (state/update-state! :db/async-queries (fn [s] (conj s name')))
  100. (p/let [result (.get-block-and-children sqlite graph id children?)
  101. {:keys [properties block children] :as result'} (ldb/read-transit-str result)
  102. conn (db/get-db graph false)
  103. block-and-children (concat properties [block] children)
  104. _ (d/transact! conn block-and-children)]
  105. (react/refresh-affected-queries!
  106. graph
  107. [[:frontend.worker.react/block (:db/id block)]])
  108. (state/update-state! :db/async-queries (fn [s] (disj s name')))
  109. (if children?
  110. block
  111. result'))))))
  112. (defn <get-right-sibling
  113. [graph db-id]
  114. (assert (integer? db-id))
  115. (when-let [^Object worker @db-browser/*worker]
  116. (p/let [result-str (.get-right-sibling worker graph db-id)
  117. result (ldb/read-transit-str result-str)
  118. conn (db/get-db graph false)
  119. _ (when result (d/transact! conn [result]))]
  120. result)))
  121. (defn <get-block-parents
  122. [graph id depth]
  123. (assert (integer? id))
  124. (when-let [^Object worker @db-browser/*worker]
  125. (when-let [block-id (:block/uuid (db/entity graph id))]
  126. (state/update-state! :db/async-queries (fn [s] (conj s (str block-id "-parents"))))
  127. (p/let [result-str (.get-block-parents worker graph id depth)
  128. result (ldb/read-transit-str result-str)
  129. conn (db/get-db graph false)
  130. _ (d/transact! conn result)]
  131. (state/update-state! :db/async-queries (fn [s] (disj s (str block-id "-parents"))))
  132. result))))
  133. (defn <get-block-refs
  134. [graph eid]
  135. (assert (integer? eid))
  136. (when-let [^Object worker @db-browser/*worker]
  137. (state/update-state! :db/async-queries (fn [s] (conj s (str eid "-refs"))))
  138. (p/let [result-str (.get-block-refs worker graph eid)
  139. result (ldb/read-transit-str result-str)
  140. conn (db/get-db graph false)
  141. _ (d/transact! conn result)]
  142. (state/update-state! :db/async-queries (fn [s] (disj s (str eid "-refs"))))
  143. result)))
  144. (defn <get-block-refs-count
  145. [graph eid]
  146. (assert (integer? eid))
  147. (when-let [^Object worker @db-browser/*worker]
  148. (.get-block-refs-count worker graph eid)))
  149. (defn <get-all-referenced-blocks-uuid
  150. "Get all uuids of blocks with any back link exists."
  151. [graph]
  152. (<q graph {:transact-db? false}
  153. '[:find [?refed-uuid ...]
  154. :where
  155. ;; ?referee-b is block with ref towards ?refed-b
  156. [?refed-b :block/uuid ?refed-uuid]
  157. [?referee-b :block/refs ?refed-b]]))
  158. (defn <get-file
  159. [graph path]
  160. (when (and graph path)
  161. (p/let [result (<pull graph [:file/path path])]
  162. (:file/content result))))
  163. (defn <get-date-scheduled-or-deadlines
  164. [journal-title]
  165. (when-let [date (date/journal-title->int journal-title)]
  166. (let [future-days (state/get-scheduled-future-days)
  167. date-format (tf/formatter "yyyyMMdd")
  168. current-day (tf/parse date-format (str date))
  169. future-day (some->> (t/plus current-day (t/days future-days))
  170. (tf/unparse date-format)
  171. (parse-long))]
  172. (when future-day
  173. (when-let [repo (state/get-current-repo)]
  174. (p/let [result (<q repo {}
  175. '[:find [(pull ?block ?block-attrs) ...]
  176. :in $ ?day ?future ?block-attrs
  177. :where
  178. (or
  179. [?block :block/scheduled ?d]
  180. [?block :block/deadline ?d])
  181. [(get-else $ ?block :block/repeated? false) ?repeated]
  182. [(get-else $ ?block :block/marker "NIL") ?marker]
  183. [(not= ?marker "DONE")]
  184. [(not= ?marker "CANCELED")]
  185. [(not= ?marker "CANCELLED")]
  186. [(<= ?d ?future)]
  187. (or-join [?repeated ?d ?day]
  188. [(true? ?repeated)]
  189. [(>= ?d ?day)])]
  190. date
  191. future-day
  192. db-model/block-attrs)]
  193. (->> result
  194. db-model/sort-by-left-recursive
  195. db-utils/group-by-page)))))))
  196. (defn <get-tag-pages
  197. [graph tag-id]
  198. (<q graph {:transact-db? true}
  199. '[:find [(pull ?page [:db/id :block/uuid :block/name :block/original-name :block/created-at :block/updated-at])]
  200. :in $ ?tag-id
  201. :where
  202. [?page :block/tags ?tag-id]]
  203. tag-id))
  204. (defn <get-tags
  205. [graph]
  206. (<q graph {:transact-db? false}
  207. '[:find [(pull ?tag-id [:db/id :block/original-name])]
  208. :in $ ?tag-id
  209. :where
  210. [?page :block/tags ?tag-id]]))
  211. (defn <fetch-all-pages
  212. [graph]
  213. (when-let [^Object worker @db-browser/*worker]
  214. (let [db (db/get-db graph)
  215. exclude-ids (->> (d/datoms db :avet :block/name)
  216. (map :db/id)
  217. (ldb/write-transit-str))]
  218. (.fetch-all-pages worker graph exclude-ids))))