Schema Cartographer provides a means to visualize, navigate, create, edit and share the relationships that exist in your Datomic schema.
To generate a schema file loadable by the application, the following script is provided:
clojure -m cli.core -h
Schema Cartographer Schema Export:
Usage: clojure -m server.core [options]
Options:
-r, --region REGION Region where Datomic cloud is located
-s, --system SYSTEM Datomic cloud system name
-d, --db DATABASE Database Name
-o, --output FILE Write schema edn to FILE
-a, --audit Audit schema annotations and log gaps. Boolean
-h, --help
clojure -m cli.core -r "us-east-1" -s "my-system" -d "ice-cream-shop" -o "ice-cream-shop-schema"
The resulting schema file is saved to the /doc
directory
To ensure your schema is properly annotated run the audit script. This will identify missing namespaces, references, etc.
clojure -m cli.core -r "us-east-1" -s "my-system" -d "ice-cream-shop" --audit
The results are logged to the console.
bin/kaocha clj-unit
A statically hosted version of the application can be found at https://c-132.com/schema-cartographer
- Install application deps:
yarn install
- Install sass:
(cd src/sass && yarn install && yarn css)
- Start application:
clojure -Acljs-dev
- App will be running at
http://localhost:9875/#/
clj -A:cljs-test
Then visit:
http://localhost:8021/
Stylesheet source files are located in /src/sass
and are written in Sass .scss
syntax.
Stylesheet Development:
# Install dependencies
cd src/sass
yarn install
# Compile CSS once, while in /sass dir
yarn css
# Compile and watch, while in /sass dir
yarn watch:css
(cd src/sass && yarn css)
clojure -Acljs-min
- The app will be in
resources/public/
Per the documentation "Datomic Schema is stored as data, you can and should annotate your schema elements with useful information". Those useful annotations can enable many things. This particular application uses annotations to build a visualization of the structure and relationships between schema elements.
By creating attrs that are designated as a entity
or enumeration
grouping. We can provide documentation related to the intended usage and attributes of the group that
have :db/ident
's which share the same namespace. This information can be leveraged to create a very traditional feeling relational data like visualization of the schema.
The annotations used by the application are:
(def annotation-schema-tx [{:db/ident :cartographer/entity
:db/valueType :db.type/keyword
:db/unique :db.unique/identity
:db/cardinality :db.cardinality/one
:db/doc "Creating an entity with this attr will cause its value to be considered an entity-grouping namespace in the application."}
{:db/ident :cartographer/enumeration
:db/unique :db.unique/identity
:db/valueType :db.type/keyword
:db/cardinality :db.cardinality/one
:db/doc "Creating an entity with this attr will cause its value to be considered an enumeration-grouping namespace in the application."}
{:db/ident :cartographer/deprecated?
:db/valueType :db.type/boolean
:db/cardinality :db.cardinality/one
:db/doc "Boolean flag indicating the field has been deprecated."}
{:db/ident :cartographer/replaced-by
:db/valueType :db.type/ref
:db/cardinality :db.cardinality/many
:db/doc "Used to document when a deprecated field is replaced by other."}
{:db/ident :cartographer/references-namespaces
:db/valueType :db.type/ref
:db/cardinality :db.cardinality/many
:db/doc "Used to indicate which specific :cartographer/entity or :cartographer/enumeration are intended to be referenced by :db.type/ref"}
{:db/ident :cartographer/validates-namespace
:db/valueType :db.type/ref
:db/cardinality :db.cardinality/one
:db/doc "Used to indicate which specific :cartographer/entity is intended to be validated by :db.type/ref"}])
By adhering to a convention of creating a :cartographer/entity
with a value of :store
.
We can then conclude all attrs with a :db/ident
having a keyword with the namespace store
will be grouped together in the application.
;; == Create a 'grouping' of 'store'
{:cartographer/entity :store
:db/doc "An entity representing an individual ice cream store"}
;; == The following elements all have idents with a keyword namespace of 'store' and will be grouped together
{:db/ident :store/id
:db/valueType :db.type/uuid
:db/cardinality :db.cardinality/one
:db/unique :db.unique/identity
:db/doc "Unique id assigned to each store"}
{:db/ident :store/address
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one
:db/doc "Street address of a specific store location"}
{:db/ident :store/employees
:db/valueType :db.type/ref
:db/cardinality :db.cardinality/many
:db/doc "Employees who may work at a given store"
:cartographer/references-namespaces ["employee"]} ;; Specifies a specific entity that is referenced
By adhering to a convention of creating a :cartographer/enumeration
with a value of :ice-cream-flavor
.
We can then conclude all attrs with a :db/ident
having a keyword with the namespace ice-cream-flavor
will be grouped together in the application.
;; == Create a 'grouping' of 'ice-cream-flavor'
{:cartographer/enumeration :ice-cream-flavor
:db/doc "Ice cream flavor options, currently available in store."}
;; == The following enumerations all have idents with a keyword namespace of 'ice-cream-flavor' and will be grouped together
{:db/ident :ice-cream-flavor/strawberry}
{:db/ident :ice-cream-flavor/chocolate}
{:db/ident :ice-cream-flavor/vanilla}
Create a connection to a new Datomic database and transact the following example schema. This will provide a complete fully annotated schema suitable to experiment with the application and for use as a reference.
Copyright © 2019 Jarrod Taylor
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.