Skip to content

Instantly share code, notes, and snippets.

@ichramm
Last active September 16, 2022 14:22
Show Gist options
  • Save ichramm/793fa5515da7b02adc7e0e58e09d4082 to your computer and use it in GitHub Desktop.
Save ichramm/793fa5515da7b02adc7e0e58e09d4082 to your computer and use it in GitHub Desktop.
datomic registry
(ns components.datomic-registry.service
(:require [datomic.api :as d]
[components.lifecycle.protocol :as lifecycle]
[components.datomic.service :refer [make-uri]]
[components.datomic-registry.protocol :as protocol]))
(defrecord DatomicRegistryService [db ns-name state]
lifecycle/Lifecycle
(start [this system]
(let [db (lifecycle/handler db)
id-field (keyword (name ns-name) "id")
dbs (->> (d/q [:find '?c :in '$ :where
['?c id-field]]
(d/db db))
(map first)
(map (partial d/entity (d/db db)))
;; remove namespace from attribute names
(map #(reduce-kv (fn [m k v]
(assoc m (keyword (name k)) v)) {} %))
; index by id
(map (juxt :id identity))
(into {}))]
(swap! state assoc :registry dbs)))
(stop [this system]
(doseq [conn (keep (comp :datomic second) (:registry @state))]
(d/release conn)))
lifecycle/Service
(handler [this]
this) ; to avoid any confusion
protocol/Registry
(get-db [this db-id]
(let [m (swap! state
(fn [current-state]
(if-let [db-reg (get-in current-state [:registry db-id])]
(if (nil? (:datomic db-reg))
(assoc-in current-state
[:registry db-id :datomic]
(d/connect (make-uri (:driver db-reg)
db-reg)))
;; already connected
current-state)
;; unknown database
current-state)))]
(get m [:registry db-id :datomic]))))
(defn make [db ns-name]
"Creates a service instance. Entities should have the follwing attributes:
- :<ns-name>/driver (one of #{:postgres :sql-server :cassandra :mem})
- :<ns-name>/id (keyword)
- :<ns-name>/db (string)
- :<ns-name>/host (string)
- :<ns-name>/port (long)
- :<ns-name>/user (string)
- :<ns-name>/password (string)"
(->DatomicRegistryService db ns-name (atom {})))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment