2023-12-23 11:17:35 +08:00
|
|
|
package v2
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2024-03-19 21:53:44 +08:00
|
|
|
"fmt"
|
2023-12-23 11:17:35 +08:00
|
|
|
|
|
|
|
"google.golang.org/grpc/codes"
|
|
|
|
"google.golang.org/grpc/status"
|
|
|
|
|
|
|
|
apiv2pb "github.com/usememos/memos/proto/gen/api/v2"
|
|
|
|
"github.com/usememos/memos/store"
|
|
|
|
)
|
|
|
|
|
|
|
|
func (s *APIV2Service) SetMemoRelations(ctx context.Context, request *apiv2pb.SetMemoRelationsRequest) (*apiv2pb.SetMemoRelationsResponse, error) {
|
2024-03-18 23:23:53 +08:00
|
|
|
id, err := ExtractMemoIDFromName(request.Name)
|
|
|
|
if err != nil {
|
|
|
|
return nil, status.Errorf(codes.InvalidArgument, "invalid memo name: %v", err)
|
|
|
|
}
|
2023-12-23 11:17:35 +08:00
|
|
|
referenceType := store.MemoRelationReference
|
|
|
|
// Delete all reference relations first.
|
|
|
|
if err := s.Store.DeleteMemoRelation(ctx, &store.DeleteMemoRelation{
|
2024-03-18 23:23:53 +08:00
|
|
|
MemoID: &id,
|
2023-12-23 11:17:35 +08:00
|
|
|
Type: &referenceType,
|
|
|
|
}); err != nil {
|
|
|
|
return nil, status.Errorf(codes.Internal, "failed to delete memo relation")
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, relation := range request.Relations {
|
2024-01-13 07:21:19 +08:00
|
|
|
// Ignore reflexive relations.
|
2024-03-19 21:53:44 +08:00
|
|
|
if request.Name == relation.RelatedMemo {
|
2024-01-13 07:21:19 +08:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
// Ignore comment relations as there's no need to update a comment's relation.
|
|
|
|
// Inserting/Deleting a comment is handled elsewhere.
|
|
|
|
if relation.Type == apiv2pb.MemoRelation_COMMENT {
|
|
|
|
continue
|
|
|
|
}
|
2024-03-19 21:53:44 +08:00
|
|
|
relatedMemoID, err := ExtractMemoIDFromName(relation.RelatedMemo)
|
|
|
|
if err != nil {
|
|
|
|
return nil, status.Errorf(codes.InvalidArgument, "invalid related memo name: %v", err)
|
|
|
|
}
|
2023-12-23 11:17:35 +08:00
|
|
|
if _, err := s.Store.UpsertMemoRelation(ctx, &store.MemoRelation{
|
2024-03-18 23:23:53 +08:00
|
|
|
MemoID: id,
|
2024-03-19 21:53:44 +08:00
|
|
|
RelatedMemoID: relatedMemoID,
|
2023-12-23 11:17:35 +08:00
|
|
|
Type: convertMemoRelationTypeToStore(relation.Type),
|
|
|
|
}); err != nil {
|
|
|
|
return nil, status.Errorf(codes.Internal, "failed to upsert memo relation")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return &apiv2pb.SetMemoRelationsResponse{}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *APIV2Service) ListMemoRelations(ctx context.Context, request *apiv2pb.ListMemoRelationsRequest) (*apiv2pb.ListMemoRelationsResponse, error) {
|
2024-03-18 23:23:53 +08:00
|
|
|
id, err := ExtractMemoIDFromName(request.Name)
|
|
|
|
if err != nil {
|
|
|
|
return nil, status.Errorf(codes.InvalidArgument, "invalid memo name: %v", err)
|
|
|
|
}
|
2023-12-23 11:17:35 +08:00
|
|
|
relationList := []*apiv2pb.MemoRelation{}
|
|
|
|
tempList, err := s.Store.ListMemoRelations(ctx, &store.FindMemoRelation{
|
2024-03-18 23:23:53 +08:00
|
|
|
MemoID: &id,
|
2023-12-23 11:17:35 +08:00
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
for _, relation := range tempList {
|
|
|
|
relationList = append(relationList, convertMemoRelationFromStore(relation))
|
|
|
|
}
|
|
|
|
tempList, err = s.Store.ListMemoRelations(ctx, &store.FindMemoRelation{
|
2024-03-18 23:23:53 +08:00
|
|
|
RelatedMemoID: &id,
|
2023-12-23 11:17:35 +08:00
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
for _, relation := range tempList {
|
|
|
|
relationList = append(relationList, convertMemoRelationFromStore(relation))
|
|
|
|
}
|
|
|
|
|
|
|
|
response := &apiv2pb.ListMemoRelationsResponse{
|
|
|
|
Relations: relationList,
|
|
|
|
}
|
|
|
|
return response, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func convertMemoRelationFromStore(memoRelation *store.MemoRelation) *apiv2pb.MemoRelation {
|
|
|
|
return &apiv2pb.MemoRelation{
|
2024-03-19 21:53:44 +08:00
|
|
|
Memo: fmt.Sprintf("%s%d", MemoNamePrefix, memoRelation.MemoID),
|
|
|
|
RelatedMemo: fmt.Sprintf("%s%d", MemoNamePrefix, memoRelation.RelatedMemoID),
|
|
|
|
Type: convertMemoRelationTypeFromStore(memoRelation.Type),
|
2023-12-23 11:17:35 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func convertMemoRelationTypeFromStore(relationType store.MemoRelationType) apiv2pb.MemoRelation_Type {
|
|
|
|
switch relationType {
|
|
|
|
case store.MemoRelationReference:
|
|
|
|
return apiv2pb.MemoRelation_REFERENCE
|
|
|
|
case store.MemoRelationComment:
|
|
|
|
return apiv2pb.MemoRelation_COMMENT
|
|
|
|
default:
|
|
|
|
return apiv2pb.MemoRelation_TYPE_UNSPECIFIED
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func convertMemoRelationTypeToStore(relationType apiv2pb.MemoRelation_Type) store.MemoRelationType {
|
|
|
|
switch relationType {
|
|
|
|
case apiv2pb.MemoRelation_REFERENCE:
|
|
|
|
return store.MemoRelationReference
|
|
|
|
case apiv2pb.MemoRelation_COMMENT:
|
|
|
|
return store.MemoRelationComment
|
|
|
|
default:
|
|
|
|
return store.MemoRelationReference
|
|
|
|
}
|
|
|
|
}
|