From c4944ee8e75f363012a38159b53bbf0d1523e4f7 Mon Sep 17 00:00:00 2001 From: gered Date: Fri, 4 Jul 2014 10:54:19 -0400 Subject: [PATCH] improve search parameter handling. add support for namespaced values --- src/clj_hl7_fhir/core.clj | 75 +++++++++++++++++++++++++++------------ 1 file changed, 53 insertions(+), 22 deletions(-) diff --git a/src/clj_hl7_fhir/core.clj b/src/clj_hl7_fhir/core.clj index 30a4d58..cb9c74f 100644 --- a/src/clj_hl7_fhir/core.clj +++ b/src/clj_hl7_fhir/core.clj @@ -19,36 +19,26 @@ :body (json/parse-string true)))) -(defn- format-search-value [x] - (-> (cond - (instance? Date x) (->iso-date x) - :else (str x)) - (.replace "\\" "\\\\") - (.replace "$" "\\$") - (.replace "," "\\,") - (.replace "|" "\\|"))) - -(defn- make-search-param-name [parameter & [modifier]] +(defn- ->search-param-name [parameter & [modifier]] (keyword (str (name parameter) (if modifier (str ":" (name modifier)))))) +(defn ->search-param-descriptor [parameter value operator {:keys [modifier]}] + {:name (->search-param-name parameter modifier) + :operator operator + :value value}) + (defmacro single-search-op [name operator] - `(defn ~name [parameter# value# & {:keys [modifier#]}] - [(make-search-param-name parameter# modifier#) - (str (if-not (= "=" ~operator) ~operator) - (format-search-value value#))])) + `(defn ~name [parameter# value# & options#] + [(->search-param-descriptor parameter# value# ~operator (apply hash-map options#))])) (defmacro double-search-op [name operator1 operator2] - `(defn ~name [parameter# value1# value2# & {:keys [modifier#]}] - [(make-search-param-name parameter# modifier#) - (str (if-not (= "=" ~operator1) ~operator1) - (format-search-value value1#)) - (make-search-param-name parameter# modifier#) - (str (if-not (= "=" ~operator2) ~operator2) - (format-search-value value2#))])) + `(defn ~name [parameter# value1# value2# & options#] + [(->search-param-descriptor parameter# value1# ~operator1 (apply hash-map options#)) + (->search-param-descriptor parameter# value2# ~operator2 (apply hash-map options#))])) (single-search-op eq "=") (single-search-op lt "<") @@ -57,6 +47,47 @@ (single-search-op gte ">=") (double-search-op between ">" "<") +(defn namespaced + ([value] + (namespaced nil value)) + ([namespace value] + {:namespace namespace + :value value})) + +(defn- escape-parameter [value] + (-> value + (.replace "\\" "\\\\") + (.replace "$" "\\$") + (.replace "," "\\,") + (.replace "|" "\\|"))) + +(defn- format-search-value [value] + (cond + (sequential? value) + (->> value + (map format-search-value) + (str/join ",")) + + (map? value) + (str (:namespace value) "|" (format-search-value (:value value))) + + (instance? Date value) + (->iso-date value) + + :else + (-> value str escape-parameter))) + +(defn- search-params->query-kvs [params] + (->> params + (apply concat) + (map + (fn [{:keys [name operator value]}] + [name + (str + (if-not (= "=" operator) operator) + (format-search-value value))])) + (apply concat))) + (defn get-resource "gets a single resource from a FHIR server. can optionally get a specific version of a resource. @@ -98,5 +129,5 @@ (fhir-get-request base-url (apply join-paths url-components) - (apply concat params)))) + (search-params->query-kvs params))))