Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for search #88

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 27 additions & 17 deletions src/com/ashafa/clutch.clj
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
"Returns a database meta information if it already exists else creates a new database and returns
the meta information for the new database."
[db]
(merge db
(merge db
(or (database-info db)
(and (create-database db)
(database-info db)))))
Expand Down Expand Up @@ -111,14 +111,14 @@
(.length ^File data)
(or filename (.getName ^File data))
(or mime-type (utils/get-mime-type data))]

(instance? InputStream data)
[data (check :data-length data-length) (check :filename filename) (check :mime-type mime-type)]

(= byte-array-class (class data))
[(java.io.ByteArrayInputStream. data) (count data)
(check :filename filename) (check :mime-type mime-type)]

:default
(throw (IllegalArgumentException. (str "Cannot handle attachment data of type " (class data))))))))

Expand Down Expand Up @@ -309,14 +309,24 @@
url
:data (when (seq post-data-map) post-data-map))))

(defn- get-or-search-view*
[action [db design-document view-key & [query-params-map post-data-map :as args]]]
(apply get-view* db
["_design" design-document action (name view-key)]
args))

(defdbop get-view
"Get documents associated with a design document. Also takes an optional map
for querying options, and a second map of {:key [keys]} to be POSTed.
(see: http://wiki.apache.org/couchdb/HTTP_view_API)."
[db design-document view-key & [query-params-map post-data-map :as args]]
(apply get-view* db
["_design" design-document "_view" (name view-key)]
args))
[& args]
(get-or-search-view* "_view" args))

(defdbop search-view
"Search for documents associated with a design document, per CloudAnt search
options: https://cloudant.com/for-developers/search/"
[& args]
(get-or-search-view* "_search" args))

(defdbop all-documents
"Returns the meta (_id and _rev) of all documents in a database. By adding
Expand Down Expand Up @@ -348,14 +358,14 @@
(defdbop put-attachment
"Updates (or creates) the attachment for the given document. `data` can be a string path
to a file, a java.io.File, a byte array, or an InputStream.

If `data` is a byte array or InputStream, you _must_ include the following otherwise-optional
kwargs:

:filename — name to be given to the attachment in the document
:mime-type — type of attachment data

These are derived from a file path or File if not provided. (Mime types are derived from
These are derived from a file path or File if not provided. (Mime types are derived from
filename extensions; see com.ashafa.clutch.utils/get-mime-type for determining mime type
yourself from a File object.)"
[db document data & {:keys [filename mime-type data-length]}]
Expand Down Expand Up @@ -424,7 +434,7 @@
`add-watch` in order to be notified of changes. The
returned change agent is entirely 'managed', with
`start-changes` and `stop-changes` controlling its operation
and sent actions. If you send actions to a change agent,
and sent actions. If you send actions to a change agent,
bad things will likely happen."
[db & {:as opts}]
(agent nil :meta {::changes-config (atom (change-agent-config db opts))}))
Expand Down Expand Up @@ -503,7 +513,7 @@
"PUTs a document into CouchDB. Equivalent to (conj! couch [id document]).")
(dissoc! [this id-or-doc]
"DELETEs a document from CouchDB. Uses a given document map's :_id and :_rev
if provided; alternatively, if passed a string, will blindly attempt to
if provided; alternatively, if passed a string, will blindly attempt to
delete the current revision of the corresponding document."))

(defn- with-result-meta
Expand All @@ -527,24 +537,24 @@
(this id))]
(with-result-meta this (delete-document url d))
(with-result-meta this nil)))

clojure.lang.ILookup
(valAt [this k] (get-document url k))
(valAt [this k default] (or (.valAt this k) default))

clojure.lang.Counted
(count [this] (->> (database-info url) (fail-on-404 url) :doc_count))

clojure.lang.Seqable
(seq [this]
(->> (all-documents url {:include_docs true})
(map :doc)
(map #(clojure.lang.MapEntry. (:_id %) %))))

clojure.lang.IFn
(invoke [this key] (.valAt this key))
(invoke [this key default] (.valAt this key default))

clojure.lang.IMeta
(meta [this] meta)
clojure.lang.IObj
Expand Down
48 changes: 36 additions & 12 deletions src/com/ashafa/clutch/http_client.clj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
(ns com.ashafa.clutch.http-client
(:require [clj-http.client :as http]
[cheshire.core :as json]

[clojure.java.io :as io]
[clojure.string :as str]
[com.ashafa.clutch.utils :as utils])
Expand Down Expand Up @@ -79,6 +79,34 @@ complete HTTP response of the last couchdb request."
[& args]
(:body (apply couchdb-request* args)))

(defn response-handle-if-parsed*
"Was the response already parsed as JSON? send that. Otherwise,
parse the line as JSON."
[line]
(if (and (string? line) (.startsWith line "{"))
(json/parse-string line true)
(if (not (string? line))
line)
))

(defn response-parse*
"Separate rows|results from the headers"
[s]
(json/parse-string (str/replace s #",?\"(rows|results)\":\[\s*$" "}") true)) ; TODO this is going to break eventually :-/

(defn response-with-header*
"Handle sorting out what is the response."
[lines]
[(if (empty? (rest lines)) (:rows (response-parse* (first lines))) (rest lines))
(-> (first lines)
(response-parse*))]
)

(defn response-no-header*
"No header? Just send back lines."
[lines]
[lines nil])

(defn lazy-view-seq
"Given the body of a view result or _changes feed (should be an InputStream),
returns a lazy seq of each row of data therein.
Expand All @@ -92,18 +120,14 @@ complete HTTP response of the last couchdb request."
[response-body header?]
(let [lines (utils/read-lines response-body)
[lines meta] (if header?
[(rest lines)
(-> (first lines)
(str/replace #",?\"(rows|results)\":\[\s*$" "}") ; TODO this is going to break eventually :-/
(json/parse-string true))]
[lines nil])]
(response-with-header* lines)
(response-no-header* lines))]
(with-meta (->> lines
(map (fn [^String line]
(when (.startsWith line "{")
(json/parse-string line true))))
(remove nil?))
;; TODO why are we dissoc'ing :rows here?
(dissoc meta :rows))))
(map (fn [^String line]
(response-handle-if-parsed* line)))
(remove nil?))
;; TODO why are we dissoc'ing :rows here?
(dissoc meta :rows))))

(defn view-request
"Accepts the same arguments as couchdb-request*, but processes the result assuming that the
Expand Down