Skip to content

Commit

Permalink
chore: add pagination to list inboxes
Browse files Browse the repository at this point in the history
  • Loading branch information
boojack committed Oct 14, 2024
1 parent b4d72e3 commit 14712b4
Show file tree
Hide file tree
Showing 9 changed files with 170 additions and 55 deletions.
10 changes: 10 additions & 0 deletions proto/api/v1/inbox_service.proto
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,20 @@ message Inbox {
message ListInboxesRequest {
// Format: users/{id}
string user = 1;

// The maximum number of inbox to return.
int32 page_size = 2;

// Provide this to retrieve the subsequent page.
string page_token = 3;
}

message ListInboxesResponse {
repeated Inbox inboxes = 1;

// A token, which can be sent as `page_token` to retrieve the next page.
// If this field is omitted, there are no subsequent pages.
string next_page_token = 2;
}

message UpdateInboxRequest {
Expand Down
137 changes: 86 additions & 51 deletions proto/gen/api/v1/inbox_service.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions proto/gen/apidocs.swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,17 @@ paths:
in: query
required: false
type: string
- name: pageSize
description: The maximum number of inbox to return.
in: query
required: false
type: integer
format: int32
- name: pageToken
description: Provide this to retrieve the subsequent page.
in: query
required: false
type: string
tags:
- InboxService
/api/v1/markdown/link:metadata:
Expand Down Expand Up @@ -2491,6 +2502,11 @@ definitions:
items:
type: object
$ref: '#/definitions/v1Inbox'
nextPageToken:
type: string
description: |-
A token, which can be sent as `page_token` to retrieve the next page.
If this field is omitted, there are no subsequent pages.
v1ListMemoCommentsResponse:
type: object
properties:
Expand Down
36 changes: 32 additions & 4 deletions server/router/api/v1/inbox_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,30 +14,58 @@ import (
"github.com/usememos/memos/store"
)

func (s *APIV1Service) ListInboxes(ctx context.Context, _ *v1pb.ListInboxesRequest) (*v1pb.ListInboxesResponse, error) {
func (s *APIV1Service) ListInboxes(ctx context.Context, request *v1pb.ListInboxesRequest) (*v1pb.ListInboxesResponse, error) {
user, err := s.GetCurrentUser(ctx)
if err != nil {
return nil, status.Errorf(codes.Internal, "failed to get user")
}

var limit, offset int
if request.PageToken != "" {
var pageToken v1pb.PageToken
if err := unmarshalPageToken(request.PageToken, &pageToken); err != nil {
return nil, status.Errorf(codes.InvalidArgument, "invalid page token: %v", err)
}
limit = int(pageToken.Limit)
offset = int(pageToken.Offset)
} else {
limit = int(request.PageSize)
}
if limit <= 0 {
limit = DefaultPageSize
}
limitPlusOne := limit + 1

inboxes, err := s.Store.ListInboxes(ctx, &store.FindInbox{
ReceiverID: &user.ID,
Limit: &limitPlusOne,
Offset: &offset,
})
if err != nil {
return nil, status.Errorf(codes.Internal, "failed to list inbox: %v", err)
}

response := &v1pb.ListInboxesResponse{
Inboxes: []*v1pb.Inbox{},
inboxMessages := []*v1pb.Inbox{}
nextPageToken := ""
if len(inboxes) == limitPlusOne {
inboxes = inboxes[:limit]
nextPageToken, err = getPageToken(limit, offset+limit)
if err != nil {
return nil, status.Errorf(codes.Internal, "failed to get next page token, error: %v", err)
}
}
for _, inbox := range inboxes {
inboxMessage := convertInboxFromStore(inbox)
if inboxMessage.Type == v1pb.Inbox_TYPE_UNSPECIFIED {
continue
}
response.Inboxes = append(response.Inboxes, inboxMessage)
inboxMessages = append(inboxMessages, inboxMessage)
}

response := &v1pb.ListInboxesResponse{
Inboxes: inboxMessages,
NextPageToken: nextPageToken,
}
return response, nil
}

Expand Down
1 change: 1 addition & 0 deletions server/router/api/v1/memo_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
)

const (
// DefaultPageSize is the default page size for listing memos.
DefaultPageSize = 10
)

Expand Down
7 changes: 7 additions & 0 deletions store/db/mysql/inbox.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package mysql

import (
"context"
"fmt"
"strings"

"github.com/pkg/errors"
Expand Down Expand Up @@ -61,6 +62,12 @@ func (d *DB) ListInboxes(ctx context.Context, find *store.FindInbox) ([]*store.I
}

query := "SELECT `id`, UNIX_TIMESTAMP(`created_ts`), `sender_id`, `receiver_id`, `status`, `message` FROM `inbox` WHERE " + strings.Join(where, " AND ") + " ORDER BY `created_ts` DESC"
if find.Limit != nil {
query = fmt.Sprintf("%s LIMIT %d", query, *find.Limit)
if find.Offset != nil {
query = fmt.Sprintf("%s OFFSET %d", query, *find.Offset)
}
}
rows, err := d.db.QueryContext(ctx, query, args...)
if err != nil {
return nil, err
Expand Down
7 changes: 7 additions & 0 deletions store/db/postgres/inbox.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package postgres

import (
"context"
"fmt"
"strings"

"github.com/pkg/errors"
Expand Down Expand Up @@ -51,6 +52,12 @@ func (d *DB) ListInboxes(ctx context.Context, find *store.FindInbox) ([]*store.I
}

query := "SELECT id, created_ts, sender_id, receiver_id, status, message FROM inbox WHERE " + strings.Join(where, " AND ") + " ORDER BY created_ts DESC"
if find.Limit != nil {
query = fmt.Sprintf("%s LIMIT %d", query, *find.Limit)
if find.Offset != nil {
query = fmt.Sprintf("%s OFFSET %d", query, *find.Offset)
}
}
rows, err := d.db.QueryContext(ctx, query, args...)
if err != nil {
return nil, err
Expand Down
7 changes: 7 additions & 0 deletions store/db/sqlite/inbox.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package sqlite

import (
"context"
"fmt"
"strings"

"github.com/pkg/errors"
Expand Down Expand Up @@ -53,6 +54,12 @@ func (d *DB) ListInboxes(ctx context.Context, find *store.FindInbox) ([]*store.I
}

query := "SELECT `id`, `created_ts`, `sender_id`, `receiver_id`, `status`, `message` FROM `inbox` WHERE " + strings.Join(where, " AND ") + " ORDER BY `created_ts` DESC"
if find.Limit != nil {
query = fmt.Sprintf("%s LIMIT %d", query, *find.Limit)
if find.Offset != nil {
query = fmt.Sprintf("%s OFFSET %d", query, *find.Offset)
}
}
rows, err := d.db.QueryContext(ctx, query, args...)
if err != nil {
return nil, err
Expand Down
4 changes: 4 additions & 0 deletions store/inbox.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ type FindInbox struct {
SenderID *int32
ReceiverID *int32
Status *InboxStatus

// Pagination
Limit *int
Offset *int
}

type DeleteInbox struct {
Expand Down

0 comments on commit 14712b4

Please sign in to comment.