diff --git a/src/com/ashafa/clutch.clj b/src/com/ashafa/clutch.clj index ff8f64e..11f2788 100644 --- a/src/com/ashafa/clutch.clj +++ b/src/com/ashafa/clutch.clj @@ -342,21 +342,33 @@ (defmacro view-server-fns [options fns] - (let [[language options] (if (map? options) - [(or (:language options) :javascript) (dissoc options :language)] - [options])] - [(:language (view-transformer language)) - `(#'map-leaves ((:compiler (view-transformer ~language)) ~options) '~fns)])) + (let [[view-opts options] (if (map? options) + [{:language (or (:language options) :javascript) + :code-version (:code-version options)} + (dissoc options :language :code-version)] + [{:language options}])] + [{:language (:language (view-transformer (:language view-opts))) + :code-version (:code-version view-opts)} + `(#'map-leaves ((:compiler (view-transformer ~(:language view-opts))) ~options) '~fns)])) (defdbop save-design-document "Create/update a design document containing functions used for database queries/filtering/validation/etc." - [db fn-type design-document-name [language view-server-fns]] + [db fn-type design-document-name [view-opts view-server-fns]] (let [design-doc-id (str "_design/" design-document-name) - ddoc {fn-type view-server-fns - :language (name language)}] + code-version (:code-version view-opts) + ddoc- {fn-type view-server-fns + :language (name (:language view-opts))} + ddoc (if code-version + (assoc ddoc- :code-version code-version) + ddoc-)] (if-let [design-doc (get-document db design-doc-id)] - (update-document db design-doc merge ddoc) + (if (or (not (:code-version design-doc)) + (and code-version + (:code-version design-doc) + (> code-version (:code-version design-doc)))) + (update-document db design-doc merge ddoc) + design-doc) (put-document db (assoc ddoc :_id design-doc-id))))) (defdbop save-view @@ -405,8 +417,8 @@ "One-off queries (i.e. views you don't want to save in the CouchDB database). Ad-hoc views should be used only during development. Also takes an optional map for querying options (see: http://wiki.apache.org/couchdb/HTTP_view_API)." - [db [language view-server-fns] & [query-params-map]] - (get-view* db ["_temp_view"] query-params-map (into {:language language} view-server-fns))) + [db [view-opts view-server-fns] & [query-params-map]] + (get-view* db ["_temp_view"] query-params-map (into {:language (:language view-opts)} view-server-fns))) (defdbop bulk-update "Takes a sequential collection of documents (maps) and inserts or updates (if \"_id\" and \"_rev\" keys diff --git a/test/test_clutch.clj b/test/test_clutch.clj index 0797412..a6d478d 100644 --- a/test/test_clutch.clj +++ b/test/test_clutch.clj @@ -269,6 +269,102 @@ {:map #(if (> (:score %) 70) [[nil (:name %)]])}}))] (is (map? (-> (get-document (view-document :_id)) :views :names-with-score-over-70)))))) +(defdbtest create-a-versioned-design-view + (when *clj-view-svr-config* + (let [view-document (save-view "users" + (view-server-fns + {:language view-server-name + :code-version 1} + {:names-with-score-over-70 + {:map #(if (> (:score %) 70) [[nil (:name %)]])}})) + test-view (get-document (view-document :_id))] + (is (map? (-> test-view :views :names-with-score-over-70))) + (is (= 1 (-> test-view :code-version)))))) + +(defdbtest update-a-versioned-design-view + (when *clj-view-svr-config* + (let [view-document (save-view "users" + (view-server-fns + {:language view-server-name + :code-version 1} + {:names-with-score-over-70 + {:map #(if (> (:score %) 70) [[nil (:name %)]])}})) + test-view (get-document (view-document :_id))] + (is (map? (-> test-view :views :names-with-score-over-70))) + (is (= 1 (-> test-view :code-version)))) + (let [updated-doc (save-view "users" + (view-server-fns + {:language view-server-name + :code-version 2} + {:names-with-score-over-60 + {:map #(if (> (:score %) 60) [[nil (:name %)]])}})) + test-updated (get-document (updated-doc :_id))] + (is (map? (-> test-updated :views :names-with-score-over-60))) + (is (= 2 (-> test-updated :code-version)))))) + +(defdbtest change-to-a-versioned-design-view + (when *clj-view-svr-config* + (let [view-document (save-view "users" + (view-server-fns + view-server-name + {:names-with-score-over-70 + {:map #(if (> (:score %) 70) [[nil (:name %)]])}})) + test-view (get-document (view-document :_id))] + (is (map? (-> test-view :views :names-with-score-over-70))) + (is (not (-> test-view :code-version)))) + (let [updated-doc (save-view "users" + (view-server-fns + {:language view-server-name + :code-version 1} + {:names-with-score-over-60 + {:map #(if (> (:score %) 60) [[nil (:name %)]])}})) + test-updated (get-document (updated-doc :_id))] + (is (map? (-> test-updated :views :names-with-score-over-60))) + (is (= 1 (-> test-updated :code-version)))))) + +(defdbtest fail-to-downdate-a-versioned-design-view + (when *clj-view-svr-config* + (let [view-document (save-view "users" + (view-server-fns + {:language view-server-name + :code-version 2} + {:names-with-score-over-70 + {:map #(if (> (:score %) 70) [[nil (:name %)]])}})) + test-view (get-document (view-document :_id))] + (is (map? (-> test-view :views :names-with-score-over-70))) + (is (= 2 (-> test-view :code-version)))) + (let [updated-doc (save-view "users" + (view-server-fns + {:language view-server-name + :code-version 1} + {:names-with-score-over-60 + {:map #(if (> (:score %) 60) [[nil (:name %)]])}})) + test-updated (get-document (updated-doc :_id))] + (is (map? (-> test-updated :views :names-with-score-over-70))) + (is (not (-> test-updated :views :names-with-socre-over-60))) + (is (= 2 (-> test-updated :code-version)))))) + +(defdbtest fail-to-unversion-a-versioned-design-view + (when *clj-view-svr-config* + (let [view-document (save-view "users" + (view-server-fns + {:language view-server-name + :code-version 1} + {:names-with-score-over-70 + {:map #(if (> (:score %) 70) [[nil (:name %)]])}})) + test-view (get-document (view-document :_id))] + (is (map? (-> test-view :views :names-with-score-over-70))) + (is (= 1 (-> test-view :code-version)))) + (let [updated-doc (save-view "users" + (view-server-fns + view-server-name + {:names-with-score-over-60 + {:map #(if (> (:score %) 60) [[nil (:name %)]])}})) + test-updated (get-document (updated-doc :_id))] + (is (map? (-> test-updated :views :names-with-score-over-70))) + (is (not (-> test-updated :views :names-with-socre-over-60))) + (is (= 1 (-> test-updated :code-version)))))) + (defdbtest use-a-design-view-with-spaces-in-key (when *clj-view-svr-config* (put-document test-document-1)