|
@@ -5,8 +5,11 @@
|
|
|
[clojure.pprint :as pprint]
|
|
|
[clojure.string :as string]
|
|
|
[datascript.core :as d]
|
|
|
+ [datascript.impl.entity :as de]
|
|
|
[logseq.cli.util :as cli-util]
|
|
|
+ [logseq.common.util :as common-util]
|
|
|
[logseq.db.common.sqlite-cli :as sqlite-cli]
|
|
|
+ [logseq.db.frontend.property :as db-property]
|
|
|
[logseq.db.frontend.rules :as rules]
|
|
|
[promesa.core :as p]))
|
|
|
|
|
@@ -24,32 +27,66 @@
|
|
|
res)]
|
|
|
(pprint/pprint results)))
|
|
|
(cli-util/api-handle-error-response resp)))
|
|
|
- (p/catch (fn [err]
|
|
|
- (js/console.error "Error:" err)
|
|
|
- (js/process.exit 1))))))
|
|
|
+ (p/catch cli-util/command-catch-handler))))
|
|
|
+
|
|
|
+(defn- readable-properties
|
|
|
+ "Expands an entity's properties and tags to be readable. Similar to
|
|
|
+ db-test/readable-properties but to be customized for CLI use"
|
|
|
+ [ent]
|
|
|
+ (->> (db-property/properties ent)
|
|
|
+ (mapv (fn [[k v]]
|
|
|
+ [k
|
|
|
+ (cond
|
|
|
+ (#{:block/tags :logseq.property.class/extends} k)
|
|
|
+ (mapv :db/ident v)
|
|
|
+ (and (set? v) (every? de/entity? v))
|
|
|
+ (set (map db-property/property-value-content v))
|
|
|
+ (de/entity? v)
|
|
|
+ (or (:db/ident v) (db-property/property-value-content v))
|
|
|
+ :else
|
|
|
+ v)]))
|
|
|
+ (into {})))
|
|
|
+
|
|
|
+(defn- local-entities-query
|
|
|
+ "Queries by calling d/entity"
|
|
|
+ [db properties-expand args]
|
|
|
+ (map #(when-let [ent (d/entity db
|
|
|
+ (cond
|
|
|
+ (and (string? %) (common-util/uuid-string? %))
|
|
|
+ [:block/uuid (uuid %)]
|
|
|
+ (string? %)
|
|
|
+ (edn/read-string %)
|
|
|
+ :else
|
|
|
+ %))]
|
|
|
+ (let [m (into {:db/id (:db/id ent)} ent)]
|
|
|
+ (if properties-expand
|
|
|
+ (merge m (readable-properties m))
|
|
|
+ m)))
|
|
|
+ args))
|
|
|
+
|
|
|
+(defn- local-query
|
|
|
+ [{{:keys [graph args graphs properties-readable]} :opts}]
|
|
|
+ (let [graphs' (into [graph] graphs)]
|
|
|
+ (doseq [graph' graphs']
|
|
|
+ (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 args)) (common-util/safe-read-string {:log-error? false} (first args)))
|
|
|
+ ;; 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))
|
|
|
+ (local-entities-query @conn properties-readable args))]
|
|
|
+ (when (> (count graphs') 1)
|
|
|
+ (println "Results for graph" (pr-str graph')))
|
|
|
+ (pprint/pprint results))
|
|
|
+ (println "Graph" (pr-str graph') "does not exist")))))
|
|
|
|
|
|
(defn query
|
|
|
- [{{:keys [graph queries graphs api-query-token]} :opts}]
|
|
|
+ [{{:keys [graph args api-query-token]} :opts :as m}]
|
|
|
(if api-query-token
|
|
|
;; graph can be query since it's not used for api-query
|
|
|
- (api-query (or graph (first queries)) api-query-token)
|
|
|
- (let [graphs' (into [graph] graphs)]
|
|
|
- (doseq [graph' graphs']
|
|
|
- (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"))))))
|
|
|
+ (api-query (or graph (first args)) api-query-token)
|
|
|
+ (local-query m)))
|