diff options
-rw-r--r-- | system/api/handlers.go | 26 | ||||
-rw-r--r-- | system/db/content.go | 35 |
2 files changed, 61 insertions, 0 deletions
diff --git a/system/api/handlers.go b/system/api/handlers.go index c238ca9..7a2073d 100644 --- a/system/api/handlers.go +++ b/system/api/handlers.go @@ -91,6 +91,12 @@ func contentHandler(res http.ResponseWriter, req *http.Request) { q := req.URL.Query() id := q.Get("id") t := q.Get("type") + slug := q.Get("slug") + + if slug != "" { + contentHandlerBySlug(res, req) + return + } if _, ok := content.Types[t]; !ok { res.WriteHeader(http.StatusNotFound) @@ -117,6 +123,26 @@ func contentHandler(res http.ResponseWriter, req *http.Request) { sendData(res, j, http.StatusOK) } +func contentHandlerBySlug(res http.ResponseWriter, req *http.Request) { + slug := req.URL.Query().Get("slug") + + // lookup type:id by slug key in __contentIndex + post, err := db.ContentBySlug(slug) + if err != nil { + log.Println("Error finding content by slug:", slug, err) + res.WriteHeader(http.StatusInternalServerError) + return + } + + j, err := fmtJSON(json.RawMessage(post)) + if err != nil { + res.WriteHeader(http.StatusInternalServerError) + return + } + + sendData(res, j, http.StatusOK) +} + func fmtJSON(data ...json.RawMessage) ([]byte, error) { var msg = []json.RawMessage{} for _, d := range data { diff --git a/system/db/content.go b/system/db/content.go index 0661556..87b3e69 100644 --- a/system/db/content.go +++ b/system/db/content.go @@ -229,6 +229,41 @@ func Content(target string) ([]byte, error) { return val.Bytes(), nil } +// ContentBySlug does a lookup in the content index to find the type and id of +// the requested content. Subsequently, issues the lookup in the type bucket and +// returns the data at that ID or nil if nothing exists. +func ContentBySlug(slug string) ([]byte, error) { + val := &bytes.Buffer{} + err := store.View(func(tx *bolt.Tx) error { + var t, id string + b := tx.Bucket([]byte("__contentIndex")) + idx := b.Get([]byte(slug)) + + if idx != nil { + tid := strings.Split(string(idx), ":") + + if len(tid) < 2 { + return fmt.Errorf("Bad data in content index for slug: %s", slug) + } + + t, id = tid[0], tid[1] + } + + c := tx.Bucket([]byte(t)) + _, err := val.Write(c.Get([]byte(id))) + if err != nil { + return err + } + + return nil + }) + if err != nil { + return nil, err + } + + return val.Bytes(), nil +} + // ContentAll retrives all items from the database within the provided namespace func ContentAll(namespace string) [][]byte { var posts [][]byte |