Skip to content

Commit 0bc0892

Browse files
enhance(cli): Add import-edn command
Works for both current and local graphs. Addresses CLI and API for https://discord.com/channels/725182569297215569/1365819617079066744/1365819617079066744
1 parent 085f909 commit 0bc0892

File tree

8 files changed

+75
-4
lines changed

8 files changed

+75
-4
lines changed

deps/cli/.carve/ignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ logseq.cli.commands.search/search
77
logseq.cli.commands.export/export
88
logseq.cli.commands.append/append
99
logseq.cli.commands.mcp-server/start
10+
logseq.cli.commands.import-edn/import-edn

deps/cli/README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ query [options] Query DB graph(s)
3131
export [options] Export DB graph as Markdown
3232
export-edn [options] Export DB graph as EDN
3333
append [options] Appends text to current page
34+
mcp-server [options] Run a MCP server
35+
import-edn [options] Import into DB graph with EDN
3436
help Print a command's help
3537
3638
$ logseq list
@@ -120,7 +122,11 @@ Exported 41 pages to yep_markdown_1756128259.zip
120122
121123
# Export DB graph as EDN
122124
$ logseq export-edn woot -f woot.edn
123-
Exported 16 properties, 16 classes and 36 pages
125+
Exported 16 properties, 1 classes and 36 pages to woot.edn
126+
127+
# Import into current graph with EDN
128+
$ logseq import-edn -f woot-ontology.edn
129+
Imported 16 properties, 1 classes and 0 pages!
124130
125131
# Append text to current page
126132
$ logseq append add this text -a my-token

deps/cli/src/logseq/cli.cljs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@
103103
:description "Run a MCP server against a local graph if --graph is given or against the current in-app graph. By default the MCP server runs as a HTTP Streamable server. Use --stdio to run it as a stdio server."
104104
:fn (lazy-load-fn 'logseq.cli.commands.mcp-server/start)
105105
:spec cli-spec/mcp-server}
106+
{:cmds ["import-edn"] :desc "Import into DB graph with EDN"
107+
:description "Import with EDN into a local graph or the current in-app graph if --api-server-token is given. See https://github.com/logseq/docs/blob/master/db-version.md#edn-data-export for more about this import type."
108+
:fn (lazy-load-fn 'logseq.cli.commands.import-edn/import-edn)
109+
:spec cli-spec/import-edn}
106110
{:cmds ["help"] :fn help-command :desc "Print a command's help"
107111
:args->opts [:command] :require [:command]}
108112
{:cmds []
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
(ns logseq.cli.commands.import-edn
2+
"Import edn command"
3+
(:require ["fs" :as fs]
4+
[clojure.edn :as edn]
5+
[logseq.cli.util :as cli-util]
6+
[logseq.db :as ldb]
7+
[logseq.db.common.sqlite-cli :as sqlite-cli]
8+
[logseq.db.sqlite.export :as sqlite-export]
9+
[logseq.db.sqlite.util :as sqlite-util]
10+
[promesa.core :as p]))
11+
12+
(defn- print-success [import-map]
13+
(println "Imported" (count (:properties import-map)) "properties,"
14+
(count (:classes import-map)) "classes and"
15+
(count (:pages-and-blocks import-map)) "pages!"))
16+
17+
(defn- api-import [api-server-token import-map]
18+
(-> (p/let [resp (cli-util/api-fetch api-server-token "logseq.cli.import_edn" [(sqlite-util/transit-write import-map)])]
19+
(if (= 200 (.-status resp))
20+
(print-success import-map)
21+
(cli-util/api-handle-error-response resp)))
22+
(p/catch cli-util/command-catch-handler)))
23+
24+
(defn- local-import [{:keys [graph]} import-map]
25+
(if (and graph (fs/existsSync (cli-util/get-graph-path graph)))
26+
(let [conn (apply sqlite-cli/open-db! (cli-util/->open-db-args graph))
27+
{:keys [init-tx block-props-tx misc-tx]}
28+
(sqlite-export/build-import import-map @conn {})
29+
txs (vec (concat init-tx block-props-tx misc-tx))]
30+
(ldb/transact! conn txs)
31+
(print-success import-map))
32+
(cli-util/error "Graph" (pr-str graph) "does not exist")))
33+
34+
(defn import-edn [{{:keys [api-server-token file] :as opts} :opts}]
35+
(let [edn (edn/read-string (str (fs/readFileSync file)))]
36+
(if api-server-token
37+
(api-import api-server-token edn)
38+
(local-import opts edn))))

deps/cli/src/logseq/cli/spec.cljs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,15 @@
2525
:desc "Export type"
2626
:default :graph}})
2727

28+
(def import-edn
29+
{:api-server-token {:alias :a
30+
:desc "API server token to query current graph"}
31+
:graph {:alias :g
32+
:desc "Local graph to import into"}
33+
:file {:alias :f
34+
:require true
35+
:desc "EDN File to import"}})
36+
2837
(def query
2938
{:graphs {:alias :g
3039
:coerce []

src/electron/electron/server.cljs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
[electron.utils :as utils]
1313
[electron.window :as window]
1414
[logseq.cli.common.mcp.server :as cli-common-mcp-server]
15-
[promesa.core :as p]))
15+
[promesa.core :as p]
16+
[logseq.db.sqlite.util :as sqlite-util]))
1617

1718
(defonce ^:private *win (atom nil))
1819
(defonce ^:private *server (atom nil))

src/main/logseq/api.cljs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@
212212
(def ^:export list_pages cli-based-api/list-pages)
213213
(def ^:export get_page_data cli-based-api/get-page-data)
214214
(def ^:export upsert_nodes cli-based-api/upsert-nodes)
215+
(def ^:export import_edn cli-based-api/import-edn)
215216

216217
;; file based graph APIs
217218
(def ^:export get_current_graph_templates file-based-api/get_current_graph_templates)

src/main/logseq/api/db_based/cli.cljs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
[frontend.modules.outliner.ui :as ui-outliner-tx]
66
[frontend.state :as state]
77
[logseq.cli.common.mcp.tools :as cli-common-mcp-tools]
8-
[promesa.core :as p]))
8+
[promesa.core :as p]
9+
[logseq.db.sqlite.util :as sqlite-util]))
910

1011
(defn list-tags
1112
[options]
@@ -48,4 +49,14 @@
4849
(outliner-op/batch-import-edn! edn-data {})))]
4950
(when error (throw (ex-info error {})))
5051
(ui-handler/re-render-root!)
51-
(cli-common-mcp-tools/summarize-upsert-operations ops options)))
52+
(cli-common-mcp-tools/summarize-upsert-operations ops options)))
53+
54+
(defn import-edn
55+
"Given EDN data as a transitized string, converts to EDN and imports it."
56+
[edn-data*]
57+
(p/let [edn-data (sqlite-util/transit-read edn-data*)
58+
{:keys [error]} (ui-outliner-tx/transact!
59+
{:outliner-op :batch-import-edn}
60+
(outliner-op/batch-import-edn! edn-data {}))]
61+
(when error (throw (ex-info error {})))
62+
(ui-handler/re-render-root!)))

0 commit comments

Comments
 (0)