Browse Source

enhance: query DB graph(s)

Gabriel Horner 3 months ago
parent
commit
cf02369a20
2 changed files with 47 additions and 3 deletions
  1. 7 3
      deps/cli/src/logseq/cli.cljs
  2. 40 0
      deps/cli/src/logseq/cli/commands/query.cljs

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

@@ -5,7 +5,8 @@
             [babashka.cli :as cli]
             [clojure.string :as string]
             [logseq.cli.commands.graph :as cli-graph]
-            [logseq.cli.common.graph :as cli-common-graph]))
+            [logseq.cli.common.graph :as cli-common-graph]
+            [logseq.cli.commands.query :as cli-query]))
 
 (defn- format-commands [{:keys [table]}]
   (let [table (mapv (fn [{:keys [cmds desc]}]
@@ -35,8 +36,11 @@
 
 (def ^:private table
   [{:cmds ["list"] :fn cli-graph/list-graphs :desc "List graphs"}
-   {:cmds ["show"] :fn cli-graph/show-graph :args->opts [:graphs] :desc "Show DB graph(s) info"
-    :coerce {:graphs []}}
+   {:cmds ["show"] :fn cli-graph/show-graph :desc "Show DB graph(s) info"
+    :args->opts [:graphs] :coerce {:graphs []}}
+   {: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 []
     :spec default-spec
     :fn default-command}])

+ 40 - 0
deps/cli/src/logseq/cli/commands/query.cljs

@@ -0,0 +1,40 @@
+(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.db.common.sqlite-cli :as sqlite-cli]
+            [logseq.db.frontend.rules :as rules]))
+
+(def spec
+  "Query spec"
+  {:additional-graphs {:alias :a
+                       :coerce []
+                       :desc "Additional graphs to query"}})
+
+(defn query
+  [{{: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"))))))