spec for datomic/datascript
bamarco opened this issue · comments
Eventually this will either be replaced or put into datscript/datomic themselves, but getting it started here.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ### spec - datomic schema
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(s/def :datomic.db.valueType #{:db.type/string :db.type/boolean :db.type/long :db.type/bigint :db.type/float :db.type/double :db.type/bigdec :db.type/ref :db.type/instant :db.type/uuid :db.type/uri :db.type/bytes})
(s/def :datomic.db.ident keyword?)
(s/def :datomic.db.cardinality #{:db.cardinality/one :db.cardinality/many})
(s/def :datomic.db.doc string?)
(s/def :datomic.db.unique #{:db.unique/value :db.unique/identity})
(s/def :datomic.db.index boolean?)
(s/def :datomic.db.fulltext boolean?)
(s/def :datomic.db.isComponent boolean?)
(s/def :datomic.db.noHistory boolean?)
(s/def :datomic.db.schema (s/keys :req-un [:datomic.db.valueType :datomic.db.ident :datomic.db.cardinality]
:opt-un [:datomic.db.doc :datomic.db.unique :datomic.db.index :datomic.db.fulltext :datomic.db.isComponent :datomic.db.noHistory]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ### spec - db not part of schema
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(s/def :datomic.db.id integer?)
(s/def :datomic.db.lookup-ref (s/tuple :datomic.db.ident :datomic.db.id))
(s/def :datomic.db.type.string string?)
(s/def :datomic.db.type.boolean boolean?)
(s/def :datomic.db.type.long long?)
(s/def :datomic.db.type.bigint bigint?)
(s/def :datomic.db.type.float float?)
(s/def :datomic.db.type.double double?)
(s/def :datomic.db.type.bigdec bigdec?)
(s/def :datomic.db.type.ref (s/or :datomic.db.id :datomic.db.lookup-ref))
(s/def :datomic.db.type.instant instant?)
(s/def :datomic.db.type.uuid uuid?)
(s/def :datomic.db.type.uri uri?)
(s/def :datomic.db.type.bytes bytes?)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ### spec - pull
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defn strymbol= [strymbol-a strymbol-b]
(= (str strymbol-a) (str strymbol-b)))
(defn positive? [number]
(> number 0))
(defonce any? (contantly true))
(s/def :datomic.pull.recursion-limit (s/or positive? (partial = '...)))
(s/def :datomic.pull.default-expr (s/tuple (partial strymbol 'default) :datomic.pull.attr-name any?))
(s/def :datomic.pull.limit-expr (s/tuple (partial strymbol= 'limit) :datomic.pull.attr-name (s/nilable positive?)))
(s/def :datomic.pull.att-expr (s/or :datomic.pull.limit-expr :datomic.pull.default-expr))
(s/def :datomic.pull.map-spec (s/map-of (s/or :datomic.pull.attr-name :datomic.pull.limit-expr) (s/coll-of (s/+ (s/or :datomic.pull.pattern :datomic.pull.recursion-limit)))))
(s/def :datomic.pull.wildcard (partial strymbol= '*))
(s/def :datomic.pull.attr-name :datomic.db.ident)
(s/def :datomic.pull.attr-spec (s/or :datomic.pull.attr-name :datomic.pull.wildcard :datomic.pull.map-spec :datomic.pull.attr-expr))
(s/def :datomic.pull.pattern (s/coll-of :datomic.pull.attr-spec))
;;(defn pull [pattern eid])
(s/fdef pull
:args (s/cat :pattern :datomic.pull.pattern
:eid :datomic.db.type.ref))
That's great! So are you going to try to tackle q
as well? Tonskey has a parser in DataScript you could use to make sure it's right.
Perhaps a side question, but I'm curious how y'all would spec a posh'd connection.
Right now my answer is this, curious if there is a smarter way
(def posh? #(-> %
meta
:listeners
deref
:posh-listener
))
(s/def ::posh-conn posh?)
(s/def :datomic.db.ident keyword?)
CompilerException java.lang.AssertionError: Assert failed: k must be namespaced keyword or resolvable symbol
(c/and (ident? k) (namespace k)), compiling:(form-init6481213635829195379.clj:1:1)
(s/def :datomic.db/ident keyword?)
=> :datomic.db/ident