mirror of
https://github.com/usememos/memos.git
synced 2025-03-07 02:53:29 +08:00
feat: implement memo property
This commit is contained in:
parent
555b4fbe32
commit
c561362d62
13 changed files with 883 additions and 593 deletions
|
@ -1462,6 +1462,36 @@ paths:
|
|||
pattern: users/[^/]+
|
||||
tags:
|
||||
- UserService
|
||||
/api/v1/{name}:rebuild:
|
||||
post:
|
||||
summary: RebuildMemoProperty rebuilds a memo property.
|
||||
operationId: MemoService_RebuildMemoProperty
|
||||
responses:
|
||||
"200":
|
||||
description: A successful response.
|
||||
schema:
|
||||
type: object
|
||||
properties: {}
|
||||
default:
|
||||
description: An unexpected error response.
|
||||
schema:
|
||||
$ref: '#/definitions/googlerpcStatus'
|
||||
parameters:
|
||||
- name: name
|
||||
description: |-
|
||||
The name of the memo.
|
||||
Format: memos/{id}. Use "memos/-" to rebuild all memos.
|
||||
in: path
|
||||
required: true
|
||||
type: string
|
||||
pattern: memos/[^/]+
|
||||
- name: body
|
||||
in: body
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/MemoServiceRebuildMemoPropertyBody'
|
||||
tags:
|
||||
- MemoService
|
||||
/api/v1/{parent}/tags:
|
||||
get:
|
||||
summary: ListMemoTags lists tags for a memo.
|
||||
|
@ -1484,11 +1514,6 @@ paths:
|
|||
required: true
|
||||
type: string
|
||||
pattern: memos/[^/]+
|
||||
- name: rebuild
|
||||
description: Rebuild the tags.
|
||||
in: query
|
||||
required: false
|
||||
type: boolean
|
||||
tags:
|
||||
- MemoService
|
||||
/api/v1/{parent}/tags/{tag}:
|
||||
|
@ -1765,6 +1790,8 @@ paths:
|
|||
tags:
|
||||
- UserService
|
||||
definitions:
|
||||
MemoServiceRebuildMemoPropertyBody:
|
||||
type: object
|
||||
MemoServiceRenameMemoTagBody:
|
||||
type: object
|
||||
properties:
|
||||
|
|
|
@ -57,6 +57,13 @@ service MemoService {
|
|||
body: "*"
|
||||
};
|
||||
}
|
||||
// RebuildMemoProperty rebuilds a memo property.
|
||||
rpc RebuildMemoProperty(RebuildMemoPropertyRequest) returns (google.protobuf.Empty) {
|
||||
option (google.api.http) = {
|
||||
post: "/api/v1/{name=memos/*}:rebuild"
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
// ListMemoTags lists tags for a memo.
|
||||
rpc ListMemoTags(ListMemoTagsRequest) returns (ListMemoTagsResponse) {
|
||||
option (google.api.http) = {get: "/api/v1/{parent=memos/*}/tags"};
|
||||
|
@ -247,13 +254,16 @@ message ExportMemosResponse {
|
|||
bytes content = 1;
|
||||
}
|
||||
|
||||
message RebuildMemoPropertyRequest {
|
||||
// The name of the memo.
|
||||
// Format: memos/{id}. Use "memos/-" to rebuild all memos.
|
||||
string name = 1;
|
||||
}
|
||||
|
||||
message ListMemoTagsRequest {
|
||||
// The parent, who owns the tags.
|
||||
// Format: memos/{id}. Use "memos/-" to list all tags.
|
||||
string parent = 1;
|
||||
|
||||
// Rebuild the tags.
|
||||
bool rebuild = 2;
|
||||
}
|
||||
|
||||
message ListMemoTagsResponse {
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -359,9 +359,65 @@ func local_request_MemoService_ExportMemos_0(ctx context.Context, marshaler runt
|
|||
|
||||
}
|
||||
|
||||
var (
|
||||
filter_MemoService_ListMemoTags_0 = &utilities.DoubleArray{Encoding: map[string]int{"parent": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}}
|
||||
)
|
||||
func request_MemoService_RebuildMemoProperty_0(ctx context.Context, marshaler runtime.Marshaler, client MemoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq RebuildMemoPropertyRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["name"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name")
|
||||
}
|
||||
|
||||
protoReq.Name, err = runtime.String(val)
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err)
|
||||
}
|
||||
|
||||
msg, err := client.RebuildMemoProperty(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_MemoService_RebuildMemoProperty_0(ctx context.Context, marshaler runtime.Marshaler, server MemoServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq RebuildMemoPropertyRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["name"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name")
|
||||
}
|
||||
|
||||
protoReq.Name, err = runtime.String(val)
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err)
|
||||
}
|
||||
|
||||
msg, err := server.RebuildMemoProperty(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func request_MemoService_ListMemoTags_0(ctx context.Context, marshaler runtime.Marshaler, client MemoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq ListMemoTagsRequest
|
||||
|
@ -384,13 +440,6 @@ func request_MemoService_ListMemoTags_0(ctx context.Context, marshaler runtime.M
|
|||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "parent", err)
|
||||
}
|
||||
|
||||
if err := req.ParseForm(); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_MemoService_ListMemoTags_0); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := client.ListMemoTags(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
|
@ -417,13 +466,6 @@ func local_request_MemoService_ListMemoTags_0(ctx context.Context, marshaler run
|
|||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "parent", err)
|
||||
}
|
||||
|
||||
if err := req.ParseForm(); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_MemoService_ListMemoTags_0); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := server.ListMemoTags(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
|
@ -1296,6 +1338,31 @@ func RegisterMemoServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux
|
|||
|
||||
})
|
||||
|
||||
mux.Handle("POST", pattern_MemoService_RebuildMemoProperty_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
var stream runtime.ServerTransportStream
|
||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
var err error
|
||||
var annotatedContext context.Context
|
||||
annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.MemoService/RebuildMemoProperty", runtime.WithHTTPPathPattern("/api/v1/{name=memos/*}:rebuild"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_MemoService_RebuildMemoProperty_0(annotatedContext, inboundMarshaler, server, req, pathParams)
|
||||
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_MemoService_RebuildMemoProperty_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_MemoService_ListMemoTags_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
|
@ -1816,6 +1883,28 @@ func RegisterMemoServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux
|
|||
|
||||
})
|
||||
|
||||
mux.Handle("POST", pattern_MemoService_RebuildMemoProperty_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
var err error
|
||||
var annotatedContext context.Context
|
||||
annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.MemoService/RebuildMemoProperty", runtime.WithHTTPPathPattern("/api/v1/{name=memos/*}:rebuild"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_MemoService_RebuildMemoProperty_0(annotatedContext, inboundMarshaler, client, req, pathParams)
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_MemoService_RebuildMemoProperty_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_MemoService_ListMemoTags_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
|
@ -2120,6 +2209,8 @@ var (
|
|||
|
||||
pattern_MemoService_ExportMemos_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "memos"}, "export"))
|
||||
|
||||
pattern_MemoService_RebuildMemoProperty_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3}, []string{"api", "v1", "memos", "name"}, "rebuild"))
|
||||
|
||||
pattern_MemoService_ListMemoTags_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3, 2, 4}, []string{"api", "v1", "memos", "parent", "tags"}, ""))
|
||||
|
||||
pattern_MemoService_RenameMemoTag_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3, 2, 4}, []string{"api", "v1", "memos", "parent", "tags"}, "rename"))
|
||||
|
@ -2162,6 +2253,8 @@ var (
|
|||
|
||||
forward_MemoService_ExportMemos_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_MemoService_RebuildMemoProperty_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_MemoService_ListMemoTags_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_MemoService_RenameMemoTag_0 = runtime.ForwardResponseMessage
|
||||
|
|
|
@ -20,26 +20,27 @@ import (
|
|||
const _ = grpc.SupportPackageIsVersion7
|
||||
|
||||
const (
|
||||
MemoService_CreateMemo_FullMethodName = "/memos.api.v1.MemoService/CreateMemo"
|
||||
MemoService_ListMemos_FullMethodName = "/memos.api.v1.MemoService/ListMemos"
|
||||
MemoService_SearchMemos_FullMethodName = "/memos.api.v1.MemoService/SearchMemos"
|
||||
MemoService_GetMemo_FullMethodName = "/memos.api.v1.MemoService/GetMemo"
|
||||
MemoService_UpdateMemo_FullMethodName = "/memos.api.v1.MemoService/UpdateMemo"
|
||||
MemoService_DeleteMemo_FullMethodName = "/memos.api.v1.MemoService/DeleteMemo"
|
||||
MemoService_ExportMemos_FullMethodName = "/memos.api.v1.MemoService/ExportMemos"
|
||||
MemoService_ListMemoTags_FullMethodName = "/memos.api.v1.MemoService/ListMemoTags"
|
||||
MemoService_RenameMemoTag_FullMethodName = "/memos.api.v1.MemoService/RenameMemoTag"
|
||||
MemoService_DeleteMemoTag_FullMethodName = "/memos.api.v1.MemoService/DeleteMemoTag"
|
||||
MemoService_SetMemoResources_FullMethodName = "/memos.api.v1.MemoService/SetMemoResources"
|
||||
MemoService_ListMemoResources_FullMethodName = "/memos.api.v1.MemoService/ListMemoResources"
|
||||
MemoService_SetMemoRelations_FullMethodName = "/memos.api.v1.MemoService/SetMemoRelations"
|
||||
MemoService_ListMemoRelations_FullMethodName = "/memos.api.v1.MemoService/ListMemoRelations"
|
||||
MemoService_CreateMemoComment_FullMethodName = "/memos.api.v1.MemoService/CreateMemoComment"
|
||||
MemoService_ListMemoComments_FullMethodName = "/memos.api.v1.MemoService/ListMemoComments"
|
||||
MemoService_GetUserMemosStats_FullMethodName = "/memos.api.v1.MemoService/GetUserMemosStats"
|
||||
MemoService_ListMemoReactions_FullMethodName = "/memos.api.v1.MemoService/ListMemoReactions"
|
||||
MemoService_UpsertMemoReaction_FullMethodName = "/memos.api.v1.MemoService/UpsertMemoReaction"
|
||||
MemoService_DeleteMemoReaction_FullMethodName = "/memos.api.v1.MemoService/DeleteMemoReaction"
|
||||
MemoService_CreateMemo_FullMethodName = "/memos.api.v1.MemoService/CreateMemo"
|
||||
MemoService_ListMemos_FullMethodName = "/memos.api.v1.MemoService/ListMemos"
|
||||
MemoService_SearchMemos_FullMethodName = "/memos.api.v1.MemoService/SearchMemos"
|
||||
MemoService_GetMemo_FullMethodName = "/memos.api.v1.MemoService/GetMemo"
|
||||
MemoService_UpdateMemo_FullMethodName = "/memos.api.v1.MemoService/UpdateMemo"
|
||||
MemoService_DeleteMemo_FullMethodName = "/memos.api.v1.MemoService/DeleteMemo"
|
||||
MemoService_ExportMemos_FullMethodName = "/memos.api.v1.MemoService/ExportMemos"
|
||||
MemoService_RebuildMemoProperty_FullMethodName = "/memos.api.v1.MemoService/RebuildMemoProperty"
|
||||
MemoService_ListMemoTags_FullMethodName = "/memos.api.v1.MemoService/ListMemoTags"
|
||||
MemoService_RenameMemoTag_FullMethodName = "/memos.api.v1.MemoService/RenameMemoTag"
|
||||
MemoService_DeleteMemoTag_FullMethodName = "/memos.api.v1.MemoService/DeleteMemoTag"
|
||||
MemoService_SetMemoResources_FullMethodName = "/memos.api.v1.MemoService/SetMemoResources"
|
||||
MemoService_ListMemoResources_FullMethodName = "/memos.api.v1.MemoService/ListMemoResources"
|
||||
MemoService_SetMemoRelations_FullMethodName = "/memos.api.v1.MemoService/SetMemoRelations"
|
||||
MemoService_ListMemoRelations_FullMethodName = "/memos.api.v1.MemoService/ListMemoRelations"
|
||||
MemoService_CreateMemoComment_FullMethodName = "/memos.api.v1.MemoService/CreateMemoComment"
|
||||
MemoService_ListMemoComments_FullMethodName = "/memos.api.v1.MemoService/ListMemoComments"
|
||||
MemoService_GetUserMemosStats_FullMethodName = "/memos.api.v1.MemoService/GetUserMemosStats"
|
||||
MemoService_ListMemoReactions_FullMethodName = "/memos.api.v1.MemoService/ListMemoReactions"
|
||||
MemoService_UpsertMemoReaction_FullMethodName = "/memos.api.v1.MemoService/UpsertMemoReaction"
|
||||
MemoService_DeleteMemoReaction_FullMethodName = "/memos.api.v1.MemoService/DeleteMemoReaction"
|
||||
)
|
||||
|
||||
// MemoServiceClient is the client API for MemoService service.
|
||||
|
@ -60,6 +61,8 @@ type MemoServiceClient interface {
|
|||
DeleteMemo(ctx context.Context, in *DeleteMemoRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
|
||||
// ExportMemos exports memos.
|
||||
ExportMemos(ctx context.Context, in *ExportMemosRequest, opts ...grpc.CallOption) (*ExportMemosResponse, error)
|
||||
// RebuildMemoProperty rebuilds a memo property.
|
||||
RebuildMemoProperty(ctx context.Context, in *RebuildMemoPropertyRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
|
||||
// ListMemoTags lists tags for a memo.
|
||||
ListMemoTags(ctx context.Context, in *ListMemoTagsRequest, opts ...grpc.CallOption) (*ListMemoTagsResponse, error)
|
||||
// RenameMemoTag renames a tag for a memo.
|
||||
|
@ -159,6 +162,15 @@ func (c *memoServiceClient) ExportMemos(ctx context.Context, in *ExportMemosRequ
|
|||
return out, nil
|
||||
}
|
||||
|
||||
func (c *memoServiceClient) RebuildMemoProperty(ctx context.Context, in *RebuildMemoPropertyRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) {
|
||||
out := new(emptypb.Empty)
|
||||
err := c.cc.Invoke(ctx, MemoService_RebuildMemoProperty_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *memoServiceClient) ListMemoTags(ctx context.Context, in *ListMemoTagsRequest, opts ...grpc.CallOption) (*ListMemoTagsResponse, error) {
|
||||
out := new(ListMemoTagsResponse)
|
||||
err := c.cc.Invoke(ctx, MemoService_ListMemoTags_FullMethodName, in, out, opts...)
|
||||
|
@ -294,6 +306,8 @@ type MemoServiceServer interface {
|
|||
DeleteMemo(context.Context, *DeleteMemoRequest) (*emptypb.Empty, error)
|
||||
// ExportMemos exports memos.
|
||||
ExportMemos(context.Context, *ExportMemosRequest) (*ExportMemosResponse, error)
|
||||
// RebuildMemoProperty rebuilds a memo property.
|
||||
RebuildMemoProperty(context.Context, *RebuildMemoPropertyRequest) (*emptypb.Empty, error)
|
||||
// ListMemoTags lists tags for a memo.
|
||||
ListMemoTags(context.Context, *ListMemoTagsRequest) (*ListMemoTagsResponse, error)
|
||||
// RenameMemoTag renames a tag for a memo.
|
||||
|
@ -348,6 +362,9 @@ func (UnimplementedMemoServiceServer) DeleteMemo(context.Context, *DeleteMemoReq
|
|||
func (UnimplementedMemoServiceServer) ExportMemos(context.Context, *ExportMemosRequest) (*ExportMemosResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method ExportMemos not implemented")
|
||||
}
|
||||
func (UnimplementedMemoServiceServer) RebuildMemoProperty(context.Context, *RebuildMemoPropertyRequest) (*emptypb.Empty, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method RebuildMemoProperty not implemented")
|
||||
}
|
||||
func (UnimplementedMemoServiceServer) ListMemoTags(context.Context, *ListMemoTagsRequest) (*ListMemoTagsResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method ListMemoTags not implemented")
|
||||
}
|
||||
|
@ -526,6 +543,24 @@ func _MemoService_ExportMemos_Handler(srv interface{}, ctx context.Context, dec
|
|||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _MemoService_RebuildMemoProperty_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(RebuildMemoPropertyRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(MemoServiceServer).RebuildMemoProperty(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: MemoService_RebuildMemoProperty_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(MemoServiceServer).RebuildMemoProperty(ctx, req.(*RebuildMemoPropertyRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _MemoService_ListMemoTags_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ListMemoTagsRequest)
|
||||
if err := dec(in); err != nil {
|
||||
|
@ -795,6 +830,10 @@ var MemoService_ServiceDesc = grpc.ServiceDesc{
|
|||
MethodName: "ExportMemos",
|
||||
Handler: _MemoService_ExportMemos_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "RebuildMemoProperty",
|
||||
Handler: _MemoService_RebuildMemoProperty_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "ListMemoTags",
|
||||
Handler: _MemoService_ListMemoTags_Handler,
|
||||
|
|
|
@ -73,9 +73,9 @@ type MemoPayload_Property struct {
|
|||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Tags []string `protobuf:"bytes,1,rep,name=tags,proto3" json:"tags,omitempty"`
|
||||
HasLink bool `protobuf:"varint,2,opt,name=has_link,json=hasLink,proto3" json:"has_link,omitempty"`
|
||||
HasTodo bool `protobuf:"varint,3,opt,name=has_todo,json=hasTodo,proto3" json:"has_todo,omitempty"`
|
||||
Tags []string `protobuf:"bytes,1,rep,name=tags,proto3" json:"tags,omitempty"`
|
||||
HasLink bool `protobuf:"varint,2,opt,name=has_link,json=hasLink,proto3" json:"has_link,omitempty"`
|
||||
HasTaskList bool `protobuf:"varint,3,opt,name=has_task_list,json=hasTaskList,proto3" json:"has_task_list,omitempty"`
|
||||
}
|
||||
|
||||
func (x *MemoPayload_Property) Reset() {
|
||||
|
@ -124,9 +124,9 @@ func (x *MemoPayload_Property) GetHasLink() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func (x *MemoPayload_Property) GetHasTodo() bool {
|
||||
func (x *MemoPayload_Property) GetHasTaskList() bool {
|
||||
if x != nil {
|
||||
return x.HasTodo
|
||||
return x.HasTaskList
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
@ -136,27 +136,27 @@ var File_store_memo_proto protoreflect.FileDescriptor
|
|||
var file_store_memo_proto_rawDesc = []byte{
|
||||
0x0a, 0x10, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x12, 0x0b, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x22,
|
||||
0xa2, 0x01, 0x0a, 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12,
|
||||
0xab, 0x01, 0x0a, 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12,
|
||||
0x3d, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x21, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e,
|
||||
0x4d, 0x65, 0x6d, 0x6f, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x50, 0x72, 0x6f, 0x70,
|
||||
0x65, 0x72, 0x74, 0x79, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x1a, 0x54,
|
||||
0x65, 0x72, 0x74, 0x79, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x1a, 0x5d,
|
||||
0x0a, 0x08, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61,
|
||||
0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x19,
|
||||
0x0a, 0x08, 0x68, 0x61, 0x73, 0x5f, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08,
|
||||
0x52, 0x07, 0x68, 0x61, 0x73, 0x4c, 0x69, 0x6e, 0x6b, 0x12, 0x19, 0x0a, 0x08, 0x68, 0x61, 0x73,
|
||||
0x5f, 0x74, 0x6f, 0x64, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x68, 0x61, 0x73,
|
||||
0x54, 0x6f, 0x64, 0x6f, 0x42, 0x94, 0x01, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x65, 0x6d,
|
||||
0x6f, 0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x42, 0x09, 0x4d, 0x65, 0x6d, 0x6f, 0x50, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x29, 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, 0x73, 0x74, 0x6f, 0x72, 0x65,
|
||||
0xa2, 0x02, 0x03, 0x4d, 0x53, 0x58, 0xaa, 0x02, 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x53,
|
||||
0x74, 0x6f, 0x72, 0x65, 0xca, 0x02, 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x53, 0x74, 0x6f,
|
||||
0x72, 0x65, 0xe2, 0x02, 0x17, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x53, 0x74, 0x6f, 0x72, 0x65,
|
||||
0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0c, 0x4d,
|
||||
0x65, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x33,
|
||||
0x52, 0x07, 0x68, 0x61, 0x73, 0x4c, 0x69, 0x6e, 0x6b, 0x12, 0x22, 0x0a, 0x0d, 0x68, 0x61, 0x73,
|
||||
0x5f, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08,
|
||||
0x52, 0x0b, 0x68, 0x61, 0x73, 0x54, 0x61, 0x73, 0x6b, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x94, 0x01,
|
||||
0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72,
|
||||
0x65, 0x42, 0x09, 0x4d, 0x65, 0x6d, 0x6f, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x29,
|
||||
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, 0x73, 0x74, 0x6f, 0x72, 0x65, 0xa2, 0x02, 0x03, 0x4d, 0x53, 0x58, 0xaa,
|
||||
0x02, 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0xca, 0x02, 0x0b,
|
||||
0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x53, 0x74, 0x6f, 0x72, 0x65, 0xe2, 0x02, 0x17, 0x4d, 0x65,
|
||||
0x6d, 0x6f, 0x73, 0x5c, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74,
|
||||
0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x53,
|
||||
0x74, 0x6f, 0x72, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
|
|
@ -11,6 +11,6 @@ message MemoPayload {
|
|||
message Property {
|
||||
repeated string tags = 1;
|
||||
bool has_link = 2;
|
||||
bool has_todo = 3;
|
||||
bool has_task_list = 3;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,11 +62,13 @@ func (s *APIV1Service) CreateMemo(ctx context.Context, request *v1pb.CreateMemoR
|
|||
if len(create.Content) > contentLengthLimit {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "content too long (max %d characters)", contentLengthLimit)
|
||||
}
|
||||
tags, err := ExtractTagsFromContent(create.Content)
|
||||
property, err := getMemoPropertyFromContent(create.Content)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "failed to extract tags")
|
||||
return nil, status.Errorf(codes.Internal, "failed to get memo property: %v", err)
|
||||
}
|
||||
create.Payload = &storepb.MemoPayload{
|
||||
Property: property,
|
||||
}
|
||||
create.Tags = tags
|
||||
|
||||
memo, err := s.Store.CreateMemo(ctx, create)
|
||||
if err != nil {
|
||||
|
@ -246,11 +248,14 @@ func (s *APIV1Service) UpdateMemo(ctx context.Context, request *v1pb.UpdateMemoR
|
|||
return nil, status.Errorf(codes.InvalidArgument, "content too long (max %d characters)", contentLengthLimit)
|
||||
}
|
||||
update.Content = &request.Memo.Content
|
||||
tags, err := ExtractTagsFromContent(*update.Content)
|
||||
|
||||
property, err := getMemoPropertyFromContent(*update.Content)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "failed to extract tags")
|
||||
return nil, status.Errorf(codes.Internal, "failed to get memo property: %v", err)
|
||||
}
|
||||
update.Tags = &tags
|
||||
payload := memo.Payload
|
||||
payload.Property = property
|
||||
update.Payload = payload
|
||||
} else if path == "uid" {
|
||||
update.UID = &request.Memo.Name
|
||||
if !util.UIDMatcher.MatchString(*update.UID) {
|
||||
|
@ -547,6 +552,48 @@ func (s *APIV1Service) ExportMemos(ctx context.Context, request *v1pb.ExportMemo
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (s *APIV1Service) RebuildMemoProperty(ctx context.Context, request *v1pb.RebuildMemoPropertyRequest) (*emptypb.Empty, error) {
|
||||
user, err := getCurrentUser(ctx, s.Store)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "failed to get current user")
|
||||
}
|
||||
|
||||
normalRowStatus := store.Normal
|
||||
memoFind := &store.FindMemo{
|
||||
CreatorID: &user.ID,
|
||||
RowStatus: &normalRowStatus,
|
||||
ExcludeComments: true,
|
||||
}
|
||||
if (request.Name) != "memos/-" {
|
||||
memoID, err := ExtractMemoIDFromName(request.Name)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "invalid memo name: %v", err)
|
||||
}
|
||||
memoFind.ID = &memoID
|
||||
}
|
||||
|
||||
memos, err := s.Store.ListMemos(ctx, memoFind)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "failed to list memos")
|
||||
}
|
||||
|
||||
for _, memo := range memos {
|
||||
property, err := getMemoPropertyFromContent(memo.Content)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "failed to get memo property: %v", err)
|
||||
}
|
||||
memo.Payload.Property = property
|
||||
if err := s.Store.UpdateMemo(ctx, &store.UpdateMemo{
|
||||
ID: memo.ID,
|
||||
Payload: memo.Payload,
|
||||
}); err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "failed to update memo")
|
||||
}
|
||||
}
|
||||
|
||||
return &emptypb.Empty{}, nil
|
||||
}
|
||||
|
||||
func (s *APIV1Service) ListMemoTags(ctx context.Context, request *v1pb.ListMemoTagsRequest) (*v1pb.ListMemoTagsResponse, error) {
|
||||
user, err := getCurrentUser(ctx, s.Store)
|
||||
if err != nil {
|
||||
|
@ -568,36 +615,17 @@ func (s *APIV1Service) ListMemoTags(ctx context.Context, request *v1pb.ListMemoT
|
|||
}
|
||||
memoFind.ID = &memoID
|
||||
}
|
||||
if request.Rebuild {
|
||||
// If rebuild is true, include content to extract tags.
|
||||
memoFind.ExcludeContent = false
|
||||
}
|
||||
|
||||
memos, err := s.Store.ListMemos(ctx, memoFind)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "failed to list memos")
|
||||
}
|
||||
|
||||
if request.Rebuild {
|
||||
for _, memo := range memos {
|
||||
tags, err := ExtractTagsFromContent(memo.Content)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "failed to extract tags")
|
||||
}
|
||||
memo.Tags = tags
|
||||
if err := s.Store.UpdateMemo(ctx, &store.UpdateMemo{
|
||||
ID: memo.ID,
|
||||
Tags: &tags,
|
||||
}); err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "failed to update memo")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tagAmounts := map[string]int32{}
|
||||
for _, memo := range memos {
|
||||
for _, tag := range memo.Tags {
|
||||
tagAmounts[tag]++
|
||||
if memo.Payload.Property != nil {
|
||||
for _, tag := range memo.Payload.Property.Tags {
|
||||
tagAmounts[tag]++
|
||||
}
|
||||
}
|
||||
}
|
||||
return &v1pb.ListMemoTagsResponse{
|
||||
|
@ -613,7 +641,7 @@ func (s *APIV1Service) RenameMemoTag(ctx context.Context, request *v1pb.RenameMe
|
|||
|
||||
memoFind := &store.FindMemo{
|
||||
CreatorID: &user.ID,
|
||||
Tag: &request.OldTag,
|
||||
PayloadFind: &store.FindMemoPayload{Tag: &request.OldTag},
|
||||
ExcludeComments: true,
|
||||
}
|
||||
if (request.Parent) != "memos/-" {
|
||||
|
@ -640,11 +668,17 @@ func (s *APIV1Service) RenameMemoTag(ctx context.Context, request *v1pb.RenameMe
|
|||
}
|
||||
})
|
||||
content := restore.Restore(nodes)
|
||||
tags := util.ReplaceString(memo.Tags, request.OldTag, request.NewTag)
|
||||
|
||||
property, err := getMemoPropertyFromContent(content)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "failed to get memo property: %v", err)
|
||||
}
|
||||
payload := memo.Payload
|
||||
payload.Property = property
|
||||
if err := s.Store.UpdateMemo(ctx, &store.UpdateMemo{
|
||||
ID: memo.ID,
|
||||
Content: &content,
|
||||
Tags: &tags,
|
||||
Payload: payload,
|
||||
}); err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "failed to update memo: %v", err)
|
||||
}
|
||||
|
@ -661,7 +695,7 @@ func (s *APIV1Service) DeleteMemoTag(ctx context.Context, request *v1pb.DeleteMe
|
|||
|
||||
memoFind := &store.FindMemo{
|
||||
CreatorID: &user.ID,
|
||||
Tag: &request.Tag,
|
||||
PayloadFind: &store.FindMemoPayload{Tag: &request.Tag},
|
||||
ExcludeContent: true,
|
||||
ExcludeComments: true,
|
||||
}
|
||||
|
@ -798,7 +832,10 @@ func (s *APIV1Service) buildMemoFindWithFilter(ctx context.Context, find *store.
|
|||
find.VisibilityList = filter.Visibilities
|
||||
}
|
||||
if filter.Tag != nil {
|
||||
find.Tag = filter.Tag
|
||||
if find.PayloadFind == nil {
|
||||
find.PayloadFind = &store.FindMemoPayload{}
|
||||
}
|
||||
find.PayloadFind.Tag = filter.Tag
|
||||
}
|
||||
if filter.OrderByPinned {
|
||||
find.OrderByPinned = filter.OrderByPinned
|
||||
|
@ -998,6 +1035,29 @@ func findSearchMemosField(callExpr *expr.Expr_Call, filter *SearchMemosFilter) {
|
|||
}
|
||||
}
|
||||
|
||||
func getMemoPropertyFromContent(content string) (*storepb.MemoPayload_Property, error) {
|
||||
nodes, err := parser.Parse(tokenizer.Tokenize(content))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to parse content")
|
||||
}
|
||||
|
||||
property := &storepb.MemoPayload_Property{}
|
||||
TraverseASTNodes(nodes, func(node ast.Node) {
|
||||
switch n := node.(type) {
|
||||
case *ast.Tag:
|
||||
tag := n.Content
|
||||
if !slices.Contains(property.Tags, tag) {
|
||||
property.Tags = append(property.Tags, tag)
|
||||
}
|
||||
case *ast.Link, *ast.AutoLink:
|
||||
property.HasLink = true
|
||||
case *ast.TaskList:
|
||||
property.HasTaskList = true
|
||||
}
|
||||
})
|
||||
return property, nil
|
||||
}
|
||||
|
||||
func ExtractTagsFromContent(content string) ([]string, error) {
|
||||
nodes, err := parser.Parse(tokenizer.Tokenize(content))
|
||||
if err != nil {
|
||||
|
|
|
@ -95,8 +95,13 @@ func (d *DB) ListMemos(ctx context.Context, find *store.FindMemo) ([]*store.Memo
|
|||
}
|
||||
where = append(where, fmt.Sprintf("`memo`.`visibility` in (%s)", strings.Join(placeholder, ",")))
|
||||
}
|
||||
if v := find.Tag; v != nil {
|
||||
where, args = append(where, "JSON_CONTAINS(`memo`.`tags`, ?, '$')"), append(args, *v)
|
||||
if v := find.PayloadFind; v != nil {
|
||||
if v.Raw != nil {
|
||||
where, args = append(where, "`memo`.`payload` = ?"), append(args, *v.Raw)
|
||||
}
|
||||
if v.Tag != nil {
|
||||
where, args = append(where, "JSON_CONTAINS(JSON_EXTRACT(payload, '$.property.tags[*]'), ?, '$')"), append(args, *v.Tag)
|
||||
}
|
||||
}
|
||||
if find.ExcludeComments {
|
||||
having = append(having, "`parent_id` IS NULL")
|
||||
|
@ -221,13 +226,6 @@ func (d *DB) UpdateMemo(ctx context.Context, update *store.UpdateMemo) error {
|
|||
if v := update.Visibility; v != nil {
|
||||
set, args = append(set, "`visibility` = ?"), append(args, *v)
|
||||
}
|
||||
if v := update.Tags; v != nil {
|
||||
tagsBytes, err := json.Marshal(v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
set, args = append(set, "`tags` = ?"), append(args, string(tagsBytes))
|
||||
}
|
||||
if v := update.Payload; v != nil {
|
||||
payloadBytes, err := protojson.Marshal(v)
|
||||
if err != nil {
|
||||
|
|
|
@ -86,9 +86,13 @@ func (d *DB) ListMemos(ctx context.Context, find *store.FindMemo) ([]*store.Memo
|
|||
}
|
||||
where = append(where, fmt.Sprintf("memo.visibility in (%s)", strings.Join(holders, ", ")))
|
||||
}
|
||||
if v := find.Tag; v != nil {
|
||||
where = append(where, "memo.tags @> "+placeholder(len(args)+1))
|
||||
args = append(args, fmt.Sprintf(`["%s"]`, *v))
|
||||
if v := find.PayloadFind; v != nil {
|
||||
if v.Raw != nil {
|
||||
where, args = append(where, "memo.payload = "+placeholder(len(args)+1)), append(args, *v.Raw)
|
||||
}
|
||||
if v.Tag != nil {
|
||||
where, args = append(where, "memo.payload->'property'->'tags' @> "+placeholder(len(args)+1)), append(args, fmt.Sprintf(`["%s"]`, *v.Tag))
|
||||
}
|
||||
}
|
||||
if find.ExcludeComments {
|
||||
where = append(where, "memo_relation.related_memo_id IS NULL")
|
||||
|
@ -218,13 +222,6 @@ func (d *DB) UpdateMemo(ctx context.Context, update *store.UpdateMemo) error {
|
|||
if v := update.Visibility; v != nil {
|
||||
set, args = append(set, "visibility = "+placeholder(len(args)+1)), append(args, *v)
|
||||
}
|
||||
if v := update.Tags; v != nil {
|
||||
tagsBytes, err := json.Marshal(v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
set, args = append(set, "tags = "+placeholder(len(args)+1)), append(args, string(tagsBytes))
|
||||
}
|
||||
if v := update.Payload; v != nil {
|
||||
payloadBytes, err := protojson.Marshal(v)
|
||||
if err != nil {
|
||||
|
|
|
@ -87,8 +87,13 @@ func (d *DB) ListMemos(ctx context.Context, find *store.FindMemo) ([]*store.Memo
|
|||
}
|
||||
where = append(where, fmt.Sprintf("`memo`.`visibility` IN (%s)", strings.Join(placeholder, ",")))
|
||||
}
|
||||
if v := find.Tag; v != nil {
|
||||
where, args = append(where, "JSON_EXTRACT(`memo`.`tags`, '$') LIKE ?"), append(args, fmt.Sprintf(`%%"%s"%%`, *v))
|
||||
if v := find.PayloadFind; v != nil {
|
||||
if v.Raw != nil {
|
||||
where, args = append(where, "`memo`.`payload` = ?"), append(args, *v.Raw)
|
||||
}
|
||||
if v.Tag != nil {
|
||||
where, args = append(where, "JSON_EXTRACT(`memo`.`payload`, '$.property.tags') LIKE ?"), append(args, fmt.Sprintf(`%%"%s"%%`, *v.Tag))
|
||||
}
|
||||
}
|
||||
if find.ExcludeComments {
|
||||
where = append(where, "`parent_id` IS NULL")
|
||||
|
@ -204,13 +209,6 @@ func (d *DB) UpdateMemo(ctx context.Context, update *store.UpdateMemo) error {
|
|||
if v := update.Visibility; v != nil {
|
||||
set, args = append(set, "`visibility` = ?"), append(args, *v)
|
||||
}
|
||||
if v := update.Tags; v != nil {
|
||||
tagsBytes, err := json.Marshal(v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
set, args = append(set, "`tags` = ?"), append(args, string(tagsBytes))
|
||||
}
|
||||
if v := update.Payload; v != nil {
|
||||
payloadBytes, err := protojson.Marshal(v)
|
||||
if err != nil {
|
||||
|
|
|
@ -71,7 +71,7 @@ type FindMemo struct {
|
|||
// Domain specific fields
|
||||
ContentSearch []string
|
||||
VisibilityList []Visibility
|
||||
Tag *string
|
||||
PayloadFind *FindMemoPayload
|
||||
ExcludeContent bool
|
||||
ExcludeComments bool
|
||||
Random bool
|
||||
|
@ -83,6 +83,11 @@ type FindMemo struct {
|
|||
OrderByPinned bool
|
||||
}
|
||||
|
||||
type FindMemoPayload struct {
|
||||
Raw *string
|
||||
Tag *string
|
||||
}
|
||||
|
||||
type UpdateMemo struct {
|
||||
ID int32
|
||||
UID *string
|
||||
|
@ -91,7 +96,6 @@ type UpdateMemo struct {
|
|||
RowStatus *RowStatus
|
||||
Content *string
|
||||
Visibility *Visibility
|
||||
Tags *[]string
|
||||
Payload *storepb.MemoPayload
|
||||
}
|
||||
|
||||
|
|
|
@ -33,9 +33,8 @@ const TagsSection = () => {
|
|||
style: "warning",
|
||||
dialogName: "rebuild-memo-tags-dialog",
|
||||
onConfirm: async () => {
|
||||
await memoServiceClient.listMemoTags({
|
||||
parent: "memos/-",
|
||||
rebuild: true,
|
||||
await memoServiceClient.rebuildMemoProperty({
|
||||
name: "memos/-",
|
||||
});
|
||||
await tagStore.fetchTags({ skipCache: true });
|
||||
toast.success("Rebuild tags successfully");
|
||||
|
|
Loading…
Reference in a new issue