Selaa lähdekoodia

enhance: add export edn command

Also DRY up graph-dir related fns
Gabriel Horner 3 kuukautta sitten
vanhempi
sitoutus
465dceae17

+ 1 - 0
deps/cli/.clj-kondo/config.edn

@@ -12,6 +12,7 @@
              datascript.core d
              logseq.cli.commands.graph cli-graph
              logseq.cli.common.graph cli-common-graph
+             logseq.cli.util cli-util
              logseq.common.config common-config
              logseq.common.graph common-graph
              logseq.common.util.date-time date-time-util

+ 3 - 0
deps/cli/src/logseq/cli.cljs

@@ -4,6 +4,7 @@
             ["path" :as node-path]
             [babashka.cli :as cli]
             [clojure.string :as string]
+            [logseq.cli.commands.export-edn :as cli-export-edn]
             [logseq.cli.commands.graph :as cli-graph]
             [logseq.cli.commands.query :as cli-query]
             [logseq.cli.common.graph :as cli-common-graph]
@@ -42,6 +43,8 @@
    {:cmds ["query"] :fn cli-query/query :desc "Query DB graph(s)"
     :args->opts [:graph :queries] :coerce {:queries []} :no-keyword-opts true
     :spec cli-query/spec}
+   {:cmds ["export-edn"] :fn cli-export-edn/export :desc "Export DB graph as EDN"
+    :args->opts [:graph] :spec cli-export-edn/spec}
    {:cmds []
     :spec default-spec
     :fn default-command}])

+ 44 - 0
deps/cli/src/logseq/cli/commands/export_edn.cljs

@@ -0,0 +1,44 @@
+(ns logseq.cli.commands.export-edn
+  "Export edn command"
+  (:require ["fs" :as fs]
+            [clojure.pprint :as pprint]
+            [logseq.db.common.sqlite-cli :as sqlite-cli]
+            [logseq.db.sqlite.export :as sqlite-export]
+            [logseq.cli.util :as cli-util]))
+
+(def spec
+  "Options spec"
+  {:include-timestamps? {:alias :T
+                         :desc "Include timestamps in export"}
+   :file {:alias :f
+          :desc "Saves edn to file"}
+   :catch-validation-errors? {:alias :c
+                              :desc "Catch validation errors for dev"}
+   :exclude-namespaces {:alias :e
+                        :coerce #{}
+                        :desc "Namespaces to exclude from properties and classes"}
+   :exclude-built-in-pages? {:alias :b
+                             :desc "Exclude built-in pages"}
+   :exclude-files? {:alias :F
+                    :desc "Exclude :file/path files"}
+   :export-type {:alias :t
+                 :coerce :keyword
+                 :desc "Export type"
+                 :default :graph}})
+
+(defn export [{{:keys [graph] :as options} :opts}]
+  (if (fs/existsSync (cli-util/get-graph-dir graph))
+   (let [conn (apply sqlite-cli/open-db! (cli-util/->open-db-args graph))
+         export-map (sqlite-export/build-export @conn
+                                                (cond-> {:export-type (:export-type options)}
+                                                  (= :graph (:export-type options))
+                                                  (assoc :graph-options (dissoc options :file :export-type :graph))))]
+     (if (:file options)
+       (do
+         (println "Exported" (count (:properties export-map)) "properties,"
+                  (count (:properties export-map)) "classes and"
+                  (count (:pages-and-blocks export-map)) "pages")
+         (fs/writeFileSync (:file options)
+                           (with-out-str (pprint/pprint export-map))))
+       (pprint/pprint export-map)))
+    (println "Graph" (pr-str graph) "does not exist")))

+ 3 - 3
deps/cli/src/logseq/cli/commands/graph.cljs

@@ -7,9 +7,9 @@
             [clojure.string :as string]
             [datascript.core :as d]
             [logseq.cli.common.graph :as cli-common-graph]
+            [logseq.cli.util :as cli-util]
             [logseq.common.config :as common-config]
             [logseq.common.util.date-time :as date-time-util]
-            [logseq.db.common.sqlite :as common-sqlite]
             [logseq.db.common.sqlite-cli :as sqlite-cli]))
 
 (defn- ms->journal-title
@@ -19,9 +19,9 @@
 (defn show-graph
   [{{:keys [graphs]} :opts}]
   (doseq [graph graphs]
-    (let [graph-dir (node-path/join (cli-common-graph/get-db-graphs-dir) (common-sqlite/sanitize-db-name graph))]
+    (let [graph-dir (cli-util/get-graph-dir graph)]
       (if (fs/existsSync graph-dir)
-        (let [conn (sqlite-cli/open-db! (cli-common-graph/get-db-graphs-dir) (common-sqlite/sanitize-db-name graph))
+        (let [conn (apply sqlite-cli/open-db! (cli-util/->open-db-args graph))
               kv-value #(:kv/value (d/entity @conn %))]
           (pprint/print-table
            (map #(array-map "Name" (first %) "Value" (second %))

+ 19 - 21
deps/cli/src/logseq/cli/commands/query.cljs

@@ -1,12 +1,10 @@
 (ns logseq.cli.commands.query
   "Query command"
   (:require ["fs" :as fs]
-            ["path" :as node-path]
             [clojure.edn :as edn]
             [clojure.pprint :as pprint]
             [datascript.core :as d]
-            [logseq.cli.common.graph :as cli-common-graph]
-            [logseq.db.common.sqlite :as common-sqlite]
+            [logseq.cli.util :as cli-util]
             [logseq.db.common.sqlite-cli :as sqlite-cli]
             [logseq.db.frontend.rules :as rules]))
 
@@ -20,21 +18,21 @@
   [{{:keys [graph queries additional-graphs]} :opts}]
   (let [graphs (into [graph] additional-graphs)]
     (doseq [graph' graphs]
-      (let [graph-dir (node-path/join (cli-common-graph/get-db-graphs-dir) (common-sqlite/sanitize-db-name graph'))]
-        (if (fs/existsSync graph-dir)
-          (let [conn (sqlite-cli/open-db! (cli-common-graph/get-db-graphs-dir) (common-sqlite/sanitize-db-name graph'))
-                query* (when (string? (first queries)) (edn/read-string (first queries)))
-                results (if (and (vector? query*) (= :find (first query*)))
-                      ;; assumes no :in are in queries
-                          (let [query' (into query* [:in '$ '%])
-                                res (d/q query' @conn (rules/extract-rules rules/db-query-dsl-rules))]
-                        ;; Remove nesting for most queries which just have one :find binding
-                            (if (= 1 (count (first res))) (mapv first res) res))
-                          (map #(when-let [ent (d/entity @conn
-                                                         (if (string? %) (edn/read-string %) %))]
-                                  (into {:db/id (:db/id ent)} ent))
-                               queries))]
-            (when (> (count graphs) 1)
-              (println "Results for graph" (pr-str graph')))
-            (pprint/pprint results))
-          (println "Graph" (pr-str graph') "does not exist"))))))
+      (if (fs/existsSync (cli-util/get-graph-dir graph'))
+        (let [conn (apply sqlite-cli/open-db! (cli-util/->open-db-args graph))
+              query* (when (string? (first queries)) (edn/read-string (first queries)))
+              ;; If datalog query detected run it or else default to entity lookups
+              results (if (and (vector? query*) (= :find (first query*)))
+                        ;; assumes no :in are in queries
+                        (let [query' (into query* [:in '$ '%])
+                              res (d/q query' @conn (rules/extract-rules rules/db-query-dsl-rules))]
+                          ;; Remove nesting for most queries which just have one :find binding
+                          (if (= 1 (count (first res))) (mapv first res) res))
+                        (map #(when-let [ent (d/entity @conn
+                                                       (if (string? %) (edn/read-string %) %))]
+                                (into {:db/id (:db/id ent)} ent))
+                             queries))]
+          (when (> (count graphs) 1)
+            (println "Results for graph" (pr-str graph')))
+          (pprint/pprint results))
+        (println "Graph" (pr-str graph') "does not exist")))))

+ 14 - 0
deps/cli/src/logseq/cli/util.cljs

@@ -0,0 +1,14 @@
+(ns logseq.cli.util
+  "Util fns"
+  (:require ["path" :as node-path]
+            [logseq.cli.common.graph :as cli-common-graph]
+            [logseq.db.common.sqlite :as common-sqlite]))
+
+(defn get-graph-dir
+  [graph]
+  (node-path/join (cli-common-graph/get-db-graphs-dir) (common-sqlite/sanitize-db-name graph)))
+
+(defn ->open-db-args
+  "Creates args for sqlite-cli/open-db! given a graph. Similar to sqlite-cli/->open-db-args"
+  [graph]
+  [(cli-common-graph/get-db-graphs-dir) (common-sqlite/sanitize-db-name graph)])