Skip to content

Commit

Permalink
feat: sort schemas topologically
Browse files Browse the repository at this point in the history
  • Loading branch information
krvital committed Sep 26, 2024
1 parent 62493fb commit c19c799
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 2 deletions.
33 changes: 33 additions & 0 deletions src/aidbox_sdk/converter.clj
Original file line number Diff line number Diff line change
Expand Up @@ -359,3 +359,36 @@

result
constraint-schemas))))))

;;
;; Topological Sorting of IR Schemas
;;

(defn- build-dependency-graph [schemas]
(let [name->map (reduce (fn [acc v] (assoc acc (:url v) v)) schemas)]
(reduce (fn [graph {:keys [url base]}]
(if (and base (contains? name->map base))
(update graph url conj base)
graph))
(zipmap (map :url schemas) (repeat #{}))
schemas)))

(defn- topological-sort
"https://en.wikipedia.org/wiki/Topological_sorting"
[graph]
(when (seq graph)
(when-let [depless (keep (fn [[k v]] (when (empty? v) k)) graph)]
(concat depless
(topological-sort
(into {}
(map (fn [[k v]] [k (apply disj v depless)]))
(apply dissoc graph depless)))))))

(defn sort-by-base
"Sorts IR schemas by base class in topological order.
This ensures that base classes are generated before their inheriting classes."
[ir-schemas]
(->> ir-schemas
build-dependency-graph
topological-sort
(map (fn [url] (fhir/find-by-url url ir-schemas)))))
7 changes: 5 additions & 2 deletions src/aidbox_sdk/core.clj
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
:typescript typescript/generator
:java java/generator))


(defn generate! [target-language input options]
(let [output-dir (io/file (:output-dir options))
save-files! #(save-files! output-dir %)
Expand Down Expand Up @@ -95,8 +96,10 @@
(println "---")

(println "Generating datatypes")
(save-files! (generator/generate-datatypes generator' (into base-ir-schemas
datatype-ir-schemas)))
(save-files! (generator/generate-datatypes
generator'
(converter/sort-by-base
(into base-ir-schemas datatype-ir-schemas))))

(println "Generating resources")
(save-files! (map generate-resource-module resource-ir-schemas))
Expand Down
5 changes: 5 additions & 0 deletions src/aidbox_sdk/fhir.clj
Original file line number Diff line number Diff line change
Expand Up @@ -150,3 +150,8 @@
(defmethod primitive-element? "hl7.fhir.r4b.core" [_ {:keys [type]}] (contains? r4b-primitive-types type))
(defmethod primitive-element? "hl7.fhir.r5.core" [_ {:keys [type]}] (contains? r5-primitive-types type))
(defmethod primitive-element? :default [_ _] false)

(defn filter-by-url [url schemas]
(filter #(= url (:url %)) schemas))

(def find-by-url (comp first filter-by-url))
13 changes: 13 additions & 0 deletions test/aidbox_sdk/converter_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,19 @@
(sut/convert-constraints fixtures/observation-constraints
[fixtures/observation-ir-schema])))))

(deftest test-sort-by-base
(match
(sut/sort-by-base
[{:url "http://hl7.org/fhir/StructureDefinition/Resource" :base nil}
{:url "http://hl7.org/fhir/StructureDefinition/Element" :base nil}
{:url "http://hl7.org/fhir/StructureDefinition/SampledData"
:base "http://hl7.org/fhir/StructureDefinition/Element"}])

[{:url "http://hl7.org/fhir/StructureDefinition/Resource", :base nil}
{:url "http://hl7.org/fhir/StructureDefinition/Element", :base nil}
{:url "http://hl7.org/fhir/StructureDefinition/SampledData",
:base "http://hl7.org/fhir/StructureDefinition/Element"}]))

(comment
(fixt/load-data!)

Expand Down

0 comments on commit c19c799

Please sign in to comment.