diff --git a/api/memo.go b/api/memo.go index dddf6974..b93f9641 100644 --- a/api/memo.go +++ b/api/memo.go @@ -39,10 +39,9 @@ type MemoResponse struct { Pinned bool `json:"pinned"` // Related fields - CreatorName string `json:"creatorName"` - ResourceIDList []int - ResourceList []*Resource `json:"resourceList"` - RelationList []*MemoRelation `json:"relationList"` + CreatorName string `json:"creatorName"` + ResourceList []*Resource `json:"resourceList"` + RelationList []*MemoRelation `json:"relationList"` } type CreateMemoRequest struct { diff --git a/server/memo.go b/server/memo.go index 102890a7..589c2ab1 100644 --- a/server/memo.go +++ b/server/memo.go @@ -119,7 +119,7 @@ func (s *Server) registerMemoRoutes(g *echo.Group) { if err != nil { return echo.NewHTTPError(http.StatusInternalServerError, "Failed to compose memo").SetInternal(err) } - memoResponse, err := s.ComposeMemoResponse(ctx, convertMemoMessageToMemoResponse(memoMessage)) + memoResponse, err := s.composeMemoMessageToMemoResponse(ctx, memoMessage) if err != nil { return echo.NewHTTPError(http.StatusInternalServerError, "Failed to compose memo response").SetInternal(err) } @@ -235,7 +235,7 @@ func (s *Server) registerMemoRoutes(g *echo.Group) { if err != nil { return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find memo").SetInternal(err) } - memoResponse, err := s.ComposeMemoResponse(ctx, convertMemoMessageToMemoResponse(memoMessage)) + memoResponse, err := s.composeMemoMessageToMemoResponse(ctx, memoMessage) if err != nil { return echo.NewHTTPError(http.StatusInternalServerError, "Failed to compose memo response").SetInternal(err) } @@ -298,7 +298,7 @@ func (s *Server) registerMemoRoutes(g *echo.Group) { } memoResponseList := []*api.MemoResponse{} for _, memoMessage := range memoMessageList { - memoResponse, err := s.ComposeMemoResponse(ctx, convertMemoMessageToMemoResponse(memoMessage)) + memoResponse, err := s.composeMemoMessageToMemoResponse(ctx, memoMessage) if err != nil { return echo.NewHTTPError(http.StatusInternalServerError, "Failed to compose memo response").SetInternal(err) } @@ -334,7 +334,7 @@ func (s *Server) registerMemoRoutes(g *echo.Group) { return echo.NewHTTPError(http.StatusForbidden, "this memo is protected, missing user in session") } } - memoResponse, err := s.ComposeMemoResponse(ctx, convertMemoMessageToMemoResponse(memoMessage)) + memoResponse, err := s.composeMemoMessageToMemoResponse(ctx, memoMessage) if err != nil { return echo.NewHTTPError(http.StatusInternalServerError, "Failed to compose memo response").SetInternal(err) } @@ -373,7 +373,7 @@ func (s *Server) registerMemoRoutes(g *echo.Group) { } return echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("Failed to find memo by ID: %v", memoID)).SetInternal(err) } - memoResponse, err := s.ComposeMemoResponse(ctx, convertMemoMessageToMemoResponse(memoMessage)) + memoResponse, err := s.composeMemoMessageToMemoResponse(ctx, memoMessage) if err != nil { return echo.NewHTTPError(http.StatusInternalServerError, "Failed to compose memo response").SetInternal(err) } @@ -461,7 +461,7 @@ func (s *Server) registerMemoRoutes(g *echo.Group) { } memoResponseList := []*api.MemoResponse{} for _, memoMessage := range memoMessageList { - memoResponse, err := s.ComposeMemoResponse(ctx, convertMemoMessageToMemoResponse(memoMessage)) + memoResponse, err := s.composeMemoMessageToMemoResponse(ctx, memoMessage) if err != nil { return echo.NewHTTPError(http.StatusInternalServerError, "Failed to compose memo response").SetInternal(err) } @@ -584,27 +584,18 @@ func convertCreateMemoRequestToMemoMessage(memoCreate *api.CreateMemoRequest) *s } } -func convertMemoMessageToMemoResponse(memoMessage *store.MemoMessage) *api.MemoResponse { - relationList := []*api.MemoRelation{} - for _, relation := range memoMessage.RelationList { - relationList = append(relationList, convertMemoRelationMessageToMemoRelation(relation)) +func (s *Server) composeMemoMessageToMemoResponse(ctx context.Context, memoMessage *store.MemoMessage) (*api.MemoResponse, error) { + memoResponse := &api.MemoResponse{ + ID: memoMessage.ID, + RowStatus: api.RowStatus(memoMessage.RowStatus.String()), + CreatorID: memoMessage.CreatorID, + CreatedTs: memoMessage.CreatedTs, + UpdatedTs: memoMessage.UpdatedTs, + Content: memoMessage.Content, + Visibility: api.Visibility(memoMessage.Visibility.String()), + Pinned: memoMessage.Pinned, } - return &api.MemoResponse{ - ID: memoMessage.ID, - RowStatus: api.RowStatus(memoMessage.RowStatus.String()), - CreatorID: memoMessage.CreatorID, - CreatedTs: memoMessage.CreatedTs, - UpdatedTs: memoMessage.UpdatedTs, - Content: memoMessage.Content, - Visibility: api.Visibility(memoMessage.Visibility.String()), - Pinned: memoMessage.Pinned, - ResourceIDList: memoMessage.ResourceIDList, - RelationList: relationList, - } -} - -func (s *Server) ComposeMemoResponse(ctx context.Context, memoResponse *api.MemoResponse) (*api.MemoResponse, error) { user, err := s.Store.FindUser(ctx, &api.UserFind{ ID: &memoResponse.CreatorID, }) @@ -618,16 +609,23 @@ func (s *Server) ComposeMemoResponse(ctx context.Context, memoResponse *api.Memo memoResponse.CreatorName = user.Username } - memoResponse.ResourceList = []*api.Resource{} - for _, resourceID := range memoResponse.ResourceIDList { + relationList := []*api.MemoRelation{} + for _, relation := range memoMessage.RelationList { + relationList = append(relationList, convertMemoRelationMessageToMemoRelation(relation)) + } + memoResponse.RelationList = relationList + + resourceList := []*api.Resource{} + for _, resourceID := range memoMessage.ResourceIDList { resource, err := s.Store.FindResource(ctx, &api.ResourceFind{ ID: &resourceID, }) if err != nil { return nil, err } - memoResponse.ResourceList = append(memoResponse.ResourceList, resource) + resourceList = append(resourceList, resource) } + memoResponse.ResourceList = resourceList return memoResponse, nil } diff --git a/store/resource.go b/store/resource.go index fea62ece..e7d42cdd 100644 --- a/store/resource.go +++ b/store/resource.go @@ -73,6 +73,28 @@ func (s *Store) CreateResource(ctx context.Context, create *api.ResourceCreate) return resource, nil } +func (s *Store) PatchResource(ctx context.Context, patch *api.ResourcePatch) (*api.Resource, error) { + tx, err := s.db.BeginTx(ctx, nil) + if err != nil { + return nil, FormatError(err) + } + defer tx.Rollback() + + resourceRaw, err := patchResourceImpl(ctx, tx, patch) + if err != nil { + return nil, err + } + + if err := tx.Commit(); err != nil { + return nil, FormatError(err) + } + + s.resourceCache.Store(resourceRaw.ID, resourceRaw) + resource := resourceRaw.toResource() + + return resource, nil +} + func (s *Store) FindResourceList(ctx context.Context, find *api.ResourceFind) ([]*api.Resource, error) { tx, err := s.db.BeginTx(ctx, nil) if err != nil { @@ -87,6 +109,9 @@ func (s *Store) FindResourceList(ctx context.Context, find *api.ResourceFind) ([ resourceList := []*api.Resource{} for _, raw := range resourceRawList { + if !find.GetBlob { + s.resourceCache.Store(raw.ID, raw) + } resourceList = append(resourceList, raw.toResource()) } @@ -94,6 +119,11 @@ func (s *Store) FindResourceList(ctx context.Context, find *api.ResourceFind) ([ } func (s *Store) FindResource(ctx context.Context, find *api.ResourceFind) (*api.Resource, error) { + if !find.GetBlob && find.ID != nil { + if raw, ok := s.resourceCache.Load(find.ID); ok { + return raw.(*resourceRaw).toResource(), nil + } + } tx, err := s.db.BeginTx(ctx, nil) if err != nil { return nil, FormatError(err) @@ -110,6 +140,9 @@ func (s *Store) FindResource(ctx context.Context, find *api.ResourceFind) (*api. } resourceRaw := list[0] + if !find.GetBlob { + s.resourceCache.Store(resourceRaw.ID, resourceRaw) + } resource := resourceRaw.toResource() return resource, nil @@ -132,31 +165,11 @@ func (s *Store) DeleteResource(ctx context.Context, delete *api.ResourceDelete) if err := tx.Commit(); err != nil { return FormatError(err) } + s.resourceCache.Delete(delete.ID) return nil } -func (s *Store) PatchResource(ctx context.Context, patch *api.ResourcePatch) (*api.Resource, error) { - tx, err := s.db.BeginTx(ctx, nil) - if err != nil { - return nil, FormatError(err) - } - defer tx.Rollback() - - resourceRaw, err := patchResourceImpl(ctx, tx, patch) - if err != nil { - return nil, err - } - - if err := tx.Commit(); err != nil { - return nil, FormatError(err) - } - - resource := resourceRaw.toResource() - - return resource, nil -} - func createResourceImpl(ctx context.Context, tx *sql.Tx, create *api.ResourceCreate) (*resourceRaw, error) { fields := []string{"filename", "blob", "external_link", "type", "size", "creator_id", "internal_path", "public_id"} values := []any{create.Filename, create.Blob, create.ExternalLink, create.Type, create.Size, create.CreatorID, create.InternalPath, create.PublicID} diff --git a/store/store.go b/store/store.go index d9925d57..159c953a 100644 --- a/store/store.go +++ b/store/store.go @@ -17,6 +17,7 @@ type Store struct { userSettingCache sync.Map // map[string]*userSettingRaw shortcutCache sync.Map // map[int]*shortcutRaw idpCache sync.Map // map[int]*identityProviderMessage + resourceCache sync.Map // map[int]*resourceRaw } // New creates a new instance of Store.