From d63715d4d97bc77eb63dfbe3d373f225d5267a84 Mon Sep 17 00:00:00 2001 From: Steven Date: Wed, 13 Sep 2023 20:42:44 +0800 Subject: [PATCH] feat: implement list memos filter --- api/v2/memo_service.go | 105 ++++++++++++------ proto/api/v2/memo_service.proto | 2 - proto/gen/api/v2/README.md | 1 - proto/gen/api/v2/memo_service.pb.go | 86 +++++++------- store/memo.go | 12 +- .../types/proto/api/v2/memo_service_pb.d.ts | 5 - web/src/types/proto/api/v2/memo_service_pb.js | 1 - 7 files changed, 117 insertions(+), 95 deletions(-) diff --git a/api/v2/memo_service.go b/api/v2/memo_service.go index 9d14a30c..5e2f7391 100644 --- a/api/v2/memo_service.go +++ b/api/v2/memo_service.go @@ -7,6 +7,7 @@ import ( "github.com/pkg/errors" apiv2pb "github.com/usememos/memos/proto/gen/api/v2" "github.com/usememos/memos/store" + v1alpha1 "google.golang.org/genproto/googleapis/api/expr/v1alpha1" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -26,19 +27,32 @@ func NewMemoService(store *store.Store) *MemoService { func (s *MemoService) ListMemos(ctx context.Context, request *apiv2pb.ListMemosRequest) (*apiv2pb.ListMemosResponse, error) { memoFind := &store.FindMemo{} + if request.Filter != "" { + filter, err := parseListMemosFilter(request.Filter) + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, "invalid filter: %v", err) + } + if filter.Visibility != nil { + memoFind.VisibilityList = []store.Visibility{*filter.Visibility} + } + if filter.CreatedTsBefore != nil { + memoFind.CreatedTsBefore = filter.CreatedTsBefore + } + if filter.CreatedTsAfter != nil { + memoFind.CreatedTsAfter = filter.CreatedTsAfter + } + } + userIDPtr := ctx.Value(UserIDContextKey) + // If the user is not authenticated, only public memos are visible. + if userIDPtr == nil { + memoFind.VisibilityList = []store.Visibility{store.Public} + } if request.PageSize != 0 { offset := int(request.Page * request.PageSize) limit := int(request.PageSize) memoFind.Offset = &offset memoFind.Limit = &limit } - if request.Filter != "" { - visibilityString, err := getVisibilityFilter(request.Filter) - if err != nil { - return nil, status.Errorf(codes.InvalidArgument, "invalid filter: %v", err) - } - memoFind.VisibilityList = []store.Visibility{store.Visibility(visibilityString)} - } memos, err := s.Store.ListMemos(ctx, memoFind) if err != nil { return nil, err @@ -49,9 +63,8 @@ func (s *MemoService) ListMemos(ctx context.Context, request *apiv2pb.ListMemosR memoMessages[i] = convertMemoFromStore(memo) } - // TODO(steven): Add privalige checks. response := &apiv2pb.ListMemosResponse{ - Memos: nil, + Memos: memoMessages, } return response, nil } @@ -83,39 +96,59 @@ func (s *MemoService) GetMemo(ctx context.Context, request *apiv2pb.GetMemoReque return response, nil } -// getVisibilityFilter will parse the simple filter such as `visibility = "PRIVATE"` to "PRIVATE" . -func getVisibilityFilter(filter string) (string, error) { - formatInvalidErr := errors.Errorf("invalid filter %q", filter) - e, err := cel.NewEnv(cel.Variable("visibility", cel.StringType)) +// ListMemosFilterCELAttributes are the CEL attributes for ListMemosFilter. +var ListMemosFilterCELAttributes = []cel.EnvOption{ + cel.Variable("visibility", cel.StringType), + cel.Variable("created_ts_before", cel.IntType), + cel.Variable("created_ts_after", cel.IntType), +} + +type ListMemosFilter struct { + Visibility *store.Visibility + CreatedTsBefore *int64 + CreatedTsAfter *int64 +} + +func parseListMemosFilter(expression string) (*ListMemosFilter, error) { + e, err := cel.NewEnv(ListMemosFilterCELAttributes...) if err != nil { - return "", err + return nil, err } - ast, issues := e.Compile(filter) + ast, issues := e.Compile(expression) if issues != nil { - return "", status.Errorf(codes.InvalidArgument, issues.String()) - } - expr := ast.Expr() - if expr == nil { - return "", formatInvalidErr - } - callExpr := expr.GetCallExpr() - if callExpr == nil { - return "", formatInvalidErr + return nil, errors.Errorf("found issue %v", issues) } - if callExpr.Function != "_==_" { - return "", formatInvalidErr - } - if len(callExpr.Args) != 2 { - return "", formatInvalidErr - } - if callExpr.Args[0].GetIdentExpr() == nil || callExpr.Args[0].GetIdentExpr().Name != "visibility" { - return "", formatInvalidErr + filter := &ListMemosFilter{} + callExpr := ast.Expr().GetCallExpr() + findField(callExpr, filter) + return filter, nil +} + +func findField(callExpr *v1alpha1.Expr_Call, filter *ListMemosFilter) { + if len(callExpr.Args) == 2 { + idExpr := callExpr.Args[0].GetIdentExpr() + if idExpr != nil { + if idExpr.Name == "visibility" { + visibility := store.Visibility(callExpr.Args[1].GetConstExpr().GetStringValue()) + filter.Visibility = &visibility + } + if idExpr.Name == "created_ts_before" { + createdTsBefore := callExpr.Args[1].GetConstExpr().GetInt64Value() + filter.CreatedTsBefore = &createdTsBefore + } + if idExpr.Name == "created_ts_after" { + createdTsAfter := callExpr.Args[1].GetConstExpr().GetInt64Value() + filter.CreatedTsAfter = &createdTsAfter + } + return + } } - constExpr := callExpr.Args[1].GetConstExpr() - if constExpr == nil { - return "", formatInvalidErr + for _, arg := range callExpr.Args { + callExpr := arg.GetCallExpr() + if callExpr != nil { + findField(callExpr, filter) + } } - return constExpr.GetStringValue(), nil } func convertMemoFromStore(memo *store.Memo) *apiv2pb.Memo { diff --git a/proto/api/v2/memo_service.proto b/proto/api/v2/memo_service.proto index 5957eaf3..2479f3d3 100644 --- a/proto/api/v2/memo_service.proto +++ b/proto/api/v2/memo_service.proto @@ -48,8 +48,6 @@ message ListMemosRequest { message ListMemosResponse { repeated Memo memos = 1; - - int32 total = 2; } message GetMemoRequest { diff --git a/proto/gen/api/v2/README.md b/proto/gen/api/v2/README.md index f7f5b54c..9bf1fe0b 100644 --- a/proto/gen/api/v2/README.md +++ b/proto/gen/api/v2/README.md @@ -143,7 +143,6 @@ | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | memos | [Memo](#memos-api-v2-Memo) | repeated | | -| total | [int32](#int32) | | | diff --git a/proto/gen/api/v2/memo_service.pb.go b/proto/gen/api/v2/memo_service.pb.go index 3690c8b4..50e6d497 100644 --- a/proto/gen/api/v2/memo_service.pb.go +++ b/proto/gen/api/v2/memo_service.pb.go @@ -246,7 +246,6 @@ type ListMemosResponse struct { unknownFields protoimpl.UnknownFields Memos []*Memo `protobuf:"bytes,1,rep,name=memos,proto3" json:"memos,omitempty"` - Total int32 `protobuf:"varint,2,opt,name=total,proto3" json:"total,omitempty"` } func (x *ListMemosResponse) Reset() { @@ -288,13 +287,6 @@ func (x *ListMemosResponse) GetMemos() []*Memo { return nil } -func (x *ListMemosResponse) GetTotal() int32 { - if x != nil { - return x.Total - } - return 0 -} - type GetMemoRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -422,49 +414,47 @@ var file_api_v2_memo_service_proto_rawDesc = []byte{ 0x05, 0x52, 0x04, 0x70, 0x61, 0x67, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, 0x53, 0x0a, 0x11, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, 0x3d, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x05, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, - 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x05, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x74, - 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, - 0x6c, 0x22, 0x20, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x02, 0x69, 0x64, 0x22, 0x39, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x04, 0x6d, 0x65, 0x6d, 0x6f, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, - 0x2e, 0x76, 0x32, 0x2e, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x04, 0x6d, 0x65, 0x6d, 0x6f, 0x2a, 0x50, - 0x0a, 0x0a, 0x56, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x1a, 0x0a, 0x16, - 0x56, 0x49, 0x53, 0x49, 0x42, 0x49, 0x4c, 0x49, 0x54, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, - 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x50, 0x52, 0x49, 0x56, - 0x41, 0x54, 0x45, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x50, 0x52, 0x4f, 0x54, 0x45, 0x43, 0x54, - 0x45, 0x44, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x10, 0x03, - 0x32, 0xdb, 0x01, 0x0a, 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x12, 0x63, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x12, 0x1e, 0x2e, - 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, - 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x15, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0f, 0x12, 0x0d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, - 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x12, 0x67, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x6d, 0x6f, - 0x12, 0x1c, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, - 0x47, 0x65, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, - 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, - 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0xda, - 0x41, 0x02, 0x69, 0x64, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x14, 0x12, 0x12, 0x2f, 0x61, 0x70, 0x69, - 0x2f, 0x76, 0x32, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x42, 0xa8, - 0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, - 0x2e, 0x76, 0x32, 0x42, 0x10, 0x4d, 0x65, 0x6d, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x75, 0x73, 0x65, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x65, 0x6d, - 0x6f, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x61, 0x70, 0x69, - 0x2f, 0x76, 0x32, 0x3b, 0x61, 0x70, 0x69, 0x76, 0x32, 0xa2, 0x02, 0x03, 0x4d, 0x41, 0x58, 0xaa, - 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x70, 0x69, 0x2e, 0x56, 0x32, 0xca, 0x02, - 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0xe2, 0x02, 0x18, - 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0x5c, 0x47, 0x50, 0x42, - 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0e, 0x4d, 0x65, 0x6d, 0x6f, 0x73, - 0x3a, 0x3a, 0x41, 0x70, 0x69, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x05, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x22, 0x20, 0x0a, 0x0e, 0x47, + 0x65, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x22, 0x39, 0x0a, + 0x0f, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x26, 0x0a, 0x04, 0x6d, 0x65, 0x6d, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, + 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4d, 0x65, + 0x6d, 0x6f, 0x52, 0x04, 0x6d, 0x65, 0x6d, 0x6f, 0x2a, 0x50, 0x0a, 0x0a, 0x56, 0x69, 0x73, 0x69, + 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x1a, 0x0a, 0x16, 0x56, 0x49, 0x53, 0x49, 0x42, 0x49, + 0x4c, 0x49, 0x54, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, + 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x10, 0x01, 0x12, + 0x0d, 0x0a, 0x09, 0x50, 0x52, 0x4f, 0x54, 0x45, 0x43, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x0a, + 0x0a, 0x06, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x10, 0x03, 0x32, 0xdb, 0x01, 0x0a, 0x0b, 0x4d, + 0x65, 0x6d, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x63, 0x0a, 0x09, 0x4c, 0x69, + 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x12, 0x1e, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x15, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0f, + 0x12, 0x0d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x12, + 0x67, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x12, 0x1c, 0x2e, 0x6d, 0x65, 0x6d, + 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x6d, + 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0xda, 0x41, 0x02, 0x69, 0x64, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x14, 0x12, 0x12, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x6d, 0x65, + 0x6d, 0x6f, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x42, 0xa8, 0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, + 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x42, 0x10, 0x4d, + 0x65, 0x6d, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, + 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x75, 0x73, + 0x65, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x3b, 0x61, 0x70, + 0x69, 0x76, 0x32, 0xa2, 0x02, 0x03, 0x4d, 0x41, 0x58, 0xaa, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, + 0x73, 0x2e, 0x41, 0x70, 0x69, 0x2e, 0x56, 0x32, 0xca, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, + 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0xe2, 0x02, 0x18, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, + 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0xea, 0x02, 0x0e, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x41, 0x70, 0x69, 0x3a, + 0x3a, 0x56, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/store/memo.go b/store/memo.go index af259b72..6fd39c3e 100644 --- a/store/memo.go +++ b/store/memo.go @@ -57,8 +57,10 @@ type FindMemo struct { ID *int32 // Standard fields - RowStatus *RowStatus - CreatorID *int32 + RowStatus *RowStatus + CreatorID *int32 + CreatedTsAfter *int64 + CreatedTsBefore *int64 // Domain specific fields Pinned *bool @@ -131,6 +133,12 @@ func (s *Store) ListMemos(ctx context.Context, find *FindMemo) ([]*Memo, error) if v := find.RowStatus; v != nil { where, args = append(where, "memo.row_status = ?"), append(args, *v) } + if v := find.CreatedTsBefore; v != nil { + where, args = append(where, "memo.created_ts < ?"), append(args, *v) + } + if v := find.CreatedTsAfter; v != nil { + where, args = append(where, "memo.created_ts > ?"), append(args, *v) + } if v := find.Pinned; v != nil { where = append(where, "memo_organizer.pinned = 1") } diff --git a/web/src/types/proto/api/v2/memo_service_pb.d.ts b/web/src/types/proto/api/v2/memo_service_pb.d.ts index 45b935b3..30839902 100644 --- a/web/src/types/proto/api/v2/memo_service_pb.d.ts +++ b/web/src/types/proto/api/v2/memo_service_pb.d.ts @@ -136,11 +136,6 @@ export declare class ListMemosResponse extends Message { */ memos: Memo[]; - /** - * @generated from field: int32 total = 2; - */ - total: number; - constructor(data?: PartialMessage); static readonly runtime: typeof proto3; diff --git a/web/src/types/proto/api/v2/memo_service_pb.js b/web/src/types/proto/api/v2/memo_service_pb.js index c77c4cf4..10f20597 100644 --- a/web/src/types/proto/api/v2/memo_service_pb.js +++ b/web/src/types/proto/api/v2/memo_service_pb.js @@ -55,7 +55,6 @@ export const ListMemosResponse = proto3.makeMessageType( "memos.api.v2.ListMemosResponse", () => [ { no: 1, name: "memos", kind: "message", T: Memo, repeated: true }, - { no: 2, name: "total", kind: "scalar", T: 5 /* ScalarType.INT32 */ }, ], );