-
Notifications
You must be signed in to change notification settings - Fork 6
/
schema.clj
75 lines (60 loc) · 2.25 KB
/
schema.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
(ns rally.api.schema
(:require [clojure.walk :as walk]
[rally.api :as api]
[rally.api.data :as data]
[rally.api.request :as request]))
(defn- required-attribute? [{:keys [read-only required constrained]}]
(and (not read-only)
required
(not constrained)))
(defn- map-by-element-name [s]
(->> s
(map #(vector (:element-name %) %))
(into {})))
(defn- ->cleanup-schema [m]
(let [transform (fn [[k v]]
(let [new-v (case k
:element-name (data/rally-type->clojure-type v)
:attributes (map-by-element-name v)
v)]
[k new-v]))]
(walk/postwalk (fn [x] (if (map? x) (into {} (map transform x)) x)) m)))
(defn current-schema
([] (current-schema api/*current-user*))
([{:keys [rally] :as rest-api}]
(let [current-project (api/find rest-api (request/get-current-project rest-api))]
;; The schema endpoint ignores page information and gives you the entire result.
(-> (api/query rest-api [:slm :schema (:version rally) :project (str (:object-id current-project))])
->cleanup-schema
map-by-element-name))))
(defn type-def
([type] (type-def api/*current-user* type))
([rest-api type]
(let [schema-for-project (current-schema rest-api)
rally-type (data/clojure-type->rally-type type)]
(get schema-for-project type))))
(defn attribute-def
([type attribute]
(attribute-def api/*current-user* type attribute))
([rest-api type attribute]
(-> (type-def rest-api type)
(get-in [:attributes attribute]))))
(defn filtered-attributes
([type pref]
(filtered-attributes api/*current-user* type pref))
([rest-api type pred]
(->> (type-def rest-api type)
:attributes
vals
(filter pred)
(map :element-name)
sort)))
(defn attribute-names
([type] (attribute-names api/*current-user* type))
([rest-api type]
(filtered-attributes rest-api type (constantly true))))
(defn required-attribute-names
([type]
(required-attribute-names api/*current-user* type))
([rest-api type]
(filtered-attributes rest-api type required-attribute?)))