From bb10bb200c74865832648f1ff771795444a37b1f Mon Sep 17 00:00:00 2001 From: Steven Date: Sat, 30 Mar 2024 13:50:18 +0800 Subject: [PATCH] chore: implement search random memos --- server/route/api/v2/memo_service.go | 23 ++++++++++++++++++++--- store/db/mysql/memo.go | 3 +++ store/db/postgres/memo.go | 3 +++ store/db/sqlite/memo.go | 15 +++++++++------ store/memo.go | 1 + 5 files changed, 36 insertions(+), 9 deletions(-) diff --git a/server/route/api/v2/memo_service.go b/server/route/api/v2/memo_service.go index c9173583..bba8a887 100644 --- a/server/route/api/v2/memo_service.go +++ b/server/route/api/v2/memo_service.go @@ -134,16 +134,17 @@ func (s *APIV2Service) ListMemos(ctx context.Context, request *apiv2pb.ListMemos } func (s *APIV2Service) SearchMemos(ctx context.Context, request *apiv2pb.SearchMemosRequest) (*apiv2pb.SearchMemosResponse, error) { + defaultSearchLimit := 10 memoFind := &store.FindMemo{ // Exclude comments by default. ExcludeComments: true, + Limit: &defaultSearchLimit, } - if err := s.buildMemoFindWithFilter(ctx, memoFind, request.Filter); err != nil { + err := s.buildMemoFindWithFilter(ctx, memoFind, request.Filter) + if err != nil { return nil, status.Errorf(codes.InvalidArgument, "failed to build find memos with filter") } - defaultSearchLimit := 10 - memoFind.Limit = &defaultSearchLimit memos, err := s.Store.ListMemos(ctx, memoFind) if err != nil { return nil, status.Errorf(codes.Internal, "failed to search memos") @@ -696,6 +697,12 @@ func (s *APIV2Service) buildMemoFindWithFilter(ctx context.Context, find *store. if filter.RowStatus != nil { find.RowStatus = filter.RowStatus } + if filter.Random { + find.Random = filter.Random + } + if filter.Limit != nil { + find.Limit = filter.Limit + } } // If the user is not authenticated, only public memos are visible. @@ -730,6 +737,8 @@ var SearchMemosFilterCELAttributes = []cel.EnvOption{ cel.Variable("creator", cel.StringType), cel.Variable("uid", cel.StringType), cel.Variable("row_status", cel.StringType), + cel.Variable("random", cel.BoolType), + cel.Variable("limit", cel.IntType), } type SearchMemosFilter struct { @@ -741,6 +750,8 @@ type SearchMemosFilter struct { Creator *string UID *string RowStatus *store.RowStatus + Random bool + Limit *int } func parseSearchMemosFilter(expression string) (*SearchMemosFilter, error) { @@ -798,6 +809,12 @@ func findSearchMemosField(callExpr *expr.Expr_Call, filter *SearchMemosFilter) { } else if idExpr.Name == "row_status" { rowStatus := store.RowStatus(callExpr.Args[1].GetConstExpr().GetStringValue()) filter.RowStatus = &rowStatus + } else if idExpr.Name == "random" { + value := callExpr.Args[1].GetConstExpr().GetBoolValue() + filter.Random = value + } else if idExpr.Name == "limit" { + limit := int(callExpr.Args[1].GetConstExpr().GetInt64Value()) + filter.Limit = &limit } return } diff --git a/store/db/mysql/memo.go b/store/db/mysql/memo.go index 4ed837d4..33b95b33 100644 --- a/store/db/mysql/memo.go +++ b/store/db/mysql/memo.go @@ -91,6 +91,9 @@ func (d *DB) ListMemos(ctx context.Context, find *store.FindMemo) ([]*store.Memo orders = append(orders, "`created_ts` DESC") } orders = append(orders, "`id` DESC") + if find.Random { + orders = append(orders, "RAND()") + } fields := []string{ "`memo`.`id` AS `id`", diff --git a/store/db/postgres/memo.go b/store/db/postgres/memo.go index bfae66eb..a4284ae5 100644 --- a/store/db/postgres/memo.go +++ b/store/db/postgres/memo.go @@ -82,6 +82,9 @@ func (d *DB) ListMemos(ctx context.Context, find *store.FindMemo) ([]*store.Memo orders = append(orders, "created_ts DESC") } orders = append(orders, "id DESC") + if find.Random { + orders = append(orders, "RAND()") + } fields := []string{ `memo.id AS id`, diff --git a/store/db/sqlite/memo.go b/store/db/sqlite/memo.go index 38b63318..a00b941c 100644 --- a/store/db/sqlite/memo.go +++ b/store/db/sqlite/memo.go @@ -71,16 +71,19 @@ func (d *DB) ListMemos(ctx context.Context, find *store.FindMemo) ([]*store.Memo where = append(where, "`parent_id` IS NULL") } - orders := []string{} + orderBy := []string{} if find.OrderByPinned { - orders = append(orders, "`pinned` DESC") + orderBy = append(orderBy, "`pinned` DESC") } if find.OrderByUpdatedTs { - orders = append(orders, "`updated_ts` DESC") + orderBy = append(orderBy, "`updated_ts` DESC") } else { - orders = append(orders, "`created_ts` DESC") + orderBy = append(orderBy, "`created_ts` DESC") + } + orderBy = append(orderBy, "`id` DESC") + if find.Random { + orderBy = []string{"RANDOM()"} } - orders = append(orders, "`id` DESC") fields := []string{ "`memo`.`id` AS `id`", @@ -101,7 +104,7 @@ func (d *DB) ListMemos(ctx context.Context, find *store.FindMemo) ([]*store.Memo "LEFT JOIN `memo_organizer` ON `memo`.`id` = `memo_organizer`.`memo_id` AND `memo`.`creator_id` = `memo_organizer`.`user_id` " + "LEFT JOIN `memo_relation` ON `memo`.`id` = `memo_relation`.`memo_id` AND `memo_relation`.`type` = \"COMMENT\" " + "WHERE " + strings.Join(where, " AND ") + " " + - "ORDER BY " + strings.Join(orders, ", ") + "ORDER BY " + strings.Join(orderBy, ", ") if find.Limit != nil { query = fmt.Sprintf("%s LIMIT %d", query, *find.Limit) if find.Offset != nil { diff --git a/store/memo.go b/store/memo.go index 77c6985b..5de413b9 100644 --- a/store/memo.go +++ b/store/memo.go @@ -69,6 +69,7 @@ type FindMemo struct { VisibilityList []Visibility ExcludeContent bool ExcludeComments bool + Random bool // Pagination Limit *int