Skip to content

Instantly share code, notes, and snippets.

@arnaudbos
Last active January 17, 2023 02:07
Show Gist options
  • Save arnaudbos/b41ae4e6a91b14a29abaf0215f719ac0 to your computer and use it in GitHub Desktop.
Save arnaudbos/b41ae4e6a91b14a29abaf0215f719ac0 to your computer and use it in GitHub Desktop.
Clojure embedded-mongodb
{
:db-version "3.2.13"
:db-port 27017
:db-data-dir "/tmp/mongo-data-files"
}
de.flapdoodle.embed/de.flapdoodle.embed.mongo {:mvn/version "2.0.0"}
(ns embed-mongo
(:require [clojure.java.io :as io]
)
(:import [de.flapdoodle.embed.mongo Command MongodStarter]
[de.flapdoodle.embed.mongo.config RuntimeConfigBuilder MongodConfigBuilder Net Storage]
[de.flapdoodle.embed.mongo.distribution Feature Version Versions]
[de.flapdoodle.embed.process.config.io ProcessOutput]
[de.flapdoodle.embed.process.distribution IVersion]
[de.flapdoodle.embed.process.io IStreamProcessor NamedOutputStreamProcessor]
[de.flapdoodle.embed.process.runtime Network]
))
(def logging-lock (Object.))
(def file-stream-processor
(proxy [IStreamProcessor] []
(process [block]
(locking logging-lock
(with-open [writer (io/writer "embed-mongo.log" :append true)]
(.write writer block))))
(onProcessed []
(.process this "\n"))))
(def logger (ProcessOutput.
(NamedOutputStreamProcessor. "[mongod output]" file-stream-processor)
(NamedOutputStreamProcessor. "[mongod error]" file-stream-processor)
(NamedOutputStreamProcessor. "[mongod commands]" file-stream-processor)))
(def runtime-config
(-> (RuntimeConfigBuilder.)
(.defaults Command/MongoD)
(.processOutput logger)
(.build)))
(defn- parse-version [v]
(try
(Version/valueOf v)
(catch IllegalArgumentException e
(Versions/withFeatures (reify IVersion (asInDownloadPath [_] v)) (make-array Feature 0)))))
(defn start-mongo [version port data-dir]
(.. MongodStarter
(getInstance runtime-config)
(prepare (.. (MongodConfigBuilder.)
(version (parse-version version))
(net (Net. "localhost" port (Network/localhostIsIPv6)))
(replication (Storage. data-dir nil 0)) (build)))
(start)))
(ns dev-database
(:require [com.stuartsierra.component :refer [Lifecycle]]
[embed-mongo :refer [start-mongo]]
[monger.core :as mg]
[monger.collection :as mc]
[monger.db :as mb]
[taoensso.timbre :refer [info]]
[my-ns.util :refer [clear-keys]]
))
(defrecord MongoEmbedded [version port data-dir db-name]
Lifecycle
(start [this]
(when-not (:mongod this)
(info "Starting dev database.")
(let [mongod (start-mongo version port data-dir)
conn (mg/connect {:port port})
db (mg/get-db conn db-name)
]
(assoc this
:mongod mongod
:connection conn
:db db))))
(stop [this]
(when-let [mongod (:mongod this)]
(info "Stopping dev database.")
(let [{:keys [connection db]} this
collections (mb/get-collection-names db)]
(doseq [coll collections]
(mc/remove db coll))
(mg/disconnect connection)
(.stop mongod)
(clear-keys this :mongod :connection :db)))))
(defn mongodb [config]
(let [{version :db-version
port :db-port
data-dir :db-data-dir
db-name :db-name} config]
(->MongoEmbedded version (Integer. port) data-dir db-name)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment