M internal/c/content/content.go => internal/c/content/content.go +5 -2
@@ 46,7 46,7 @@ type DBer interface {
ContentGet(space space.Space, ct contenttype.ContentType, contentID string) (content.Content, error)
ContentUpdate(space space.Space, ct contenttype.ContentType, content content.Content, newParams []db.ContentNewParam, updateParams []db.ContentUpdateParam) (content.Content, error)
ContentDelete(space space.Space, ct contenttype.ContentType, content content.Content) error
- ContentSearch(space space.Space, ct contenttype.ContentType, name, query string, before int) (content.ContentList, error)
+ ContentSearch(space space.Space, ct contenttype.ContentType, name, query string, perPage, before, after int) (content.ContentList, error)
}
type E3er interface {
@@ 419,8 419,11 @@ func (c *Content) search(w http.ResponseWriter, r *http.Request) {
return
}
+ perpage, _ := strconv.Atoi(r.URL.Query().Get("perpage"))
before, _ := strconv.Atoi(r.URL.Query().Get("before"))
- list, err := c.db.ContentSearch(space, ct, field, query, before)
+ after, _ := strconv.Atoi(r.URL.Query().Get("after"))
+
+ list, err := c.db.ContentSearch(space, ct, field, query, perpage, before, after)
if err != nil {
c.log.Println(err)
c.Error(w, r, http.StatusInternalServerError, "failed to find desired content")
M internal/c/contenttype/contenttype.go => internal/c/contenttype/contenttype.go +10 -4
@@ 34,8 34,8 @@ type dber interface {
ContentTypeGet(space space.Space, contenttypeID string) (contenttype.ContentType, error)
ContentTypeUpdate(space space.Space, contenttype contenttype.ContentType, name string, newParams []db.ContentTypeNewParam, updateParams []db.ContentTypeUpdateParam) (contenttype.ContentType, error)
ContentTypeDelete(space space.Space, ct contenttype.ContentType) error
- ContentTypeSearch(space space.Space, query string, before int) (contenttype.ContentTypeList, error)
- ContentPerContentType(space space.Space, ct contenttype.ContentType, before int, order db.OrderType, sortField string) (content.ContentList, error)
+ ContentTypeSearch(space space.Space, query string, perPage, before, after int) (contenttype.ContentTypeList, error)
+ ContentPerContentType(space space.Space, ct contenttype.ContentType, perPage, before, after int, order db.OrderType, sortField string) (content.ContentList, error)
}
func New(log *log.Logger, db dber) *ContentType {
@@ 260,8 260,11 @@ func (c *ContentType) serve(w http.ResponseWriter, r *http.Request, spaceID, con
f = "name" // All guaranteed to have.
}
+ perpage, _ := strconv.Atoi(r.URL.Query().Get("perpage"))
before, _ := strconv.Atoi(r.URL.Query().Get("before"))
- list, err := c.db.ContentPerContentType(space, ct, before, o, f)
+ after, _ := strconv.Atoi(r.URL.Query().Get("after"))
+
+ list, err := c.db.ContentPerContentType(space, ct, perpage, before, after, o, f)
if err != nil {
c.log.Println(err)
c.Error(w, r, http.StatusInternalServerError, "failed to find content for contenttype")
@@ 325,8 328,11 @@ func (c *ContentType) search(w http.ResponseWriter, r *http.Request) {
return
}
+ perpage, _ := strconv.Atoi(r.URL.Query().Get("perpage"))
before, _ := strconv.Atoi(r.URL.Query().Get("before"))
- list, err := c.db.ContentTypeSearch(space, query, before)
+ after, _ := strconv.Atoi(r.URL.Query().Get("after"))
+
+ list, err := c.db.ContentTypeSearch(space, query, perpage, before, after)
if err != nil {
c.Error(w, r, http.StatusInternalServerError, "failed to find desired contenttype")
return
M internal/c/space/space.go => internal/c/space/space.go +10 -4
@@ 33,8 33,8 @@ type dber interface {
SpaceUpdate(user user.User, space space.Space, name, desc string) (space.Space, error)
SpaceCopy(user user.User, space space.Space, name, desc string) (space.Space, error)
SpaceDelete(user user.User, space space.Space) error
- ContentTypesPerSpace(space space.Space, before int) (contenttype.ContentTypeList, error)
- HooksPerSpace(space space.Space, before int) (hook.HookList, error)
+ ContentTypesPerSpace(space space.Space, perPage, before, after int) (contenttype.ContentTypeList, error)
+ HooksPerSpace(space space.Space, perPage, before, after int) (hook.HookList, error)
}
func New(log *log.Logger, db dber) *Space {
@@ 58,15 58,21 @@ func (s *Space) serve(w http.ResponseWriter, r *http.Request, spaceID string) {
return
}
+ perpagect, _ := strconv.Atoi(r.URL.Query().Get("perpagect"))
beforect, _ := strconv.Atoi(r.URL.Query().Get("beforect"))
- cts, err := s.db.ContentTypesPerSpace(space, beforect)
+ afterct, _ := strconv.Atoi(r.URL.Query().Get("afterct"))
+
+ cts, err := s.db.ContentTypesPerSpace(space, perpagect, beforect, afterct)
if err != nil {
s.Error(w, r, http.StatusInternalServerError, "failed to find contenttypes for space")
return
}
+ perpagehook, _ := strconv.Atoi(r.URL.Query().Get("perpagehook"))
beforehook, _ := strconv.Atoi(r.URL.Query().Get("beforehook"))
- hooks, err := s.db.HooksPerSpace(space, beforehook)
+ afterhook, _ := strconv.Atoi(r.URL.Query().Get("afterhook"))
+
+ hooks, err := s.db.HooksPerSpace(space, perpagehook, beforehook, afterhook)
if err != nil {
s.log.Println(err)
s.Error(w, r, http.StatusInternalServerError, "failed to find webhooks for space")
M internal/c/user/user.go => internal/c/user/user.go +4 -2
@@ 26,7 26,7 @@ type dber interface {
UserNew(username, password, verifyPassword string) (user.User, error)
UserGet(username, password string) (user.User, error)
UserGetFromToken(token string) (user.User, error)
- SpacesPerUser(user user.User, before int) (space.SpaceList, error)
+ SpacesPerUser(user user.User, perPage, before, after int) (space.SpaceList, error)
}
func New(log *log.Logger, db dber, signupEnabled bool) *User {
@@ 90,9 90,11 @@ func (l *User) home(w http.ResponseWriter, r *http.Request) {
// Don't care about the error value here. When error occurs before is zero
// value.
+ perpage, _ := strconv.Atoi(r.URL.Query().Get("perpage"))
before, _ := strconv.Atoi(r.URL.Query().Get("before"))
+ after, _ := strconv.Atoi(r.URL.Query().Get("after"))
- spaces, err := l.db.SpacesPerUser(user, before)
+ spaces, err := l.db.SpacesPerUser(user, perpage, before, after)
if err != nil {
l.Error(w, r, http.StatusInternalServerError, "failed to find spaces for user")
return
M internal/m/content/content.go => internal/m/content/content.go +1 -0
@@ 16,4 16,5 @@ type ContentList interface {
List() []Content
More() bool
Before() int // Some table ID to fetch next set of results.
+ After() int
}
M internal/m/contenttype/contenttype.go => internal/m/contenttype/contenttype.go +1 -0
@@ 15,4 15,5 @@ type ContentTypeList interface {
List() []ContentType
More() bool
Before() int
+ After() int
}
M internal/m/hook/hook.go => internal/m/hook/hook.go +1 -0
@@ 9,4 9,5 @@ type HookList interface {
List() []Hook
More() bool
Before() int
+ After() int
}
M internal/m/space/space.go => internal/m/space/space.go +1 -0
@@ 10,4 10,5 @@ type SpaceList interface {
List() []Space
More() bool
Before() int
+ After() int
}
M internal/s/db/content.go => internal/s/db/content.go +33 -17
@@ 782,8 782,9 @@ func sortinfo(t *sql.Tx, ct contenttype.ContentType, sortField string) (string,
return sortFieldValueType, sortFieldTableName, nil
}
-func (db *DB) contentPerContentType(t *sql.Tx, space space.Space, ct contenttype.ContentType, before int, order OrderType, sortField string, depth int) (content.ContentList, error) {
+func (db *DB) contentPerContentType(t *sql.Tx, space space.Space, ct contenttype.ContentType, perPage, before, after int, order OrderType, sortField string, depth int) (content.ContentList, error) {
var (
+ firstID int
tmpID int
tmpContentID string
@@ 791,7 792,9 @@ func (db *DB) contentPerContentType(t *sql.Tx, space space.Space, ct contenttype
hasMore bool
)
- before = beformat(before)
+ before = bfmt(before)
+ after = afmt(after)
+ perPage = pfmt(perPage)
order = orderTypeReverse(order)
// Create temporary table for queries.
@@ 838,8 841,8 @@ func (db *DB) contentPerContentType(t *sql.Tx, space space.Space, ct contenttype
}
// Query the temporary table.
- q = fmt.Sprintf("SELECT ID, CONTENT_ID FROM %s WHERE ID < ? ORDER BY ID DESC LIMIT ?", tbl)
- rows, err := t.Query(q, before, perPage+1)
+ q = fmt.Sprintf("SELECT ID, CONTENT_ID FROM %s WHERE ID < ? AND ID > ? ORDER BY ID DESC LIMIT ?", tbl)
+ rows, err := t.Query(q, before, after, perPage+1)
if err != nil {
return nil, err
}
@@ 855,6 858,10 @@ func (db *DB) contentPerContentType(t *sql.Tx, space space.Space, ct contenttype
return nil, err
}
+ if firstID == 0 {
+ firstID = tmpID
+ }
+
c, err := db.ContentGet(space, ct, tmpContentID)
if err != nil {
return nil, err
@@ 863,17 870,17 @@ func (db *DB) contentPerContentType(t *sql.Tx, space space.Space, ct contenttype
r = append(r, c)
}
- return newContentList(r, hasMore, tmpID), nil
+ return newContentList(r, hasMore, tmpID, firstID), nil
}
-func (db *DB) ContentPerContentType(space space.Space, ct contenttype.ContentType, before int, order OrderType, sortField string) (content.ContentList, error) {
+func (db *DB) ContentPerContentType(space space.Space, ct contenttype.ContentType, perPage, before, after int, order OrderType, sortField string) (content.ContentList, error) {
t, err := db.Begin()
if err != nil {
return nil, err
}
defer t.Rollback()
- list, err := db.contentPerContentType(t, space, ct, before, order, sortField, defaultDepth)
+ list, err := db.contentPerContentType(t, space, ct, perPage, before, after, order, sortField, defaultDepth)
if err != nil {
return nil, err
}
@@ 881,8 888,9 @@ func (db *DB) ContentPerContentType(space space.Space, ct contenttype.ContentTyp
return list, t.Commit()
}
-func (db *DB) ContentSearch(space space.Space, ct contenttype.ContentType, sortField, query string, before int) (content.ContentList, error) {
+func (db *DB) ContentSearch(space space.Space, ct contenttype.ContentType, sortField, query string, perPage, before, after int) (content.ContentList, error) {
var (
+ firstID int
tmpID int
tmpContentID string
@@ 891,7 899,9 @@ func (db *DB) ContentSearch(space space.Space, ct contenttype.ContentType, sortF
hasMore bool
)
- before = beformat(before)
+ before = bfmt(before)
+ after = afmt(after)
+ perPage = pfmt(perPage)
t, err := db.Begin()
if err != nil {
@@ 942,8 952,8 @@ func (db *DB) ContentSearch(space space.Space, ct contenttype.ContentType, sortF
}
// Query the temporary table.
- q = fmt.Sprintf("SELECT ID, CONTENT_ID FROM %s WHERE ID < ? ORDER BY ID DESC LIMIT ?", tbl)
- rows, err := t.Query(q, before, perPage+1)
+ q = fmt.Sprintf("SELECT ID, CONTENT_ID FROM %s WHERE ID < ? AND ID > ? ORDER BY ID DESC LIMIT ?", tbl)
+ rows, err := t.Query(q, before, after, perPage+1)
if err != nil {
return nil, err
}
@@ 959,6 969,10 @@ func (db *DB) ContentSearch(space space.Space, ct contenttype.ContentType, sortF
return nil, err
}
+ if firstID == 0 {
+ firstID = tmpID
+ }
+
c, err := db.ContentGet(space, ct, tmpContentID)
if err != nil {
return nil, err
@@ 967,7 981,7 @@ func (db *DB) ContentSearch(space space.Space, ct contenttype.ContentType, sortF
r = append(r, c)
}
- return newContentList(r, hasMore, tmpID), t.Commit()
+ return newContentList(r, hasMore, tmpID, firstID), t.Commit()
}
func (db *DB) contentGet(t *sql.Tx, space space.Space, ct contenttype.ContentType, contentID string, depth int) (content.Content, error) {
@@ 1248,7 1262,7 @@ type contentIter struct {
}
func (db *DB) contentIter(t *sql.Tx, space space.Space, ct contenttype.ContentType, sortField string) *contentIter {
- iter := &contentIter{db, t, space, ct, sortField, newContentList(nil, false, 0), nil}
+ iter := &contentIter{db, t, space, ct, sortField, newContentList(nil, false, 0, 0), nil}
iter.pump()
return iter
}
@@ 1262,7 1276,7 @@ func (db *DB) ContentIter(space space.Space, ct contenttype.ContentType, sortFie
}
func (iter *contentIter) pump() {
- list, err := iter.db.contentPerContentType(iter.t, iter.space, iter.ct, iter.list.Before(), OrderAsc, iter.sortField, defaultDepth)
+ list, err := iter.db.contentPerContentType(iter.t, iter.space, iter.ct, maxPerPage, iter.list.Before(), iter.list.After(), OrderAsc, iter.sortField, defaultDepth)
iter.list = list
iter.err = err
}
@@ 1287,7 1301,7 @@ func (iter *contentIter) Scan() (content.Content, error) {
list := iter.list.List()
first, rest := list[0], list[1:]
- iter.list = newContentList(rest, iter.list.More(), iter.list.Before())
+ iter.list = newContentList(rest, iter.list.More(), iter.list.Before(), iter.list.Before())
if err != nil {
return nil, err
}
@@ 1305,12 1319,14 @@ type ContentList struct {
ContentList []content.Content
ContentListMore bool
ContentListBefore int
+ ContentListAfter int
}
-func newContentList(list []content.Content, hasMore bool, last int) *ContentList {
- return &ContentList{list, hasMore, last}
+func newContentList(list []content.Content, hasMore bool, last, first int) *ContentList {
+ return &ContentList{list, hasMore, last, first}
}
func (cl *ContentList) List() []content.Content { return cl.ContentList }
func (cl *ContentList) More() bool { return cl.ContentListMore }
func (cl *ContentList) Before() int { return cl.ContentListBefore }
+func (cl *ContentList) After() int { return cl.ContentListAfter }
M internal/s/db/contenttype.go => internal/s/db/contenttype.go +33 -17
@@ 167,23 167,26 @@ func (db *DB) ContentTypeUpdate(space space.Space, contenttype contenttype.Conte
return db.ContentTypeGet(space, contenttype.ID())
}
-func (db *DB) contentTypesPerSpace(t *sql.Tx, space space.Space, before int) (contenttype.ContentTypeList, error) {
+func (db *DB) contentTypesPerSpace(t *sql.Tx, space space.Space, perPage, before, after int) (contenttype.ContentTypeList, error) {
var (
r []contenttype.ContentType
+ first int
id int
hasMore bool
)
- before = beformat(before)
+ before = bfmt(before)
+ after = afmt(after)
+ perPage = pfmt(perPage)
q := `
SELECT ID
FROM cms_contenttype
- WHERE SPACE_ID = ? AND ID < ?
+ WHERE SPACE_ID = ? AND ID < ? AND ID > ?
ORDER BY ID DESC LIMIT ?
`
- rows, err := db.Query(q, space.ID(), before, perPage+1)
+ rows, err := db.Query(q, space.ID(), before, after, perPage+1)
if err != nil {
return nil, err
}
@@ 198,6 201,10 @@ func (db *DB) contentTypesPerSpace(t *sql.Tx, space space.Space, before int) (co
return nil, err
}
+ if first == 0 {
+ first = id
+ }
+
ct, err := db.contentTypeGet(t, space, strconv.Itoa(id))
if err != nil {
return nil, err
@@ 206,17 213,17 @@ func (db *DB) contentTypesPerSpace(t *sql.Tx, space space.Space, before int) (co
r = append(r, ct)
}
- return newContentTypeList(r, hasMore, id), nil
+ return newContentTypeList(r, hasMore, id, first), nil
}
-func (db *DB) ContentTypesPerSpace(space space.Space, before int) (contenttype.ContentTypeList, error) {
+func (db *DB) ContentTypesPerSpace(space space.Space, perPage, before, after int) (contenttype.ContentTypeList, error) {
t, err := db.Begin()
if err != nil {
return nil, err
}
defer t.Rollback()
- list, err := db.contentTypesPerSpace(t, space, before)
+ list, err := db.contentTypesPerSpace(t, space, perPage, before, after)
if err != nil {
db.log.Println(err)
return nil, err
@@ 263,19 270,22 @@ func (db *DB) ContentTypeGet(space space.Space, contenttypeID string) (contentty
// TODO: Consolidate with other list function here. They are the same except for
// the query used.
-func (db *DB) ContentTypeSearch(space space.Space, query string, before int) (contenttype.ContentTypeList, error) {
+func (db *DB) ContentTypeSearch(space space.Space, query string, perPage, before, after int) (contenttype.ContentTypeList, error) {
var (
r []contenttype.ContentType
+ first int
id int
hasMore bool
)
- before = beformat(before)
+ before = bfmt(before)
+ after = afmt(after)
+ perPage = pfmt(perPage)
// TODO: May want to make a temp table for this query for proper ordering.
- q := `SELECT ID FROM cms_contenttype WHERE NAME LIKE ? AND SPACE_ID = ? AND ID < ? ORDER BY ID DESC LIMIT ?`
+ q := `SELECT ID FROM cms_contenttype WHERE NAME LIKE ? AND SPACE_ID = ? AND ID < ? AND ID > ? ORDER BY ID DESC LIMIT ?`
- rows, err := db.Query(q, fmt.Sprintf("%%%s%%", query), space.ID(), before, perPage)
+ rows, err := db.Query(q, fmt.Sprintf("%%%s%%", query), space.ID(), before, after, perPage)
if err != nil {
db.log.Println("1", err)
return nil, err
@@ 287,6 297,10 @@ func (db *DB) ContentTypeSearch(space space.Space, query string, before int) (co
return nil, err
}
+ if first == 0 {
+ first = id
+ }
+
ct, err := db.ContentTypeGet(space, strconv.Itoa(id))
if err != nil {
db.log.Println("3", err)
@@ 296,7 310,7 @@ func (db *DB) ContentTypeSearch(space space.Space, query string, before int) (co
r = append(r, ct)
}
- return newContentTypeList(r, hasMore, id), nil
+ return newContentTypeList(r, hasMore, id, first), nil
}
func (db *DB) ContentTypeDelete(space space.Space, ct contenttype.ContentType) error {
@@ 368,13 382,13 @@ type contentTypeIter struct {
}
func (db *DB) ContentTypeIter(t *sql.Tx, space space.Space) *contentTypeIter {
- iter := &contentTypeIter{db, t, space, newContentTypeList(nil, false, 0), nil}
+ iter := &contentTypeIter{db, t, space, newContentTypeList(nil, false, 0, 0), nil}
iter.pump()
return iter
}
func (iter *contentTypeIter) pump() {
- list, err := iter.db.contentTypesPerSpace(iter.t, iter.space, iter.list.Before())
+ list, err := iter.db.contentTypesPerSpace(iter.t, iter.space, maxPerPage, iter.list.Before(), iter.list.After())
iter.list = list
iter.err = err
}
@@ 399,7 413,7 @@ func (iter *contentTypeIter) Scan() (contenttype.ContentType, error) {
list := iter.list.List()
first, rest := list[0], list[1:]
- iter.list = newContentTypeList(rest, iter.list.More(), iter.list.Before())
+ iter.list = newContentTypeList(rest, iter.list.More(), iter.list.Before(), iter.list.After())
if err != nil {
return nil, err
}
@@ 417,12 431,14 @@ type ContentTypeList struct {
ContentTypeList []contenttype.ContentType
ContentTypeListMore bool
ContentTypeListBefore int
+ ContentTypeListAfter int
}
-func newContentTypeList(list []contenttype.ContentType, hasMore bool, last int) *ContentTypeList {
- return &ContentTypeList{list, hasMore, last}
+func newContentTypeList(list []contenttype.ContentType, hasMore bool, last, first int) *ContentTypeList {
+ return &ContentTypeList{list, hasMore, last, first}
}
func (ctl *ContentTypeList) List() []contenttype.ContentType { return ctl.ContentTypeList }
func (ctl *ContentTypeList) More() bool { return ctl.ContentTypeListMore }
func (ctl *ContentTypeList) Before() int { return ctl.ContentTypeListBefore }
+func (ctl *ContentTypeList) After() int { return ctl.ContentTypeListAfter }
M internal/s/db/db.go => internal/s/db/db.go +13 -2
@@ 13,7 13,7 @@ import (
const (
// Default pagination amount. For use in LIMIT/OFFSET.
- perPage = 25
+ maxPerPage = 25
maxUint = ^uint(0)
maxInt = int(maxUint >> 1)
@@ 26,13 26,24 @@ var (
zero int
)
-func beformat(before int) int {
+func bfmt(before int) int {
if before == zero {
return maxInt
}
return before
}
+func afmt(after int) int {
+ return after
+}
+
+func pfmt(page int) int {
+ if page > maxPerPage || page < 1 {
+ return maxPerPage
+ }
+ return page
+}
+
type DB struct {
*sql.DB
log *log.Logger
M internal/s/db/hook.go => internal/s/db/hook.go +21 -12
@@ 93,22 93,25 @@ func (db *DB) HookDelete(s space.Space, h hook.Hook) error {
return t.Commit()
}
-func (db *DB) hooksPerSpace(t *sql.Tx, space space.Space, before int) (hook.HookList, error) {
+func (db *DB) hooksPerSpace(t *sql.Tx, space space.Space, perPage, before, after int) (hook.HookList, error) {
var (
r []hook.Hook
+ first int
id int
hasMore bool
)
- before = beformat(before)
+ before = bfmt(before)
+ after = afmt(after)
+ perPage = pfmt(perPage)
q := `
SELECT ID FROM cms_hooks
- WHERE SPACE_ID = ? AND ID < ?
+ WHERE SPACE_ID = ? AND ID < ? AND ID > ?
ORDER BY ID DESC LIMIT ?
`
- rows, err := db.Query(q, space.ID(), before, perPage+1)
+ rows, err := db.Query(q, space.ID(), before, after, perPage+1)
if err != nil {
return nil, err
}
@@ 123,6 126,10 @@ func (db *DB) hooksPerSpace(t *sql.Tx, space space.Space, before int) (hook.Hook
return nil, err
}
+ if first == 0 {
+ first = id
+ }
+
ct, err := db.hookGet(t, space, strconv.Itoa(id))
if err != nil {
return nil, err
@@ 131,17 138,17 @@ func (db *DB) hooksPerSpace(t *sql.Tx, space space.Space, before int) (hook.Hook
r = append(r, ct)
}
- return newHookList(r, hasMore, id), nil
+ return newHookList(r, hasMore, id, first), nil
}
-func (db *DB) HooksPerSpace(space space.Space, before int) (hook.HookList, error) {
+func (db *DB) HooksPerSpace(space space.Space, perPage, before, after int) (hook.HookList, error) {
t, err := db.Begin()
if err != nil {
return nil, err
}
defer t.Rollback()
- list, err := db.hooksPerSpace(t, space, before)
+ list, err := db.hooksPerSpace(t, space, perPage, before, after)
if err != nil {
db.log.Println(err)
return nil, err
@@ 168,13 175,13 @@ type hookIter struct {
}
func (db *DB) HookIter(t *sql.Tx, space space.Space) *hookIter {
- iter := &hookIter{db, t, space, newHookList(nil, false, 0), nil}
+ iter := &hookIter{db, t, space, newHookList(nil, false, 0, 0), nil}
iter.pump()
return iter
}
func (iter *hookIter) pump() {
- list, err := iter.db.hooksPerSpace(iter.t, iter.space, iter.list.Before())
+ list, err := iter.db.hooksPerSpace(iter.t, iter.space, maxPerPage, iter.list.Before(), iter.list.After())
iter.list = list
iter.err = err
}
@@ 199,7 206,7 @@ func (iter *hookIter) Scan() (hook.Hook, error) {
list := iter.list.List()
first, rest := list[0], list[1:]
- iter.list = newHookList(rest, iter.list.More(), iter.list.Before())
+ iter.list = newHookList(rest, iter.list.More(), iter.list.Before(), iter.list.After())
if err != nil {
return nil, err
}
@@ 217,12 224,14 @@ type HookList struct {
HookList []hook.Hook
HookListMore bool
HookListBefore int
+ HookListAfter int
}
-func newHookList(list []hook.Hook, hasMore bool, last int) *HookList {
- return &HookList{list, hasMore, last}
+func newHookList(list []hook.Hook, hasMore bool, last, first int) *HookList {
+ return &HookList{list, hasMore, last, first}
}
func (hl *HookList) List() []hook.Hook { return hl.HookList }
func (hl *HookList) More() bool { return hl.HookListMore }
func (hl *HookList) Before() int { return hl.HookListBefore }
+func (hl *HookList) After() int { return hl.HookListAfter }
M internal/s/db/space.go => internal/s/db/space.go +18 -9
@@ 341,22 341,25 @@ func (db *DB) SpaceDelete(user user.User, space space.Space) error {
return t.Commit()
}
-func (db *DB) spacesPerUser(t *sql.Tx, user user.User, before int) (space.SpaceList, error) {
+func (db *DB) spacesPerUser(t *sql.Tx, user user.User, perPage, before, after int) (space.SpaceList, error) {
var (
r []space.Space
+ first int
id int
hasMore bool
)
- before = beformat(before)
+ before = bfmt(before)
+ after = afmt(after)
+ perPage = pfmt(perPage)
q := `
SELECT SPACE_ID FROM cms_user_to_space
- WHERE USER_ID = ? AND SPACE_ID < ?
+ WHERE USER_ID = ? AND SPACE_ID < ? AND SPACE_ID > ?
ORDER BY SPACE_ID DESC LIMIT ?
`
- rows, err := db.Query(q, user.ID(), before, perPage+1)
+ rows, err := db.Query(q, user.ID(), before, after, perPage+1)
if err != nil {
return nil, err
}
@@ 371,6 374,10 @@ func (db *DB) spacesPerUser(t *sql.Tx, user user.User, before int) (space.SpaceL
return nil, err
}
+ if first == 0 {
+ first = id
+ }
+
s, err := db.spaceGet(t, user, strconv.Itoa(id))
if err != nil {
return nil, err
@@ 379,17 386,17 @@ func (db *DB) spacesPerUser(t *sql.Tx, user user.User, before int) (space.SpaceL
r = append(r, s)
}
- return newSpaceList(r, hasMore, id), nil
+ return newSpaceList(r, hasMore, id, first), nil
}
-func (db *DB) SpacesPerUser(user user.User, before int) (space.SpaceList, error) {
+func (db *DB) SpacesPerUser(user user.User, perPage, before, after int) (space.SpaceList, error) {
t, err := db.Begin()
if err != nil {
return nil, err
}
defer t.Rollback()
- list, err := db.spacesPerUser(t, user, before)
+ list, err := db.spacesPerUser(t, user, perPage, before, after)
if err != nil {
db.log.Println(err)
return nil, err
@@ 416,12 423,14 @@ type SpaceList struct {
SpaceList []space.Space
SpaceListMore bool
SpaceListBefore int
+ SpaceListAfter int
}
-func newSpaceList(list []space.Space, hasMore bool, last int) *SpaceList {
- return &SpaceList{list, hasMore, last}
+func newSpaceList(list []space.Space, hasMore bool, first, last int) *SpaceList {
+ return &SpaceList{list, hasMore, last, first}
}
func (sl *SpaceList) List() []space.Space { return sl.SpaceList }
func (sl *SpaceList) More() bool { return sl.SpaceListMore }
func (sl *SpaceList) Before() int { return sl.SpaceListBefore }
+func (sl *SpaceList) After() int { return sl.SpaceListAfter }
M internal/s/hook/hook.go => internal/s/hook/hook.go +9 -7
@@ 32,7 32,7 @@ type Hook struct {
}
type dber interface {
- HooksPerSpace(space space.Space, before int) (hook.HookList, error)
+ HooksPerSpace(space space.Space, perPage, before, after int) (hook.HookList, error)
}
func New(log *log.Logger, db dber) *Hook {
@@ 79,18 79,20 @@ func (h *Hook) do(ctx context.Context, content content.Content, hook hook.Hook,
func (h *Hook) Do(space space.Space, content content.Content, ht HookType) {
var (
- hooks hook.HookList
- before int
- err error
- eg errgroup.Group
- ctx, _ = context.WithTimeout(
+ hooks hook.HookList
+ perPage int
+ after int
+ before int
+ err error
+ eg errgroup.Group
+ ctx, _ = context.WithTimeout(
context.Background(),
10*time.Second, // TODO: May want to lower?
)
)
for i := 0; i == 0 || hooks.More(); i++ {
- hooks, err = h.db.HooksPerSpace(space, before)
+ hooks, err = h.db.HooksPerSpace(space, perPage, before, after)
if err != nil {
h.log.Println("failed to find webhooks for", space.ID(), space.Name(), err)
return