Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

POC use ent as dbv2 #2940

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
29 changes: 17 additions & 12 deletions api/v2/memo_relation_service.go
Expand Up @@ -6,6 +6,8 @@ import (
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"

"github.com/usememos/memos/ent"
"github.com/usememos/memos/ent/memorelation"
apiv2pb "github.com/usememos/memos/proto/gen/api/v2"
"github.com/usememos/memos/store"
)
Expand Down Expand Up @@ -44,23 +46,26 @@ func (s *APIV2Service) SetMemoRelations(ctx context.Context, request *apiv2pb.Se

func (s *APIV2Service) ListMemoRelations(ctx context.Context, request *apiv2pb.ListMemoRelationsRequest) (*apiv2pb.ListMemoRelationsResponse, error) {
relationList := []*apiv2pb.MemoRelation{}
tempList, err := s.Store.ListMemoRelations(ctx, &store.FindMemoRelation{
MemoID: &request.Id,
})
tempList, err := s.Store.V2.MemoRelation.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we wrap a method in the store package?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's also my first try wrapping the db inside store.

but there are a few concerns, and we can discuss:

  1. using the origin store interface has no way to distinguish v1 or v2, we can only replace the origin v1 directly in each function step by step.
  2. it seems not worth creating a new store interface only for ent operations
  3. the ent client seems to be easy enough to use

Query().
Where(memorelation.MemoID(int(request.Id))).
All(ctx)
if err != nil {
return nil, err
}

for _, relation := range tempList {
relationList = append(relationList, convertMemoRelationFromStore(relation))
relationList = append(relationList, convertMemoRelationFromStoreV2(relation))
}
tempList, err = s.Store.ListMemoRelations(ctx, &store.FindMemoRelation{
RelatedMemoID: &request.Id,
})
tempList, err = s.Store.V2.MemoRelation.
Query().
Where(memorelation.RelatedMemoID(int(request.Id))).
All(ctx)
if err != nil {
return nil, err
}
for _, relation := range tempList {
relationList = append(relationList, convertMemoRelationFromStore(relation))
relationList = append(relationList, convertMemoRelationFromStoreV2(relation))
}

response := &apiv2pb.ListMemoRelationsResponse{
Expand All @@ -69,11 +74,11 @@ func (s *APIV2Service) ListMemoRelations(ctx context.Context, request *apiv2pb.L
return response, nil
}

func convertMemoRelationFromStore(memoRelation *store.MemoRelation) *apiv2pb.MemoRelation {
func convertMemoRelationFromStoreV2(memoRelation *ent.MemoRelation) *apiv2pb.MemoRelation {
return &apiv2pb.MemoRelation{
MemoId: memoRelation.MemoID,
RelatedMemoId: memoRelation.RelatedMemoID,
Type: convertMemoRelationTypeFromStore(memoRelation.Type),
MemoId: int32(memoRelation.MemoID),
RelatedMemoId: int32(memoRelation.RelatedMemoID),
Type: convertMemoRelationTypeFromStore(store.MemoRelationType(memoRelation.Type)),
}
}

Expand Down
65 changes: 56 additions & 9 deletions api/v2/memo_service.go
Expand Up @@ -17,7 +17,7 @@
"google.golang.org/grpc/status"
"google.golang.org/protobuf/types/known/timestamppb"

apiv1 "github.com/usememos/memos/api/v1"

Check failure on line 20 in api/v2/memo_service.go

View workflow job for this annotation

GitHub Actions / go-static-checks

File is not `goimports`-ed with -local github.com/usememos/memos (goimports)
"github.com/usememos/memos/internal/log"
"github.com/usememos/memos/internal/util"
"github.com/usememos/memos/plugin/webhook"
Expand All @@ -25,6 +25,8 @@
storepb "github.com/usememos/memos/proto/gen/store"
"github.com/usememos/memos/server/service/metric"
"github.com/usememos/memos/store"
"github.com/usememos/memos/ent"
memotype "github.com/usememos/memos/ent/memo"
)

const (
Expand Down Expand Up @@ -137,29 +139,32 @@
}

func (s *APIV2Service) GetMemo(ctx context.Context, request *apiv2pb.GetMemoRequest) (*apiv2pb.GetMemoResponse, error) {
memo, err := s.Store.GetMemo(ctx, &store.FindMemo{
ID: &request.Id,
})
memo, err := s.Store.V2.Memo.
Query().
Where(memotype.ID(int(request.Id))).
Only(ctx)
if err != nil {
if ent.IsNotFound(err) {
return nil, status.Errorf(codes.NotFound, "memo not found")
}
return nil, err
}
if memo == nil {
return nil, status.Errorf(codes.NotFound, "memo not found")
}
if memo.Visibility != store.Public {

if store.Visibility(memo.Visibility) != store.Public {
user, err := getCurrentUser(ctx, s.Store)
if err != nil {
return nil, status.Errorf(codes.Internal, "failed to get user")
}
if user == nil {
return nil, status.Errorf(codes.PermissionDenied, "permission denied")
}
if memo.Visibility == store.Private && memo.CreatorID != user.ID {
if store.Visibility(memo.Visibility) == store.Private &&
int32(memo.CreatorID) != user.ID {
return nil, status.Errorf(codes.PermissionDenied, "permission denied")
}
}

memoMessage, err := s.convertMemoFromStore(ctx, memo)
memoMessage, err := s.convertMemoFromStoreV2(ctx, memo)
if err != nil {
return nil, errors.Wrap(err, "failed to convert memo")
}
Expand Down Expand Up @@ -509,6 +514,48 @@
}, nil
}

func (s *APIV2Service) convertMemoFromStoreV2(ctx context.Context, memo *ent.Memo) (*apiv2pb.Memo, error) {
displayTs := memo.CreatedTs
if displayWithUpdatedTs, err := s.getMemoDisplayWithUpdatedTsSettingValue(ctx); err == nil && displayWithUpdatedTs {
displayTs = memo.UpdatedTs
}

creatorID := int32(memo.CreatorID)
creator, err := s.Store.GetUser(ctx, &store.FindUser{ID: &creatorID})
if err != nil {
return nil, errors.Wrap(err, "failed to get creator")
}

memoID := int32(memo.ID)
listMemoRelationsResponse, err := s.ListMemoRelations(ctx, &apiv2pb.ListMemoRelationsRequest{Id: memoID})
if err != nil {
return nil, errors.Wrap(err, "failed to list memo relations")
}

listMemoResourcesResponse, err := s.ListMemoResources(ctx, &apiv2pb.ListMemoResourcesRequest{Id: memoID})
if err != nil {
return nil, errors.Wrap(err, "failed to list memo resources")
}

return &apiv2pb.Memo{
Id: int32(memo.ID),
Name: memo.ResourceName,
RowStatus: convertRowStatusFromStore(store.RowStatus(memo.RowStatus)),
Creator: fmt.Sprintf("%s%s", UserNamePrefix, creator.Username),
CreatorId: int32(memo.CreatorID),
CreateTime: timestamppb.New(memo.CreatedTs),
UpdateTime: timestamppb.New(memo.UpdatedTs),
DisplayTime: timestamppb.New(displayTs),
Content: memo.Content,
Visibility: convertVisibilityFromStore(store.Visibility(memo.Visibility)),
// TODO(kw): implement pinned
// Pinned: memo.Pinned,
// ParentId: memo.ParentID,
Relations: listMemoRelationsResponse.Relations,
Resources: listMemoResourcesResponse.Resources,
}, nil
}

func (s *APIV2Service) convertMemoFromStore(ctx context.Context, memo *store.Memo) (*apiv2pb.Memo, error) {
displayTs := memo.CreatedTs
if displayWithUpdatedTs, err := s.getMemoDisplayWithUpdatedTsSettingValue(ctx); err == nil && displayWithUpdatedTs {
Expand Down
2 changes: 2 additions & 0 deletions api/v2/v2.go
Expand Up @@ -14,6 +14,7 @@ import (
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/reflection"

"github.com/usememos/memos/ent"
"github.com/usememos/memos/internal/log"
apiv2pb "github.com/usememos/memos/proto/gen/api/v2"
"github.com/usememos/memos/server/profile"
Expand All @@ -34,6 +35,7 @@ type APIV2Service struct {
Secret string
Profile *profile.Profile
Store *store.Store
StoreV2 *ent.Client

grpcServer *grpc.Server
grpcServerPort int
Expand Down
10 changes: 9 additions & 1 deletion bin/memos/main.go
Expand Up @@ -20,6 +20,7 @@ import (
"github.com/usememos/memos/server/service/metric"
"github.com/usememos/memos/store"
"github.com/usememos/memos/store/db"
"github.com/usememos/memos/store/dbv2"
)

const (
Expand Down Expand Up @@ -60,7 +61,14 @@ var (
return
}

storeInstance := store.New(dbDriver, profile)
dbv2, err := dbv2.NewDriver(profile)
if err != nil {
cancel()
log.Error("failed to create dbv2 driver", zap.Error(err))
return
}

storeInstance := store.New(dbDriver, dbv2, profile)
s, err := server.NewServer(ctx, profile, storeInstance)
if err != nil {
cancel()
Expand Down