datascript

m3tti 2024-06-12T20:22:49.721469Z

Hi guys is there a way to use datascript with datomic schemas?

2024-06-13T12:17:04.523709Z

It requires a little massaging of the datomic schema, but yes.

2024-06-13T12:19:14.811449Z

You only want to include a :db/valueType for things that are refs or tuples. Other than that, datascript will accept a datomic schema as-is.

2024-06-13T12:19:54.740229Z

(Possible that I'm missing some other small diff, but that's all I do to get my datomic schema into datascript.)

rjsheperd 2024-06-13T23:02:28.790709Z

We end up using Datomic/DataScript with a shared schema.cljc file. To convert it from Datomic to DataScript, we end doing the following:

(defn- keep-key
  [m k valid-vals]
  (if (contains? valid-vals (get m k))
    m
    (dissoc m k)))

(defn- simplify-schema [schema]
  (-> schema
      (select-keys [:db/ident :db/valueType :db/index :db/unique :db/cardinality :db/tupleAttrs :db/isComponent])
      (keep-key :db/valueType #{:db.type/ref :db.type/tuple})
      (keep-key :db/cardinality #{:db.cardinality/many})))

(defn- required-schema? [schema]
  (or (:db/index schema)
      (:db/unique schema)
      (= (:db/cardinality schema) :db.cardinality/many)
      (#{:db.type/ref :db.type/tuple} (:db/valueType schema))))

(defn datomic->datascript-schema
  "Converts a Datomic Schema to DataScript."
  [datomic-schema]
  (->> datomic-schema
       (filter required-schema?)
       (map simplify-schema)
       (reduce (fn [acc cur] (assoc acc
                                    (:db/ident cur)
                                    (dissoc cur :db/ident)))
               {})))
This ends up producing a DataScript schema, which is basically a map of attributes to their properties. I will also just mention: there are some fun type conversions that you'll want to look out for (particularly java.Long).