diff --git a/README.md b/README.md index 95e0173..34ef873 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ type Cat struct { cat := Cat{Name: "Octo", Cool: true} -id, rev, err := lc.Save(cat) +res, err := lc.Save(cat) if err != nil { // Do whatever @@ -28,14 +28,14 @@ if err != nil { lazyCat := Cat{} -err := lc.Get(id, lazyCat) +err := lc.Get(res.ID, lazyCat) fmt.Println(lazyCat) -lc.Delete(id, rev) +lc.Delete(res.ID, res.Rev) params := url.Values{"limit": []string{"5"}} -results, err := c.View("myapp", "all", ¶ms) +results, err := c.ViewRaw("myapp", "all", ¶ms) if err != nil { // Do whatever } diff --git a/couch.go b/couch.go index a19dc34..382efe0 100644 --- a/couch.go +++ b/couch.go @@ -65,14 +65,12 @@ func (c *Client) DeleteDB(name string) (map[string] interface{}, error) { return res, nil } -func (c *Client) Save(doc interface{}) (string, string, error) { +func (c *Client) Save(doc interface{}) (res *Response, err error) { id, _, err := ParseIdRev(doc) if err != nil { - return "", "", err + return } - res := Response{} - // If no id is provided, we assume POST if id == "" { _, err = c.execJSON("POST", c.URL.Path, &res, doc, nil, nil) @@ -81,14 +79,14 @@ func (c *Client) Save(doc interface{}) (string, string, error) { } if err != nil { - return "", "", err + return } if res.Error != "" { - return "", "", fmt.Errorf(fmt.Sprintf("%s: %s", res.Error, res.Reason)) + return res, fmt.Errorf(fmt.Sprintf("%s: %s", res.Error, res.Reason)) } - return res.ID, res.Rev, nil + return } func (c *Client) Get(id string, doc interface{}) error { @@ -114,7 +112,7 @@ type BulkSaveRequest struct { Docs []interface{} `json:"docs"` } -func (c *Client) BulkSave(docs ...interface{}) (resp *http.Response, err error) { +func (c *Client) BulkSave(docs ...interface{}) (resp *[]Response, code int, err error) { bulkSaveRequest := &BulkSaveRequest{Docs: docs} reader, err := docReader(bulkSaveRequest) @@ -122,7 +120,11 @@ func (c *Client) BulkSave(docs ...interface{}) (resp *http.Response, err error) if err != nil { return } - resp, err = http.DefaultClient.Do(req) + httpResp, err := http.DefaultClient.Do(req) + if err != nil { + return + } + code, err = c.HandleResponse(httpResp, &resp) if err != nil { return } @@ -154,7 +156,7 @@ func (c *Client) View(design string, name string, options *url.Values) (*MultiDo return multiDocResponse, nil } -func (c *Client) Copy(src string, dest string, destRev *string) (resp *http.Response, err error) { +func (c *Client) Copy(src string, dest string, destRev *string) (resp *Response, code int, err error) { if destRev != nil { dest += "?rev=" + *destRev } @@ -164,7 +166,11 @@ func (c *Client) Copy(src string, dest string, destRev *string) (resp *http.Resp if err != nil { return } - resp, err = http.DefaultClient.Do(req) + httpResp, err := http.DefaultClient.Do(req) + if err != nil { + return + } + code, err = c.HandleResponse(httpResp, &resp) if err != nil { return } @@ -189,7 +195,31 @@ func (c *Client) NewRequest(method, url string, body io.Reader, headers *http.He return } -func (c *Client) handleResponseError(code int, resBytes []byte) error { +func (c *Client) UrlString(path string, values *url.Values) string { + u := *c.URL + u.Path = path + if values != nil { + u.RawQuery = values.Encode() + } + return u.String() +} + +func (c *Client) HandleResponse(resp *http.Response, result interface{}) (code int, err error) { + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return + } + code = resp.StatusCode + if err = c.HandleResponseError(code, body); err != nil { + return code, err + } + if err = json.Unmarshal(body, result); err != nil { + return 0, err + } + return +} + +func (c *Client) HandleResponseError(code int, resBytes []byte) error { if code < 200 || code >= 300 { res := Response{} if err := json.Unmarshal(resBytes, &res); err != nil { @@ -200,21 +230,12 @@ func (c *Client) handleResponseError(code int, resBytes []byte) error { return nil } -func (c *Client) UrlString(path string, values *url.Values) string { - u := *c.URL - u.Path = path - if values != nil { - u.RawQuery = values.Encode() - } - return u.String() -} - func (c *Client) execJSON(method string, path string, result interface{}, doc interface{}, values *url.Values, headers *http.Header) (int, error) { resBytes, code, err := c.execRead(method, path, doc, values, headers) if err != nil { return 0, err } - if err = c.handleResponseError(code, resBytes); err != nil { + if err = c.HandleResponseError(code, resBytes); err != nil { return code, err } if err = json.Unmarshal(resBytes, result); err != nil { diff --git a/couch_test.go b/couch_test.go index 1b217ad..50bb8e3 100644 --- a/couch_test.go +++ b/couch_test.go @@ -47,19 +47,12 @@ func TestCreateAndDeleteDB(t *testing.T) { func TestSave(t *testing.T) { c, _ := NewClientURL(DB) - id, rev, err := c.Save(map[string]string{"test1": "value1", "test2": "value2"}) + res, err := c.Save(map[string]string{"test1": "value1", "test2": "value2"}) if err != nil { t.Error(err) } - - if id == "" { - t.Error(err) - } - - if rev == "" { - t.Error(err) - } - + fmt.Println("Save") + fmt.Println(res) } type Cow struct { @@ -75,10 +68,12 @@ func TestSaveWithId(t *testing.T) { c.Get("testcow", cow) c.Delete("testcow", cow.Rev) fmt.Println(cow) - _, _, err := c.Save(Cow{ID: "testcow", Name: "Fred"}) + res, err := c.Save(Cow{ID: "testcow", Name: "Fred"}) if err != nil { t.Error(err) } + fmt.Println("SaveWithId") + fmt.Println(res) } func TestGetAndSave(t *testing.T) { @@ -92,21 +87,23 @@ func TestGetAndSave(t *testing.T) { doc["updatekey"] = "updated" - _, _, err = c.Save(doc) + res, err := c.Save(doc) if err != nil { t.Error(err) } + fmt.Println("GetAndSave") + fmt.Println(res) } func TestDelete(t *testing.T) { c, _ := NewClientURL(DB) doc := map[string]string{"_id": "deleteme"} - id, rev, err := c.Save(doc) + res, err := c.Save(doc) if err != nil { t.Error(err) } - err = c.Delete(id, rev) + err = c.Delete(res.ID, res.Rev) if err != nil { t.Error(err) } @@ -127,7 +124,7 @@ func TestBulkSave(t *testing.T) { cats := []interface{}{} cats = append(cats, cat1, cat2) - resp, err := c.BulkSave(cats...) + resp, _, err := c.BulkSave(cats...) if err != nil { t.Error(err) } @@ -151,7 +148,7 @@ func TestView(t *testing.T) { func TestCopy(t *testing.T) { c, _ := NewClientURL(DB) - res, err := c.Copy("explicit", "explicit-copy", nil) + res, _, err := c.Copy("explicit", "explicit-copy", nil) if err != nil { t.Error(err) }