From 90b58cd14179fb4eec6e8a28387fe4eda1397adb Mon Sep 17 00:00:00 2001 From: Daniel Compton Date: Mon, 12 Oct 2015 09:54:45 +1300 Subject: [PATCH] Add `default` query term The default function lets you provide a default value/function when a field or value is null or missing. Fixes #29, fixes #99 --- CHANGELOG.md | 1 + src/rethinkdb/query.cljc | 9 +++++++++ test/rethinkdb/core_test.clj | 9 ++++++++- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 50e235c..846d53a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file. This change - clojure.tools.logging support. [#72](https://github.com/apa512/clj-rethinkdb/pull/72) - `fn` macro to ClojureScript `rethinkdb.query` namespace. [#64](https://github.com/apa512/clj-rethinkdb/issues/64) - `rethinkdb.query/order-by` function to ClojureScript. [#65](https://github.com/apa512/clj-rethinkdb/issues/65) +- `rethinkdb.query/default` function, for supplying a default value/function for missing values. ### Changed - Update dependency to Clojure 1.7. [#59](https://github.com/apa512/clj-rethinkdb/pull/59) diff --git a/src/rethinkdb/query.cljc b/src/rethinkdb/query.cljc index fef7d06..eebf81b 100644 --- a/src/rethinkdb/query.cljc +++ b/src/rethinkdb/query.cljc @@ -781,6 +781,15 @@ ([] (term :ERROR [])) ([s] (term :ERROR [s]))) +(defn default + "Provide a default value in case of non-existence errors. default evaluates its + first argument (the value it’s chained to). If that argument returns null or a + non-existence error is thrown in evaluation, then default returns its second argument. + The second argument is usually a default value, but it can be a RethinkDB function that + returns a value." + [any default] + (term :DEFAULT [any default])) + (defn coerce-to "Convert a value of one type into another." [x s] diff --git a/test/rethinkdb/core_test.clj b/test/rethinkdb/core_test.clj index ae4fd49..6168e17 100644 --- a/test/rethinkdb/core_test.clj +++ b/test/rethinkdb/core_test.clj @@ -113,7 +113,14 @@ (is (= (r/run (-> (r/db test-db) (r/table test-table) (r/filter (r/fn [row] - (r/eq (r/get-field row :name) "Pikachu")))) conn) [(first pokemons)]))))) + (r/eq (r/get-field row :name) "Pikachu")))) conn) [(first pokemons)])) + (is (= 1 (r/run (r/get-field {:a 1} :a) conn)))) + + (testing "default values" + (is (= "not found" (r/run (-> (r/get-field {:a 1} :b) (r/default "not found")) conn))) + (is (= "not found" (r/run (-> (r/max [nil]) (r/default "not found")) conn))) + (is (= "Cannot take the average of an empty stream. (If you passed `avg` a field name, it may be that no elements of the stream had that field.)" + (r/run (-> (r/avg [nil]) (r/default (r/fn [row] row))) conn)))))) (deftest db-in-connection (testing "run a query with an implicit database"