Skip to content

Instantly share code, notes, and snippets.

@narma
Last active January 27, 2016 13:13
Show Gist options
  • Save narma/b44bd93be44bc213976a to your computer and use it in GitHub Desktop.
Save narma/b44bd93be44bc213976a to your computer and use it in GitHub Desktop.
Convert json dump or just regular data to seq for `d/transact!`
(ns datascript-utils
(:require [datascript :as d]))
(defn data->datoms [prefix json]
(let [make-prefix
(fn [p]
(let [[full short]
(re-matches #"(.+?)s?$" p)]
short))]
(loop [current json
data-rest []
ctx [{:prefix (make-prefix prefix)
:id (d/tempid :db.part/user)}]
acc []]
(cond
(and (empty? current) (empty? data-rest))
acc
(empty? current)
(recur (first data-rest) (rest data-rest)
(if (sequential? current)
(pop ctx)
(conj (pop ctx) (assoc (peek ctx) :id (d/tempid :db.part/user))))
(if (and (map? current)
(-> (count ctx) (> 1)))
(let [ictx (peek ctx)
pctx
(nth ctx (- (count ctx) 2))]
(conj acc [:db/add
(:id pctx)
(-> (:prefix pctx)
(str "/" (:prefix ictx) "s")
keyword)
(:id ictx)]))
acc))
(map? current)
(let [k (first (keys current))
v (get current k)
ictx (peek ctx)]
(if (sequential? v)
(recur v
(conj data-rest (dissoc current k))
(conj ctx {:id (d/tempid :db.part/user)
:prefix (make-prefix k)
})
acc)
(recur (dissoc current k)
data-rest
ctx
(conj acc [:db/add (:id ictx)
(keyword (str (:prefix ictx) "/" k))
v]))))
(sequential? current)
(recur (first current)
(cons (rest current) data-rest)
ctx
acc)))))
(def data [{"id" 15
"name" "Henry"
"pets" [{"id" 2
"name" "Rocky"
"type" "dog"
"toys" [{"id" 55
"name" "bone"
}
{"id" 41
"name" "Sammy"
}]
}
{"id" 4
"name" "Sammy"
"type" "cat"
"toys" []
}]
}])
(data->datoms "household" data)
;; => will produce
[[:db/add -1000199 :household/id 15]
[:db/add -1000199 :household/name "Henry"]
[:db/add -1000200 :pet/id 2]
[:db/add -1000200 :pet/name "Rocky"]
[:db/add -1000200 :pet/type "dog"]
[:db/add -1000201 :toy/id 55]
[:db/add -1000201 :toy/name "bone"]
[:db/add -1000200 :pet/toys -1000201]
[:db/add -1000202 :toy/id 41]
[:db/add -1000202 :toy/name "Sammy"]
[:db/add -1000200 :pet/toys -1000202]
[:db/add -1000199 :household/pets -1000200]
[:db/add -1000204 :pet/id 4]
[:db/add -1000204 :pet/name "Sammy"]
[:db/add -1000204 :pet/type "cat"]
[:db/add -1000199 :household/pets -1000204]]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment