Save your first file
Save a three-byte attachment in an in-memory database, give it a name and read it back. This tutorial assumes you can use a Clojure REPL. It does not create files on disk.
Start the REPL
From an authorised xitstash checkout, with Java 17 or later, Clojure CLI and Babashka installed, run:
bb javac
clojure -Sdeps '{:deps {io.github.radarroark/xitdb {:mvn/version "0.48.0"}}}' -M
Wait for the user⇒ prompt.
Load the library
(require ' [ol.xitstash :as objects])
(import ' [io.github.radarroark.xitdb
CoreMemory Database Database$ContextFunction Hasher RandomAccessMemory
ReadCountedHashMap WriteCountedHashMap]
' [java.security MessageDigest])
The require returns nil.
The import returns java.security.MessageDigest.
Save and read the attachment
Evaluate the following expression.
It prepares the content, commits a file named note.bin and returns the saved path and bytes:
(with-open [core (CoreMemory. (RandomAccessMemory.))
prepared (objects/prepare (byte-array [1 2 3 ]))]
(let [db (Database. core (Hasher. (MessageDigest/getInstance "SHA-256" )))]
(locking db
(.runContext db
(reify Database$ContextFunction
(run [_ root]
(let [store (.putCursor (WriteCountedHashMap. root) "objects" )]
(objects/initialize! store)
(objects/put! store prepared)
(objects/create! store [{:name "note.bin"
:digest (:digest prepared)}])))))
(let [store (.getCursor (ReadCountedHashMap. (.rootCursor db)) "objects" )
file (objects/lookup store 0 "note.bin" )]
(with-open [input (objects/open store (:digest file))]
{:path (objects/path store (:id file))
:bytes (vec (.readAllBytes input))})))))
Result:
{:path ["note.bin" ] :bytes [1 2 3 ]}
The file lives below catalog root 0.
Its bytes were prepared before the transaction and read after the commit.
The enclosing with-open forms close the stream, prepared content and memory database.
Run the expression again. It creates a fresh database and returns the same result.
Next
Use xitdb-clj transactions to save attachments alongside Clojure application records. Read Content and history for the distinction between a file name and a payload.