1//  Copyright (c) 2014 Couchbase, Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// 		http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package http
16
17import (
18	"encoding/json"
19	"fmt"
20	"io/ioutil"
21	"net/http"
22)
23
24type DocIndexHandler struct {
25	defaultIndexName string
26	IndexNameLookup  varLookupFunc
27	DocIDLookup      varLookupFunc
28}
29
30func NewDocIndexHandler(defaultIndexName string) *DocIndexHandler {
31	return &DocIndexHandler{
32		defaultIndexName: defaultIndexName,
33	}
34}
35
36func (h *DocIndexHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
37
38	// find the index to operate on
39	var indexName string
40	if h.IndexNameLookup != nil {
41		indexName = h.IndexNameLookup(req)
42	}
43	if indexName == "" {
44		indexName = h.defaultIndexName
45	}
46	index := IndexByName(indexName)
47	if index == nil {
48		showError(w, req, fmt.Sprintf("no such index '%s'", indexName), 404)
49		return
50	}
51
52	// find the doc id
53	var docID string
54	if h.DocIDLookup != nil {
55		docID = h.DocIDLookup(req)
56	}
57	if docID == "" {
58		showError(w, req, "document id cannot be empty", 400)
59		return
60	}
61
62	// read the request body
63	requestBody, err := ioutil.ReadAll(req.Body)
64	if err != nil {
65		showError(w, req, fmt.Sprintf("error reading request body: %v", err), 400)
66		return
67	}
68
69	// parse request body as json
70	var doc interface{}
71	err = json.Unmarshal(requestBody, &doc)
72	if err != nil {
73		showError(w, req, fmt.Sprintf("error parsing request body as JSON: %v", err), 400)
74		return
75	}
76
77	err = index.Index(docID, doc)
78	if err != nil {
79		showError(w, req, fmt.Sprintf("error indexing document '%s': %v", docID, err), 500)
80		return
81	}
82
83	rv := struct {
84		Status string `json:"status"`
85	}{
86		Status: "ok",
87	}
88	mustEncode(w, rv)
89}
90