From a5e00ddcf1008383601c09359691a9fdcf38899f Mon Sep 17 00:00:00 2001 From: Daniel Petranek Date: Mon, 20 Jan 2025 14:08:05 -0600 Subject: [PATCH] add support for empty result set with selectOne --- src/fluree/server/handler.clj | 12 +++++- .../server/integration/basic_query_test.clj | 42 ++++++++++++------- 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/src/fluree/server/handler.clj b/src/fluree/server/handler.clj index 1d9a3db2..451f2154 100644 --- a/src/fluree/server/handler.clj +++ b/src/fluree/server/handler.clj @@ -93,7 +93,7 @@ (def QueryResponse (m/schema [:orn [:select [:sequential [:or coll? map?]]] - [:select-one [:or coll? map?]]])) + [:select-one [:or coll? map? nil? [:enum "null"]]]])) (def HistoryQuery (m/schema (fqh/history-query-schema [[:from LedgerAlias]]) @@ -248,6 +248,15 @@ (handler req*)))) (handler req))))) +(def wrap-no-result + "Handle a nil response from a selectOne query with no results." + (fn [handler] + (fn [req] + (let [{:keys [status body] :as result} (handler req)] + (if (and (= 200 status) (nil? body)) + (assoc result :body "null") + result))))) + (defn wrap-set-fuel-header [handler] (fn [req] @@ -361,6 +370,7 @@ [200 coercion/coerce-exceptions-middleware] [300 coercion/coerce-response-middleware] [400 coercion/coerce-request-middleware] + [450 wrap-no-result] [500 wrap-policy-metadata] [600 (wrap-closed-mode root-identities closed-mode)] [1000 exception-middleware]]))) diff --git a/test/fluree/server/integration/basic_query_test.clj b/test/fluree/server/integration/basic_query_test.clj index 5019a777..a29dfdfc 100644 --- a/test/fluree/server/integration/basic_query_test.clj +++ b/test/fluree/server/integration/basic_query_test.clj @@ -118,21 +118,33 @@ "type" "schema:Test" "ex:name" "query-test"}]}) :headers json-headers} - txn-res (api-post :transact txn-req) - _ (assert (= 200 (:status txn-res))) - query-req {:body - (json/write-value-as-string - {"@context" test-system/default-context - "from" ledger-name - "selectOne" '{?t ["*"]} - "where" '{"id" ?t, "type" "schema:Test"}}) - :headers json-headers} - query-res (api-post :query query-req)] - (is (= 200 (:status query-res))) - (is (= {"id" "ex:query-test" - "type" "schema:Test" - "ex:name" "query-test"} - (-> query-res :body json/read-value))))) + txn-res (api-post :transact txn-req)] + (assert (= 200 (:status txn-res))) + (testing "with result" + (let [query-req {:body + (json/write-value-as-string + {"@context" test-system/default-context + "from" ledger-name + "selectOne" '{?t ["*"]} + "where" '{"id" ?t, "type" "schema:Test"}}) + :headers json-headers} + query-res (api-post :query query-req)] + (is (= 200 (:status query-res))) + (is (= {"id" "ex:query-test" + "type" "schema:Test" + "ex:name" "query-test"} + (-> query-res :body json/read-value))))) + (testing "without result" + (let [query-req {:body + (json/write-value-as-string + {"@context" test-system/default-context + "from" ledger-name + "selectOne" '{?t ["*"]} + "where" '{"id" ?t, "type" "schema:Foo"}}) + :headers json-headers} + query-res (api-post :query query-req)] + (is (= 200 (:status query-res))) + (is (nil? (-> query-res :body json/read-value))))))) (testing "bind query works" (let [ledger-name (create-rand-ledger "query-endpoint-bind-test")