// HTTP handler for a PUT of a document func (h *handler) handlePutDoc() error { docid := h.PathVar("docid") body, err := h.readDocument() if err != nil { return err } var newRev string if h.getQuery("new_edits") != "false" { // Regular PUT: if oldRev := h.getQuery("rev"); oldRev != "" { body["_rev"] = oldRev } else if ifMatch := h.rq.Header.Get("If-Match"); ifMatch != "" { body["_rev"] = ifMatch } newRev, err = h.db.Put(docid, body) if err != nil { return err } h.setHeader("Etag", strconv.Quote(newRev)) } else { // Replicator-style PUT with new_edits=false: revisions := db.ParseRevisions(body) if revisions == nil { return base.HTTPErrorf(http.StatusBadRequest, "Bad _revisions") } err = h.db.PutExistingRev(docid, body, revisions) if err != nil { return err } newRev = body["_rev"].(string) } h.writeJSONStatus(http.StatusCreated, db.Body{"ok": true, "id": docid, "rev": newRev}) return nil }
// HTTP handler for a POST to _bulk_docs func (h *handler) handleBulkDocs() error { body, err := h.readJSON() if err != nil { return err } newEdits, ok := body["new_edits"].(bool) if !ok { newEdits = true } docs, ok := body["docs"].([]interface{}) if !ok { err = base.HTTPErrorf(http.StatusBadRequest, "missing 'docs' property") return err } h.db.ReserveSequences(uint64(len(docs))) result := make([]db.Body, 0, len(docs)) for _, item := range docs { doc := item.(map[string]interface{}) docid, _ := doc["_id"].(string) var err error var revid string if newEdits { if docid != "" { revid, err = h.db.Put(docid, doc) } else { docid, revid, err = h.db.Post(doc) } } else { revisions := db.ParseRevisions(doc) if revisions == nil { err = base.HTTPErrorf(http.StatusBadRequest, "Bad _revisions") } else { revid = revisions[0] err = h.db.PutExistingRev(docid, doc, revisions) } } status := db.Body{} if docid != "" { status["id"] = docid } if err != nil { code, msg := base.ErrorAsHTTPStatus(err) status["status"] = code status["error"] = base.CouchHTTPErrorName(code) status["reason"] = msg base.Logf("\tBulkDocs: Doc %q --> %d %s (%v)", docid, code, msg, err) err = nil // wrote it to output already; not going to return it } else { status["rev"] = revid } result = append(result, status) } h.writeJSONStatus(http.StatusCreated, result) return nil }
// HTTP handler for a POST to _bulk_docs func (h *handler) handleBulkDocs() error { body, err := h.readJSON() if err != nil { return err } newEdits, ok := body["new_edits"].(bool) if !ok { newEdits = true } userDocs, ok := body["docs"].([]interface{}) if !ok { err = base.HTTPErrorf(http.StatusBadRequest, "missing 'docs' property") return err } lenDocs := len(userDocs) // split out local docs, save them on their own localDocs := make([]interface{}, 0, lenDocs) docs := make([]interface{}, 0, lenDocs) for _, item := range userDocs { doc := item.(map[string]interface{}) docid, _ := doc["_id"].(string) if strings.HasPrefix(docid, "_local/") { localDocs = append(localDocs, doc) } else { docs = append(docs, doc) } } h.db.ReserveSequences(uint64(len(docs))) result := make([]db.Body, 0, len(docs)) for _, item := range docs { doc := item.(map[string]interface{}) docid, _ := doc["_id"].(string) var err error var revid string if newEdits { if docid != "" { revid, err = h.db.Put(docid, doc) } else { docid, revid, err = h.db.Post(doc) } } else { revisions := db.ParseRevisions(doc) if revisions == nil { err = base.HTTPErrorf(http.StatusBadRequest, "Bad _revisions") } else { revid = revisions[0] err = h.db.PutExistingRev(docid, doc, revisions) } } status := db.Body{} if docid != "" { status["id"] = docid } if err != nil { code, msg := base.ErrorAsHTTPStatus(err) status["status"] = code status["error"] = base.CouchHTTPErrorName(code) status["reason"] = msg base.Logf("\tBulkDocs: Doc %q --> %d %s (%v)", docid, code, msg, err) err = nil // wrote it to output already; not going to return it } else { status["rev"] = revid } result = append(result, status) } for _, item := range localDocs { doc := item.(map[string]interface{}) for k, v := range doc { doc[k] = base.FixJSONNumbers(v) } var err error var revid string offset := len("_local/") docid, _ := doc["_id"].(string) idslug := docid[offset:] revid, err = h.db.PutSpecial("local", idslug, doc) status := db.Body{} status["id"] = docid if err != nil { code, msg := base.ErrorAsHTTPStatus(err) status["status"] = code status["error"] = base.CouchHTTPErrorName(code) status["reason"] = msg base.Logf("\tBulkDocs: Local Doc %q --> %d %s (%v)", docid, code, msg, err) err = nil } else { status["rev"] = revid } result = append(result, status) } h.writeJSONStatus(http.StatusCreated, result) return nil }