diff options
-rw-r--r-- | system/api/handlers.go | 48 | ||||
-rw-r--r-- | system/db/content.go | 61 |
2 files changed, 76 insertions, 33 deletions
diff --git a/system/api/handlers.go b/system/api/handlers.go index 8356683..d1758f0 100644 --- a/system/api/handlers.go +++ b/system/api/handlers.go @@ -36,6 +36,11 @@ func postsHandler(res http.ResponseWriter, req *http.Request) { return } + if _, ok := content.Types[t]; !ok { + res.WriteHeader(http.StatusNotFound) + return + } + count, err := strconv.Atoi(q.Get("count")) // int: determines number of posts to return (10 default, -1 is all) if err != nil { if q.Get("count") == "" { @@ -57,46 +62,23 @@ func postsHandler(res http.ResponseWriter, req *http.Request) { } order := strings.ToLower(q.Get("order")) // string: sort order of posts by timestamp ASC / DESC (DESC default) - if order != "asc" || order == "" { + if order != "asc" { order = "desc" } - // TODO: time-based ?after=time.Time, ?before=time.Time between=time.Time|time.Time - - posts := db.ContentAll(t + "_sorted") - var all = []json.RawMessage{} - for _, post := range posts { - all = append(all, post) + opts := db.QueryOptions{ + Count: count, + Offset: offset, + Order: order, } - var start, end int - switch count { - case -1: - start = 0 - end = len(posts) - - default: - start = count * offset - end = start + count - } - - // bounds check on posts given the start & end count - if start > len(posts) { - start = len(posts) - count - } - if end > len(posts) { - end = len(posts) - } - - // reverse the sorted order if ASC - if order == "asc" { - all = []json.RawMessage{} - for i := len(posts) - 1; i >= 0; i-- { - all = append(all, posts[i]) - } + bb := db.Query(t+"_sorted", opts) + var result = []json.RawMessage{} + for i := range bb { + result = append(result, bb[i]) } - j, err := fmtJSON(all[start:end]...) + j, err := fmtJSON(result...) if err != nil { res.WriteHeader(http.StatusInternalServerError) return diff --git a/system/db/content.go b/system/db/content.go index bd1ee4b..84695cc 100644 --- a/system/db/content.go +++ b/system/db/content.go @@ -202,6 +202,67 @@ func ContentAll(namespace string) [][]byte { return posts } +// QueryOptions holds options for a query +type QueryOptions struct { + Count int + Offset int + Order string +} + +// Query retrieves a set of content from the db based on options +func Query(namespace string, opts QueryOptions) [][]byte { + var posts [][]byte + store.View(func(tx *bolt.Tx) error { + b := tx.Bucket([]byte(namespace)) + c := b.Cursor() + + i := 0 // count of num posts added + cur := 0 // count of where cursor is + switch opts.Order { + case "asc": + for k, v := c.Last(); k != nil; c.Prev() { + if cur < opts.Offset*opts.Count { + cur++ + continue + } + + if i >= opts.Count { + break + } + + posts = append(posts, v) + i++ + } + + case "desc": + for k, v := c.First(); k != nil; c.Next() { + if cur < opts.Offset*opts.Count { + cur++ + continue + } + + if i >= opts.Count { + break + } + + posts = append(posts, v) + i++ + } + } + + return nil + }) + + // if opts.order == "asc" { + // posts = []json.RawMessage{} + // for i := len(posts) - 1; i >= 0; i-- { + // posts = append(all, posts[i]) + // } + // } + + return posts +} + // SortContent sorts all content of the type supplied as the namespace by time, // in descending order, from most recent to least recent // Should be called from a goroutine after SetContent is successful |