Skip to content

ivarref/datomic-schema

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

53 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

datomic-schema

Simplified writing of Datomic schemas.

Installation

Clojars Project

Add [ivarref/datomic-schema "0.2.0"] to your dependency vector.

Syntax

The syntax is

#d/schema[[attribute-name cardinality? type toggles* docstring?]*]

attribute-name = The name of your attribute
cardinality    = :one or :many. Defaults to :one
type           = A type from the list below
toggles        = Zero or more toggles
docstring      = An optional documentation string

type           = :bigdec
               | :bigint
               | :boolean
               | :bytes
               | :double
               | :float
               | :instant
               | :keyword
               | :long
               | :ref
               | :string
               | :symbol
               | :uri
               | :uuid
               | tuple-type

tuple-type     = Composite tuple: a 2-8 length vector referring other attributes
               | Heterogeneous fixed length tuples: a 2-8 length vector referring scalar types such as :long, :string, etc.
               | Homogeneous variable length tuples: a 1 length vector referring a single scalar type.

toggles        = :component
               | :fulltext
               | :id         ; alias for :identity
               | :identity
               | :index
               | :indexed    ; alias for :index
               | :no-history
               | :unique

Enums are also supported: #d/schema [[attribute-name :enum]]

Example usage from REPL

(require 'datomic-schema.core) ; namespace needs to be required so that reader literal is loaded

#d/schema [[:entity/attr :one :string "Documentation"]]
=> [#:db{:ident       :entity/attr
         :cardinality :db.cardinality/one
         :valueType   :db.type/string
         :doc         "Documentation"}]

#d/schema [[:entity/attr :string]] ; default cardinality is :one
=> [#:db{:ident       :entity/attr
         :cardinality :db.cardinality/one
         :valueType   :db.type/string}]

#d/schema [[:entity/attr :many :long]] ; cardinality :many
=> [#:db{:ident       :entity/attr
         :cardinality :db.cardinality/many
         :valueType   :db.type/long}]

#d/schema [[:entity/id :uuid :id]] ; use :id toggle for :db.unique/identity
=> [#:db{:ident       :entity/id
         :cardinality :db.cardinality/one
         :valueType   :db.type/uuid
         :unique      :db.unique/identity}]

#d/schema [[:e/id :uuid :id]
           [:e/info :string]] ; multiple attribute definitions
=> [#:db{:ident :e/id   :cardinality :db.cardinality/one :valueType :db.type/uuid :unique :db.unique/identity}
    #:db{:ident :e/info :cardinality :db.cardinality/one :valueType :db.type/string}]

#d/schema [[:entity/attr :enum]] ; enums
=> [#:db{:ident :entity/attr}]

and so forth.

Example usage with conformity

In order to use this library with conformity, you will need to require the namespace so that the reader literal is loaded before conformity runs.

Add the following file to resources/:

;; resources/something.edn
{:my-project/something-schema
 {:txes [#d/schema[[:something/title :one :string]
                   [:something/author :one :uuid]]]}}

Then in your code:

(ns my-project.something
  (:require [datomic-schema.core] ; namespace needs to be required so that reader literal is loaded
            [io.rkn.conformity :as c]
            [datomic.api :as d]))

(def uri "datomic:mem://my-project")
(d/create-database uri)
(def conn (d/connect uri))

(def norms-map (c/read-resource "something.edn"))

(println (str "Has attribute? " (c/has-attribute? (d/db conn) :something/title)))
(c/ensure-conforms conn norms-map [:my-project/something-schema])
(println (str "Has attribute? " (c/has-attribute? (d/db conn) :something/title)))

Example development usage

(ns dato-ivre.dev-demo
  (:require [datomic.api :as d]
            [datomic-schema.core])) ; namespace needs to be required so that reader literal is loaded

(defn create-empty-in-memory-db []
  (let [uri "datomic:mem://pet-owners-test-db"]
    (d/delete-database uri)
    (d/create-database uri)
    (let [conn (d/connect uri)]
      conn)))

(def conn (create-empty-in-memory-db))

@(d/transact conn #d/schema[[:m/id :string :id]
                            [:m/info :string]])

@(d/transact conn [{:m/id "id1" :m/info "Hello"}]) ; upsert (insert)

@(d/transact conn [{:m/id "id1" :m/info "Hello2"}]) ; upsert (update)

(println (d/pull (d/db conn) '[:*] [:m/id "id1"]))
; {:db/id 17592186045418, :m/id id1, :m/info Hello2}

Acknowledgements

This project is derived from cognitect-labs/vase. Please see their LICENSE.

License

Copyright © 2015-2017 Cognitect, Inc. All rights reserved.

Copyright © 2018-2020 Ivar Refsdal.

Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.

About

Simplified writing of Datomic schemas.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published