Skip to content

Instantly share code, notes, and snippets.

@hmaurer
Last active August 30, 2017 20:47
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hmaurer/6ae4142be2bb9dc43f20bb80f079de38 to your computer and use it in GitHub Desktop.
Save hmaurer/6ae4142be2bb9dc43f20bb80f079de38 to your computer and use it in GitHub Desktop.
hello.clj
(ns graph8.core
(:require [datomic.api :as datomic]
[clojure.spec.alpha :as s]
[spec-tools.spec :as spec]
[spec-tools.core :as st]
[clojure.walk :as walk]
wef-backend.schema
spec-tools.impl))
(def attributes-config
{:identity/first-name {}
:identity/last-name {}
:identity/address {:edge-target :node.label/address}
:address/street-address {}})
(def identity-node-config
{:keys {:req [:identity/first-name
:identity/last-name]}})
(def address-node-config
{:keys {:req [:address/street-address]}})
(def config
{:attributes attributes-config
:nodes
{:node.label/identity identity-node-config
:node.label/address address-node-config}})
(defn pull-extra-info
"Pulls information from Datomic about an attribute."
[db attr]
(if-let [entity (datomic/entity db attr)]
(select-keys entity [:db/valueType
:db/isComponent
:db/cardinality])))
(defn validate-ref-attribute
"Validates an attribute which is of type :db.type/ref."
[config attr]
(let [attr-info (get-in config [:attributes attr])]
(when-not (contains? attr-info :edge-target)
(throw (Exception.
(str "Attribute " attr " has value type ref in Datomic"
" and is therefore expected to specify a :edge-target."))))
(when-not (contains? (:nodes config) (:edge-target attr-info))
(throw (Exception.
(str "Target " (:edge-target attr-info) " not found for"
" attribute " attr "."))))))
(defn init-attributes
"Validate the attributes config and merges Datomic schema info."
[config db]
(update config :attributes
#(into {}
(map (fn [[k v]]
(if-let [extra-info (pull-extra-info db k)]
(do
(if (= :db.type/ref (:db/valueType extra-info))
(validate-ref-attribute config k))
[k (merge v extra-info)])
(throw (Exception.
(str "Attribute " k " not present in Datomic.")))))
%))))
(defn init-nodes
"Validates the nodes config."
[config db]
(doseq [[k v] (:nodes config)]
(when (nil? (datomic/entity db k))
(throw (Exception.
(str "Node type " k " not defined in Datomic."))))
(doseq [attr (concat (get-in v [:keys :req]) (get-in v [:keys :opt]))]
(when-not (contains? (:attributes config) attr)
(throw (Exception.
(str "Attribute " attr " listed for node " k
" is not present under :attributes in the config map."))))))
config)
(defn init
"Validates a config and merges in Datomic schema infos."
[db config]
(-> config
(init-attributes db)
(init-nodes db)))
(datomic/create-database "datomic:mem://hello")
(def conn (datomic/connect "datomic:mem://hello"))
@(datomic/transact conn wef-backend.schema/schema)
(init (datomic/db conn) config)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment