diff --git a/model/articles.go b/model/articles.go index ccffc6e..99fea5d 100644 --- a/model/articles.go +++ b/model/articles.go @@ -15,35 +15,26 @@ import ( type ArticlesModel struct{} //Read get articles -func (artModel *ArticlesModel) Read(qFilter string, qSkip string, qLimit string) (result []store.Article, err error) { +func (artModel *ArticlesModel) Read(qFilter string) (result []store.Article, total int, left int, err error) { artDb := store.ArticlesCollectionConnect() query, isSort, err := artModel.convertFilter(qFilter) if err != nil { return } + skip, limit := getSkipLimit(qFilter) query["deleted"] = false if isSort == false { - fields := bson.M{} - - skip, err := strconv.Atoi(qSkip) - if err != nil { - skip = 0 - } - limit, err := strconv.Atoi(qLimit) - if err != nil { - limit = 0 - } - result, err = artDb.Read(query, fields, skip, limit) + result, total, left, err = artDb.Read(query, fields, skip, limit) } else { - result, err = artDb.Search(query) + result, total, left, err = artDb.Search(query, skip, limit) } if err != nil { return } - return result, nil + return result, total, left, nil } //ReadOne get article by ID @@ -172,3 +163,27 @@ func (artModel *ArticlesModel) Delete(qID string) (err error) { return } + +func getSkipLimit(filter string) (skip int, limit int) { + if filter != "" { + jParser, err := gabs.ParseJSON([]byte(filter)) + if err != nil { + return + } + + if s := jParser.Exists("skip"); s == true { + sTmp, ok := jParser.Path("skip").Data().(string) + if ok == true { + skip, _ = strconv.Atoi(sTmp) + } + } + + if l := jParser.Exists("limit"); l == true { + lTmp, ok := jParser.Path("limit").Data().(string) + if ok == true { + limit, _ = strconv.Atoi(lTmp) + } + } + } + return skip, limit +} diff --git a/store/articles.go b/store/articles.go index dd55a19..fd881c4 100644 --- a/store/articles.go +++ b/store/articles.go @@ -51,7 +51,7 @@ func ArticlesCollectionConnect() *ArticlesCollection { } //Read return entries of Articles collections -func (art *ArticlesCollection) Read(query bson.M, fields bson.M, skip int, limit int) (result []Article, err error) { +func (art *ArticlesCollection) Read(query bson.M, fields bson.M, skip int, limit int) (result []Article, total int, left int, err error) { session, artCollection, err := art.conn.getSessionAndCollection(art.collection) if err != nil { return @@ -59,12 +59,19 @@ func (art *ArticlesCollection) Read(query bson.M, fields bson.M, skip int, limit defer session.Close() result = make([]Article, 0) err = artCollection.Find(query).Select(fields).Skip(skip).Limit(limit).All(&result) - if err != nil { return } - - return result, nil + count := len(result) + total, err = artCollection.Find(query).Count() + if err != nil { + return + } + left = total - (skip + count) + if left < 0 { + left = 0 + } + return result, total, left, nil } //ReadOne return one enrty of Articles collection by query @@ -161,7 +168,7 @@ func (art *ArticlesCollection) Delete(ID bson.ObjectId) (err error) { } //Search implement full-text search -func (art *ArticlesCollection) Search(q bson.M) (result []Article, err error) { +func (art *ArticlesCollection) Search(q bson.M, skip int, limit int) (result []Article, total int, left int, err error) { session, artCollection, err := art.conn.getSessionAndCollection(art.collection) if err != nil { return @@ -175,10 +182,22 @@ func (art *ArticlesCollection) Search(q bson.M) (result []Article, err error) { } sort := "$textScore:score" result = make([]Article, 0) - err = artCollection.Find(q).Select(fields).Sort(sort).All(&result) + err = artCollection.Find(q).Select(fields).Sort(sort).Skip(skip).Limit(limit).All(&result) + if err != nil { + return + } + count := len(result) + total, err = artCollection.Find(q).Select(fields).Sort(sort).Count() + if err != nil { + return + } + left = total - (skip + count) + if left < 0 { + left = 0 + } if err != nil { return } - return result, nil + return result, total, left, nil } diff --git a/webActions/articlesWebActions.go b/webActions/articlesWebActions.go index ac41af5..56a893f 100644 --- a/webActions/articlesWebActions.go +++ b/webActions/articlesWebActions.go @@ -3,6 +3,7 @@ package webActions import ( "knowledge-base/model" "net/http" + "strconv" "github.com/gorilla/mux" ) @@ -14,11 +15,11 @@ type ArticlesWebActions struct { //Read get all articles func (art *ArticlesWebActions) Read(w http.ResponseWriter, r *http.Request) { - skip := r.URL.Query().Get("skip") - limit := r.URL.Query().Get("limit") filter := r.URL.Query().Get("filter") - data, err := art.model.Read(filter, skip, limit) + data, total, left, err := art.model.Read(filter) + w.Header().Set("X-Total-Count", strconv.Itoa(total)) + w.Header().Set("X-RateLimit-Remaining", strconv.Itoa(left)) if err != nil { ErrorWithJSON(w, r, err.Error(), 404) } else {