diff --git a/go.mod b/go.mod index e7d9097d2..ce8b6d4d7 100644 --- a/go.mod +++ b/go.mod @@ -133,7 +133,7 @@ require ( golang.org/x/arch v0.3.0 // indirect golang.org/x/net v0.17.0 // indirect golang.org/x/oauth2 v0.13.0 // indirect - golang.org/x/sys v0.13.0 // indirect + golang.org/x/sys v0.14.0 // indirect golang.org/x/text v0.13.0 // indirect golang.org/x/time v0.3.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect diff --git a/go.sum b/go.sum index b1ee37912..bebd7dd92 100644 --- a/go.sum +++ b/go.sum @@ -438,8 +438,8 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= +golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= diff --git a/internal/api/msg.go b/internal/api/msg.go index 38e207cfb..b168aea20 100644 --- a/internal/api/msg.go +++ b/internal/api/msg.go @@ -152,7 +152,7 @@ func (m *MessageApi) DeleteMsgPhysical(c *gin.Context) { } func (m *MessageApi) getSendMsgReq(c *gin.Context, req apistruct.SendMsg) (sendMsgReq *msg.SendMsgReq, err error) { - var data interface{} + var data any log.ZDebug(c, "getSendMsgReq", "req", req.Content) switch req.ContentType { case constant.Text: diff --git a/internal/msggateway/encoder.go b/internal/msggateway/encoder.go index 9791acb39..c5f1d00a8 100644 --- a/internal/msggateway/encoder.go +++ b/internal/msggateway/encoder.go @@ -22,8 +22,8 @@ import ( ) type Encoder interface { - Encode(data interface{}) ([]byte, error) - Decode(encodeData []byte, decodeData interface{}) error + Encode(data any) ([]byte, error) + Decode(encodeData []byte, decodeData any) error } type GobEncoder struct{} @@ -32,7 +32,7 @@ func NewGobEncoder() *GobEncoder { return &GobEncoder{} } -func (g *GobEncoder) Encode(data interface{}) ([]byte, error) { +func (g *GobEncoder) Encode(data any) ([]byte, error) { buff := bytes.Buffer{} enc := gob.NewEncoder(&buff) err := enc.Encode(data) @@ -42,7 +42,7 @@ func (g *GobEncoder) Encode(data interface{}) ([]byte, error) { return buff.Bytes(), nil } -func (g *GobEncoder) Decode(encodeData []byte, decodeData interface{}) error { +func (g *GobEncoder) Decode(encodeData []byte, decodeData any) error { buff := bytes.NewBuffer(encodeData) dec := gob.NewDecoder(buff) err := dec.Decode(decodeData) diff --git a/internal/msggateway/n_ws_server.go b/internal/msggateway/n_ws_server.go index 10dd988d1..a54519682 100644 --- a/internal/msggateway/n_ws_server.go +++ b/internal/msggateway/n_ws_server.go @@ -46,7 +46,7 @@ type LongConnServer interface { wsHandler(w http.ResponseWriter, r *http.Request) GetUserAllCons(userID string) ([]*Client, bool) GetUserPlatformCons(userID string, platform int) ([]*Client, bool, bool) - Validate(s interface{}) error + Validate(s any) error SetCacheHandler(cache cache.MsgModel) SetDiscoveryRegistry(client discoveryregistry.SvcDiscoveryRegistry) KickUserConn(client *Client) error @@ -57,6 +57,12 @@ type LongConnServer interface { MessageHandler } +var bufferPool = sync.Pool{ + New: func() any { + return make([]byte, 1024) + }, +} + type WsServer struct { port int wsMaxConnNum int64 @@ -116,7 +122,7 @@ func (ws *WsServer) UnRegister(c *Client) { ws.unregisterChan <- c } -func (ws *WsServer) Validate(s interface{}) error { +func (ws *WsServer) Validate(s any) error { return nil } @@ -139,7 +145,7 @@ func NewWsServer(opts ...Option) (*WsServer, error) { wsMaxConnNum: config.maxConnNum, handshakeTimeout: config.handshakeTimeout, clientPool: sync.Pool{ - New: func() interface{} { + New: func() any { return new(Client) }, }, diff --git a/internal/msgtransfer/online_history_msg_handler.go b/internal/msgtransfer/online_history_msg_handler.go index b019b0120..c53043cb2 100644 --- a/internal/msgtransfer/online_history_msg_handler.go +++ b/internal/msgtransfer/online_history_msg_handler.go @@ -61,7 +61,7 @@ type TriggerChannelValue struct { type Cmd2Value struct { Cmd int - Value interface{} + Value any } type ContextMsg struct { message *sdkws.MsgData diff --git a/internal/push/offlinepush/getui/body.go b/internal/push/offlinepush/getui/body.go index 218ed67b4..01eb22e73 100644 --- a/internal/push/offlinepush/getui/body.go +++ b/internal/push/offlinepush/getui/body.go @@ -21,9 +21,9 @@ import ( ) type Resp struct { - Code int `json:"code"` - Msg string `json:"msg"` - Data interface{} `json:"data"` + Code int `json:"code"` + Msg string `json:"msg"` + Data any `json:"data"` } func (r *Resp) parseError() (err error) { diff --git a/internal/push/offlinepush/getui/push.go b/internal/push/offlinepush/getui/push.go index 1fd65647d..b657c9c23 100644 --- a/internal/push/offlinepush/getui/push.go +++ b/internal/push/offlinepush/getui/push.go @@ -159,7 +159,7 @@ func (g *Client) singlePush(ctx context.Context, token, userID string, pushReq P return g.request(ctx, pushURL, pushReq, token, nil) } -func (g *Client) request(ctx context.Context, url string, input interface{}, token string, output interface{}) error { +func (g *Client) request(ctx context.Context, url string, input any, token string, output any) error { header := map[string]string{"token": token} resp := &Resp{} resp.Data = output @@ -170,7 +170,7 @@ func (g *Client) postReturn( ctx context.Context, url string, header map[string]string, - input interface{}, + input any, output RespI, timeout int, ) error { diff --git a/internal/push/offlinepush/jpush/body/audience.go b/internal/push/offlinepush/jpush/body/audience.go index f29930886..43a7148b8 100644 --- a/internal/push/offlinepush/jpush/body/audience.go +++ b/internal/push/offlinepush/jpush/body/audience.go @@ -23,7 +23,7 @@ const ( ) type Audience struct { - Object interface{} + Object any audience map[string][]string } diff --git a/internal/push/offlinepush/jpush/body/message.go b/internal/push/offlinepush/jpush/body/message.go index 670cd4c78..e885d1d69 100644 --- a/internal/push/offlinepush/jpush/body/message.go +++ b/internal/push/offlinepush/jpush/body/message.go @@ -15,10 +15,10 @@ package body type Message struct { - MsgContent string `json:"msg_content"` - Title string `json:"title,omitempty"` - ContentType string `json:"content_type,omitempty"` - Extras map[string]interface{} `json:"extras,omitempty"` + MsgContent string `json:"msg_content"` + Title string `json:"title,omitempty"` + ContentType string `json:"content_type,omitempty"` + Extras map[string]any `json:"extras,omitempty"` } func (m *Message) SetMsgContent(c string) { @@ -33,9 +33,9 @@ func (m *Message) SetContentType(c string) { m.ContentType = c } -func (m *Message) SetExtras(key string, value interface{}) { +func (m *Message) SetExtras(key string, value any) { if m.Extras == nil { - m.Extras = make(map[string]interface{}) + m.Extras = make(map[string]any) } m.Extras[key] = value } diff --git a/internal/push/offlinepush/jpush/body/platform.go b/internal/push/offlinepush/jpush/body/platform.go index 9de2b8711..1ef136f2c 100644 --- a/internal/push/offlinepush/jpush/body/platform.go +++ b/internal/push/offlinepush/jpush/body/platform.go @@ -29,7 +29,7 @@ const ( ) type Platform struct { - Os interface{} + Os any osArry []string } diff --git a/internal/push/offlinepush/jpush/body/pushobj.go b/internal/push/offlinepush/jpush/body/pushobj.go index c8c112f69..3dc133d0a 100644 --- a/internal/push/offlinepush/jpush/body/pushobj.go +++ b/internal/push/offlinepush/jpush/body/pushobj.go @@ -15,11 +15,11 @@ package body type PushObj struct { - Platform interface{} `json:"platform"` - Audience interface{} `json:"audience"` - Notification interface{} `json:"notification,omitempty"` - Message interface{} `json:"message,omitempty"` - Options interface{} `json:"options,omitempty"` + Platform any `json:"platform"` + Audience any `json:"audience"` + Notification any `json:"notification,omitempty"` + Message any `json:"message,omitempty"` + Options any `json:"options,omitempty"` } func (p *PushObj) SetPlatform(pf *Platform) { diff --git a/internal/push/offlinepush/jpush/push.go b/internal/push/offlinepush/jpush/push.go index 44de7ff65..567269f3c 100644 --- a/internal/push/offlinepush/jpush/push.go +++ b/internal/push/offlinepush/jpush/push.go @@ -69,11 +69,11 @@ func (j *JPush) Push(ctx context.Context, userIDs []string, title, content strin pushObj.SetNotification(&no) pushObj.SetMessage(&msg) pushObj.SetOptions(&opt) - var resp interface{} + var resp any return j.request(ctx, pushObj, resp, 5) } -func (j *JPush) request(ctx context.Context, po body.PushObj, resp interface{}, timeout int) error { +func (j *JPush) request(ctx context.Context, po body.PushObj, resp any, timeout int) error { return http2.PostReturn( ctx, config.Config.Push.Jpns.PushUrl, diff --git a/internal/push/push_to_client.go b/internal/push/push_to_client.go index 75a1c1380..2ee8c457f 100644 --- a/internal/push/push_to_client.go +++ b/internal/push/push_to_client.go @@ -133,7 +133,7 @@ func (p *Pusher) Push2User(ctx context.Context, userIDs []string, msg *sdkws.Msg return nil } -func (p *Pusher) UnmarshalNotificationElem(bytes []byte, t interface{}) error { +func (p *Pusher) UnmarshalNotificationElem(bytes []byte, t any) error { var notification sdkws.NotificationElem if err := json.Unmarshal(bytes, ¬ification); err != nil { return err diff --git a/internal/rpc/conversation/conversaion.go b/internal/rpc/conversation/conversaion.go index d39881b35..12e3e96fd 100644 --- a/internal/rpc/conversation/conversaion.go +++ b/internal/rpc/conversation/conversaion.go @@ -16,6 +16,10 @@ package conversation import ( "context" + "errors" + "github.com/openimsdk/open-im-server/v3/pkg/common/db/newmgo" + tx2 "github.com/openimsdk/open-im-server/v3/pkg/common/db/tx" + "github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation" "google.golang.org/grpc" @@ -24,13 +28,11 @@ import ( "github.com/OpenIMSDK/tools/discoveryregistry" "github.com/OpenIMSDK/tools/errs" "github.com/OpenIMSDK/tools/log" - "github.com/OpenIMSDK/tools/tx" "github.com/OpenIMSDK/tools/utils" "github.com/openimsdk/open-im-server/v3/pkg/common/convert" "github.com/openimsdk/open-im-server/v3/pkg/common/db/cache" "github.com/openimsdk/open-im-server/v3/pkg/common/db/controller" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/relation" tablerelation "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" "github.com/openimsdk/open-im-server/v3/pkg/rpcclient" "github.com/openimsdk/open-im-server/v3/pkg/rpcclient/notification" @@ -43,24 +45,28 @@ type conversationServer struct { } func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error { - db, err := relation.NewGormDB() + rdb, err := cache.NewRedis() if err != nil { return err } - if err := db.AutoMigrate(&tablerelation.ConversationModel{}); err != nil { + mongo, err := unrelation.NewMongo() + if err != nil { return err } - rdb, err := cache.NewRedis() + tx, err := tx2.NewAuto(context.Background(), mongo.GetClient()) + if err != nil { + return err + } + conversationDB, err := newmgo.NewConversationMongo(mongo.GetDatabase()) if err != nil { return err } - conversationDB := relation.NewConversationGorm(db) groupRpcClient := rpcclient.NewGroupRpcClient(client) msgRpcClient := rpcclient.NewMessageRpcClient(client) pbconversation.RegisterConversationServer(server, &conversationServer{ conversationNotificationSender: notification.NewConversationNotificationSender(&msgRpcClient), groupRpcClient: &groupRpcClient, - conversationDatabase: controller.NewConversationDatabase(conversationDB, cache.NewConversationRedis(rdb, cache.GetDefaultOpt(), conversationDB), tx.NewGorm(db)), + conversationDatabase: controller.NewConversationDatabase(conversationDB, cache.NewConversationRedis(rdb, cache.GetDefaultOpt(), conversationDB), tx), }) return nil } @@ -145,7 +151,7 @@ func (c *conversationServer) SetConversations(ctx context.Context, conversation.ConversationType = req.Conversation.ConversationType conversation.UserID = req.Conversation.UserID conversation.GroupID = req.Conversation.GroupID - m := make(map[string]interface{}) + m := make(map[string]any) if req.Conversation.RecvMsgOpt != nil { m["recv_msg_opt"] = req.Conversation.RecvMsgOpt.Value if req.Conversation.RecvMsgOpt.Value != conv.RecvMsgOpt { @@ -229,11 +235,12 @@ func (c *conversationServer) SetConversations(ctx context.Context, // 获取超级大群开启免打扰的用户ID. func (c *conversationServer) GetRecvMsgNotNotifyUserIDs(ctx context.Context, req *pbconversation.GetRecvMsgNotNotifyUserIDsReq) (*pbconversation.GetRecvMsgNotNotifyUserIDsResp, error) { - userIDs, err := c.conversationDatabase.FindRecvMsgNotNotifyUserIDs(ctx, req.GroupID) - if err != nil { - return nil, err - } - return &pbconversation.GetRecvMsgNotNotifyUserIDsResp{UserIDs: userIDs}, nil + //userIDs, err := c.conversationDatabase.FindRecvMsgNotNotifyUserIDs(ctx, req.GroupID) + //if err != nil { + // return nil, err + //} + //return &pbconversation.GetRecvMsgNotNotifyUserIDsResp{UserIDs: userIDs}, nil + return nil, errors.New("deprecated") } // create conversation without notification for msg redis transfer. @@ -284,7 +291,7 @@ func (c *conversationServer) CreateGroupChatConversations(ctx context.Context, r func (c *conversationServer) SetConversationMaxSeq(ctx context.Context, req *pbconversation.SetConversationMaxSeqReq) (*pbconversation.SetConversationMaxSeqResp, error) { if err := c.conversationDatabase.UpdateUsersConversationFiled(ctx, req.OwnerUserID, req.ConversationID, - map[string]interface{}{"max_seq": req.MaxSeq}); err != nil { + map[string]any{"max_seq": req.MaxSeq}); err != nil { return nil, err } return &pbconversation.SetConversationMaxSeqResp{}, nil diff --git a/internal/rpc/friend/friend.go b/internal/rpc/friend/friend.go index c563f77fe..e79888d0c 100644 --- a/internal/rpc/friend/friend.go +++ b/internal/rpc/friend/friend.go @@ -37,8 +37,9 @@ import ( "github.com/openimsdk/open-im-server/v3/pkg/common/db/cache" "github.com/openimsdk/open-im-server/v3/pkg/common/db/controller" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/relation" + "github.com/openimsdk/open-im-server/v3/pkg/common/db/newmgo" tablerelation "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" + "github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation" "github.com/openimsdk/open-im-server/v3/pkg/rpcclient/notification" ) @@ -52,41 +53,61 @@ type friendServer struct { } func Start(client registry.SvcDiscoveryRegistry, server *grpc.Server) error { - db, err := relation.NewGormDB() + // Initialize MongoDB + mongo, err := unrelation.NewMongo() if err != nil { return err } - if err := db.AutoMigrate(&tablerelation.FriendModel{}, &tablerelation.FriendRequestModel{}, &tablerelation.BlackModel{}); err != nil { + + // Initialize Redis + rdb, err := cache.NewRedis() + if err != nil { return err } - rdb, err := cache.NewRedis() + + friendMongoDB, err := newmgo.NewFriendMongo(mongo.GetDatabase()) + if err != nil { + return err + } + + friendRequestMongoDB, err := newmgo.NewFriendRequestMongo(mongo.GetDatabase()) if err != nil { return err } - blackDB := relation.NewBlackGorm(db) - friendDB := relation.NewFriendGorm(db) + + blackMongoDB, err := newmgo.NewBlackMongo(mongo.GetDatabase()) + if err != nil { + return err + } + + // Initialize RPC clients userRpcClient := rpcclient.NewUserRpcClient(client) msgRpcClient := rpcclient.NewMessageRpcClient(client) + + // Initialize notification sender notificationSender := notification.NewFriendNotificationSender( &msgRpcClient, notification.WithRpcFunc(userRpcClient.GetUsersInfo), ) + + // Register Friend server with refactored MongoDB and Redis integrations pbfriend.RegisterFriendServer(server, &friendServer{ friendDatabase: controller.NewFriendDatabase( - friendDB, - relation.NewFriendRequestGorm(db), - cache.NewFriendCacheRedis(rdb, friendDB, cache.GetDefaultOpt()), - tx.NewGorm(db), + friendMongoDB, + friendRequestMongoDB, + cache.NewFriendCacheRedis(rdb, friendMongoDB, cache.GetDefaultOpt()), + tx.NewMongo(mongo.GetClient()), ), blackDatabase: controller.NewBlackDatabase( - blackDB, - cache.NewBlackCacheRedis(rdb, blackDB, cache.GetDefaultOpt()), + blackMongoDB, + cache.NewBlackCacheRedis(rdb, blackMongoDB, cache.GetDefaultOpt()), ), userRpcClient: &userRpcClient, notificationSender: notificationSender, RegisterCenter: client, conversationRpcClient: rpcclient.NewConversationRpcClient(client), }) + return nil } diff --git a/internal/rpc/group/cache.go b/internal/rpc/group/cache.go index 23c57ff89..fc387736d 100644 --- a/internal/rpc/group/cache.go +++ b/internal/rpc/group/cache.go @@ -26,7 +26,7 @@ func (s *groupServer) GetGroupInfoCache( ctx context.Context, req *pbgroup.GetGroupInfoCacheReq, ) (resp *pbgroup.GetGroupInfoCacheResp, err error) { - group, err := s.GroupDatabase.TakeGroup(ctx, req.GroupID) + group, err := s.db.TakeGroup(ctx, req.GroupID) if err != nil { return nil, err } @@ -38,7 +38,7 @@ func (s *groupServer) GetGroupMemberCache( ctx context.Context, req *pbgroup.GetGroupMemberCacheReq, ) (resp *pbgroup.GetGroupMemberCacheResp, err error) { - members, err := s.GroupDatabase.TakeGroupMember(ctx, req.GroupID, req.GroupMemberID) + members, err := s.db.TakeGroupMember(ctx, req.GroupID, req.GroupMemberID) if err != nil { return nil, err } diff --git a/internal/rpc/group/fill.go b/internal/rpc/group/fill.go index cb47d9f6e..2110de218 100644 --- a/internal/rpc/group/fill.go +++ b/internal/rpc/group/fill.go @@ -17,119 +17,145 @@ package group import ( "context" - "github.com/OpenIMSDK/tools/utils" - relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" ) -func (s *groupServer) FindGroupMember(ctx context.Context, groupIDs []string, userIDs []string, roleLevels []int32) ([]*relationtb.GroupMemberModel, error) { - members, err := s.GroupDatabase.FindGroupMember(ctx, groupIDs, userIDs, roleLevels) - if err != nil { - return nil, err - } - emptyUserIDs := make(map[string]struct{}) - for _, member := range members { - if member.Nickname == "" || member.FaceURL == "" { - emptyUserIDs[member.UserID] = struct{}{} - } - } - if len(emptyUserIDs) > 0 { - users, err := s.User.GetPublicUserInfoMap(ctx, utils.Keys(emptyUserIDs), true) - if err != nil { - return nil, err - } - for i, member := range members { - user, ok := users[member.UserID] - if !ok { - continue - } - if member.Nickname == "" { - members[i].Nickname = user.Nickname - } - if member.FaceURL == "" { - members[i].FaceURL = user.FaceURL - } - } - } - return members, nil -} +//func (s *groupServer) FindGroupMember(ctx context.Context, groupIDs []string, userIDs []string, roleLevels []int32) ([]*relationtb.GroupMemberModel, error) { +// members, err := s.db.FindGroupMember(ctx, groupIDs, userIDs, roleLevels) +// if err != nil { +// return nil, err +// } +// emptyUserIDs := make(map[string]struct{}) +// for _, member := range members { +// if member.Nickname == "" || member.FaceURL == "" { +// emptyUserIDs[member.UserID] = struct{}{} +// } +// } +// if len(emptyUserIDs) > 0 { +// users, err := s.User.GetPublicUserInfoMap(ctx, utils.Keys(emptyUserIDs), true) +// if err != nil { +// return nil, err +// } +// for i, member := range members { +// user, ok := users[member.UserID] +// if !ok { +// continue +// } +// if member.Nickname == "" { +// members[i].Nickname = user.Nickname +// } +// if member.FaceURL == "" { +// members[i].FaceURL = user.FaceURL +// } +// } +// } +// return members, nil +//} -func (s *groupServer) TakeGroupMember( - ctx context.Context, - groupID string, - userID string, -) (*relationtb.GroupMemberModel, error) { - member, err := s.GroupDatabase.TakeGroupMember(ctx, groupID, userID) - if err != nil { - return nil, err - } - if member.Nickname == "" || member.FaceURL == "" { - user, err := s.User.GetPublicUserInfo(ctx, userID) - if err != nil { - return nil, err - } - if member.Nickname == "" { - member.Nickname = user.Nickname - } - if member.FaceURL == "" { - member.FaceURL = user.FaceURL - } - } - return member, nil +func (s *groupServer) PopulateGroupMember(ctx context.Context, members ...*relationtb.GroupMemberModel) error { + return s.Notification.PopulateGroupMember(ctx, members...) + //if len(members) == 0 { + // return nil + //} + //emptyUserIDs := make(map[string]struct{}) + //for _, member := range members { + // if member.Nickname == "" || member.FaceURL == "" { + // emptyUserIDs[member.UserID] = struct{}{} + // } + //} + //if len(emptyUserIDs) > 0 { + // users, err := s.User.GetPublicUserInfoMap(ctx, utils.Keys(emptyUserIDs), true) + // if err != nil { + // return err + // } + // for i, member := range members { + // user, ok := users[member.UserID] + // if !ok { + // continue + // } + // if member.Nickname == "" { + // members[i].Nickname = user.Nickname + // } + // if member.FaceURL == "" { + // members[i].FaceURL = user.FaceURL + // } + // } + //} + //return nil } -func (s *groupServer) TakeGroupOwner(ctx context.Context, groupID string) (*relationtb.GroupMemberModel, error) { - owner, err := s.GroupDatabase.TakeGroupOwner(ctx, groupID) - if err != nil { - return nil, err - } - if owner.Nickname == "" || owner.FaceURL == "" { - user, err := s.User.GetUserInfo(ctx, owner.UserID) - if err != nil { - return nil, err - } - if owner.Nickname == "" { - owner.Nickname = user.Nickname - } - if owner.FaceURL == "" { - owner.FaceURL = user.FaceURL - } - } - return owner, nil -} +//func (s *groupServer) TakeGroupMembers(ctx context.Context, groupID string, userID string) (*relationtb.GroupMemberModel, error) { +// member, err := s.db.TakeGroupMember(ctx, groupID, userID) +// if err != nil { +// return nil, err +// } +// if member.Nickname == "" || member.FaceURL == "" { +// user, err := s.User.GetPublicUserInfo(ctx, userID) +// if err != nil { +// return nil, err +// } +// if member.Nickname == "" { +// member.Nickname = user.Nickname +// } +// if member.FaceURL == "" { +// member.FaceURL = user.FaceURL +// } +// } +// return member, nil +//} -func (s *groupServer) PageGetGroupMember( - ctx context.Context, - groupID string, - pageNumber, showNumber int32, -) (uint32, []*relationtb.GroupMemberModel, error) { - total, members, err := s.GroupDatabase.PageGetGroupMember(ctx, groupID, pageNumber, showNumber) - if err != nil { - return 0, nil, err - } - emptyUserIDs := make(map[string]struct{}) - for _, member := range members { - if member.Nickname == "" || member.FaceURL == "" { - emptyUserIDs[member.UserID] = struct{}{} - } - } - if len(emptyUserIDs) > 0 { - users, err := s.User.GetPublicUserInfoMap(ctx, utils.Keys(emptyUserIDs), true) - if err != nil { - return 0, nil, err - } - for i, member := range members { - user, ok := users[member.UserID] - if !ok { - continue - } - if member.Nickname == "" { - members[i].Nickname = user.Nickname - } - if member.FaceURL == "" { - members[i].FaceURL = user.FaceURL - } - } - } - return total, members, nil -} +//func (s *groupServer) TakeGroupOwner(ctx context.Context, groupID string) (*relationtb.GroupMemberModel, error) { +// owner, err := s.db.TakeGroupOwner(ctx, groupID) +// if err != nil { +// return nil, err +// } +// if owner.Nickname == "" || owner.FaceURL == "" { +// user, err := s.User.GetUserInfo(ctx, owner.UserID) +// if err != nil { +// return nil, err +// } +// if owner.Nickname == "" { +// owner.Nickname = user.Nickname +// } +// if owner.FaceURL == "" { +// owner.FaceURL = user.FaceURL +// } +// } +// return owner, nil +//} +// +//func (s *groupServer) PageGetGroupMember( +// ctx context.Context, +// groupID string, +// pageNumber, showNumber int32, +//) (uint32, []*relationtb.GroupMemberModel, error) { +// total, members, err := s.db.PageGetGroupMember(ctx, groupID, pageNumber, showNumber) +// if err != nil { +// return 0, nil, err +// } +// emptyUserIDs := make(map[string]struct{}) +// for _, member := range members { +// if member.Nickname == "" || member.FaceURL == "" { +// emptyUserIDs[member.UserID] = struct{}{} +// } +// } +// if len(emptyUserIDs) > 0 { +// users, err := s.User.GetPublicUserInfoMap(ctx, utils.Keys(emptyUserIDs), true) +// if err != nil { +// return 0, nil, err +// } +// for i, member := range members { +// user, ok := users[member.UserID] +// if !ok { +// continue +// } +// if member.Nickname == "" { +// members[i].Nickname = user.Nickname +// } +// if member.FaceURL == "" { +// members[i].FaceURL = user.FaceURL +// } +// } +// } +// return total, members, nil +//} diff --git a/internal/rpc/group/group.go b/internal/rpc/group/group.go index 85b78cfb2..7822cc31a 100644 --- a/internal/rpc/group/group.go +++ b/internal/rpc/group/group.go @@ -16,10 +16,10 @@ package group import ( "context" - "crypto/md5" - "encoding/binary" - "encoding/json" "fmt" + "github.com/openimsdk/open-im-server/v3/pkg/common/db/newmgo" + tx2 "github.com/openimsdk/open-im-server/v3/pkg/common/db/tx" + "github.com/openimsdk/open-im-server/v3/pkg/rpcclient/grouphash" "math/big" "math/rand" "strconv" @@ -73,12 +73,28 @@ func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) e if err != nil { return err } + groupDB, err := newmgo.NewGroupMongo(mongo.GetDatabase()) + if err != nil { + return err + } + groupMemberDB, err := newmgo.NewGroupMember(mongo.GetDatabase()) + if err != nil { + return err + } + groupRequestDB, err := newmgo.NewGroupRequestMgo(mongo.GetDatabase()) + if err != nil { + return err + } userRpcClient := rpcclient.NewUserRpcClient(client) msgRpcClient := rpcclient.NewMessageRpcClient(client) conversationRpcClient := rpcclient.NewConversationRpcClient(client) + tx, err := tx2.NewAuto(context.Background(), mongo.GetClient()) + if err != nil { + return err + } var gs groupServer - database := controller.InitGroupDatabase(db, rdb, mongo.GetDatabase(), gs.groupMemberHashCode) - gs.GroupDatabase = database + database := controller.NewGroupDatabase(rdb, groupDB, groupMemberDB, groupRequestDB, tx, grouphash.NewGroupHashFromGroupServer(&gs)) + gs.db = database gs.User = userRpcClient gs.Notification = notification.NewGroupNotificationSender(database, &msgRpcClient, &userRpcClient, func(ctx context.Context, userIDs []string) ([]notification.CommonUser, error) { users, err := userRpcClient.GetUsersInfo(ctx, userIDs) @@ -90,24 +106,11 @@ func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) e gs.conversationRpcClient = conversationRpcClient gs.msgRpcClient = msgRpcClient pbgroup.RegisterGroupServer(server, &gs) - //pbgroup.RegisterGroupServer(server, &groupServer{ - // GroupDatabase: database, - // User: userRpcClient, - // Notification: notification.NewGroupNotificationSender(database, &msgRpcClient, &userRpcClient, func(ctx context.Context, userIDs []string) ([]notification.CommonUser, error) { - // users, err := userRpcClient.GetUsersInfo(ctx, userIDs) - // if err != nil { - // return nil, err - // } - // return utils.Slice(users, func(e *sdkws.UserInfo) notification.CommonUser { return e }), nil - // }), - // conversationRpcClient: conversationRpcClient, - // msgRpcClient: msgRpcClient, - //}) return nil } type groupServer struct { - GroupDatabase controller.GroupDatabase + db controller.GroupDatabase User rpcclient.UserRpcClient Notification *notification.GroupNotificationSender conversationRpcClient rpcclient.ConversationRpcClient @@ -116,11 +119,13 @@ type groupServer struct { func (s *groupServer) NotificationUserInfoUpdate(ctx context.Context, req *pbgroup.NotificationUserInfoUpdateReq) (*pbgroup.NotificationUserInfoUpdateResp, error) { defer log.ZDebug(ctx, "return") - - members, err := s.GroupDatabase.FindGroupMember(ctx, nil, []string{req.UserID}, nil) + members, err := s.db.FindGroupMemberUser(ctx, nil, req.UserID) if err != nil { return nil, err } + if err := s.PopulateGroupMember(ctx, members...); err != nil { + return nil, err + } groupIDs := make([]string, 0, len(members)) for _, member := range members { if member.Nickname != "" && member.FaceURL != "" { @@ -134,7 +139,7 @@ func (s *groupServer) NotificationUserInfoUpdate(ctx context.Context, req *pbgro log.ZError(ctx, "NotificationUserInfoUpdate setGroupMemberInfo notification failed", err, "groupID", groupID) } } - if err := s.GroupDatabase.DeleteGroupMemberHash(ctx, groupIDs); err != nil { + if err := s.db.DeleteGroupMemberHash(ctx, groupIDs); err != nil { log.ZError(ctx, "NotificationUserInfoUpdate DeleteGroupMemberHash", err, "groupID", groupIDs) } @@ -143,7 +148,7 @@ func (s *groupServer) NotificationUserInfoUpdate(ctx context.Context, req *pbgro func (s *groupServer) CheckGroupAdmin(ctx context.Context, groupID string) error { if !authverify.IsAppManagerUid(ctx) { - groupMember, err := s.GroupDatabase.TakeGroupMember(ctx, groupID, mcontext.GetOpUserID(ctx)) + groupMember, err := s.db.TakeGroupMember(ctx, groupID, mcontext.GetOpUserID(ctx)) if err != nil { return err } @@ -173,7 +178,7 @@ func (s *groupServer) IsNotFound(err error) bool { func (s *groupServer) GenGroupID(ctx context.Context, groupID *string) error { if *groupID != "" { - _, err := s.GroupDatabase.TakeGroup(ctx, *groupID) + _, err := s.db.TakeGroup(ctx, *groupID) if err == nil { return errs.ErrGroupIDExisted.Wrap("group id existed " + *groupID) } else if s.IsNotFound(err) { @@ -187,7 +192,7 @@ func (s *groupServer) GenGroupID(ctx context.Context, groupID *string) error { bi := big.NewInt(0) bi.SetString(id[0:8], 16) id = bi.String() - _, err := s.GroupDatabase.TakeGroup(ctx, id) + _, err := s.db.TakeGroup(ctx, id) if err == nil { continue } else if s.IsNotFound(err) { @@ -201,12 +206,12 @@ func (s *groupServer) GenGroupID(ctx context.Context, groupID *string) error { } func (s *groupServer) CreateGroup(ctx context.Context, req *pbgroup.CreateGroupReq) (*pbgroup.CreateGroupResp, error) { + if req.GroupInfo.GroupType != constant.WorkingGroup { + return nil, errs.ErrArgs.Wrap(fmt.Sprintf("group type only supports %d", constant.WorkingGroup)) + } if req.OwnerUserID == "" { return nil, errs.ErrArgs.Wrap("no group owner") } - if req.GroupInfo.GroupType != constant.WorkingGroup { - return nil, errs.ErrArgs.Wrap(fmt.Sprintf("group type %d not support", req.GroupInfo.GroupType)) - } if err := authverify.CheckAccessV3(ctx, req.OwnerUserID); err != nil { return nil, err } @@ -253,51 +258,36 @@ func (s *groupServer) CreateGroup(ctx context.Context, req *pbgroup.CreateGroupR if err := joinGroup(req.OwnerUserID, constant.GroupOwner); err != nil { return nil, err } - if req.GroupInfo.GroupType == constant.SuperGroup { - if err := s.GroupDatabase.CreateSuperGroup(ctx, group.GroupID, userIDs); err != nil { + for _, userID := range req.AdminUserIDs { + if err := joinGroup(userID, constant.GroupAdmin); err != nil { return nil, err } - } else { - for _, userID := range req.AdminUserIDs { - if err := joinGroup(userID, constant.GroupAdmin); err != nil { - return nil, err - } - } - for _, userID := range req.MemberUserIDs { - if err := joinGroup(userID, constant.GroupOrdinaryUsers); err != nil { - return nil, err - } + } + for _, userID := range req.MemberUserIDs { + if err := joinGroup(userID, constant.GroupOrdinaryUsers); err != nil { + return nil, err } } - if err := s.GroupDatabase.CreateGroup(ctx, []*relationtb.GroupModel{group}, groupMembers); err != nil { + if err := s.db.CreateGroup(ctx, []*relationtb.GroupModel{group}, groupMembers); err != nil { return nil, err } resp := &pbgroup.CreateGroupResp{GroupInfo: &sdkws.GroupInfo{}} resp.GroupInfo = convert.Db2PbGroupInfo(group, req.OwnerUserID, uint32(len(userIDs))) resp.GroupInfo.MemberCount = uint32(len(userIDs)) - if req.GroupInfo.GroupType == constant.SuperGroup { - go func() { - for _, userID := range userIDs { - s.Notification.SuperGroupNotification(ctx, userID, userID) - } - }() - } else { - // s.Notification.GroupCreatedNotification(ctx, group, groupMembers, userMap) - tips := &sdkws.GroupCreatedTips{ - Group: resp.GroupInfo, - OperationTime: group.CreateTime.UnixMilli(), - GroupOwnerUser: s.groupMemberDB2PB(groupMembers[0], userMap[groupMembers[0].UserID].AppMangerLevel), - } - for _, member := range groupMembers { - member.Nickname = userMap[member.UserID].Nickname - tips.MemberList = append(tips.MemberList, s.groupMemberDB2PB(member, userMap[member.UserID].AppMangerLevel)) - if member.UserID == opUserID { - tips.OpUser = s.groupMemberDB2PB(member, userMap[member.UserID].AppMangerLevel) - break - } + tips := &sdkws.GroupCreatedTips{ + Group: resp.GroupInfo, + OperationTime: group.CreateTime.UnixMilli(), + GroupOwnerUser: s.groupMemberDB2PB(groupMembers[0], userMap[groupMembers[0].UserID].AppMangerLevel), + } + for _, member := range groupMembers { + member.Nickname = userMap[member.UserID].Nickname + tips.MemberList = append(tips.MemberList, s.groupMemberDB2PB(member, userMap[member.UserID].AppMangerLevel)) + if member.UserID == opUserID { + tips.OpUser = s.groupMemberDB2PB(member, userMap[member.UserID].AppMangerLevel) + break } - s.Notification.GroupCreatedNotification(ctx, tips) } + s.Notification.GroupCreatedNotification(ctx, tips) return resp, nil } @@ -306,35 +296,32 @@ func (s *groupServer) GetJoinedGroupList(ctx context.Context, req *pbgroup.GetJo if err := authverify.CheckAccessV3(ctx, req.FromUserID); err != nil { return nil, err } - var pageNumber, showNumber int32 - if req.Pagination != nil { - pageNumber = req.Pagination.PageNumber - showNumber = req.Pagination.ShowNumber - } - // total, members, err := s.GroupDatabase.PageGroupMember(ctx, nil, []string{req.FromUserID}, nil, pageNumber, showNumber) - total, members, err := s.GroupDatabase.PageGetJoinGroup(ctx, req.FromUserID, pageNumber, showNumber) + total, members, err := s.db.PageGetJoinGroup(ctx, req.FromUserID, req.Pagination) if err != nil { return nil, err } - resp.Total = total + resp.Total = uint32(total) if len(members) == 0 { return resp, nil } groupIDs := utils.Slice(members, func(e *relationtb.GroupMemberModel) string { return e.GroupID }) - groups, err := s.GroupDatabase.FindGroup(ctx, groupIDs) + groups, err := s.db.FindGroup(ctx, groupIDs) if err != nil { return nil, err } - groupMemberNum, err := s.GroupDatabase.MapGroupMemberNum(ctx, groupIDs) + groupMemberNum, err := s.db.MapGroupMemberNum(ctx, groupIDs) if err != nil { return nil, err } - owners, err := s.FindGroupMember(ctx, groupIDs, nil, []int32{constant.GroupOwner}) + owners, err := s.db.FindGroupsOwner(ctx, groupIDs) if err != nil { return nil, err } + if err := s.PopulateGroupMember(ctx, members...); err != nil { + return nil, err + } ownerMap := utils.SliceToMap(owners, func(e *relationtb.GroupMemberModel) string { return e.GroupID }) @@ -358,7 +345,7 @@ func (s *groupServer) InviteUserToGroup(ctx context.Context, req *pbgroup.Invite if utils.Duplicate(req.InvitedUserIDs) { return nil, errs.ErrArgs.Wrap("userID duplicate") } - group, err := s.GroupDatabase.TakeGroup(ctx, req.GroupID) + group, err := s.db.TakeGroup(ctx, req.GroupID) if err != nil { return nil, err } @@ -376,14 +363,14 @@ func (s *groupServer) InviteUserToGroup(ctx context.Context, req *pbgroup.Invite var opUserID string if !authverify.IsAppManagerUid(ctx) { opUserID = mcontext.GetOpUserID(ctx) - groupMembers, err := s.FindGroupMember(ctx, []string{req.GroupID}, []string{opUserID}, nil) + var err error + groupMember, err = s.db.TakeGroupMember(ctx, req.GroupID, opUserID) if err != nil { return nil, err } - if len(groupMembers) <= 0 { - return nil, errs.ErrNoPermission.Wrap("not in group") + if err := s.PopulateGroupMember(ctx, groupMember); err != nil { + return nil, err } - groupMember = groupMembers[0] } if group.NeedVerification == constant.AllNeedVerification { if !authverify.IsAppManagerUid(ctx) { @@ -399,7 +386,7 @@ func (s *groupServer) InviteUserToGroup(ctx context.Context, req *pbgroup.Invite HandledTime: time.Unix(0, 0), }) } - if err := s.GroupDatabase.CreateGroupRequest(ctx, requests); err != nil { + if err := s.db.CreateGroupRequest(ctx, requests); err != nil { return nil, err } for _, request := range requests { @@ -414,75 +401,43 @@ func (s *groupServer) InviteUserToGroup(ctx context.Context, req *pbgroup.Invite } } } - - if group.GroupType == constant.SuperGroup { - if err := s.GroupDatabase.CreateSuperGroupMember(ctx, req.GroupID, req.InvitedUserIDs); err != nil { - return nil, err - } - if err := s.conversationRpcClient.GroupChatFirstCreateConversation(ctx, req.GroupID, req.InvitedUserIDs); err != nil { - return nil, err - } - for _, userID := range req.InvitedUserIDs { - s.Notification.SuperGroupNotification(ctx, userID, userID) - } - } else { - opUserID := mcontext.GetOpUserID(ctx) - var groupMembers []*relationtb.GroupMemberModel - for _, userID := range req.InvitedUserIDs { - member := &relationtb.GroupMemberModel{ - GroupID: req.GroupID, - UserID: userID, - RoleLevel: constant.GroupOrdinaryUsers, - OperatorUserID: opUserID, - InviterUserID: opUserID, - JoinSource: constant.JoinByInvitation, - JoinTime: time.Now(), - MuteEndTime: time.UnixMilli(0), - } - if err := CallbackBeforeMemberJoinGroup(ctx, member, group.Ex); err != nil { - return nil, err - } - groupMembers = append(groupMembers, member) - } - if err := s.GroupDatabase.CreateGroup(ctx, nil, groupMembers); err != nil { - return nil, err + var groupMembers []*relationtb.GroupMemberModel + for _, userID := range req.InvitedUserIDs { + member := &relationtb.GroupMemberModel{ + GroupID: req.GroupID, + UserID: userID, + RoleLevel: constant.GroupOrdinaryUsers, + OperatorUserID: opUserID, + InviterUserID: opUserID, + JoinSource: constant.JoinByInvitation, + JoinTime: time.Now(), + MuteEndTime: time.UnixMilli(0), } - if err := s.conversationRpcClient.GroupChatFirstCreateConversation(ctx, req.GroupID, req.InvitedUserIDs); err != nil { + if err := CallbackBeforeMemberJoinGroup(ctx, member, group.Ex); err != nil { return nil, err } - s.Notification.MemberInvitedNotification(ctx, req.GroupID, req.Reason, req.InvitedUserIDs) + groupMembers = append(groupMembers, member) + } + if err := s.db.CreateGroup(ctx, nil, groupMembers); err != nil { + return nil, err } + if err := s.conversationRpcClient.GroupChatFirstCreateConversation(ctx, req.GroupID, req.InvitedUserIDs); err != nil { + return nil, err + } + s.Notification.MemberInvitedNotification(ctx, req.GroupID, req.Reason, req.InvitedUserIDs) return resp, nil } func (s *groupServer) GetGroupAllMember(ctx context.Context, req *pbgroup.GetGroupAllMemberReq) (*pbgroup.GetGroupAllMemberResp, error) { - resp := &pbgroup.GetGroupAllMemberResp{} - group, err := s.GroupDatabase.TakeGroup(ctx, req.GroupID) + members, err := s.db.FindGroupMemberAll(ctx, req.GroupID) if err != nil { return nil, err } - if group.GroupType == constant.SuperGroup { - return nil, errs.ErrArgs.Wrap("unsupported super group") - } - members, err := s.FindGroupMember(ctx, []string{req.GroupID}, nil, nil) - if err != nil { - return nil, err - } - publicUserInfoMap, err := s.GetPublicUserInfoMap(ctx, utils.Filter(members, func(e *relationtb.GroupMemberModel) (string, bool) { - return e.UserID, e.Nickname == "" || e.FaceURL == "" - }), true) - if err != nil { + if err := s.PopulateGroupMember(ctx, members...); err != nil { return nil, err } + resp := &pbgroup.GetGroupAllMemberResp{} resp.Members = utils.Slice(members, func(e *relationtb.GroupMemberModel) *sdkws.GroupMemberFullInfo { - if userInfo, ok := publicUserInfoMap[e.UserID]; ok { - if e.Nickname == "" { - e.Nickname = userInfo.Nickname - } - if e.FaceURL == "" { - e.FaceURL = userInfo.FaceURL - } - } return convert.Db2PbGroupMember(e) }) return resp, nil @@ -490,20 +445,21 @@ func (s *groupServer) GetGroupAllMember(ctx context.Context, req *pbgroup.GetGro func (s *groupServer) GetGroupMemberList(ctx context.Context, req *pbgroup.GetGroupMemberListReq) (*pbgroup.GetGroupMemberListResp, error) { resp := &pbgroup.GetGroupMemberListResp{} - total, members, err := s.PageGetGroupMember(ctx, req.GroupID, req.Pagination.PageNumber, req.Pagination.ShowNumber) - log.ZDebug(ctx, "GetGroupMemberList", "total", total, "members", members, "length", len(members)) + total, members, err := s.db.PageGetGroupMember(ctx, req.GroupID, req.Pagination) + if err != nil { + return nil, err + } if err != nil { return nil, err } - resp.Total = total + resp.Total = uint32(total) resp.Members = utils.Batch(convert.Db2PbGroupMember, members) - log.ZDebug(ctx, "GetGroupMemberList", "resp", resp, "length", len(resp.Members)) return resp, nil } func (s *groupServer) KickGroupMember(ctx context.Context, req *pbgroup.KickGroupMemberReq) (*pbgroup.KickGroupMemberResp, error) { resp := &pbgroup.KickGroupMemberResp{} - group, err := s.GroupDatabase.TakeGroup(ctx, req.GroupID) + group, err := s.db.TakeGroup(ctx, req.GroupID) if err != nil { return nil, err } @@ -517,92 +473,81 @@ func (s *groupServer) KickGroupMember(ctx context.Context, req *pbgroup.KickGrou if utils.IsContain(opUserID, req.KickedUserIDs) { return nil, errs.ErrArgs.Wrap("opUserID in KickedUserIDs") } - if group.GroupType == constant.SuperGroup { - if err := s.GroupDatabase.DeleteSuperGroupMember(ctx, req.GroupID, req.KickedUserIDs); err != nil { - return nil, err - } - go func() { - for _, userID := range req.KickedUserIDs { - s.Notification.SuperGroupNotification(ctx, userID, userID) - } - }() - } else { - members, err := s.FindGroupMember(ctx, []string{req.GroupID}, append(req.KickedUserIDs, opUserID), nil) - if err != nil { - return nil, err - } - memberMap := make(map[string]*relationtb.GroupMemberModel) - for i, member := range members { - memberMap[member.UserID] = members[i] + members, err := s.db.FindGroupMembers(ctx, req.GroupID, append(req.KickedUserIDs, opUserID)) + if err != nil { + return nil, err + } + if err := s.PopulateGroupMember(ctx, members...); err != nil { + return nil, err + } + memberMap := make(map[string]*relationtb.GroupMemberModel) + for i, member := range members { + memberMap[member.UserID] = members[i] + } + isAppManagerUid := authverify.IsAppManagerUid(ctx) + opMember := memberMap[opUserID] + for _, userID := range req.KickedUserIDs { + member, ok := memberMap[userID] + if !ok { + return nil, errs.ErrUserIDNotFound.Wrap(userID) } - isAppManagerUid := authverify.IsAppManagerUid(ctx) - opMember := memberMap[opUserID] - for _, userID := range req.KickedUserIDs { - member, ok := memberMap[userID] - if !ok { - return nil, errs.ErrUserIDNotFound.Wrap(userID) + if !isAppManagerUid { + if opMember == nil { + return nil, errs.ErrNoPermission.Wrap("opUserID no in group") } - if !isAppManagerUid { - if opMember == nil { - return nil, errs.ErrNoPermission.Wrap("opUserID no in group") - } - switch opMember.RoleLevel { - case constant.GroupOwner: - case constant.GroupAdmin: - if member.RoleLevel == constant.GroupOwner || member.RoleLevel == constant.GroupAdmin { - return nil, errs.ErrNoPermission.Wrap("group admins cannot remove the group owner and other admins") - } - case constant.GroupOrdinaryUsers: - return nil, errs.ErrNoPermission.Wrap("opUserID no permission") - default: - return nil, errs.ErrNoPermission.Wrap("opUserID roleLevel unknown") + switch opMember.RoleLevel { + case constant.GroupOwner: + case constant.GroupAdmin: + if member.RoleLevel == constant.GroupOwner || member.RoleLevel == constant.GroupAdmin { + return nil, errs.ErrNoPermission.Wrap("group admins cannot remove the group owner and other admins") } + case constant.GroupOrdinaryUsers: + return nil, errs.ErrNoPermission.Wrap("opUserID no permission") + default: + return nil, errs.ErrNoPermission.Wrap("opUserID roleLevel unknown") } } - num, err := s.GroupDatabase.FindGroupMemberNum(ctx, req.GroupID) - if err != nil { - return nil, err - } - owner, err := s.FindGroupMember(ctx, []string{req.GroupID}, nil, []int32{constant.GroupOwner}) - if err != nil { - return nil, err - } - if err := s.GroupDatabase.DeleteGroupMember(ctx, group.GroupID, req.KickedUserIDs); err != nil { - return nil, err - } - tips := &sdkws.MemberKickedTips{ - Group: &sdkws.GroupInfo{ - GroupID: group.GroupID, - GroupName: group.GroupName, - Notification: group.Notification, - Introduction: group.Introduction, - FaceURL: group.FaceURL, - // OwnerUserID: owner[0].UserID, - CreateTime: group.CreateTime.UnixMilli(), - MemberCount: num, - Ex: group.Ex, - Status: group.Status, - CreatorUserID: group.CreatorUserID, - GroupType: group.GroupType, - NeedVerification: group.NeedVerification, - LookMemberInfo: group.LookMemberInfo, - ApplyMemberFriend: group.ApplyMemberFriend, - NotificationUpdateTime: group.NotificationUpdateTime.UnixMilli(), - NotificationUserID: group.NotificationUserID, - }, - KickedUserList: []*sdkws.GroupMemberFullInfo{}, - } - if len(owner) > 0 { - tips.Group.OwnerUserID = owner[0].UserID - } - if opMember, ok := memberMap[opUserID]; ok { - tips.OpUser = convert.Db2PbGroupMember(opMember) - } - for _, userID := range req.KickedUserIDs { - tips.KickedUserList = append(tips.KickedUserList, convert.Db2PbGroupMember(memberMap[userID])) - } - s.Notification.MemberKickedNotification(ctx, tips) } + num, err := s.db.FindGroupMemberNum(ctx, req.GroupID) + if err != nil { + return nil, err + } + owner, err := s.db.TakeGroupOwner(ctx, req.GroupID) + if err != nil { + return nil, err + } + if err := s.db.DeleteGroupMember(ctx, group.GroupID, req.KickedUserIDs); err != nil { + return nil, err + } + tips := &sdkws.MemberKickedTips{ + Group: &sdkws.GroupInfo{ + GroupID: group.GroupID, + GroupName: group.GroupName, + Notification: group.Notification, + Introduction: group.Introduction, + FaceURL: group.FaceURL, + OwnerUserID: owner.UserID, + CreateTime: group.CreateTime.UnixMilli(), + MemberCount: num, + Ex: group.Ex, + Status: group.Status, + CreatorUserID: group.CreatorUserID, + GroupType: group.GroupType, + NeedVerification: group.NeedVerification, + LookMemberInfo: group.LookMemberInfo, + ApplyMemberFriend: group.ApplyMemberFriend, + NotificationUpdateTime: group.NotificationUpdateTime.UnixMilli(), + NotificationUserID: group.NotificationUserID, + }, + KickedUserList: []*sdkws.GroupMemberFullInfo{}, + } + if opMember, ok := memberMap[opUserID]; ok { + tips.OpUser = convert.Db2PbGroupMember(opMember) + } + for _, userID := range req.KickedUserIDs { + tips.KickedUserList = append(tips.KickedUserList, convert.Db2PbGroupMember(memberMap[userID])) + } + s.Notification.MemberKickedNotification(ctx, tips) if err := s.deleteMemberAndSetConversationSeq(ctx, req.GroupID, req.KickedUserIDs); err != nil { return nil, err } @@ -617,32 +562,21 @@ func (s *groupServer) GetGroupMembersInfo(ctx context.Context, req *pbgroup.GetG if req.GroupID == "" { return nil, errs.ErrArgs.Wrap("groupID empty") } - members, err := s.FindGroupMember(ctx, []string{req.GroupID}, req.UserIDs, nil) + members, err := s.db.FindGroupMembers(ctx, req.GroupID, req.UserIDs) if err != nil { return nil, err } - publicUserInfoMap, err := s.GetPublicUserInfoMap(ctx, utils.Filter(members, func(e *relationtb.GroupMemberModel) (string, bool) { - return e.UserID, e.Nickname == "" || e.FaceURL == "" - }), true) - if err != nil { + if err := s.PopulateGroupMember(ctx, members...); err != nil { return nil, err } resp.Members = utils.Slice(members, func(e *relationtb.GroupMemberModel) *sdkws.GroupMemberFullInfo { - if userInfo, ok := publicUserInfoMap[e.UserID]; ok { - if e.Nickname == "" { - e.Nickname = userInfo.Nickname - } - if e.FaceURL == "" { - e.FaceURL = userInfo.FaceURL - } - } return convert.Db2PbGroupMember(e) }) return resp, nil } func (s *groupServer) GetGroupApplicationList(ctx context.Context, req *pbgroup.GetGroupApplicationListReq) (*pbgroup.GetGroupApplicationListResp, error) { - groupIDs, err := s.GroupDatabase.FindUserManagedGroupID(ctx, req.FromUserID) + groupIDs, err := s.db.FindUserManagedGroupID(ctx, req.FromUserID) if err != nil { return nil, err } @@ -650,11 +584,11 @@ func (s *groupServer) GetGroupApplicationList(ctx context.Context, req *pbgroup. if len(groupIDs) == 0 { return resp, nil } - total, groupRequests, err := s.GroupDatabase.PageGroupRequest(ctx, groupIDs, req.Pagination.PageNumber, req.Pagination.ShowNumber) + total, groupRequests, err := s.db.PageGroupRequest(ctx, groupIDs, req.Pagination) if err != nil { return nil, err } - resp.Total = total + resp.Total = uint32(total) if len(groupRequests) == 0 { return resp, nil } @@ -668,7 +602,7 @@ func (s *groupServer) GetGroupApplicationList(ctx context.Context, req *pbgroup. if err != nil { return nil, err } - groups, err := s.GroupDatabase.FindGroup(ctx, utils.Distinct(groupIDs)) + groups, err := s.db.FindGroup(ctx, utils.Distinct(groupIDs)) if err != nil { return nil, err } @@ -678,14 +612,17 @@ func (s *groupServer) GetGroupApplicationList(ctx context.Context, req *pbgroup. if ids := utils.Single(utils.Keys(groupMap), groupIDs); len(ids) > 0 { return nil, errs.ErrGroupIDNotFound.Wrap(strings.Join(ids, ",")) } - groupMemberNumMap, err := s.GroupDatabase.MapGroupMemberNum(ctx, groupIDs) + groupMemberNumMap, err := s.db.MapGroupMemberNum(ctx, groupIDs) if err != nil { return nil, err } - owners, err := s.FindGroupMember(ctx, groupIDs, nil, []int32{constant.GroupOwner}) + owners, err := s.db.FindGroupsOwner(ctx, groupIDs) if err != nil { return nil, err } + if err := s.PopulateGroupMember(ctx, owners...); err != nil { + return nil, err + } ownerMap := utils.SliceToMap(owners, func(e *relationtb.GroupMemberModel) string { return e.GroupID }) @@ -704,18 +641,21 @@ func (s *groupServer) GetGroupsInfo(ctx context.Context, req *pbgroup.GetGroupsI if len(req.GroupIDs) == 0 { return nil, errs.ErrArgs.Wrap("groupID is empty") } - groups, err := s.GroupDatabase.FindGroup(ctx, req.GroupIDs) + groups, err := s.db.FindGroup(ctx, req.GroupIDs) if err != nil { return nil, err } - groupMemberNumMap, err := s.GroupDatabase.MapGroupMemberNum(ctx, req.GroupIDs) + groupMemberNumMap, err := s.db.MapGroupMemberNum(ctx, req.GroupIDs) if err != nil { return nil, err } - owners, err := s.FindGroupMember(ctx, req.GroupIDs, nil, []int32{constant.GroupOwner}) + owners, err := s.db.FindGroupsOwner(ctx, req.GroupIDs) if err != nil { return nil, err } + if err := s.PopulateGroupMember(ctx, owners...); err != nil { + return nil, err + } ownerMap := utils.SliceToMap(owners, func(e *relationtb.GroupMemberModel) string { return e.GroupID }) @@ -735,7 +675,7 @@ func (s *groupServer) GroupApplicationResponse(ctx context.Context, req *pbgroup return nil, errs.ErrArgs.Wrap("HandleResult unknown") } if !authverify.IsAppManagerUid(ctx) { - groupMember, err := s.GroupDatabase.TakeGroupMember(ctx, req.GroupID, mcontext.GetOpUserID(ctx)) + groupMember, err := s.db.TakeGroupMember(ctx, req.GroupID, mcontext.GetOpUserID(ctx)) if err != nil { return nil, err } @@ -743,11 +683,11 @@ func (s *groupServer) GroupApplicationResponse(ctx context.Context, req *pbgroup return nil, errs.ErrNoPermission.Wrap("no group owner or admin") } } - group, err := s.GroupDatabase.TakeGroup(ctx, req.GroupID) + group, err := s.db.TakeGroup(ctx, req.GroupID) if err != nil { return nil, err } - groupRequest, err := s.GroupDatabase.TakeGroupRequest(ctx, req.GroupID, req.FromUserID) + groupRequest, err := s.db.TakeGroupRequest(ctx, req.GroupID, req.FromUserID) if err != nil { return nil, err } @@ -755,7 +695,7 @@ func (s *groupServer) GroupApplicationResponse(ctx context.Context, req *pbgroup return nil, errs.ErrGroupRequestHandled.Wrap("group request already processed") } var inGroup bool - if _, err := s.GroupDatabase.TakeGroupMember(ctx, req.GroupID, req.FromUserID); err == nil { + if _, err := s.db.TakeGroupMember(ctx, req.GroupID, req.FromUserID); err == nil { inGroup = true // 已经在群里了 } else if !s.IsNotFound(err) { return nil, err @@ -783,7 +723,7 @@ func (s *groupServer) GroupApplicationResponse(ctx context.Context, req *pbgroup } } log.ZDebug(ctx, "GroupApplicationResponse", "inGroup", inGroup, "HandleResult", req.HandleResult, "member", member) - if err := s.GroupDatabase.HandlerGroupRequest(ctx, req.GroupID, req.FromUserID, req.HandledMsg, req.HandleResult, member); err != nil { + if err := s.db.HandlerGroupRequest(ctx, req.GroupID, req.FromUserID, req.HandledMsg, req.HandleResult, member); err != nil { return nil, err } switch req.HandleResult { @@ -809,14 +749,14 @@ func (s *groupServer) JoinGroup(ctx context.Context, req *pbgroup.JoinGroupReq) if err != nil { return nil, err } - group, err := s.GroupDatabase.TakeGroup(ctx, req.GroupID) + group, err := s.db.TakeGroup(ctx, req.GroupID) if err != nil { return nil, err } if group.Status == constant.GroupStatusDismissed { return nil, errs.ErrDismissedAlready.Wrap() } - _, err = s.GroupDatabase.TakeGroupMember(ctx, req.GroupID, req.InviterUserID) + _, err = s.db.TakeGroupMember(ctx, req.GroupID, req.InviterUserID) if err == nil { return nil, errs.ErrArgs.Wrap("already in group") } else if !s.IsNotFound(err) && utils.Unwrap(err) != errs.ErrRecordNotFound { @@ -825,9 +765,6 @@ func (s *groupServer) JoinGroup(ctx context.Context, req *pbgroup.JoinGroupReq) log.ZInfo(ctx, "JoinGroup.groupInfo", "group", group, "eq", group.NeedVerification == constant.Directly) resp = &pbgroup.JoinGroupResp{} if group.NeedVerification == constant.Directly { - if group.GroupType == constant.SuperGroup { - return nil, errs.ErrGroupTypeNotSupport.Wrap() - } groupMember := &relationtb.GroupMemberModel{ GroupID: group.GroupID, UserID: user.UserID, @@ -840,7 +777,7 @@ func (s *groupServer) JoinGroup(ctx context.Context, req *pbgroup.JoinGroupReq) if err := CallbackBeforeMemberJoinGroup(ctx, groupMember, group.Ex); err != nil { return nil, err } - if err := s.GroupDatabase.CreateGroup(ctx, nil, []*relationtb.GroupMemberModel{groupMember}); err != nil { + if err := s.db.CreateGroup(ctx, nil, []*relationtb.GroupMemberModel{groupMember}); err != nil { return nil, err } if err := s.conversationRpcClient.GroupChatFirstCreateConversation(ctx, req.GroupID, []string{req.InviterUserID}); err != nil { @@ -857,7 +794,7 @@ func (s *groupServer) JoinGroup(ctx context.Context, req *pbgroup.JoinGroupReq) ReqTime: time.Now(), HandledTime: time.Unix(0, 0), } - if err := s.GroupDatabase.CreateGroupRequest(ctx, []*relationtb.GroupRequestModel{&groupRequest}); err != nil { + if err := s.db.CreateGroupRequest(ctx, []*relationtb.GroupRequestModel{&groupRequest}); err != nil { return nil, err } s.Notification.JoinGroupApplicationNotification(ctx, req) @@ -873,29 +810,21 @@ func (s *groupServer) QuitGroup(ctx context.Context, req *pbgroup.QuitGroupReq) return nil, err } } - group, err := s.GroupDatabase.TakeGroup(ctx, req.GroupID) + member, err := s.db.TakeGroupMember(ctx, req.GroupID, req.UserID) if err != nil { return nil, err } - if group.GroupType == constant.SuperGroup { - if err := s.GroupDatabase.DeleteSuperGroupMember(ctx, req.GroupID, []string{req.UserID}); err != nil { - return nil, err - } - _ = s.Notification.SuperGroupNotification(ctx, req.UserID, req.UserID) - } else { - info, err := s.TakeGroupMember(ctx, req.GroupID, req.UserID) - if err != nil { - return nil, err - } - if info.RoleLevel == constant.GroupOwner { - return nil, errs.ErrNoPermission.Wrap("group owner can't quit") - } - err = s.GroupDatabase.DeleteGroupMember(ctx, req.GroupID, []string{req.UserID}) - if err != nil { - return nil, err - } - _ = s.Notification.MemberQuitNotification(ctx, s.groupMemberDB2PB(info, 0)) + if member.RoleLevel == constant.GroupOwner { + return nil, errs.ErrNoPermission.Wrap("group owner can't quit") + } + if err := s.PopulateGroupMember(ctx, member); err != nil { + return nil, err } + err = s.db.DeleteGroupMember(ctx, req.GroupID, []string{req.UserID}) + if err != nil { + return nil, err + } + _ = s.Notification.MemberQuitNotification(ctx, s.groupMemberDB2PB(member, 0)) if err := s.deleteMemberAndSetConversationSeq(ctx, req.GroupID, []string{req.UserID}); err != nil { return nil, err } @@ -916,15 +845,18 @@ func (s *groupServer) SetGroupInfo(ctx context.Context, req *pbgroup.SetGroupInf var opMember *relationtb.GroupMemberModel if !authverify.IsAppManagerUid(ctx) { var err error - opMember, err = s.TakeGroupMember(ctx, req.GroupInfoForSet.GroupID, mcontext.GetOpUserID(ctx)) + opMember, err = s.db.TakeGroupMember(ctx, req.GroupInfoForSet.GroupID, mcontext.GetOpUserID(ctx)) if err != nil { return nil, err } if !(opMember.RoleLevel == constant.GroupOwner || opMember.RoleLevel == constant.GroupAdmin) { return nil, errs.ErrNoPermission.Wrap("no group owner or admin") } + if err := s.PopulateGroupMember(ctx, opMember); err != nil { + return nil, err + } } - group, err := s.GroupDatabase.TakeGroup(ctx, req.GroupInfoForSet.GroupID) + group, err := s.db.TakeGroup(ctx, req.GroupInfoForSet.GroupID) if err != nil { return nil, err } @@ -932,22 +864,25 @@ func (s *groupServer) SetGroupInfo(ctx context.Context, req *pbgroup.SetGroupInf return nil, utils.Wrap(errs.ErrDismissedAlready, "") } resp := &pbgroup.SetGroupInfoResp{} - count, err := s.GroupDatabase.FindGroupMemberNum(ctx, group.GroupID) + count, err := s.db.FindGroupMemberNum(ctx, group.GroupID) if err != nil { return nil, err } - owner, err := s.TakeGroupOwner(ctx, group.GroupID) + owner, err := s.db.TakeGroupOwner(ctx, group.GroupID) if err != nil { return nil, err } + if err := s.PopulateGroupMember(ctx, owner); err != nil { + return nil, err + } data := UpdateGroupInfoMap(ctx, req.GroupInfoForSet) if len(data) == 0 { return resp, nil } - if err := s.GroupDatabase.UpdateGroup(ctx, group.GroupID, data); err != nil { + if err := s.db.UpdateGroup(ctx, group.GroupID, data); err != nil { return nil, err } - group, err = s.GroupDatabase.TakeGroup(ctx, req.GroupInfoForSet.GroupID) + group, err = s.db.TakeGroup(ctx, req.GroupInfoForSet.GroupID) if err != nil { return nil, err } @@ -959,45 +894,42 @@ func (s *groupServer) SetGroupInfo(ctx context.Context, req *pbgroup.SetGroupInf if opMember != nil { tips.OpUser = s.groupMemberDB2PB(opMember, 0) } - var num int - if req.GroupInfoForSet.Notification != "" { - go func() { - nctx := mcontext.NewCtx("@@@" + mcontext.GetOperationID(ctx)) - conversation := &pbconversation.ConversationReq{ - ConversationID: msgprocessor.GetConversationIDBySessionType(constant.SuperGroupChatType, req.GroupInfoForSet.GroupID), - ConversationType: constant.SuperGroupChatType, - GroupID: req.GroupInfoForSet.GroupID, - } - resp, err := s.GetGroupMemberUserIDs(nctx, &pbgroup.GetGroupMemberUserIDsReq{GroupID: req.GroupInfoForSet.GroupID}) - if err != nil { - log.ZWarn(ctx, "GetGroupMemberIDs", err) - return - } - conversation.GroupAtType = &wrapperspb.Int32Value{Value: constant.GroupNotification} - if err := s.conversationRpcClient.SetConversations(nctx, resp.UserIDs, conversation); err != nil { - log.ZWarn(ctx, "SetConversations", err, resp.UserIDs, conversation) - } - }() - num++ - s.Notification.GroupInfoSetAnnouncementNotification(ctx, &sdkws.GroupInfoSetAnnouncementTips{Group: tips.Group, OpUser: tips.OpUser}) - } - switch len(data) - num { - case 0: - case 1: - if req.GroupInfoForSet.GroupName == "" { - s.Notification.GroupInfoSetNotification(ctx, tips) - } else { - s.Notification.GroupInfoSetNameNotification(ctx, &sdkws.GroupInfoSetNameTips{Group: tips.Group, OpUser: tips.OpUser}) + var notified bool + if len(data) == 1 && req.GroupInfoForSet.Notification != "" { + switch { + case req.GroupInfoForSet.Notification != "": + func() { + conversation := &pbconversation.ConversationReq{ + ConversationID: msgprocessor.GetConversationIDBySessionType(constant.SuperGroupChatType, req.GroupInfoForSet.GroupID), + ConversationType: constant.SuperGroupChatType, + GroupID: req.GroupInfoForSet.GroupID, + } + resp, err := s.GetGroupMemberUserIDs(ctx, &pbgroup.GetGroupMemberUserIDsReq{GroupID: req.GroupInfoForSet.GroupID}) + if err != nil { + log.ZWarn(ctx, "GetGroupMemberIDs", err) + return + } + conversation.GroupAtType = &wrapperspb.Int32Value{Value: constant.GroupNotification} + if err := s.conversationRpcClient.SetConversations(ctx, resp.UserIDs, conversation); err != nil { + log.ZWarn(ctx, "SetConversations", err, resp.UserIDs, conversation) + } + }() + _ = s.Notification.GroupInfoSetAnnouncementNotification(ctx, &sdkws.GroupInfoSetAnnouncementTips{Group: tips.Group, OpUser: tips.OpUser}) + notified = true + case req.GroupInfoForSet.GroupName != "": + _ = s.Notification.GroupInfoSetNameNotification(ctx, &sdkws.GroupInfoSetNameTips{Group: tips.Group, OpUser: tips.OpUser}) + notified = true } - default: - s.Notification.GroupInfoSetNotification(ctx, tips) + } + if !notified { + _ = s.Notification.GroupInfoSetNotification(ctx, tips) } return resp, nil } func (s *groupServer) TransferGroupOwner(ctx context.Context, req *pbgroup.TransferGroupOwnerReq) (*pbgroup.TransferGroupOwnerResp, error) { resp := &pbgroup.TransferGroupOwnerResp{} - group, err := s.GroupDatabase.TakeGroup(ctx, req.GroupID) + group, err := s.db.TakeGroup(ctx, req.GroupID) if err != nil { return nil, err } @@ -1007,10 +939,13 @@ func (s *groupServer) TransferGroupOwner(ctx context.Context, req *pbgroup.Trans if req.OldOwnerUserID == req.NewOwnerUserID { return nil, errs.ErrArgs.Wrap("OldOwnerUserID == NewOwnerUserID") } - members, err := s.FindGroupMember(ctx, []string{req.GroupID}, []string{req.OldOwnerUserID, req.NewOwnerUserID}, nil) + members, err := s.db.FindGroupMembers(ctx, req.GroupID, []string{req.OldOwnerUserID, req.NewOwnerUserID}) if err != nil { return nil, err } + if err := s.PopulateGroupMember(ctx, members...); err != nil { + return nil, err + } memberMap := utils.SliceToMap(members, func(e *relationtb.GroupMemberModel) string { return e.UserID }) if ids := utils.Single([]string{req.OldOwnerUserID, req.NewOwnerUserID}, utils.Keys(memberMap)); len(ids) > 0 { return nil, errs.ErrArgs.Wrap("user not in group " + strings.Join(ids, ",")) @@ -1028,7 +963,7 @@ func (s *groupServer) TransferGroupOwner(ctx context.Context, req *pbgroup.Trans return nil, errs.ErrNoPermission.Wrap("no permission transfer group owner") } } - if err := s.GroupDatabase.TransferGroupOwner(ctx, req.GroupID, req.OldOwnerUserID, req.NewOwnerUserID, newOwner.RoleLevel); err != nil { + if err := s.db.TransferGroupOwner(ctx, req.GroupID, req.OldOwnerUserID, req.NewOwnerUserID, newOwner.RoleLevel); err != nil { return nil, err } s.Notification.GroupOwnerTransferredNotification(ctx, req) @@ -1042,10 +977,12 @@ func (s *groupServer) GetGroups(ctx context.Context, req *pbgroup.GetGroupsReq) err error ) if req.GroupID != "" { - groups, err = s.GroupDatabase.FindGroup(ctx, []string{req.GroupID}) + groups, err = s.db.FindGroup(ctx, []string{req.GroupID}) resp.Total = uint32(len(groups)) } else { - resp.Total, groups, err = s.GroupDatabase.SearchGroup(ctx, req.GroupName, req.Pagination.PageNumber, req.Pagination.ShowNumber) + var total int64 + total, groups, err = s.db.SearchGroup(ctx, req.GroupName, req.Pagination) + resp.Total = uint32(total) } if err != nil { return nil, err @@ -1053,14 +990,14 @@ func (s *groupServer) GetGroups(ctx context.Context, req *pbgroup.GetGroupsReq) groupIDs := utils.Slice(groups, func(e *relationtb.GroupModel) string { return e.GroupID }) - ownerMembers, err := s.FindGroupMember(ctx, groupIDs, nil, []int32{constant.GroupOwner}) + ownerMembers, err := s.db.FindGroupsOwner(ctx, groupIDs) if err != nil { return nil, err } ownerMemberMap := utils.SliceToMap(ownerMembers, func(e *relationtb.GroupMemberModel) string { return e.GroupID }) - groupMemberNumMap, err := s.GroupDatabase.MapGroupMemberNum(ctx, groupIDs) + groupMemberNumMap, err := s.db.MapGroupMemberNum(ctx, groupIDs) if err != nil { return nil, err } @@ -1079,27 +1016,17 @@ func (s *groupServer) GetGroups(ctx context.Context, req *pbgroup.GetGroupsReq) } func (s *groupServer) GetGroupMembersCMS(ctx context.Context, req *pbgroup.GetGroupMembersCMSReq) (*pbgroup.GetGroupMembersCMSResp, error) { + // todo resp := &pbgroup.GetGroupMembersCMSResp{} - total, members, err := s.GroupDatabase.SearchGroupMember(ctx, req.UserName, []string{req.GroupID}, nil, nil, req.Pagination.PageNumber, req.Pagination.ShowNumber) + total, members, err := s.db.SearchGroupMember(ctx, req.UserName, req.GroupID, req.Pagination) if err != nil { return nil, err } - resp.Total = total - publicUserInfoMap, err := s.GetPublicUserInfoMap(ctx, utils.Filter(members, func(e *relationtb.GroupMemberModel) (string, bool) { - return e.UserID, e.Nickname == "" || e.FaceURL == "" - }), true) - if err != nil { + resp.Total = uint32(total) + if err := s.PopulateGroupMember(ctx, members...); err != nil { return nil, err } resp.Members = utils.Slice(members, func(e *relationtb.GroupMemberModel) *sdkws.GroupMemberFullInfo { - if userInfo, ok := publicUserInfoMap[e.UserID]; ok { - if e.Nickname == "" { - e.Nickname = userInfo.Nickname - } - if e.FaceURL == "" { - e.FaceURL = userInfo.FaceURL - } - } return convert.Db2PbGroupMember(e) }) return resp, nil @@ -1111,37 +1038,35 @@ func (s *groupServer) GetUserReqApplicationList(ctx context.Context, req *pbgrou if err != nil { return nil, err } - var pageNumber, showNumber int32 - if req.Pagination != nil { - pageNumber = req.Pagination.PageNumber - showNumber = req.Pagination.ShowNumber - } - total, requests, err := s.GroupDatabase.PageGroupRequestUser(ctx, req.UserID, pageNumber, showNumber) + total, requests, err := s.db.PageGroupRequestUser(ctx, req.UserID, req.Pagination) if err != nil { return nil, err } - resp.Total = total + resp.Total = uint32(total) if len(requests) == 0 { return resp, nil } groupIDs := utils.Distinct(utils.Slice(requests, func(e *relationtb.GroupRequestModel) string { return e.GroupID })) - groups, err := s.GroupDatabase.FindGroup(ctx, groupIDs) + groups, err := s.db.FindGroup(ctx, groupIDs) if err != nil { return nil, err } groupMap := utils.SliceToMap(groups, func(e *relationtb.GroupModel) string { return e.GroupID }) - owners, err := s.FindGroupMember(ctx, groupIDs, nil, []int32{constant.GroupOwner}) + owners, err := s.db.FindGroupsOwner(ctx, groupIDs) if err != nil { return nil, err } + if err := s.PopulateGroupMember(ctx, owners...); err != nil { + return nil, err + } ownerMap := utils.SliceToMap(owners, func(e *relationtb.GroupMemberModel) string { return e.GroupID }) - groupMemberNum, err := s.GroupDatabase.MapGroupMemberNum(ctx, groupIDs) + groupMemberNum, err := s.db.MapGroupMemberNum(ctx, groupIDs) if err != nil { return nil, err } @@ -1158,7 +1083,7 @@ func (s *groupServer) GetUserReqApplicationList(ctx context.Context, req *pbgrou func (s *groupServer) DismissGroup(ctx context.Context, req *pbgroup.DismissGroupReq) (*pbgroup.DismissGroupResp, error) { defer log.ZInfo(ctx, "DismissGroup.return") resp := &pbgroup.DismissGroupResp{} - owner, err := s.TakeGroupOwner(ctx, req.GroupID) + owner, err := s.db.TakeGroupOwner(ctx, req.GroupID) if err != nil { return nil, err } @@ -1167,54 +1092,47 @@ func (s *groupServer) DismissGroup(ctx context.Context, req *pbgroup.DismissGrou return nil, errs.ErrNoPermission.Wrap("not group owner") } } - group, err := s.GroupDatabase.TakeGroup(ctx, req.GroupID) + if err := s.PopulateGroupMember(ctx, owner); err != nil { + return nil, err + } + group, err := s.db.TakeGroup(ctx, req.GroupID) if err != nil { return nil, err } if req.DeleteMember == false && group.Status == constant.GroupStatusDismissed { return nil, errs.ErrDismissedAlready.Wrap("group status is dismissed") } - //if group.Status == constant.GroupStatusDismissed { - // return nil, errs.ErrArgs.Wrap("group status is dismissed") - //} - if err := s.GroupDatabase.DismissGroup(ctx, req.GroupID, req.DeleteMember); err != nil { + if err := s.db.DismissGroup(ctx, req.GroupID, req.DeleteMember); err != nil { return nil, err } - if group.GroupType == constant.SuperGroup { - if err := s.GroupDatabase.DeleteSuperGroup(ctx, group.GroupID); err != nil { + if !req.DeleteMember { + num, err := s.db.FindGroupMemberNum(ctx, req.GroupID) + if err != nil { return nil, err } - } else { - if !req.DeleteMember { - num, err := s.GroupDatabase.FindGroupMemberNum(ctx, req.GroupID) - if err != nil { - return nil, err - } - // s.Notification.GroupDismissedNotification(ctx, req) - tips := &sdkws.GroupDismissedTips{ - Group: s.groupDB2PB(group, owner.UserID, num), - OpUser: &sdkws.GroupMemberFullInfo{}, - } - if mcontext.GetOpUserID(ctx) == owner.UserID { - tips.OpUser = s.groupMemberDB2PB(owner, 0) - } - s.Notification.GroupDismissedNotification(ctx, tips) + tips := &sdkws.GroupDismissedTips{ + Group: s.groupDB2PB(group, owner.UserID, num), + OpUser: &sdkws.GroupMemberFullInfo{}, } + if mcontext.GetOpUserID(ctx) == owner.UserID { + tips.OpUser = s.groupMemberDB2PB(owner, 0) + } + s.Notification.GroupDismissedNotification(ctx, tips) } return resp, nil } func (s *groupServer) MuteGroupMember(ctx context.Context, req *pbgroup.MuteGroupMemberReq) (*pbgroup.MuteGroupMemberResp, error) { resp := &pbgroup.MuteGroupMemberResp{} - //if err := tokenverify.CheckAccessV3(ctx, req.UserID); err != nil { - // return nil, err - //} - member, err := s.TakeGroupMember(ctx, req.GroupID, req.UserID) + member, err := s.db.TakeGroupMember(ctx, req.GroupID, req.UserID) if err != nil { return nil, err } + if err := s.PopulateGroupMember(ctx, member); err != nil { + return nil, err + } if !authverify.IsAppManagerUid(ctx) { - opMember, err := s.TakeGroupMember(ctx, req.GroupID, mcontext.GetOpUserID(ctx)) + opMember, err := s.db.TakeGroupMember(ctx, req.GroupID, mcontext.GetOpUserID(ctx)) if err != nil { return nil, err } @@ -1232,7 +1150,7 @@ func (s *groupServer) MuteGroupMember(ctx context.Context, req *pbgroup.MuteGrou } } data := UpdateGroupMemberMutedTimeMap(time.Now().Add(time.Second * time.Duration(req.MutedSeconds))) - if err := s.GroupDatabase.UpdateGroupMember(ctx, member.GroupID, member.UserID, data); err != nil { + if err := s.db.UpdateGroupMember(ctx, member.GroupID, member.UserID, data); err != nil { return nil, err } s.Notification.GroupMemberMutedNotification(ctx, req.GroupID, req.UserID, req.MutedSeconds) @@ -1240,29 +1158,15 @@ func (s *groupServer) MuteGroupMember(ctx context.Context, req *pbgroup.MuteGrou } func (s *groupServer) CancelMuteGroupMember(ctx context.Context, req *pbgroup.CancelMuteGroupMemberReq) (*pbgroup.CancelMuteGroupMemberResp, error) { - resp := &pbgroup.CancelMuteGroupMemberResp{} - //member, err := s.GroupDatabase.TakeGroupMember(ctx, req.GroupID, req.UserID) - //if err != nil { - // return nil, err - //} - //if !(mcontext.GetOpUserID(ctx) == req.UserID || tokenverify.IsAppManagerUid(ctx)) { - // opMember, err := s.GroupDatabase.TakeGroupMember(ctx, req.GroupID, mcontext.GetOpUserID(ctx)) - // if err != nil { - // return nil, err - // } - // if opMember.RoleLevel <= member.RoleLevel { - // return nil, errs.ErrNoPermission.Wrap(fmt.Sprintf("self RoleLevel %d target %d", opMember.RoleLevel, member.RoleLevel)) - // } - //} - //if err := tokenverify.CheckAccessV3(ctx, req.UserID); err != nil { - // return nil, err - //} - member, err := s.TakeGroupMember(ctx, req.GroupID, req.UserID) + member, err := s.db.TakeGroupMember(ctx, req.GroupID, req.UserID) if err != nil { return nil, err } + if err := s.PopulateGroupMember(ctx, member); err != nil { + return nil, err + } if !authverify.IsAppManagerUid(ctx) { - opMember, err := s.TakeGroupMember(ctx, req.GroupID, mcontext.GetOpUserID(ctx)) + opMember, err := s.db.TakeGroupMember(ctx, req.GroupID, mcontext.GetOpUserID(ctx)) if err != nil { return nil, err } @@ -1280,11 +1184,11 @@ func (s *groupServer) CancelMuteGroupMember(ctx context.Context, req *pbgroup.Ca } } data := UpdateGroupMemberMutedTimeMap(time.Unix(0, 0)) - if err := s.GroupDatabase.UpdateGroupMember(ctx, member.GroupID, member.UserID, data); err != nil { + if err := s.db.UpdateGroupMember(ctx, member.GroupID, member.UserID, data); err != nil { return nil, err } s.Notification.GroupMemberCancelMutedNotification(ctx, req.GroupID, req.UserID) - return resp, nil + return &pbgroup.CancelMuteGroupMemberResp{}, nil } func (s *groupServer) MuteGroup(ctx context.Context, req *pbgroup.MuteGroupReq) (*pbgroup.MuteGroupResp, error) { @@ -1292,7 +1196,7 @@ func (s *groupServer) MuteGroup(ctx context.Context, req *pbgroup.MuteGroupReq) if err := s.CheckGroupAdmin(ctx, req.GroupID); err != nil { return nil, err } - if err := s.GroupDatabase.UpdateGroup(ctx, req.GroupID, UpdateGroupStatusMap(constant.GroupStatusMuted)); err != nil { + if err := s.db.UpdateGroup(ctx, req.GroupID, UpdateGroupStatusMap(constant.GroupStatusMuted)); err != nil { return nil, err } s.Notification.GroupMutedNotification(ctx, req.GroupID) @@ -1304,109 +1208,239 @@ func (s *groupServer) CancelMuteGroup(ctx context.Context, req *pbgroup.CancelMu if err := s.CheckGroupAdmin(ctx, req.GroupID); err != nil { return nil, err } - if err := s.GroupDatabase.UpdateGroup(ctx, req.GroupID, UpdateGroupStatusMap(constant.GroupOk)); err != nil { + if err := s.db.UpdateGroup(ctx, req.GroupID, UpdateGroupStatusMap(constant.GroupOk)); err != nil { return nil, err } s.Notification.GroupCancelMutedNotification(ctx, req.GroupID) return resp, nil } +//func (s *groupServer) SetGroupMemberInfo(ctx context.Context, req *pbgroup.SetGroupMemberInfoReq) (*pbgroup.SetGroupMemberInfoResp, error) { +// resp := &pbgroup.SetGroupMemberInfoResp{} +// if len(req.Members) == 0 { +// return nil, errs.ErrArgs.Wrap("members empty") +// } +// for i := range req.Members { +// req.Members[i].FaceURL = nil +// } +// duplicateMap := make(map[[2]string]struct{}) +// userIDMap := make(map[string]struct{}) +// groupIDMap := make(map[string]struct{}) +// for _, member := range req.Members { +// key := [...]string{member.GroupID, member.UserID} +// if _, ok := duplicateMap[key]; ok { +// return nil, errs.ErrArgs.Wrap("group user duplicate") +// } +// duplicateMap[key] = struct{}{} +// userIDMap[member.UserID] = struct{}{} +// groupIDMap[member.GroupID] = struct{}{} +// } +// groupIDs := utils.Keys(groupIDMap) +// userIDs := utils.Keys(userIDMap) +// // todo +// members, err := s.FindGroupMember(ctx, groupIDs, append(userIDs, mcontext.GetOpUserID(ctx)), nil) +// if err != nil { +// return nil, err +// } +// for _, member := range members { +// delete(duplicateMap, [...]string{member.GroupID, member.UserID}) +// } +// if len(duplicateMap) > 0 { +// return nil, errs.ErrArgs.Wrap("user not found" + strings.Join(utils.Slice(utils.Keys(duplicateMap), func(e [2]string) string { +// return fmt.Sprintf("[group: %s user: %s]", e[0], e[1]) +// }), ",")) +// } +// memberMap := utils.SliceToMap(members, func(e *relationtb.GroupMemberModel) [2]string { +// return [...]string{e.GroupID, e.UserID} +// }) +// if !authverify.IsAppManagerUid(ctx) { +// opUserID := mcontext.GetOpUserID(ctx) +// for _, member := range req.Members { +// if member.RoleLevel != nil { +// switch member.RoleLevel.Value { +// case constant.GroupOrdinaryUsers, constant.GroupAdmin: +// default: +// return nil, errs.ErrArgs.Wrap("invalid role level") +// } +// } +// opMember, ok := memberMap[[...]string{member.GroupID, opUserID}] +// if !ok { +// return nil, errs.ErrArgs.Wrap(fmt.Sprintf("user %s not in group %s", opUserID, member.GroupID)) +// } +// if member.UserID == opUserID { +// if member.RoleLevel != nil { +// return nil, errs.ErrNoPermission.Wrap("can not change self role level") +// } +// continue +// } +// if opMember.RoleLevel == constant.GroupOrdinaryUsers { +// return nil, errs.ErrNoPermission.Wrap("ordinary users can not change other role level") +// } +// dbMember, ok := memberMap[[...]string{member.GroupID, member.UserID}] +// if !ok { +// return nil, errs.ErrRecordNotFound.Wrap(fmt.Sprintf("user %s not in group %s", member.UserID, member.GroupID)) +// } +// //if opMember.RoleLevel == constant.GroupOwner { +// // continue +// //} +// //if dbMember.RoleLevel == constant.GroupOwner { +// // return nil, errs.ErrNoPermission.Wrap("change group owner") +// //} +// //if opMember.RoleLevel == constant.GroupAdmin && dbMember.RoleLevel == constant.GroupAdmin { +// // return nil, errs.ErrNoPermission.Wrap("admin can not change other admin role info") +// //} +// switch opMember.RoleLevel { +// case constant.GroupOrdinaryUsers: +// return nil, errs.ErrNoPermission.Wrap("ordinary users can not change other role level") +// case constant.GroupAdmin: +// if dbMember.RoleLevel != constant.GroupOrdinaryUsers { +// return nil, errs.ErrNoPermission.Wrap("admin can not change other role level") +// } +// if member.RoleLevel != nil { +// return nil, errs.ErrNoPermission.Wrap("admin can not change other role level") +// } +// case constant.GroupOwner: +// //if member.RoleLevel != nil && member.RoleLevel.Value == constant.GroupOwner { +// // return nil, errs.ErrNoPermission.Wrap("owner only one") +// //} +// } +// } +// } +// for _, member := range req.Members { +// if member.RoleLevel == nil { +// continue +// } +// if memberMap[[...]string{member.GroupID, member.UserID}].RoleLevel == constant.GroupOwner { +// return nil, errs.ErrArgs.Wrap(fmt.Sprintf("group %s user %s is owner", member.GroupID, member.UserID)) +// } +// } +// for i := 0; i < len(req.Members); i++ { +// if err := CallbackBeforeSetGroupMemberInfo(ctx, req.Members[i]); err != nil { +// return nil, err +// } +// } +// if err = s.db.UpdateGroupMembers(ctx, utils.Slice(req.Members, func(e *pbgroup.SetGroupMemberInfo) *relationtb.BatchUpdateGroupMember { +// return &relationtb.BatchUpdateGroupMember{ +// GroupID: e.GroupID, +// UserID: e.UserID, +// Map: UpdateGroupMemberMap(e), +// } +// })); err != nil { +// return nil, err +// } +// for _, member := range req.Members { +// if member.RoleLevel != nil { +// switch member.RoleLevel.Value { +// case constant.GroupAdmin: +// s.Notification.GroupMemberSetToAdminNotification(ctx, member.GroupID, member.UserID) +// case constant.GroupOrdinaryUsers: +// s.Notification.GroupMemberSetToOrdinaryUserNotification(ctx, member.GroupID, member.UserID) +// } +// } +// if member.Nickname != nil || member.FaceURL != nil || member.Ex != nil { +// log.ZDebug(ctx, "setGroupMemberInfo notification", "member", member.UserID) +// if err := s.Notification.GroupMemberInfoSetNotification(ctx, member.GroupID, member.UserID); err != nil { +// log.ZError(ctx, "setGroupMemberInfo notification failed", err, "member", member.UserID, "groupID", member.GroupID) +// } +// } +// } +// return resp, nil +//} + +func (s *groupServer) setGroupMemberInfo(ctx context.Context, memberCache map[string]*relationtb.GroupMemberModel, member *pbgroup.SetGroupMemberInfo) error { + + return nil +} + func (s *groupServer) SetGroupMemberInfo(ctx context.Context, req *pbgroup.SetGroupMemberInfoReq) (*pbgroup.SetGroupMemberInfoResp, error) { resp := &pbgroup.SetGroupMemberInfoResp{} if len(req.Members) == 0 { return nil, errs.ErrArgs.Wrap("members empty") } + opUserID := mcontext.GetOpUserID(ctx) + if opUserID == "" { + return nil, errs.ErrNoPermission.Wrap("no op user id") + } + isAppManagerUid := authverify.IsAppManagerUid(ctx) for i := range req.Members { req.Members[i].FaceURL = nil } - duplicateMap := make(map[[2]string]struct{}) - userIDMap := make(map[string]struct{}) - groupIDMap := make(map[string]struct{}) - for _, member := range req.Members { - key := [...]string{member.GroupID, member.UserID} - if _, ok := duplicateMap[key]; ok { - return nil, errs.ErrArgs.Wrap("group user duplicate") + groupMembers := make(map[string][]*pbgroup.SetGroupMemberInfo) + for i, member := range req.Members { + if member.RoleLevel != nil { + switch member.RoleLevel.Value { + case constant.GroupOwner: + return nil, errs.ErrNoPermission.Wrap("cannot set ungroup owner") + case constant.GroupAdmin, constant.GroupOrdinaryUsers: + default: + return nil, errs.ErrArgs.Wrap("invalid role level") + } } - duplicateMap[key] = struct{}{} - userIDMap[member.UserID] = struct{}{} - groupIDMap[member.GroupID] = struct{}{} - } - groupIDs := utils.Keys(groupIDMap) - userIDs := utils.Keys(userIDMap) - members, err := s.FindGroupMember(ctx, groupIDs, append(userIDs, mcontext.GetOpUserID(ctx)), nil) - if err != nil { - return nil, err - } - for _, member := range members { - delete(duplicateMap, [...]string{member.GroupID, member.UserID}) + groupMembers[member.GroupID] = append(groupMembers[member.GroupID], req.Members[i]) } - if len(duplicateMap) > 0 { - return nil, errs.ErrArgs.Wrap("user not found" + strings.Join(utils.Slice(utils.Keys(duplicateMap), func(e [2]string) string { - return fmt.Sprintf("[group: %s user: %s]", e[0], e[1]) - }), ",")) - } - memberMap := utils.SliceToMap(members, func(e *relationtb.GroupMemberModel) [2]string { - return [...]string{e.GroupID, e.UserID} - }) - if !authverify.IsAppManagerUid(ctx) { - opUserID := mcontext.GetOpUserID(ctx) - for _, member := range req.Members { - if member.RoleLevel != nil { - switch member.RoleLevel.Value { - case constant.GroupOrdinaryUsers, constant.GroupAdmin: - default: - return nil, errs.ErrArgs.Wrap("invalid role level") - } - } - opMember, ok := memberMap[[...]string{member.GroupID, opUserID}] - if !ok { - return nil, errs.ErrArgs.Wrap(fmt.Sprintf("user %s not in group %s", opUserID, member.GroupID)) + for groupID, members := range groupMembers { + temp := make(map[string]struct{}) + userIDs := make([]string, len(members)+1) + for _, member := range members { + if _, ok := temp[member.UserID]; ok { + return nil, errs.ErrArgs.Wrap(fmt.Sprintf("repeat group %s user %s", member.GroupID, member.UserID)) } + temp[member.UserID] = struct{}{} + userIDs = append(userIDs, member.UserID) + } + if _, ok := temp[opUserID]; !ok { + userIDs = append(userIDs, opUserID) + } + dbMembers, err := s.db.FindGroupMembers(ctx, groupID, userIDs) + if err != nil { + return nil, err + } + opUserIndex := -1 + for i, member := range dbMembers { if member.UserID == opUserID { - if member.RoleLevel != nil { - return nil, errs.ErrNoPermission.Wrap("can not change self role level") - } - continue + opUserIndex = i + break } - if opMember.RoleLevel == constant.GroupOrdinaryUsers { - return nil, errs.ErrNoPermission.Wrap("ordinary users can not change other role level") + } + switch len(userIDs) - len(dbMembers) { + case 0: + if !isAppManagerUid { + roleLevel := dbMembers[opUserIndex].RoleLevel + if roleLevel != constant.GroupOwner { + switch roleLevel { + case constant.GroupAdmin: + for _, member := range dbMembers { + if member.RoleLevel == constant.GroupOwner { + return nil, errs.ErrNoPermission.Wrap("admin can not change group owner") + } + if member.RoleLevel == constant.GroupAdmin && member.UserID != opUserID { + return nil, errs.ErrNoPermission.Wrap("admin can not change other group admin") + } + } + case constant.GroupOrdinaryUsers: + for _, member := range dbMembers { + if !(member.RoleLevel == constant.GroupOrdinaryUsers && member.UserID == opUserID) { + return nil, errs.ErrNoPermission.Wrap("ordinary users can not change other role level") + } + } + default: + for _, member := range dbMembers { + if member.RoleLevel >= roleLevel { + return nil, errs.ErrNoPermission.Wrap("can not change higher role level") + } + } + } + } } - dbMember, ok := memberMap[[...]string{member.GroupID, member.UserID}] - if !ok { - return nil, errs.ErrRecordNotFound.Wrap(fmt.Sprintf("user %s not in group %s", member.UserID, member.GroupID)) + case 1: + if opUserIndex >= 0 { + return nil, errs.ErrArgs.Wrap("user not in group") } - //if opMember.RoleLevel == constant.GroupOwner { - // continue - //} - //if dbMember.RoleLevel == constant.GroupOwner { - // return nil, errs.ErrNoPermission.Wrap("change group owner") - //} - //if opMember.RoleLevel == constant.GroupAdmin && dbMember.RoleLevel == constant.GroupAdmin { - // return nil, errs.ErrNoPermission.Wrap("admin can not change other admin role info") - //} - switch opMember.RoleLevel { - case constant.GroupOrdinaryUsers: - return nil, errs.ErrNoPermission.Wrap("ordinary users can not change other role level") - case constant.GroupAdmin: - if dbMember.RoleLevel != constant.GroupOrdinaryUsers { - return nil, errs.ErrNoPermission.Wrap("admin can not change other role level") - } - if member.RoleLevel != nil { - return nil, errs.ErrNoPermission.Wrap("admin can not change other role level") - } - case constant.GroupOwner: - //if member.RoleLevel != nil && member.RoleLevel.Value == constant.GroupOwner { - // return nil, errs.ErrNoPermission.Wrap("owner only one") - //} + if !isAppManagerUid { + return nil, errs.ErrNoPermission.Wrap("user not in group") } - } - } - for _, member := range req.Members { - if member.RoleLevel == nil { - continue - } - if memberMap[[...]string{member.GroupID, member.UserID}].RoleLevel == constant.GroupOwner { - return nil, errs.ErrArgs.Wrap(fmt.Sprintf("group %s user %s is owner", member.GroupID, member.UserID)) + default: + return nil, errs.ErrArgs.Wrap("user not in group") } } for i := 0; i < len(req.Members); i++ { @@ -1414,7 +1448,7 @@ func (s *groupServer) SetGroupMemberInfo(ctx context.Context, req *pbgroup.SetGr return nil, err } } - if err = s.GroupDatabase.UpdateGroupMembers(ctx, utils.Slice(req.Members, func(e *pbgroup.SetGroupMemberInfo) *relationtb.BatchUpdateGroupMember { + if err := s.db.UpdateGroupMembers(ctx, utils.Slice(req.Members, func(e *pbgroup.SetGroupMemberInfo) *relationtb.BatchUpdateGroupMember { return &relationtb.BatchUpdateGroupMember{ GroupID: e.GroupID, UserID: e.UserID, @@ -1433,10 +1467,7 @@ func (s *groupServer) SetGroupMemberInfo(ctx context.Context, req *pbgroup.SetGr } } if member.Nickname != nil || member.FaceURL != nil || member.Ex != nil { - log.ZDebug(ctx, "setGroupMemberInfo notification", "member", member.UserID) - if err := s.Notification.GroupMemberInfoSetNotification(ctx, member.GroupID, member.UserID); err != nil { - log.ZError(ctx, "setGroupMemberInfo notification failed", err, "member", member.UserID, "groupID", member.GroupID) - } + s.Notification.GroupMemberInfoSetNotification(ctx, member.GroupID, member.UserID) } } return resp, nil @@ -1450,7 +1481,7 @@ func (s *groupServer) GetGroupAbstractInfo(ctx context.Context, req *pbgroup.Get if utils.Duplicate(req.GroupIDs) { return nil, errs.ErrArgs.Wrap("groupIDs duplicate") } - groups, err := s.GroupDatabase.FindGroup(ctx, req.GroupIDs) + groups, err := s.db.FindGroup(ctx, req.GroupIDs) if err != nil { return nil, err } @@ -1459,7 +1490,7 @@ func (s *groupServer) GetGroupAbstractInfo(ctx context.Context, req *pbgroup.Get })); len(ids) > 0 { return nil, errs.ErrGroupIDNotFound.Wrap("not found group " + strings.Join(ids, ",")) } - groupUserMap, err := s.GroupDatabase.MapGroupMemberUserID(ctx, req.GroupIDs) + groupUserMap, err := s.db.MapGroupMemberUserID(ctx, req.GroupIDs) if err != nil { return nil, err } @@ -1478,25 +1509,14 @@ func (s *groupServer) GetUserInGroupMembers(ctx context.Context, req *pbgroup.Ge if len(req.GroupIDs) == 0 { return nil, errs.ErrArgs.Wrap("groupIDs empty") } - members, err := s.FindGroupMember(ctx, []string{req.UserID}, req.GroupIDs, nil) + members, err := s.db.FindGroupMemberUser(ctx, req.GroupIDs, req.UserID) if err != nil { return nil, err } - publicUserInfoMap, err := s.GetPublicUserInfoMap(ctx, utils.Filter(members, func(e *relationtb.GroupMemberModel) (string, bool) { - return e.UserID, e.Nickname == "" || e.FaceURL == "" - }), true) - if err != nil { + if err := s.PopulateGroupMember(ctx, members...); err != nil { return nil, err } resp.Members = utils.Slice(members, func(e *relationtb.GroupMemberModel) *sdkws.GroupMemberFullInfo { - if userInfo, ok := publicUserInfoMap[e.UserID]; ok { - if e.Nickname == "" { - e.Nickname = userInfo.Nickname - } - if e.FaceURL == "" { - e.FaceURL = userInfo.FaceURL - } - } return convert.Db2PbGroupMember(e) }) return resp, nil @@ -1504,7 +1524,7 @@ func (s *groupServer) GetUserInGroupMembers(ctx context.Context, req *pbgroup.Ge func (s *groupServer) GetGroupMemberUserIDs(ctx context.Context, req *pbgroup.GetGroupMemberUserIDsReq) (resp *pbgroup.GetGroupMemberUserIDsResp, err error) { resp = &pbgroup.GetGroupMemberUserIDsResp{} - resp.UserIDs, err = s.GroupDatabase.FindGroupMemberUserID(ctx, req.GroupID) + resp.UserIDs, err = s.db.FindGroupMemberUserID(ctx, req.GroupID) if err != nil { return nil, err } @@ -1516,25 +1536,14 @@ func (s *groupServer) GetGroupMemberRoleLevel(ctx context.Context, req *pbgroup. if len(req.RoleLevels) == 0 { return nil, errs.ErrArgs.Wrap("RoleLevels empty") } - members, err := s.FindGroupMember(ctx, []string{req.GroupID}, nil, req.RoleLevels) + members, err := s.db.FindGroupMemberRoleLevels(ctx, req.GroupID, req.RoleLevels) if err != nil { return nil, err } - publicUserInfoMap, err := s.GetPublicUserInfoMap(ctx, utils.Filter(members, func(e *relationtb.GroupMemberModel) (string, bool) { - return e.UserID, e.Nickname == "" || e.FaceURL == "" - }), true) - if err != nil { + if err := s.PopulateGroupMember(ctx, members...); err != nil { return nil, err } resp.Members = utils.Slice(members, func(e *relationtb.GroupMemberModel) *sdkws.GroupMemberFullInfo { - if userInfo, ok := publicUserInfoMap[e.UserID]; ok { - if e.Nickname == "" { - e.Nickname = userInfo.Nickname - } - if e.FaceURL == "" { - e.FaceURL = userInfo.FaceURL - } - } return convert.Db2PbGroupMember(e) }) return resp, nil @@ -1542,7 +1551,7 @@ func (s *groupServer) GetGroupMemberRoleLevel(ctx context.Context, req *pbgroup. func (s *groupServer) GetGroupUsersReqApplicationList(ctx context.Context, req *pbgroup.GetGroupUsersReqApplicationListReq) (*pbgroup.GetGroupUsersReqApplicationListResp, error) { resp := &pbgroup.GetGroupUsersReqApplicationListResp{} - total, requests, err := s.GroupDatabase.FindGroupRequests(ctx, req.GroupID, req.UserIDs) + requests, err := s.db.FindGroupRequests(ctx, req.GroupID, req.UserIDs) if err != nil { return nil, err } @@ -1552,7 +1561,7 @@ func (s *groupServer) GetGroupUsersReqApplicationList(ctx context.Context, req * groupIDs := utils.Distinct(utils.Slice(requests, func(e *relationtb.GroupRequestModel) string { return e.GroupID })) - groups, err := s.GroupDatabase.FindGroup(ctx, groupIDs) + groups, err := s.db.FindGroup(ctx, groupIDs) if err != nil { return nil, err } @@ -1562,14 +1571,17 @@ func (s *groupServer) GetGroupUsersReqApplicationList(ctx context.Context, req * if ids := utils.Single(groupIDs, utils.Keys(groupMap)); len(ids) > 0 { return nil, errs.ErrGroupIDNotFound.Wrap(strings.Join(ids, ",")) } - owners, err := s.FindGroupMember(ctx, groupIDs, nil, []int32{constant.GroupOwner}) + owners, err := s.db.FindGroupsOwner(ctx, groupIDs) if err != nil { return nil, err } + if err := s.PopulateGroupMember(ctx, owners...); err != nil { + return nil, err + } ownerMap := utils.SliceToMap(owners, func(e *relationtb.GroupMemberModel) string { return e.GroupID }) - groupMemberNum, err := s.GroupDatabase.MapGroupMemberNum(ctx, groupIDs) + groupMemberNum, err := s.db.MapGroupMemberNum(ctx, groupIDs) if err != nil { return nil, err } @@ -1580,40 +1592,40 @@ func (s *groupServer) GetGroupUsersReqApplicationList(ctx context.Context, req * } return convert.Db2PbGroupRequest(e, nil, convert.Db2PbGroupInfo(groupMap[e.GroupID], ownerUserID, groupMemberNum[e.GroupID])) }) - resp.Total = total + resp.Total = int64(len(resp.GroupRequests)) return resp, nil } -func (s *groupServer) groupMemberHashCode(ctx context.Context, groupID string) (uint64, error) { - userIDs, err := s.GroupDatabase.FindGroupMemberUserID(ctx, groupID) - if err != nil { - return 0, err - } - var members []*sdkws.GroupMemberFullInfo - if len(userIDs) > 0 { - resp, err := s.GetGroupMembersInfo(ctx, &pbgroup.GetGroupMembersInfoReq{GroupID: groupID, UserIDs: userIDs}) - if err != nil { - return 0, err - } - members = resp.Members - utils.Sort(userIDs, true) - } - memberMap := utils.SliceToMap(members, func(e *sdkws.GroupMemberFullInfo) string { - return e.UserID - }) - res := make([]*sdkws.GroupMemberFullInfo, 0, len(members)) - for _, userID := range userIDs { - member, ok := memberMap[userID] - if !ok { - continue - } - member.AppMangerLevel = 0 - res = append(res, member) - } - data, err := json.Marshal(res) - if err != nil { - return 0, err - } - sum := md5.Sum(data) - return binary.BigEndian.Uint64(sum[:]), nil -} +//func (s *groupServer) groupMemberHashCode(ctx context.Context, groupID string) (uint64, error) { +// userIDs, err := s.db.FindGroupMemberUserID(ctx, groupID) +// if err != nil { +// return 0, err +// } +// var members []*sdkws.GroupMemberFullInfo +// if len(userIDs) > 0 { +// resp, err := s.GetGroupMembersInfo(ctx, &pbgroup.GetGroupMembersInfoReq{GroupID: groupID, UserIDs: userIDs}) +// if err != nil { +// return 0, err +// } +// members = resp.Members +// utils.Sort(userIDs, true) +// } +// memberMap := utils.SliceToMap(members, func(e *sdkws.GroupMemberFullInfo) string { +// return e.UserID +// }) +// res := make([]*sdkws.GroupMemberFullInfo, 0, len(members)) +// for _, userID := range userIDs { +// member, ok := memberMap[userID] +// if !ok { +// continue +// } +// member.AppMangerLevel = 0 +// res = append(res, member) +// } +// data, err := json.Marshal(res) +// if err != nil { +// return 0, err +// } +// sum := md5.Sum(data) +// return binary.BigEndian.Uint64(sum[:]), nil +//} diff --git a/internal/rpc/group/statistics.go b/internal/rpc/group/statistics.go index 8aeefbee3..d909e9503 100644 --- a/internal/rpc/group/statistics.go +++ b/internal/rpc/group/statistics.go @@ -26,16 +26,16 @@ func (s *groupServer) GroupCreateCount(ctx context.Context, req *group.GroupCrea if req.Start > req.End { return nil, errs.ErrArgs.Wrap("start > end") } - total, err := s.GroupDatabase.CountTotal(ctx, nil) + total, err := s.db.CountTotal(ctx, nil) if err != nil { return nil, err } start := time.UnixMilli(req.Start) - before, err := s.GroupDatabase.CountTotal(ctx, &start) + before, err := s.db.CountTotal(ctx, &start) if err != nil { return nil, err } - count, err := s.GroupDatabase.CountRangeEverydayTotal(ctx, start, time.UnixMilli(req.End)) + count, err := s.db.CountRangeEverydayTotal(ctx, start, time.UnixMilli(req.End)) if err != nil { return nil, err } diff --git a/internal/rpc/group/super_group.go b/internal/rpc/group/super_group.go index 6cd1a2943..cb4febe7c 100644 --- a/internal/rpc/group/super_group.go +++ b/internal/rpc/group/super_group.go @@ -16,99 +16,14 @@ package group import ( "context" - "fmt" - "strings" - - "github.com/OpenIMSDK/protocol/constant" + "errors" pbgroup "github.com/OpenIMSDK/protocol/group" - sdkws "github.com/OpenIMSDK/protocol/sdkws" - "github.com/OpenIMSDK/tools/errs" - "github.com/OpenIMSDK/tools/utils" - - "github.com/openimsdk/open-im-server/v3/pkg/common/convert" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/unrelation" ) -func (s *groupServer) GetJoinedSuperGroupList( - ctx context.Context, - req *pbgroup.GetJoinedSuperGroupListReq, -) (*pbgroup.GetJoinedSuperGroupListResp, error) { - resp := &pbgroup.GetJoinedSuperGroupListResp{} - groupIDs, err := s.GroupDatabase.FindJoinSuperGroup(ctx, req.UserID) - if err != nil { - return nil, err - } - if len(groupIDs) == 0 { - return resp, nil - } - owners, err := s.FindGroupMember(ctx, groupIDs, nil, []int32{constant.GroupOwner}) - if err != nil { - return nil, err - } - ownerMap := utils.SliceToMap(owners, func(e *relation.GroupMemberModel) string { - return e.GroupID - }) - if ids := utils.Single(groupIDs, utils.Keys(ownerMap)); len(ids) > 0 { - return nil, errs.ErrData.Wrap(fmt.Sprintf("super group %s not owner", strings.Join(ids, ","))) - } - groups, err := s.GroupDatabase.FindGroup(ctx, groupIDs) - if err != nil { - return nil, err - } - groupMap := utils.SliceToMap(groups, func(e *relation.GroupModel) string { - return e.GroupID - }) - if ids := utils.Single(groupIDs, utils.Keys(groupMap)); len(ids) > 0 { - return nil, errs.ErrData.Wrap(fmt.Sprintf("super group info %s not found", strings.Join(ids, ","))) - } - superGroupMembers, err := s.GroupDatabase.FindSuperGroup(ctx, groupIDs) - if err != nil { - return nil, err - } - superGroupMemberMap := utils.SliceToMapAny( - superGroupMembers, - func(e *unrelation.SuperGroupModel) (string, []string) { - return e.GroupID, e.MemberIDs - }, - ) - resp.Groups = utils.Slice(groupIDs, func(groupID string) *sdkws.GroupInfo { - return convert.Db2PbGroupInfo(groupMap[groupID], ownerMap[groupID].UserID, uint32(len(superGroupMemberMap))) - }) - return resp, nil +func (s *groupServer) GetJoinedSuperGroupList(context.Context, *pbgroup.GetJoinedSuperGroupListReq) (*pbgroup.GetJoinedSuperGroupListResp, error) { + return nil, errors.New("deprecated") } -func (s *groupServer) GetSuperGroupsInfo( - ctx context.Context, - req *pbgroup.GetSuperGroupsInfoReq, -) (resp *pbgroup.GetSuperGroupsInfoResp, err error) { - resp = &pbgroup.GetSuperGroupsInfoResp{} - if len(req.GroupIDs) == 0 { - return nil, errs.ErrArgs.Wrap("groupIDs empty") - } - groups, err := s.GroupDatabase.FindGroup(ctx, req.GroupIDs) - if err != nil { - return nil, err - } - superGroupMembers, err := s.GroupDatabase.FindSuperGroup(ctx, req.GroupIDs) - if err != nil { - return nil, err - } - superGroupMemberMap := utils.SliceToMapAny( - superGroupMembers, - func(e *unrelation.SuperGroupModel) (string, []string) { - return e.GroupID, e.MemberIDs - }, - ) - owners, err := s.FindGroupMember(ctx, req.GroupIDs, nil, []int32{constant.GroupOwner}) - if err != nil { - return nil, err - } - ownerMap := utils.SliceToMap(owners, func(e *relation.GroupMemberModel) string { - return e.GroupID - }) - resp.GroupInfos = utils.Slice(groups, func(e *relation.GroupModel) *sdkws.GroupInfo { - return convert.Db2PbGroupInfo(e, ownerMap[e.GroupID].UserID, uint32(len(superGroupMemberMap[e.GroupID]))) - }) - return resp, nil +func (s *groupServer) GetSuperGroupsInfo(context.Context, *pbgroup.GetSuperGroupsInfoReq) (resp *pbgroup.GetSuperGroupsInfoResp, err error) { + return nil, errors.New("deprecated") } diff --git a/internal/rpc/third/log.go b/internal/rpc/third/log.go index aa83f58f7..30d95e26b 100644 --- a/internal/rpc/third/log.go +++ b/internal/rpc/third/log.go @@ -120,7 +120,7 @@ func (t *thirdServer) SearchLogs(ctx context.Context, req *third.SearchLogsReq) if req.StartTime > req.EndTime { return nil, errs.ErrArgs.Wrap("startTime>endTime") } - total, logs, err := t.thirdDatabase.SearchLogs(ctx, req.Keyword, time.UnixMilli(req.StartTime), time.UnixMilli(req.EndTime), req.Pagination.PageNumber, req.Pagination.ShowNumber) + total, logs, err := t.thirdDatabase.SearchLogs(ctx, req.Keyword, time.UnixMilli(req.StartTime), time.UnixMilli(req.EndTime), req.Pagination) if err != nil { return nil, err } @@ -128,18 +128,16 @@ func (t *thirdServer) SearchLogs(ctx context.Context, req *third.SearchLogsReq) for _, log := range logs { userIDs = append(userIDs, log.UserID) } - users, err := t.thirdDatabase.FindUsers(ctx, userIDs) + userMap, err := t.userRpcClient.GetUsersInfoMap(ctx, userIDs) if err != nil { return nil, err } - IDtoName := make(map[string]string) - for _, user := range users { - IDtoName[user.UserID] = user.Nickname - } for _, pbLog := range pbLogs { - pbLog.Nickname = IDtoName[pbLog.UserID] + if user, ok := userMap[pbLog.UserID]; ok { + pbLog.Nickname = user.Nickname + } } resp.LogsInfos = pbLogs - resp.Total = total + resp.Total = uint32(total) return &resp, nil } diff --git a/internal/rpc/third/s3.go b/internal/rpc/third/s3.go index 984af88e1..ca826e805 100644 --- a/internal/rpc/third/s3.go +++ b/internal/rpc/third/s3.go @@ -64,7 +64,7 @@ func (t *thirdServer) InitiateMultipartUpload(ctx context.Context, req *third.In Key: haErr.Object.Key, Size: haErr.Object.Size, ContentType: req.ContentType, - Cause: req.Cause, + Group: req.Cause, CreateTime: time.Now(), } if err := t.s3dataBase.SetObject(ctx, obj); err != nil { @@ -143,7 +143,7 @@ func (t *thirdServer) CompleteMultipartUpload(ctx context.Context, req *third.Co Key: result.Key, Size: result.Size, ContentType: req.ContentType, - Cause: req.Cause, + Group: req.Cause, CreateTime: time.Now(), } if err := t.s3dataBase.SetObject(ctx, obj); err != nil { diff --git a/internal/rpc/third/third.go b/internal/rpc/third/third.go index b48eddea9..8ff1ae9a7 100644 --- a/internal/rpc/third/third.go +++ b/internal/rpc/third/third.go @@ -17,6 +17,8 @@ package third import ( "context" "fmt" + "github.com/openimsdk/open-im-server/v3/pkg/common/db/newmgo" + "github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation" "net/url" "time" @@ -33,13 +35,22 @@ import ( "github.com/openimsdk/open-im-server/v3/pkg/common/config" "github.com/openimsdk/open-im-server/v3/pkg/common/db/cache" "github.com/openimsdk/open-im-server/v3/pkg/common/db/controller" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/relation" - relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" - "github.com/openimsdk/open-im-server/v3/pkg/rpcclient" ) func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error { + mongo, err := unrelation.NewMongo() + if err != nil { + return err + } + logdb, err := newmgo.NewLogMongo(mongo.GetDatabase()) + if err != nil { + return err + } + s3db, err := newmgo.NewS3Mongo(mongo.GetDatabase()) + if err != nil { + return err + } apiURL := config.Config.Object.ApiURL if apiURL == "" { return fmt.Errorf("api url is empty") @@ -55,13 +66,6 @@ func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) e if err != nil { return err } - db, err := relation.NewGormDB() - if err != nil { - return err - } - if err := db.AutoMigrate(&relationtb.ObjectModel{}); err != nil { - return err - } // 根据配置文件策略选择 oss 方式 enable := config.Config.Object.Enable var o s3.Interface @@ -78,17 +82,11 @@ func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) e if err != nil { return err } - //specialerror.AddErrHandler(func(err error) errs.CodeError { - // if o.IsNotFound(err) { - // return errs.ErrRecordNotFound - // } - // return nil - //}) third.RegisterThirdServer(server, &thirdServer{ apiURL: apiURL, - thirdDatabase: controller.NewThirdDatabase(cache.NewMsgCacheModel(rdb), db), + thirdDatabase: controller.NewThirdDatabase(cache.NewMsgCacheModel(rdb), logdb), userRpcClient: rpcclient.NewUserRpcClient(client), - s3dataBase: controller.NewS3Database(rdb, o, relation.NewObjectInfo(db)), + s3dataBase: controller.NewS3Database(rdb, o, s3db), defaultExpire: time.Hour * 24 * 7, }) return nil diff --git a/internal/rpc/user/user.go b/internal/rpc/user/user.go index f2ceb3beb..cd77c4219 100644 --- a/internal/rpc/user/user.go +++ b/internal/rpc/user/user.go @@ -17,6 +17,8 @@ package user import ( "context" "errors" + "github.com/openimsdk/open-im-server/v3/pkg/common/db/newmgo" + tx2 "github.com/openimsdk/open-im-server/v3/pkg/common/db/tx" "strings" "time" @@ -24,7 +26,6 @@ import ( "github.com/OpenIMSDK/protocol/sdkws" "github.com/OpenIMSDK/tools/errs" "github.com/OpenIMSDK/tools/log" - "github.com/OpenIMSDK/tools/tx" "github.com/openimsdk/open-im-server/v3/pkg/authverify" "github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation" @@ -35,7 +36,6 @@ import ( "github.com/openimsdk/open-im-server/v3/pkg/common/convert" "github.com/openimsdk/open-im-server/v3/pkg/common/db/cache" "github.com/openimsdk/open-im-server/v3/pkg/common/db/controller" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/relation" tablerelation "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" "github.com/openimsdk/open-im-server/v3/pkg/rpcclient" "github.com/openimsdk/open-im-server/v3/pkg/rpcclient/notification" @@ -55,10 +55,6 @@ type userServer struct { } func Start(client registry.SvcDiscoveryRegistry, server *grpc.Server) error { - db, err := relation.NewGormDB() - if err != nil { - return err - } rdb, err := cache.NewRedis() if err != nil { return err @@ -67,9 +63,6 @@ func Start(client registry.SvcDiscoveryRegistry, server *grpc.Server) error { if err != nil { return err } - if err := db.AutoMigrate(&tablerelation.UserModel{}); err != nil { - return err - } users := make([]*tablerelation.UserModel, 0) if len(config.Config.Manager.UserID) != len(config.Config.Manager.Nickname) { return errors.New("len(config.Config.Manager.AppManagerUid) != len(config.Config.Manager.Nickname)") @@ -77,10 +70,17 @@ func Start(client registry.SvcDiscoveryRegistry, server *grpc.Server) error { for k, v := range config.Config.Manager.UserID { users = append(users, &tablerelation.UserModel{UserID: v, Nickname: config.Config.Manager.Nickname[k], AppMangerLevel: constant.AppAdmin}) } - userDB := relation.NewUserGorm(db) + userDB, err := newmgo.NewUserMongo(mongo.GetDatabase()) + if err != nil { + return err + } + tx, err := tx2.NewAuto(context.Background(), mongo.GetClient()) + if err != nil { + return err + } cache := cache.NewUserCacheRedis(rdb, userDB, cache.GetDefaultOpt()) userMongoDB := unrelation.NewUserMongoDriver(mongo.GetDatabase()) - database := controller.NewUserDatabase(userDB, cache, tx.NewGorm(db), userMongoDB) + database := controller.NewUserDatabase(userDB, cache, tx, userMongoDB) friendRpcClient := rpcclient.NewFriendRpcClient(client) groupRpcClient := rpcclient.NewGroupRpcClient(client) msgRpcClient := rpcclient.NewMessageRpcClient(client) @@ -118,12 +118,11 @@ func (s *userServer) UpdateUserInfo(ctx context.Context, req *pbuser.UpdateUserI if err := CallbackBeforeUpdateUserInfo(ctx, req); err != nil { return nil, err } - user := convert.UserPb2DB(req.UserInfo) - if err != nil { - return nil, err + data := convert.UserPb2DBMap(req.UserInfo) + if len(data) == 0 { + return nil, errs.ErrArgs.Wrap("no data to update") } - err = s.Update(ctx, user) - if err != nil { + if err := s.UpdateByMap(ctx, req.UserInfo.UserID, data); err != nil { return nil, err } _ = s.friendNotificationSender.UserInfoUpdatedNotification(ctx, req.UserInfo.UserID) @@ -150,7 +149,7 @@ func (s *userServer) SetGlobalRecvMessageOpt(ctx context.Context, req *pbuser.Se if _, err := s.FindWithError(ctx, []string{req.UserID}); err != nil { return nil, err } - m := make(map[string]interface{}, 1) + m := make(map[string]any, 1) m["global_recv_msg_opt"] = req.GlobalRecvMsgOpt if err := s.UpdateByMap(ctx, req.UserID, m); err != nil { return nil, err @@ -172,7 +171,7 @@ func (s *userServer) AccountCheck(ctx context.Context, req *pbuser.AccountCheckR if err != nil { return nil, err } - userIDs := make(map[string]interface{}, 0) + userIDs := make(map[string]any, 0) for _, v := range users { userIDs[v.UserID] = nil } @@ -189,12 +188,7 @@ func (s *userServer) AccountCheck(ctx context.Context, req *pbuser.AccountCheckR } func (s *userServer) GetPaginationUsers(ctx context.Context, req *pbuser.GetPaginationUsersReq) (resp *pbuser.GetPaginationUsersResp, err error) { - var pageNumber, showNumber int32 - if req.Pagination != nil { - pageNumber = req.Pagination.PageNumber - showNumber = req.Pagination.ShowNumber - } - users, total, err := s.Page(ctx, pageNumber, showNumber) + total, users, err := s.Page(ctx, req.Pagination) if err != nil { return nil, err } @@ -259,11 +253,11 @@ func (s *userServer) GetGlobalRecvMessageOpt(ctx context.Context, req *pbuser.Ge // GetAllUserID Get user account by page. func (s *userServer) GetAllUserID(ctx context.Context, req *pbuser.GetAllUserIDReq) (resp *pbuser.GetAllUserIDResp, err error) { - userIDs, err := s.UserDatabase.GetAllUserID(ctx, req.Pagination.PageNumber, req.Pagination.ShowNumber) + total, userIDs, err := s.UserDatabase.GetAllUserID(ctx, req.Pagination) if err != nil { return nil, err } - return &pbuser.GetAllUserIDResp{UserIDs: userIDs}, nil + return &pbuser.GetAllUserIDResp{Total: int32(total), UserIDs: userIDs}, nil } // SubscribeOrCancelUsersStatus Subscribe online or cancel online users. diff --git a/internal/rpc/user/user_test.go b/internal/rpc/user/user_test.go new file mode 100644 index 000000000..abe1c5023 --- /dev/null +++ b/internal/rpc/user/user_test.go @@ -0,0 +1,132 @@ +package user + +import ( + "context" + "errors" + "github.com/OpenIMSDK/protocol/constant" + "github.com/OpenIMSDK/protocol/sdkws" + "github.com/OpenIMSDK/protocol/user" + "github.com/OpenIMSDK/tools/log" + "github.com/openimsdk/open-im-server/v3/pkg/common/config" + "github.com/openimsdk/open-im-server/v3/pkg/common/db/cache" + "github.com/openimsdk/open-im-server/v3/pkg/common/db/controller" + "github.com/openimsdk/open-im-server/v3/pkg/common/db/newmgo" + tablerelation "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" + tx2 "github.com/openimsdk/open-im-server/v3/pkg/common/db/tx" + "github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation" + "github.com/redis/go-redis/v9" + "math/rand" + "net" + "strconv" + "testing" +) + +var ( + rdb redis.UniversalClient + mgo *unrelation.Mongo + ctx context.Context +) + +func InitDB() error { + addr := "172.16.8.142" + pwd := "openIM123" + + config.Config.Redis.Address = []string{net.JoinHostPort(addr, "16379")} + config.Config.Redis.Password = pwd + config.Config.Mongo.Address = []string{net.JoinHostPort(addr, "37017")} + config.Config.Mongo.Database = "openIM_v3" + config.Config.Mongo.Username = "root" + config.Config.Mongo.Password = pwd + config.Config.Mongo.MaxPoolSize = 100 + var err error + rdb, err = cache.NewRedis() + if err != nil { + return err + } + mgo, err = unrelation.NewMongo() + if err != nil { + return err + } + tx, err := tx2.NewAuto(context.Background(), mgo.GetClient()) + if err != nil { + return err + } + + config.Config.Object.Enable = "minio" + config.Config.Object.ApiURL = "http://" + net.JoinHostPort(addr, "10002") + config.Config.Object.Minio.Bucket = "openim" + config.Config.Object.Minio.Endpoint = "http://" + net.JoinHostPort(addr, "10005") + config.Config.Object.Minio.AccessKeyID = "root" + config.Config.Object.Minio.SecretAccessKey = pwd + config.Config.Object.Minio.SignEndpoint = config.Config.Object.Minio.Endpoint + + config.Config.Manager.UserID = []string{"openIM123456"} + config.Config.Manager.Nickname = []string{"openIM123456"} + + ctx = context.WithValue(context.Background(), constant.OperationID, "debugOperationID") + ctx = context.WithValue(context.Background(), constant.OpUserID, config.Config.Manager.UserID[0]) + + if err := log.InitFromConfig("", "", 6, true, false, "", 2, 1); err != nil { + panic(err) + } + + users := make([]*tablerelation.UserModel, 0) + if len(config.Config.Manager.UserID) != len(config.Config.Manager.Nickname) { + return errors.New("len(config.Config.Manager.AppManagerUid) != len(config.Config.Manager.Nickname)") + } + for k, v := range config.Config.Manager.UserID { + users = append(users, &tablerelation.UserModel{UserID: v, Nickname: config.Config.Manager.Nickname[k], AppMangerLevel: constant.AppAdmin}) + } + userDB, err := newmgo.NewUserMongo(mgo.GetDatabase()) + if err != nil { + return err + } + + //var client registry.SvcDiscoveryRegistry + //_= client + cache := cache.NewUserCacheRedis(rdb, userDB, cache.GetDefaultOpt()) + userMongoDB := unrelation.NewUserMongoDriver(mgo.GetDatabase()) + database := controller.NewUserDatabase(userDB, cache, tx, userMongoDB) + //friendRpcClient := rpcclient.NewFriendRpcClient(client) + //groupRpcClient := rpcclient.NewGroupRpcClient(client) + //msgRpcClient := rpcclient.NewMessageRpcClient(client) + + userSrv = &userServer{ + UserDatabase: database, + //RegisterCenter: client, + //friendRpcClient: &friendRpcClient, + //groupRpcClient: &groupRpcClient, + //friendNotificationSender: notification.NewFriendNotificationSender(&msgRpcClient, notification.WithDBFunc(database.FindWithError)), + //userNotificationSender: notification.NewUserNotificationSender(&msgRpcClient, notification.WithUserFunc(database.FindWithError)), + } + + return nil +} + +func init() { + if err := InitDB(); err != nil { + panic(err) + } +} + +var userSrv *userServer + +func TestName(t *testing.T) { + userID := strconv.Itoa(int(rand.Uint32())) + res, err := userSrv.UserRegister(ctx, &user.UserRegisterReq{ + Secret: config.Config.Secret, + Users: []*sdkws.UserInfo{ + { + UserID: userID, + Nickname: userID, + FaceURL: "", + Ex: "", + }, + }, + }) + if err != nil { + panic(err) + } + t.Log(res) + +} diff --git a/internal/tools/conversation.go b/internal/tools/conversation.go index 05d963a17..c91e92078 100644 --- a/internal/tools/conversation.go +++ b/internal/tools/conversation.go @@ -16,6 +16,7 @@ package tools import ( "context" + "github.com/OpenIMSDK/protocol/sdkws" "math/rand" "time" @@ -91,7 +92,11 @@ func (c *MsgTool) ConversationsDestructMsgs() { } for i := 0; i < count; i++ { pageNumber := rand.Int63() % maxPage - conversationIDs, err := c.conversationDatabase.PageConversationIDs(ctx, int32(pageNumber), batchNum) + pagination := &sdkws.RequestPagination{ + PageNumber: int32(pageNumber), + ShowNumber: batchNum, + } + conversationIDs, err := c.conversationDatabase.PageConversationIDs(ctx, pagination) if err != nil { log.ZError(ctx, "PageConversationIDs failed", err, "pageNumber", pageNumber) continue @@ -133,7 +138,7 @@ func (c *MsgTool) ConversationsDestructMsgs() { continue } if len(seqs) > 0 { - if err := c.conversationDatabase.UpdateUsersConversationFiled(ctx, []string{conversation.OwnerUserID}, conversation.ConversationID, map[string]interface{}{"latest_msg_destruct_time": now}); err != nil { + if err := c.conversationDatabase.UpdateUsersConversationFiled(ctx, []string{conversation.OwnerUserID}, conversation.ConversationID, map[string]any{"latest_msg_destruct_time": now}); err != nil { log.ZError(ctx, "updateUsersConversationFiled failed", err, "conversationID", conversation.ConversationID, "ownerUserID", conversation.OwnerUserID) continue } diff --git a/internal/tools/msg.go b/internal/tools/msg.go index ad8f5c471..bf0231786 100644 --- a/internal/tools/msg.go +++ b/internal/tools/msg.go @@ -17,6 +17,9 @@ package tools import ( "context" "fmt" + "github.com/OpenIMSDK/protocol/sdkws" + "github.com/openimsdk/open-im-server/v3/pkg/common/db/newmgo" + tx2 "github.com/openimsdk/open-im-server/v3/pkg/common/db/tx" "math" "github.com/redis/go-redis/v9" @@ -31,13 +34,11 @@ import ( "github.com/OpenIMSDK/tools/log" "github.com/OpenIMSDK/tools/mcontext" "github.com/OpenIMSDK/tools/mw" - "github.com/OpenIMSDK/tools/tx" "github.com/OpenIMSDK/tools/utils" "github.com/openimsdk/open-im-server/v3/pkg/common/config" "github.com/openimsdk/open-im-server/v3/pkg/common/db/cache" "github.com/openimsdk/open-im-server/v3/pkg/common/db/controller" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/relation" "github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation" "github.com/openimsdk/open-im-server/v3/pkg/rpcclient" "github.com/openimsdk/open-im-server/v3/pkg/rpcclient/notification" @@ -72,33 +73,48 @@ func InitMsgTool() (*MsgTool, error) { if err != nil { return nil, err } - db, err := relation.NewGormDB() + discov, err := kdisc.NewDiscoveryRegister(config.Config.Envs.Discovery) if err != nil { return nil, err } - discov, err := kdisc.NewDiscoveryRegister(config.Config.Envs.Discovery) - /* - discov, err := zookeeper.NewClient(config.Config.Zookeeper.ZkAddr, config.Config.Zookeeper.Schema, - zookeeper.WithFreq(time.Hour), zookeeper.WithRoundRobin(), zookeeper.WithUserNameAndPassword(config.Config.Zookeeper.Username, - config.Config.Zookeeper.Password), zookeeper.WithTimeout(10), zookeeper.WithLogger(log.NewZkLogger()))*/ + discov.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials())) + userDB, err := newmgo.NewUserMongo(mongo.GetDatabase()) + if err != nil { + return nil, err + } + tx, err := tx2.NewAuto(context.Background(), mongo.GetClient()) if err != nil { return nil, err } - discov.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials())) - userDB := relation.NewUserGorm(db) msgDatabase := controller.InitCommonMsgDatabase(rdb, mongo.GetDatabase()) userMongoDB := unrelation.NewUserMongoDriver(mongo.GetDatabase()) userDatabase := controller.NewUserDatabase( userDB, - cache.NewUserCacheRedis(rdb, relation.NewUserGorm(db), cache.GetDefaultOpt()), - tx.NewGorm(db), + cache.NewUserCacheRedis(rdb, userDB, cache.GetDefaultOpt()), + tx, userMongoDB, ) - groupDatabase := controller.InitGroupDatabase(db, rdb, mongo.GetDatabase(), nil) + groupDB, err := newmgo.NewGroupMongo(mongo.GetDatabase()) + if err != nil { + return nil, err + } + groupMemberDB, err := newmgo.NewGroupMember(mongo.GetDatabase()) + if err != nil { + return nil, err + } + groupRequestDB, err := newmgo.NewGroupRequestMgo(mongo.GetDatabase()) + if err != nil { + return nil, err + } + conversationDB, err := newmgo.NewConversationMongo(mongo.GetDatabase()) + if err != nil { + return nil, err + } + groupDatabase := controller.NewGroupDatabase(rdb, groupDB, groupMemberDB, groupRequestDB, tx, nil) conversationDatabase := controller.NewConversationDatabase( - relation.NewConversationGorm(db), - cache.NewConversationRedis(rdb, cache.GetDefaultOpt(), relation.NewConversationGorm(db)), - tx.NewGorm(db), + conversationDB, + cache.NewConversationRedis(rdb, cache.GetDefaultOpt(), conversationDB), + tx, ) msgRpcClient := rpcclient.NewMessageRpcClient(discov) msgNotificationSender := notification.NewMsgNotificationSender(rpcclient.WithRpcClient(&msgRpcClient)) @@ -144,7 +160,11 @@ func (c *MsgTool) AllConversationClearMsgAndFixSeq() { } for i := 0; i < count; i++ { pageNumber := rand.Int63() % maxPage - conversationIDs, err := c.conversationDatabase.PageConversationIDs(ctx, int32(pageNumber), batchNum) + pagination := &sdkws.RequestPagination{ + PageNumber: int32(pageNumber), + ShowNumber: batchNum, + } + conversationIDs, err := c.conversationDatabase.PageConversationIDs(ctx, pagination) if err != nil { log.ZError(ctx, "PageConversationIDs failed", err, "pageNumber", pageNumber) continue diff --git a/internal/tools/msg_doc_convert.go b/internal/tools/msg_doc_convert.go index 758625be1..b9150c362 100644 --- a/internal/tools/msg_doc_convert.go +++ b/internal/tools/msg_doc_convert.go @@ -32,7 +32,7 @@ func (c *MsgTool) convertTools() { for _, conversationID := range conversationIDs { conversationIDs = append(conversationIDs, msgprocessor.GetNotificationConversationIDByConversationID(conversationID)) } - userIDs, err := c.userDatabase.GetAllUserID(ctx, 0, 0) + _, userIDs, err := c.userDatabase.GetAllUserID(ctx, nil) if err != nil { log.ZError(ctx, "get all user ids failed", err) return diff --git a/pkg/apistruct/manage.go b/pkg/apistruct/manage.go index 1e0ab3214..a48f5253c 100644 --- a/pkg/apistruct/manage.go +++ b/pkg/apistruct/manage.go @@ -36,7 +36,7 @@ type SendMsg struct { SenderPlatformID int32 `json:"senderPlatformID"` // Content is the actual content of the message, required and excluded from Swagger documentation. - Content map[string]interface{} `json:"content" binding:"required" swaggerignore:"true"` + Content map[string]any `json:"content" binding:"required" swaggerignore:"true"` // ContentType is an integer that represents the type of the content. ContentType int32 `json:"contentType" binding:"required"` diff --git a/pkg/authverify/token.go b/pkg/authverify/token.go index a8e577fde..fd01e8c5a 100644 --- a/pkg/authverify/token.go +++ b/pkg/authverify/token.go @@ -28,7 +28,7 @@ import ( ) func Secret() jwt.Keyfunc { - return func(token *jwt.Token) (interface{}, error) { + return func(token *jwt.Token) (any, error) { return []byte(config.Config.Secret), nil } } @@ -55,7 +55,7 @@ func CheckAdmin(ctx context.Context) error { return errs.ErrNoPermission.Wrap(fmt.Sprintf("user %s is not admin userID", mcontext.GetOpUserID(ctx))) } -func ParseRedisInterfaceToken(redisToken interface{}) (*tokenverify.Claims, error) { +func ParseRedisInterfaceToken(redisToken any) (*tokenverify.Claims, error) { return tokenverify.GetClaimFromToken(string(redisToken.([]uint8)), Secret()) } diff --git a/pkg/common/config/parse.go b/pkg/common/config/parse.go index f2ea962ee..22e458e00 100644 --- a/pkg/common/config/parse.go +++ b/pkg/common/config/parse.go @@ -71,7 +71,7 @@ func GetOptionsByNotification(cfg NotificationConf) msgprocessor.Options { return opts } -func initConfig(config interface{}, configName, configFolderPath string) error { +func initConfig(config any, configName, configFolderPath string) error { configFolderPath = filepath.Join(configFolderPath, configName) _, err := os.Stat(configFolderPath) if err != nil { diff --git a/pkg/common/config/parse_test.go b/pkg/common/config/parse_test.go index e34aa5b7f..38171ec08 100644 --- a/pkg/common/config/parse_test.go +++ b/pkg/common/config/parse_test.go @@ -76,7 +76,7 @@ func TestGetOptionsByNotification(t *testing.T) { func Test_initConfig(t *testing.T) { type args struct { - config interface{} + config any configName string configFolderPath string } diff --git a/pkg/common/convert/friend.go b/pkg/common/convert/friend.go index 7003c8aa6..c81cd98d6 100644 --- a/pkg/common/convert/friend.go +++ b/pkg/common/convert/friend.go @@ -16,6 +16,7 @@ package convert import ( "context" + "fmt" "github.com/OpenIMSDK/protocol/sdkws" "github.com/OpenIMSDK/tools/utils" @@ -31,23 +32,22 @@ func FriendPb2DB(friend *sdkws.FriendInfo) *relation.FriendModel { return dbFriend } -func FriendDB2Pb( - ctx context.Context, - friendDB *relation.FriendModel, +func FriendDB2Pb(ctx context.Context, friendDB *relation.FriendModel, getUsers func(ctx context.Context, userIDs []string) (map[string]*sdkws.UserInfo, error), ) (*sdkws.FriendInfo, error) { - pbfriend := &sdkws.FriendInfo{FriendUser: &sdkws.UserInfo{}} - utils.CopyStructFields(pbfriend, friendDB) users, err := getUsers(ctx, []string{friendDB.FriendUserID}) if err != nil { return nil, err } - pbfriend.FriendUser.UserID = users[friendDB.FriendUserID].UserID - pbfriend.FriendUser.Nickname = users[friendDB.FriendUserID].Nickname - pbfriend.FriendUser.FaceURL = users[friendDB.FriendUserID].FaceURL - pbfriend.FriendUser.Ex = users[friendDB.FriendUserID].Ex - pbfriend.CreateTime = friendDB.CreateTime.Unix() - return pbfriend, nil + user, ok := users[friendDB.FriendUserID] + if !ok { + return nil, fmt.Errorf("user not found: %s", friendDB.FriendUserID) + } + + return &sdkws.FriendInfo{ + FriendUser: user, + CreateTime: friendDB.CreateTime.Unix(), + }, nil } func FriendsDB2Pb( @@ -118,3 +118,37 @@ func FriendRequestDB2Pb( } return res, nil } + +// FriendPb2DBMap converts a FriendInfo protobuf object to a map suitable for database operations. +// It only includes non-zero or non-empty fields in the map. +func FriendPb2DBMap(friend *sdkws.FriendInfo) map[string]any { + if friend == nil { + return nil + } + + val := make(map[string]any) + + // Assuming FriendInfo has similar fields to those in FriendModel. + // Add or remove fields based on your actual FriendInfo and FriendModel structures. + if friend.FriendUser != nil { + if friend.FriendUser.UserID != "" { + val["friend_user_id"] = friend.FriendUser.UserID + } + if friend.FriendUser.Nickname != "" { + val["nickname"] = friend.FriendUser.Nickname + } + if friend.FriendUser.FaceURL != "" { + val["face_url"] = friend.FriendUser.FaceURL + } + if friend.FriendUser.Ex != "" { + val["ex"] = friend.FriendUser.Ex + } + } + if friend.CreateTime != 0 { + val["create_time"] = friend.CreateTime // You might need to convert this to a proper time format. + } + + // Include other fields from FriendInfo as needed, similar to the above pattern. + + return val +} diff --git a/pkg/common/convert/user.go b/pkg/common/convert/user.go index abb3a2144..8d960546a 100644 --- a/pkg/common/convert/user.go +++ b/pkg/common/convert/user.go @@ -22,29 +22,53 @@ import ( relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" ) -func UsersDB2Pb(users []*relationtb.UserModel) (result []*sdkws.UserInfo) { +func UsersDB2Pb(users []*relationtb.UserModel) []*sdkws.UserInfo { + result := make([]*sdkws.UserInfo, 0, len(users)) for _, user := range users { - var userPb sdkws.UserInfo - userPb.UserID = user.UserID - userPb.Nickname = user.Nickname - userPb.FaceURL = user.FaceURL - userPb.Ex = user.Ex - userPb.CreateTime = user.CreateTime.UnixMilli() - userPb.AppMangerLevel = user.AppMangerLevel - userPb.GlobalRecvMsgOpt = user.GlobalRecvMsgOpt - result = append(result, &userPb) + userPb := &sdkws.UserInfo{ + UserID: user.UserID, + Nickname: user.Nickname, + FaceURL: user.FaceURL, + Ex: user.Ex, + CreateTime: user.CreateTime.UnixMilli(), + AppMangerLevel: user.AppMangerLevel, + GlobalRecvMsgOpt: user.GlobalRecvMsgOpt, + } + result = append(result, userPb) } return result } func UserPb2DB(user *sdkws.UserInfo) *relationtb.UserModel { - var userDB relationtb.UserModel - userDB.UserID = user.UserID - userDB.Nickname = user.Nickname - userDB.FaceURL = user.FaceURL - userDB.Ex = user.Ex - userDB.CreateTime = time.UnixMilli(user.CreateTime) - userDB.AppMangerLevel = user.AppMangerLevel - userDB.GlobalRecvMsgOpt = user.GlobalRecvMsgOpt - return &userDB + return &relationtb.UserModel{ + UserID: user.UserID, + Nickname: user.Nickname, + FaceURL: user.FaceURL, + Ex: user.Ex, + CreateTime: time.UnixMilli(user.CreateTime), + AppMangerLevel: user.AppMangerLevel, + GlobalRecvMsgOpt: user.GlobalRecvMsgOpt, + } +} + +func UserPb2DBMap(user *sdkws.UserInfo) map[string]any { + if user == nil { + return nil + } + val := make(map[string]any) + fields := map[string]any{ + "nickname": user.Nickname, + "face_url": user.FaceURL, + "ex": user.Ex, + "app_manager_level": user.AppMangerLevel, + "global_recv_msg_opt": user.GlobalRecvMsgOpt, + } + for key, value := range fields { + if v, ok := value.(string); ok && v != "" { + val[key] = v + } else if v, ok := value.(int32); ok && v != 0 { + val[key] = v + } + } + return val } diff --git a/pkg/common/convert/user_test.go b/pkg/common/convert/user_test.go new file mode 100644 index 000000000..e58fa16c1 --- /dev/null +++ b/pkg/common/convert/user_test.go @@ -0,0 +1,86 @@ +// Copyright © 2023 OpenIM. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package convert + +import ( + "reflect" + "testing" + + "github.com/OpenIMSDK/protocol/sdkws" + relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" +) + +func TestUsersDB2Pb(t *testing.T) { + type args struct { + users []*relationtb.UserModel + } + tests := []struct { + name string + args args + wantResult []*sdkws.UserInfo + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if gotResult := UsersDB2Pb(tt.args.users); !reflect.DeepEqual(gotResult, tt.wantResult) { + t.Errorf("UsersDB2Pb() = %v, want %v", gotResult, tt.wantResult) + } + }) + } +} + +func TestUserPb2DB(t *testing.T) { + type args struct { + user *sdkws.UserInfo + } + tests := []struct { + name string + args args + want *relationtb.UserModel + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := UserPb2DB(tt.args.user); !reflect.DeepEqual(got, tt.want) { + t.Errorf("UserPb2DB() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestUserPb2DBMap(t *testing.T) { + user := &sdkws.UserInfo{ + Nickname: "TestUser", + FaceURL: "http://openim.io/logo.jpg", + Ex: "Extra Data", + AppMangerLevel: 1, + GlobalRecvMsgOpt: 2, + } + + expected := map[string]any{ + "nickname": "TestUser", + "face_url": "http://openim.io/logo.jpg", + "ex": "Extra Data", + "app_manager_level": int32(1), + "global_recv_msg_opt": int32(2), + } + + result := UserPb2DBMap(user) + if !reflect.DeepEqual(result, expected) { + t.Errorf("UserPb2DBMap returned unexpected map. Got %v, want %v", result, expected) + } +} diff --git a/pkg/common/db/cache/conversation.go b/pkg/common/db/cache/conversation.go index 9c0bcfae4..a7018bc18 100644 --- a/pkg/common/db/cache/conversation.go +++ b/pkg/common/db/cache/conversation.go @@ -26,7 +26,6 @@ import ( "github.com/OpenIMSDK/tools/utils" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/relation" relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" ) @@ -67,10 +66,10 @@ type ConversationCache interface { GetUserRecvMsgOpt(ctx context.Context, ownerUserID, conversationID string) (opt int, err error) DelUserRecvMsgOpt(ownerUserID, conversationID string) ConversationCache // get one super group recv msg but do not notification userID list - GetSuperGroupRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) (userIDs []string, err error) + //GetSuperGroupRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) (userIDs []string, err error) DelSuperGroupRecvMsgNotNotifyUserIDs(groupID string) ConversationCache // get one super group recv msg but do not notification userID list hash - GetSuperGroupRecvMsgNotNotifyUserIDsHash(ctx context.Context, groupID string) (hash uint64, err error) + //GetSuperGroupRecvMsgNotNotifyUserIDsHash(ctx context.Context, groupID string) (hash uint64, err error) DelSuperGroupRecvMsgNotNotifyUserIDsHash(groupID string) ConversationCache //GetUserAllHasReadSeqs(ctx context.Context, ownerUserID string) (map[string]int64, error) @@ -101,20 +100,20 @@ type ConversationRedisCache struct { expireTime time.Duration } -func NewNewConversationRedis( - rdb redis.UniversalClient, - conversationDB *relation.ConversationGorm, - options rockscache.Options, -) ConversationCache { - rcClient := rockscache.NewClient(rdb, options) - - return &ConversationRedisCache{ - rcClient: rcClient, - metaCache: NewMetaCacheRedis(rcClient), - conversationDB: conversationDB, - expireTime: conversationExpireTime, - } -} +//func NewNewConversationRedis( +// rdb redis.UniversalClient, +// conversationDB *relation.ConversationGorm, +// options rockscache.Options, +//) ConversationCache { +// rcClient := rockscache.NewClient(rdb, options) +// +// return &ConversationRedisCache{ +// rcClient: rcClient, +// metaCache: NewMetaCacheRedis(rcClient), +// conversationDB: conversationDB, +// expireTime: conversationExpireTime, +// } +//} func (c *ConversationRedisCache) NewCache() ConversationCache { return &ConversationRedisCache{ @@ -282,11 +281,11 @@ func (c *ConversationRedisCache) GetUserRecvMsgOpt(ctx context.Context, ownerUse }) } -func (c *ConversationRedisCache) GetSuperGroupRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) (userIDs []string, err error) { - return getCache(ctx, c.rcClient, c.getSuperGroupRecvNotNotifyUserIDsKey(groupID), c.expireTime, func(ctx context.Context) (userIDs []string, err error) { - return c.conversationDB.FindSuperGroupRecvMsgNotNotifyUserIDs(ctx, groupID) - }) -} +//func (c *ConversationRedisCache) GetSuperGroupRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) (userIDs []string, err error) { +// return getCache(ctx, c.rcClient, c.getSuperGroupRecvNotNotifyUserIDsKey(groupID), c.expireTime, func(ctx context.Context) (userIDs []string, err error) { +// return c.conversationDB.FindSuperGroupRecvMsgNotNotifyUserIDs(ctx, groupID) +// }) +//} func (c *ConversationRedisCache) DelUsersConversation(conversationID string, ownerUserIDs ...string) ConversationCache { keys := make([]string, 0, len(ownerUserIDs)) @@ -313,19 +312,19 @@ func (c *ConversationRedisCache) DelSuperGroupRecvMsgNotNotifyUserIDs(groupID st return cache } -func (c *ConversationRedisCache) GetSuperGroupRecvMsgNotNotifyUserIDsHash(ctx context.Context, groupID string) (hash uint64, err error) { - return getCache(ctx, c.rcClient, c.getSuperGroupRecvNotNotifyUserIDsHashKey(groupID), c.expireTime, func(ctx context.Context) (hash uint64, err error) { - userIDs, err := c.GetSuperGroupRecvMsgNotNotifyUserIDs(ctx, groupID) - if err != nil { - return 0, err - } - utils.Sort(userIDs, true) - bi := big.NewInt(0) - bi.SetString(utils.Md5(strings.Join(userIDs, ";"))[0:8], 16) - return bi.Uint64(), nil - }, - ) -} +//func (c *ConversationRedisCache) GetSuperGroupRecvMsgNotNotifyUserIDsHash(ctx context.Context, groupID string) (hash uint64, err error) { +// return getCache(ctx, c.rcClient, c.getSuperGroupRecvNotNotifyUserIDsHashKey(groupID), c.expireTime, func(ctx context.Context) (hash uint64, err error) { +// userIDs, err := c.GetSuperGroupRecvMsgNotNotifyUserIDs(ctx, groupID) +// if err != nil { +// return 0, err +// } +// utils.Sort(userIDs, true) +// bi := big.NewInt(0) +// bi.SetString(utils.Md5(strings.Join(userIDs, ";"))[0:8], 16) +// return bi.Uint64(), nil +// }, +// ) +//} func (c *ConversationRedisCache) DelSuperGroupRecvMsgNotNotifyUserIDsHash(groupID string) ConversationCache { cache := c.NewCache() diff --git a/pkg/common/db/cache/friend.go b/pkg/common/db/cache/friend.go index 64a358984..1708f7664 100644 --- a/pkg/common/db/cache/friend.go +++ b/pkg/common/db/cache/friend.go @@ -33,19 +33,20 @@ const ( friendKey = "FRIEND_INFO:" ) -// args fn will exec when no data in msgCache. +// FriendCache is an interface for caching friend-related data. type FriendCache interface { metaCache NewCache() FriendCache GetFriendIDs(ctx context.Context, ownerUserID string) (friendIDs []string, err error) - // call when friendID List changed + // Called when friendID list changed DelFriendIDs(ownerUserID ...string) FriendCache - // get single friendInfo from msgCache + // Get single friendInfo from the cache GetFriend(ctx context.Context, ownerUserID, friendUserID string) (friend *relationtb.FriendModel, err error) - // del friend when friend info changed + // Delete friend when friend info changed DelFriend(ownerUserID, friendUserID string) FriendCache } +// FriendCacheRedis is an implementation of the FriendCache interface using Redis. type FriendCacheRedis struct { metaCache friendDB relationtb.FriendModelInterface @@ -53,6 +54,7 @@ type FriendCacheRedis struct { rcClient *rockscache.Client } +// NewFriendCacheRedis creates a new instance of FriendCacheRedis. func NewFriendCacheRedis(rdb redis.UniversalClient, friendDB relationtb.FriendModelInterface, options rockscache.Options) FriendCache { rcClient := rockscache.NewClient(rdb, options) @@ -64,6 +66,7 @@ func NewFriendCacheRedis(rdb redis.UniversalClient, friendDB relationtb.FriendMo } } +// NewCache creates a new instance of FriendCacheRedis with the same configuration. func (f *FriendCacheRedis) NewCache() FriendCache { return &FriendCacheRedis{ rcClient: f.rcClient, @@ -73,24 +76,29 @@ func (f *FriendCacheRedis) NewCache() FriendCache { } } +// getFriendIDsKey returns the key for storing friend IDs in the cache. func (f *FriendCacheRedis) getFriendIDsKey(ownerUserID string) string { return friendIDsKey + ownerUserID } +// getTwoWayFriendsIDsKey returns the key for storing two-way friend IDs in the cache. func (f *FriendCacheRedis) getTwoWayFriendsIDsKey(ownerUserID string) string { return TwoWayFriendsIDsKey + ownerUserID } +// getFriendKey returns the key for storing friend info in the cache. func (f *FriendCacheRedis) getFriendKey(ownerUserID, friendUserID string) string { return friendKey + ownerUserID + "-" + friendUserID } +// GetFriendIDs retrieves friend IDs from the cache or the database if not found. func (f *FriendCacheRedis) GetFriendIDs(ctx context.Context, ownerUserID string) (friendIDs []string, err error) { return getCache(ctx, f.rcClient, f.getFriendIDsKey(ownerUserID), f.expireTime, func(ctx context.Context) ([]string, error) { return f.friendDB.FindFriendUserIDs(ctx, ownerUserID) }) } +// DelFriendIDs deletes friend IDs from the cache. func (f *FriendCacheRedis) DelFriendIDs(ownerUserIDs ...string) FriendCache { newGroupCache := f.NewCache() keys := make([]string, 0, len(ownerUserIDs)) @@ -102,7 +110,7 @@ func (f *FriendCacheRedis) DelFriendIDs(ownerUserIDs ...string) FriendCache { return newGroupCache } -// todo. +// GetTwoWayFriendIDs retrieves two-way friend IDs from the cache. func (f *FriendCacheRedis) GetTwoWayFriendIDs(ctx context.Context, ownerUserID string) (twoWayFriendIDs []string, err error) { friendIDs, err := f.GetFriendIDs(ctx, ownerUserID) if err != nil { @@ -121,6 +129,7 @@ func (f *FriendCacheRedis) GetTwoWayFriendIDs(ctx context.Context, ownerUserID s return twoWayFriendIDs, nil } +// DelTwoWayFriendIDs deletes two-way friend IDs from the cache. func (f *FriendCacheRedis) DelTwoWayFriendIDs(ctx context.Context, ownerUserID string) FriendCache { newFriendCache := f.NewCache() newFriendCache.AddKeys(f.getTwoWayFriendsIDsKey(ownerUserID)) @@ -128,14 +137,15 @@ func (f *FriendCacheRedis) DelTwoWayFriendIDs(ctx context.Context, ownerUserID s return newFriendCache } -func (f *FriendCacheRedis) GetFriend(ctx context.Context, ownerUserID, - friendUserID string) (friend *relationtb.FriendModel, err error) { +// GetFriend retrieves friend info from the cache or the database if not found. +func (f *FriendCacheRedis) GetFriend(ctx context.Context, ownerUserID, friendUserID string) (friend *relationtb.FriendModel, err error) { return getCache(ctx, f.rcClient, f.getFriendKey(ownerUserID, friendUserID), f.expireTime, func(ctx context.Context) (*relationtb.FriendModel, error) { return f.friendDB.Take(ctx, ownerUserID, friendUserID) }) } +// DelFriend deletes friend info from the cache. func (f *FriendCacheRedis) DelFriend(ownerUserID, friendUserID string) FriendCache { newFriendCache := f.NewCache() newFriendCache.AddKeys(f.getFriendKey(ownerUserID, friendUserID)) diff --git a/pkg/common/db/cache/group.go b/pkg/common/db/cache/group.go index 6a4b57813..bc2510d2f 100644 --- a/pkg/common/db/cache/group.go +++ b/pkg/common/db/cache/group.go @@ -16,6 +16,10 @@ package cache import ( "context" + "fmt" + "github.com/OpenIMSDK/protocol/constant" + "github.com/OpenIMSDK/tools/errs" + "strconv" "time" "github.com/OpenIMSDK/tools/log" @@ -26,21 +30,24 @@ import ( "github.com/OpenIMSDK/tools/utils" relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" - unrelationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/unrelation" ) const ( - groupExpireTime = time.Second * 60 * 60 * 12 - groupInfoKey = "GROUP_INFO:" - groupMemberIDsKey = "GROUP_MEMBER_IDS:" - groupMembersHashKey = "GROUP_MEMBERS_HASH2:" - groupMemberInfoKey = "GROUP_MEMBER_INFO:" - joinedSuperGroupsKey = "JOIN_SUPER_GROUPS:" - SuperGroupMemberIDsKey = "SUPER_GROUP_MEMBER_IDS:" - joinedGroupsKey = "JOIN_GROUPS_KEY:" - groupMemberNumKey = "GROUP_MEMBER_NUM_CACHE:" + groupExpireTime = time.Second * 60 * 60 * 12 + groupInfoKey = "GROUP_INFO:" + groupMemberIDsKey = "GROUP_MEMBER_IDS:" + groupMembersHashKey = "GROUP_MEMBERS_HASH2:" + groupMemberInfoKey = "GROUP_MEMBER_INFO:" + //groupOwnerInfoKey = "GROUP_OWNER_INFO:" + joinedGroupsKey = "JOIN_GROUPS_KEY:" + groupMemberNumKey = "GROUP_MEMBER_NUM_CACHE:" + groupRoleLevelMemberIDsKey = "GROUP_ROLE_LEVEL_MEMBER_IDS:" ) +type GroupHash interface { + GetGroupHash(ctx context.Context, groupID string) (uint64, error) +} + type GroupCache interface { metaCache NewCache() GroupCache @@ -48,11 +55,6 @@ type GroupCache interface { GetGroupInfo(ctx context.Context, groupID string) (group *relationtb.GroupModel, err error) DelGroupsInfo(groupIDs ...string) GroupCache - GetJoinedSuperGroupIDs(ctx context.Context, userID string) (joinedSuperGroupIDs []string, err error) - DelJoinedSuperGroupIDs(userIDs ...string) GroupCache - GetSuperGroupMemberIDs(ctx context.Context, groupIDs ...string) (models []*unrelationtb.SuperGroupModel, err error) - DelSuperGroupMemberIDs(groupIDs ...string) GroupCache - GetGroupMembersHash(ctx context.Context, groupID string) (hashCode uint64, err error) GetGroupMemberHashMap(ctx context.Context, groupIDs []string) (map[string]*relationtb.GroupSimpleUserID, error) DelGroupMembersHash(groupID string) GroupCache @@ -69,9 +71,15 @@ type GroupCache interface { GetGroupMembersInfo(ctx context.Context, groupID string, userID []string) (groupMembers []*relationtb.GroupMemberModel, err error) GetAllGroupMembersInfo(ctx context.Context, groupID string) (groupMembers []*relationtb.GroupMemberModel, err error) GetGroupMembersPage(ctx context.Context, groupID string, userID []string, showNumber, pageNumber int32) (total uint32, groupMembers []*relationtb.GroupMemberModel, err error) + FindGroupMemberUser(ctx context.Context, groupIDs []string, userID string) ([]*relationtb.GroupMemberModel, error) + GetGroupOwner(ctx context.Context, groupID string) (*relationtb.GroupMemberModel, error) + GetGroupsOwner(ctx context.Context, groupIDs []string) ([]*relationtb.GroupMemberModel, error) + DelGroupRoleLevel(groupID string, roleLevel []int32) GroupCache + DelGroupAllRoleLevel(groupID string) GroupCache DelGroupMembersInfo(groupID string, userID ...string) GroupCache - + GetGroupRoleLevelMemberInfo(ctx context.Context, groupID string, roleLevel int32) ([]*relationtb.GroupMemberModel, error) + GetGroupRolesLevelMemberInfo(ctx context.Context, groupID string, roleLevels []int32) ([]*relationtb.GroupMemberModel, error) GetGroupMemberNum(ctx context.Context, groupID string) (memberNum int64, err error) DelGroupsMemberNum(groupID ...string) GroupCache } @@ -81,10 +89,9 @@ type GroupCacheRedis struct { groupDB relationtb.GroupModelInterface groupMemberDB relationtb.GroupMemberModelInterface groupRequestDB relationtb.GroupRequestModelInterface - mongoDB unrelationtb.SuperGroupModelInterface expireTime time.Duration rcClient *rockscache.Client - hashCode func(ctx context.Context, groupID string) (uint64, error) + groupHash GroupHash } func NewGroupCacheRedis( @@ -92,8 +99,7 @@ func NewGroupCacheRedis( groupDB relationtb.GroupModelInterface, groupMemberDB relationtb.GroupMemberModelInterface, groupRequestDB relationtb.GroupRequestModelInterface, - mongoClient unrelationtb.SuperGroupModelInterface, - hashCode func(ctx context.Context, groupID string) (uint64, error), + hashCode GroupHash, opts rockscache.Options, ) GroupCache { rcClient := rockscache.NewClient(rdb, opts) @@ -101,8 +107,7 @@ func NewGroupCacheRedis( return &GroupCacheRedis{ rcClient: rcClient, expireTime: groupExpireTime, groupDB: groupDB, groupMemberDB: groupMemberDB, groupRequestDB: groupRequestDB, - mongoDB: mongoClient, - hashCode: hashCode, + groupHash: hashCode, metaCache: NewMetaCacheRedis(rcClient), } } @@ -114,7 +119,6 @@ func (g *GroupCacheRedis) NewCache() GroupCache { groupDB: g.groupDB, groupMemberDB: g.groupMemberDB, groupRequestDB: g.groupRequestDB, - mongoDB: g.mongoDB, metaCache: NewMetaCacheRedis(g.rcClient, g.metaCache.GetPreDelKeys()...), } } @@ -123,18 +127,10 @@ func (g *GroupCacheRedis) getGroupInfoKey(groupID string) string { return groupInfoKey + groupID } -func (g *GroupCacheRedis) getJoinedSuperGroupsIDKey(userID string) string { - return joinedSuperGroupsKey + userID -} - func (g *GroupCacheRedis) getJoinedGroupsKey(userID string) string { return joinedGroupsKey + userID } -func (g *GroupCacheRedis) getSuperGroupMemberIDsKey(groupID string) string { - return SuperGroupMemberIDsKey + groupID -} - func (g *GroupCacheRedis) getGroupMembersHashKey(groupID string) string { return groupMembersHashKey + groupID } @@ -151,6 +147,10 @@ func (g *GroupCacheRedis) getGroupMemberNumKey(groupID string) string { return groupMemberNumKey + groupID } +func (g *GroupCacheRedis) getGroupRoleLevelMemberIDsKey(groupID string, roleLevel int32) string { + return groupRoleLevelMemberIDsKey + groupID + "-" + strconv.Itoa(int(roleLevel)) +} + func (g *GroupCacheRedis) GetGroupIndex(group *relationtb.GroupModel, keys []string) (int, error) { key := g.getGroupInfoKey(group.GroupID) for i, _key := range keys { @@ -173,15 +173,7 @@ func (g *GroupCacheRedis) GetGroupMemberIndex(groupMember *relationtb.GroupMembe return 0, errIndex } -// / groupInfo. func (g *GroupCacheRedis) GetGroupsInfo(ctx context.Context, groupIDs []string) (groups []*relationtb.GroupModel, err error) { - //var keys []string - //for _, group := range groupIDs { - // keys = append(keys, g.getGroupInfoKey(group)) - //} - //return batchGetCache(ctx, g.rcClient, keys, g.expireTime, g.GetGroupIndex, func(ctx context.Context) ([]*relationtb.GroupModel, error) { - // return g.groupDB.Find(ctx, groupIDs) - //}) return batchGetCache2(ctx, g.rcClient, g.expireTime, groupIDs, func(groupID string) string { return g.getGroupInfoKey(groupID) }, func(ctx context.Context, groupID string) (*relationtb.GroupModel, error) { @@ -206,123 +198,44 @@ func (g *GroupCacheRedis) DelGroupsInfo(groupIDs ...string) GroupCache { return newGroupCache } -func (g *GroupCacheRedis) GetJoinedSuperGroupIDs(ctx context.Context, userID string) (joinedSuperGroupIDs []string, err error) { - return getCache(ctx, g.rcClient, g.getJoinedSuperGroupsIDKey(userID), g.expireTime, func(ctx context.Context) ([]string, error) { - userGroup, err := g.mongoDB.GetSuperGroupByUserID(ctx, userID) - if err != nil { - return nil, err - } - return userGroup.GroupIDs, nil - }, - ) -} - -func (g *GroupCacheRedis) GetSuperGroupMemberIDs(ctx context.Context, groupIDs ...string) (models []*unrelationtb.SuperGroupModel, err error) { - //var keys []string - //for _, group := range groupIDs { - // keys = append(keys, g.getSuperGroupMemberIDsKey(group)) - //} - //return batchGetCache(ctx, g.rcClient, keys, g.expireTime, func(model *unrelationtb.SuperGroupModel, keys []string) (int, error) { - // for i, key := range keys { - // if g.getSuperGroupMemberIDsKey(model.GroupID) == key { - // return i, nil - // } - // } - // return 0, errIndex - //}, - // func(ctx context.Context) ([]*unrelationtb.SuperGroupModel, error) { - // return g.mongoDB.FindSuperGroup(ctx, groupIDs) - // }) - return batchGetCache2(ctx, g.rcClient, g.expireTime, groupIDs, func(groupID string) string { - return g.getSuperGroupMemberIDsKey(groupID) - }, func(ctx context.Context, groupID string) (*unrelationtb.SuperGroupModel, error) { - return g.mongoDB.TakeSuperGroup(ctx, groupID) - }) -} - -// userJoinSuperGroup. -func (g *GroupCacheRedis) DelJoinedSuperGroupIDs(userIDs ...string) GroupCache { +func (g *GroupCacheRedis) DelGroupsOwner(groupIDs ...string) GroupCache { newGroupCache := g.NewCache() - keys := make([]string, 0, len(userIDs)) - for _, userID := range userIDs { - keys = append(keys, g.getJoinedSuperGroupsIDKey(userID)) + keys := make([]string, 0, len(groupIDs)) + for _, groupID := range groupIDs { + keys = append(keys, g.getGroupRoleLevelMemberIDsKey(groupID, constant.GroupOwner)) } newGroupCache.AddKeys(keys...) return newGroupCache } -func (g *GroupCacheRedis) DelSuperGroupMemberIDs(groupIDs ...string) GroupCache { +func (g *GroupCacheRedis) DelGroupRoleLevel(groupID string, roleLevels []int32) GroupCache { newGroupCache := g.NewCache() - keys := make([]string, 0, len(groupIDs)) - for _, groupID := range groupIDs { - keys = append(keys, g.getSuperGroupMemberIDsKey(groupID)) + keys := make([]string, 0, len(roleLevels)) + for _, roleLevel := range roleLevels { + keys = append(keys, g.getGroupRoleLevelMemberIDsKey(groupID, roleLevel)) } newGroupCache.AddKeys(keys...) - return newGroupCache } -// groupMembersHash. +func (g *GroupCacheRedis) DelGroupAllRoleLevel(groupID string) GroupCache { + return g.DelGroupRoleLevel(groupID, []int32{constant.GroupOwner, constant.GroupAdmin, constant.GroupOrdinaryUsers}) +} + func (g *GroupCacheRedis) GetGroupMembersHash(ctx context.Context, groupID string) (hashCode uint64, err error) { + if g.groupHash == nil { + return 0, errs.ErrInternalServer.Wrap("group hash is nil") + } return getCache(ctx, g.rcClient, g.getGroupMembersHashKey(groupID), g.expireTime, func(ctx context.Context) (uint64, error) { - return g.hashCode(ctx, groupID) + return g.groupHash.GetGroupHash(ctx, groupID) }) - - //return getCache(ctx, g.rcClient, g.getGroupMembersHashKey(groupID), g.expireTime, - // func(ctx context.Context) (uint64, error) { - // userIDs, err := g.GetGroupMemberIDs(ctx, groupID) - // if err != nil { - // return 0, err - // } - // log.ZInfo(ctx, "GetGroupMembersHash", "groupID", groupID, "userIDs", userIDs) - // var members []*relationtb.GroupMemberModel - // if len(userIDs) > 0 { - // members, err = g.GetGroupMembersInfo(ctx, groupID, userIDs) - // if err != nil { - // return 0, err - // } - // utils.Sort(userIDs, true) - // } - // memberMap := make(map[string]*relationtb.GroupMemberModel) - // for i, member := range members { - // memberMap[member.UserID] = members[i] - // } - // data := make([]string, 0, len(members)*11) - // for _, userID := range userIDs { - // member, ok := memberMap[userID] - // if !ok { - // continue - // } - // data = append(data, - // member.GroupID, - // member.UserID, - // member.Nickname, - // member.FaceURL, - // strconv.Itoa(int(member.RoleLevel)), - // strconv.FormatInt(member.JoinTime.UnixMilli(), 10), - // strconv.Itoa(int(member.JoinSource)), - // member.InviterUserID, - // member.OperatorUserID, - // strconv.FormatInt(member.MuteEndTime.UnixMilli(), 10), - // member.Ex, - // ) - // } - // log.ZInfo(ctx, "hash data info", "userIDs.len", len(userIDs), "hash.data.len", len(data)) - // log.ZInfo(ctx, "json hash data", "groupID", groupID, "data", data) - // val, err := json.Marshal(data) - // if err != nil { - // return 0, err - // } - // sum := md5.Sum(val) - // code := binary.BigEndian.Uint64(sum[:]) - // log.ZInfo(ctx, "GetGroupMembersHash", "groupID", groupID, "hashCode", code, "num", len(members)) - // return code, nil - // }, - //) } func (g *GroupCacheRedis) GetGroupMemberHashMap(ctx context.Context, groupIDs []string) (map[string]*relationtb.GroupSimpleUserID, error) { + if g.groupHash == nil { + return nil, errs.ErrInternalServer.Wrap("group hash is nil") + } res := make(map[string]*relationtb.GroupSimpleUserID) for _, groupID := range groupIDs { hash, err := g.GetGroupMembersHash(ctx, groupID) @@ -347,7 +260,6 @@ func (g *GroupCacheRedis) DelGroupMembersHash(groupID string) GroupCache { return cache } -// groupMemberIDs. func (g *GroupCacheRedis) GetGroupMemberIDs(ctx context.Context, groupID string) (groupMemberIDs []string, err error) { return getCache(ctx, g.rcClient, g.getGroupMemberIDsKey(groupID), g.expireTime, func(ctx context.Context) ([]string, error) { return g.groupMemberDB.FindMemberUserID(ctx, groupID) @@ -398,13 +310,6 @@ func (g *GroupCacheRedis) GetGroupMemberInfo(ctx context.Context, groupID, userI } func (g *GroupCacheRedis) GetGroupMembersInfo(ctx context.Context, groupID string, userIDs []string) ([]*relationtb.GroupMemberModel, error) { - //var keys []string - //for _, userID := range userIDs { - // keys = append(keys, g.getGroupMemberInfoKey(groupID, userID)) - //} - //return batchGetCache(ctx, g.rcClient, keys, g.expireTime, g.GetGroupMemberIndex, func(ctx context.Context) ([]*relationtb.GroupMemberModel, error) { - // return g.groupMemberDB.Find(ctx, []string{groupID}, userIDs, nil) - //}) return batchGetCache2(ctx, g.rcClient, g.expireTime, userIDs, func(userID string) string { return g.getGroupMemberInfoKey(groupID, userID) }, func(ctx context.Context, userID string) (*relationtb.GroupMemberModel, error) { @@ -412,12 +317,7 @@ func (g *GroupCacheRedis) GetGroupMembersInfo(ctx context.Context, groupID strin }) } -func (g *GroupCacheRedis) GetGroupMembersPage( - ctx context.Context, - groupID string, - userIDs []string, - showNumber, pageNumber int32, -) (total uint32, groupMembers []*relationtb.GroupMemberModel, err error) { +func (g *GroupCacheRedis) GetGroupMembersPage(ctx context.Context, groupID string, userIDs []string, showNumber, pageNumber int32) (total uint32, groupMembers []*relationtb.GroupMemberModel, err error) { groupMemberIDs, err := g.GetGroupMemberIDs(ctx, groupID) if err != nil { return 0, nil, err @@ -446,13 +346,6 @@ func (g *GroupCacheRedis) GetAllGroupMemberInfo(ctx context.Context, groupID str if err != nil { return nil, err } - //var keys []string - //for _, groupMemberID := range groupMemberIDs { - // keys = append(keys, g.getGroupMemberInfoKey(groupID, groupMemberID)) - //} - //return batchGetCache(ctx, g.rcClient, keys, g.expireTime, g.GetGroupMemberIndex, func(ctx context.Context) ([]*relationtb.GroupMemberModel, error) { - // return g.groupMemberDB.Find(ctx, []string{groupID}, groupMemberIDs, nil) - //}) return g.GetGroupMembersInfo(ctx, groupID, groupMemberIDs) } @@ -483,3 +376,68 @@ func (g *GroupCacheRedis) DelGroupsMemberNum(groupID ...string) GroupCache { return cache } + +func (g *GroupCacheRedis) GetGroupOwner(ctx context.Context, groupID string) (*relationtb.GroupMemberModel, error) { + members, err := g.GetGroupRoleLevelMemberInfo(ctx, groupID, constant.GroupOwner) + if err != nil { + return nil, err + } + if len(members) == 0 { + return nil, errs.ErrRecordNotFound.Wrap(fmt.Sprintf("group %s owner not found", groupID)) + } + return members[0], nil +} + +func (g *GroupCacheRedis) GetGroupsOwner(ctx context.Context, groupIDs []string) ([]*relationtb.GroupMemberModel, error) { + members := make([]*relationtb.GroupMemberModel, 0, len(groupIDs)) + for _, groupID := range groupIDs { + items, err := g.GetGroupRoleLevelMemberInfo(ctx, groupID, constant.GroupOwner) + if err != nil { + return nil, err + } + if len(items) > 0 { + members = append(members, items[0]) + } + } + return members, nil +} + +func (g *GroupCacheRedis) GetGroupRoleLevelMemberIDs(ctx context.Context, groupID string, roleLevel int32) ([]string, error) { + return getCache(ctx, g.rcClient, g.getGroupRoleLevelMemberIDsKey(groupID, roleLevel), g.expireTime, func(ctx context.Context) ([]string, error) { + return g.groupMemberDB.FindRoleLevelUserIDs(ctx, groupID, roleLevel) + }) +} + +func (g *GroupCacheRedis) GetGroupRoleLevelMemberInfo(ctx context.Context, groupID string, roleLevel int32) ([]*relationtb.GroupMemberModel, error) { + userIDs, err := g.GetGroupRoleLevelMemberIDs(ctx, groupID, roleLevel) + if err != nil { + return nil, err + } + return g.GetGroupMembersInfo(ctx, groupID, userIDs) +} + +func (g *GroupCacheRedis) GetGroupRolesLevelMemberInfo(ctx context.Context, groupID string, roleLevels []int32) ([]*relationtb.GroupMemberModel, error) { + var userIDs []string + for _, roleLevel := range roleLevels { + ids, err := g.GetGroupRoleLevelMemberIDs(ctx, groupID, roleLevel) + if err != nil { + return nil, err + } + userIDs = append(userIDs, ids...) + } + return g.GetGroupMembersInfo(ctx, groupID, userIDs) +} + +func (g *GroupCacheRedis) FindGroupMemberUser(ctx context.Context, groupIDs []string, userID string) (_ []*relationtb.GroupMemberModel, err error) { + if len(groupIDs) == 0 { + groupIDs, err = g.GetJoinedGroupIDs(ctx, userID) + if err != nil { + return nil, err + } + } + return batchGetCache2(ctx, g.rcClient, g.expireTime, groupIDs, func(groupID string) string { + return g.getGroupMemberInfoKey(groupID, userID) + }, func(ctx context.Context, groupID string) (*relationtb.GroupMemberModel, error) { + return g.groupMemberDB.Take(ctx, groupID, userID) + }) +} diff --git a/pkg/common/db/cache/meta_cache.go b/pkg/common/db/cache/meta_cache.go index ccac88d68..4bc2a046a 100644 --- a/pkg/common/db/cache/meta_cache.go +++ b/pkg/common/db/cache/meta_cache.go @@ -38,7 +38,7 @@ const ( var errIndex = errors.New("err index") type metaCache interface { - ExecDel(ctx context.Context) error + ExecDel(ctx context.Context, distinct ...bool) error // delete key rapid DelKey(ctx context.Context, key string) error AddKeys(keys ...string) @@ -57,7 +57,10 @@ type metaCacheRedis struct { retryInterval time.Duration } -func (m *metaCacheRedis) ExecDel(ctx context.Context) error { +func (m *metaCacheRedis) ExecDel(ctx context.Context, distinct ...bool) error { + if len(distinct) > 0 && distinct[0] { + m.keys = utils.Distinct(m.keys) + } if len(m.keys) > 0 { log.ZDebug(ctx, "delete cache", "keys", m.keys) for _, key := range m.keys { diff --git a/pkg/common/db/cache/msg.go b/pkg/common/db/cache/msg.go index 6d0ee8c67..5cd3cb22c 100644 --- a/pkg/common/db/cache/msg.go +++ b/pkg/common/db/cache/msg.go @@ -287,7 +287,7 @@ func (c *msgCache) GetTokensWithoutError(ctx context.Context, userID string, pla func (c *msgCache) SetTokenMapByUidPid(ctx context.Context, userID string, platform int, m map[string]int) error { key := uidPidToken + userID + ":" + constant.PlatformIDToName(platform) - mm := make(map[string]interface{}) + mm := make(map[string]any) for k, v := range m { mm[k] = v } diff --git a/pkg/common/db/cache/s3.go b/pkg/common/db/cache/s3.go index 3520ba2ec..ba40ceacc 100644 --- a/pkg/common/db/cache/s3.go +++ b/pkg/common/db/cache/s3.go @@ -14,8 +14,8 @@ import ( type ObjectCache interface { metaCache - GetName(ctx context.Context, name string) (*relationtb.ObjectModel, error) - DelObjectName(names ...string) ObjectCache + GetName(ctx context.Context, engine string, name string) (*relationtb.ObjectModel, error) + DelObjectName(engine string, names ...string) ObjectCache } func NewObjectCacheRedis(rdb redis.UniversalClient, objDB relationtb.ObjectInfoModelInterface) ObjectCache { @@ -44,23 +44,23 @@ func (g *objectCacheRedis) NewCache() ObjectCache { } } -func (g *objectCacheRedis) DelObjectName(names ...string) ObjectCache { +func (g *objectCacheRedis) DelObjectName(engine string, names ...string) ObjectCache { objectCache := g.NewCache() keys := make([]string, 0, len(names)) for _, name := range names { - keys = append(keys, g.getObjectKey(name)) + keys = append(keys, g.getObjectKey(name, engine)) } objectCache.AddKeys(keys...) return objectCache } -func (g *objectCacheRedis) getObjectKey(name string) string { - return "OBJECT:" + name +func (g *objectCacheRedis) getObjectKey(engine string, name string) string { + return "OBJECT:" + engine + ":" + name } -func (g *objectCacheRedis) GetName(ctx context.Context, name string) (*relationtb.ObjectModel, error) { - return getCache(ctx, g.rcClient, g.getObjectKey(name), g.expireTime, func(ctx context.Context) (*relationtb.ObjectModel, error) { - return g.objDB.Take(ctx, name) +func (g *objectCacheRedis) GetName(ctx context.Context, engine string, name string) (*relationtb.ObjectModel, error) { + return getCache(ctx, g.rcClient, g.getObjectKey(name, engine), g.expireTime, func(ctx context.Context) (*relationtb.ObjectModel, error) { + return g.objDB.Take(ctx, engine, name) }) } diff --git a/pkg/common/db/cache/user.go b/pkg/common/db/cache/user.go index d1164f2c0..e0f22b2f7 100644 --- a/pkg/common/db/cache/user.go +++ b/pkg/common/db/cache/user.go @@ -18,6 +18,7 @@ import ( "context" "encoding/json" "errors" + relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" "hash/crc32" "strconv" "time" @@ -31,8 +32,6 @@ import ( "github.com/dtm-labs/rockscache" "github.com/redis/go-redis/v9" - - relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" ) const ( @@ -59,7 +58,8 @@ type UserCache interface { type UserCacheRedis struct { metaCache - rdb redis.UniversalClient + rdb redis.UniversalClient + //userDB relationtb.UserModelInterface userDB relationtb.UserModelInterface expireTime time.Duration rcClient *rockscache.Client @@ -100,39 +100,13 @@ func (u *UserCacheRedis) getUserGlobalRecvMsgOptKey(userID string) string { } func (u *UserCacheRedis) GetUserInfo(ctx context.Context, userID string) (userInfo *relationtb.UserModel, err error) { - return getCache( - ctx, - u.rcClient, - u.getUserInfoKey(userID), - u.expireTime, - func(ctx context.Context) (*relationtb.UserModel, error) { - return u.userDB.Take(ctx, userID) - }, + return getCache(ctx, u.rcClient, u.getUserInfoKey(userID), u.expireTime, func(ctx context.Context) (*relationtb.UserModel, error) { + return u.userDB.Take(ctx, userID) + }, ) } func (u *UserCacheRedis) GetUsersInfo(ctx context.Context, userIDs []string) ([]*relationtb.UserModel, error) { - //var keys []string - //for _, userID := range userIDs { - // keys = append(keys, u.getUserInfoKey(userID)) - //} - //return batchGetCache( - // ctx, - // u.rcClient, - // keys, - // u.expireTime, - // func(user *relationtb.UserModel, keys []string) (int, error) { - // for i, key := range keys { - // if key == u.getUserInfoKey(user.UserID) { - // return i, nil - // } - // } - // return 0, errIndex - // }, - // func(ctx context.Context) ([]*relationtb.UserModel, error) { - // return u.userDB.Find(ctx, userIDs) - // }, - //) return batchGetCache2(ctx, u.rcClient, u.expireTime, userIDs, func(userID string) string { return u.getUserInfoKey(userID) }, func(ctx context.Context, userID string) (*relationtb.UserModel, error) { @@ -214,8 +188,7 @@ func (u *UserCacheRedis) SetUserStatus(ctx context.Context, userID string, statu UserIDNum := crc32.ChecksumIEEE([]byte(userID)) modKey := strconv.Itoa(int(UserIDNum % statusMod)) key := olineStatusKey + modKey - log.ZDebug(ctx, "SetUserStatus args", "userID", userID, "status", status, - "platformID", platformID, "modKey", modKey, "key", key) + log.ZDebug(ctx, "SetUserStatus args", "userID", userID, "status", status, "platformID", platformID, "modKey", modKey, "key", key) isNewKey, err := u.rdb.Exists(ctx, key).Result() if err != nil { return errs.Wrap(err) diff --git a/pkg/common/db/controller/conversation.go b/pkg/common/db/controller/conversation.go index 0aaa95880..6f7b8acb1 100644 --- a/pkg/common/db/controller/conversation.go +++ b/pkg/common/db/controller/conversation.go @@ -16,6 +16,7 @@ package controller import ( "context" + "github.com/openimsdk/open-im-server/v3/pkg/common/pagination" "time" "github.com/openimsdk/open-im-server/v3/pkg/msgprocessor" @@ -31,7 +32,7 @@ import ( type ConversationDatabase interface { // UpdateUserConversationFiled 更新用户该会话的属性信息 - UpdateUsersConversationFiled(ctx context.Context, userIDs []string, conversationID string, args map[string]interface{}) error + UpdateUsersConversationFiled(ctx context.Context, userIDs []string, conversationID string, args map[string]any) error // CreateConversation 创建一批新的会话 CreateConversation(ctx context.Context, conversations []*relationtb.ConversationModel) error // SyncPeerUserPrivateConversation 同步对端私聊会话内部保证事务操作 @@ -39,26 +40,26 @@ type ConversationDatabase interface { // FindConversations 根据会话ID获取某个用户的多个会话 FindConversations(ctx context.Context, ownerUserID string, conversationIDs []string) ([]*relationtb.ConversationModel, error) // FindRecvMsgNotNotifyUserIDs 获取超级大群开启免打扰的用户ID - FindRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) ([]string, error) + //FindRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) ([]string, error) // GetUserAllConversation 获取一个用户在服务器上所有的会话 GetUserAllConversation(ctx context.Context, ownerUserID string) ([]*relationtb.ConversationModel, error) // SetUserConversations 设置用户多个会话属性,如果会话不存在则创建,否则更新,内部保证原子性 SetUserConversations(ctx context.Context, ownerUserID string, conversations []*relationtb.ConversationModel) error // SetUsersConversationFiledTx 设置多个用户会话关于某个字段的更新操作,如果会话不存在则创建,否则更新,内部保证事务操作 - SetUsersConversationFiledTx(ctx context.Context, userIDs []string, conversation *relationtb.ConversationModel, filedMap map[string]interface{}) error + SetUsersConversationFiledTx(ctx context.Context, userIDs []string, conversation *relationtb.ConversationModel, filedMap map[string]any) error CreateGroupChatConversation(ctx context.Context, groupID string, userIDs []string) error GetConversationIDs(ctx context.Context, userID string) ([]string, error) GetUserConversationIDsHash(ctx context.Context, ownerUserID string) (hash uint64, err error) GetAllConversationIDs(ctx context.Context) ([]string, error) GetAllConversationIDsNumber(ctx context.Context) (int64, error) - PageConversationIDs(ctx context.Context, pageNumber, showNumber int32) (conversationIDs []string, err error) + PageConversationIDs(ctx context.Context, pagination pagination.Pagination) (conversationIDs []string, err error) //GetUserAllHasReadSeqs(ctx context.Context, ownerUserID string) (map[string]int64, error) GetConversationsByConversationID(ctx context.Context, conversationIDs []string) ([]*relationtb.ConversationModel, error) GetConversationIDsNeedDestruct(ctx context.Context) ([]*relationtb.ConversationModel, error) GetConversationNotReceiveMessageUserIDs(ctx context.Context, conversationID string) ([]string, error) } -func NewConversationDatabase(conversation relationtb.ConversationModelInterface, cache cache.ConversationCache, tx tx.Tx) ConversationDatabase { +func NewConversationDatabase(conversation relationtb.ConversationModelInterface, cache cache.ConversationCache, tx tx.CtxTx) ConversationDatabase { return &conversationDatabase{ conversationDB: conversation, cache: cache, @@ -69,22 +70,21 @@ func NewConversationDatabase(conversation relationtb.ConversationModelInterface, type conversationDatabase struct { conversationDB relationtb.ConversationModelInterface cache cache.ConversationCache - tx tx.Tx + tx tx.CtxTx } -func (c *conversationDatabase) SetUsersConversationFiledTx(ctx context.Context, userIDs []string, conversation *relationtb.ConversationModel, filedMap map[string]interface{}) (err error) { - cache := c.cache.NewCache() - if conversation.GroupID != "" { - cache = cache.DelSuperGroupRecvMsgNotNotifyUserIDs(conversation.GroupID).DelSuperGroupRecvMsgNotNotifyUserIDsHash(conversation.GroupID) - } - if err := c.tx.Transaction(func(tx any) error { - conversationTx := c.conversationDB.NewTx(tx) - haveUserIDs, err := conversationTx.FindUserID(ctx, userIDs, []string{conversation.ConversationID}) +func (c *conversationDatabase) SetUsersConversationFiledTx(ctx context.Context, userIDs []string, conversation *relationtb.ConversationModel, filedMap map[string]any) (err error) { + return c.tx.Transaction(ctx, func(ctx context.Context) error { + cache := c.cache.NewCache() + if conversation.GroupID != "" { + cache = cache.DelSuperGroupRecvMsgNotNotifyUserIDs(conversation.GroupID).DelSuperGroupRecvMsgNotNotifyUserIDsHash(conversation.GroupID) + } + haveUserIDs, err := c.conversationDB.FindUserID(ctx, userIDs, []string{conversation.ConversationID}) if err != nil { return err } if len(haveUserIDs) > 0 { - _, err = conversationTx.UpdateByMap(ctx, haveUserIDs, conversation.ConversationID, filedMap) + _, err = c.conversationDB.UpdateByMap(ctx, haveUserIDs, conversation.ConversationID, filedMap) if err != nil { return err } @@ -112,20 +112,17 @@ func (c *conversationDatabase) SetUsersConversationFiledTx(ctx context.Context, conversations = append(conversations, temp) } if len(conversations) > 0 { - err = conversationTx.Create(ctx, conversations) + err = c.conversationDB.Create(ctx, conversations) if err != nil { return err } cache = cache.DelConversationIDs(NotUserIDs...).DelUserConversationIDsHash(NotUserIDs...).DelConversations(conversation.ConversationID, NotUserIDs...) } - return nil - }); err != nil { - return err - } - return cache.ExecDel(ctx) + return cache.ExecDel(ctx) + }) } -func (c *conversationDatabase) UpdateUsersConversationFiled(ctx context.Context, userIDs []string, conversationID string, args map[string]interface{}) error { +func (c *conversationDatabase) UpdateUsersConversationFiled(ctx context.Context, userIDs []string, conversationID string, args map[string]any) error { _, err := c.conversationDB.UpdateByMap(ctx, userIDs, conversationID, args) if err != nil { return err @@ -153,19 +150,18 @@ func (c *conversationDatabase) CreateConversation(ctx context.Context, conversat } func (c *conversationDatabase) SyncPeerUserPrivateConversationTx(ctx context.Context, conversations []*relationtb.ConversationModel) error { - cache := c.cache.NewCache() - if err := c.tx.Transaction(func(tx any) error { - conversationTx := c.conversationDB.NewTx(tx) + return c.tx.Transaction(ctx, func(ctx context.Context) error { + cache := c.cache.NewCache() for _, conversation := range conversations { for _, v := range [][2]string{{conversation.OwnerUserID, conversation.UserID}, {conversation.UserID, conversation.OwnerUserID}} { ownerUserID := v[0] userID := v[1] - haveUserIDs, err := conversationTx.FindUserID(ctx, []string{ownerUserID}, []string{conversation.ConversationID}) + haveUserIDs, err := c.conversationDB.FindUserID(ctx, []string{ownerUserID}, []string{conversation.ConversationID}) if err != nil { return err } if len(haveUserIDs) > 0 { - _, err := conversationTx.UpdateByMap(ctx, []string{ownerUserID}, conversation.ConversationID, map[string]interface{}{"is_private_chat": conversation.IsPrivateChat}) + _, err := c.conversationDB.UpdateByMap(ctx, []string{ownerUserID}, conversation.ConversationID, map[string]any{"is_private_chat": conversation.IsPrivateChat}) if err != nil { return err } @@ -176,18 +172,15 @@ func (c *conversationDatabase) SyncPeerUserPrivateConversationTx(ctx context.Con newConversation.UserID = userID newConversation.ConversationID = conversation.ConversationID newConversation.IsPrivateChat = conversation.IsPrivateChat - if err := conversationTx.Create(ctx, []*relationtb.ConversationModel{&newConversation}); err != nil { + if err := c.conversationDB.Create(ctx, []*relationtb.ConversationModel{&newConversation}); err != nil { return err } cache = cache.DelConversationIDs(ownerUserID).DelUserConversationIDsHash(ownerUserID) } } } - return nil - }); err != nil { - return err - } - return cache.ExecDel(ctx) + return cache.ExecDel(ctx) + }) } func (c *conversationDatabase) FindConversations(ctx context.Context, ownerUserID string, conversationIDs []string) ([]*relationtb.ConversationModel, error) { @@ -203,28 +196,26 @@ func (c *conversationDatabase) GetUserAllConversation(ctx context.Context, owner } func (c *conversationDatabase) SetUserConversations(ctx context.Context, ownerUserID string, conversations []*relationtb.ConversationModel) error { - cache := c.cache.NewCache() - - groupIDs := utils.Distinct(utils.Filter(conversations, func(e *relationtb.ConversationModel) (string, bool) { - return e.GroupID, e.GroupID != "" - })) - for _, groupID := range groupIDs { - cache = cache.DelSuperGroupRecvMsgNotNotifyUserIDs(groupID).DelSuperGroupRecvMsgNotNotifyUserIDsHash(groupID) - } - if err := c.tx.Transaction(func(tx any) error { + return c.tx.Transaction(ctx, func(ctx context.Context) error { + cache := c.cache.NewCache() + groupIDs := utils.Distinct(utils.Filter(conversations, func(e *relationtb.ConversationModel) (string, bool) { + return e.GroupID, e.GroupID != "" + })) + for _, groupID := range groupIDs { + cache = cache.DelSuperGroupRecvMsgNotNotifyUserIDs(groupID).DelSuperGroupRecvMsgNotNotifyUserIDsHash(groupID) + } var conversationIDs []string for _, conversation := range conversations { conversationIDs = append(conversationIDs, conversation.ConversationID) cache = cache.DelConversations(conversation.OwnerUserID, conversation.ConversationID) } - conversationTx := c.conversationDB.NewTx(tx) - existConversations, err := conversationTx.Find(ctx, ownerUserID, conversationIDs) + existConversations, err := c.conversationDB.Find(ctx, ownerUserID, conversationIDs) if err != nil { return err } if len(existConversations) > 0 { for _, conversation := range conversations { - err = conversationTx.Update(ctx, conversation) + err = c.conversationDB.Update(ctx, conversation) if err != nil { return err } @@ -248,21 +239,18 @@ func (c *conversationDatabase) SetUserConversations(ctx context.Context, ownerUs } cache = cache.DelConversationIDs(ownerUserID).DelUserConversationIDsHash(ownerUserID).DelConversationNotReceiveMessageUserIDs(utils.Slice(notExistConversations, func(e *relationtb.ConversationModel) string { return e.ConversationID })...) } - return nil - }); err != nil { - return err - } - return cache.ExecDel(ctx) + return cache.ExecDel(ctx) + }) } -func (c *conversationDatabase) FindRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) ([]string, error) { - return c.cache.GetSuperGroupRecvMsgNotNotifyUserIDs(ctx, groupID) -} +//func (c *conversationDatabase) FindRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) ([]string, error) { +// return c.cache.GetSuperGroupRecvMsgNotNotifyUserIDs(ctx, groupID) +//} func (c *conversationDatabase) CreateGroupChatConversation(ctx context.Context, groupID string, userIDs []string) error { - cache := c.cache.NewCache() - conversationID := msgprocessor.GetConversationIDBySessionType(constant.SuperGroupChatType, groupID) - if err := c.tx.Transaction(func(tx any) error { + return c.tx.Transaction(ctx, func(ctx context.Context) error { + cache := c.cache.NewCache() + conversationID := msgprocessor.GetConversationIDBySessionType(constant.SuperGroupChatType, groupID) existConversationUserIDs, err := c.conversationDB.FindUserID(ctx, userIDs, []string{conversationID}) if err != nil { return err @@ -281,18 +269,15 @@ func (c *conversationDatabase) CreateGroupChatConversation(ctx context.Context, return err } } - _, err = c.conversationDB.UpdateByMap(ctx, existConversationUserIDs, conversationID, map[string]interface{}{"max_seq": 0}) + _, err = c.conversationDB.UpdateByMap(ctx, existConversationUserIDs, conversationID, map[string]any{"max_seq": 0}) if err != nil { return err } for _, v := range existConversationUserIDs { cache = cache.DelConversations(v, conversationID) } - return nil - }); err != nil { - return err - } - return cache.ExecDel(ctx) + return c.cache.ExecDel(ctx) + }) } func (c *conversationDatabase) GetConversationIDs(ctx context.Context, userID string) ([]string, error) { @@ -311,14 +296,10 @@ func (c *conversationDatabase) GetAllConversationIDsNumber(ctx context.Context) return c.conversationDB.GetAllConversationIDsNumber(ctx) } -func (c *conversationDatabase) PageConversationIDs(ctx context.Context, pageNumber, showNumber int32) ([]string, error) { - return c.conversationDB.PageConversationIDs(ctx, pageNumber, showNumber) +func (c *conversationDatabase) PageConversationIDs(ctx context.Context, pagination pagination.Pagination) ([]string, error) { + return c.conversationDB.PageConversationIDs(ctx, pagination) } -//func (c *conversationDatabase) GetUserAllHasReadSeqs(ctx context.Context, ownerUserID string) (map[string]int64, error) { -// return c.cache.GetUserAllHasReadSeqs(ctx, ownerUserID) -//} - func (c *conversationDatabase) GetConversationsByConversationID(ctx context.Context, conversationIDs []string) ([]*relationtb.ConversationModel, error) { return c.conversationDB.GetConversationsByConversationID(ctx, conversationIDs) } diff --git a/pkg/common/db/controller/friend.go b/pkg/common/db/controller/friend.go index 7816ef935..5d1c2617f 100644 --- a/pkg/common/db/controller/friend.go +++ b/pkg/common/db/controller/friend.go @@ -127,7 +127,7 @@ func (f *friendDatabase) AddFriendRequest( } // 无错误 则更新 if err == nil { - m := make(map[string]interface{}, 1) + m := make(map[string]any, 1) m["handle_result"] = 0 m["handle_msg"] = "" m["req_msg"] = reqMsg diff --git a/pkg/common/db/controller/group.go b/pkg/common/db/controller/group.go index 194f3e8b2..688f20f5b 100644 --- a/pkg/common/db/controller/group.go +++ b/pkg/common/db/controller/group.go @@ -16,23 +16,17 @@ package controller import ( "context" - "fmt" - "time" - "github.com/dtm-labs/rockscache" - "github.com/redis/go-redis/v9" - "go.mongodb.org/mongo-driver/mongo" - "gorm.io/gorm" + "github.com/openimsdk/open-im-server/v3/pkg/common/pagination" + "time" "github.com/OpenIMSDK/protocol/constant" "github.com/OpenIMSDK/tools/tx" "github.com/OpenIMSDK/tools/utils" + "github.com/redis/go-redis/v9" "github.com/openimsdk/open-im-server/v3/pkg/common/db/cache" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/relation" relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" - unrelationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/unrelation" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation" ) type GroupDatabase interface { @@ -40,23 +34,25 @@ type GroupDatabase interface { CreateGroup(ctx context.Context, groups []*relationtb.GroupModel, groupMembers []*relationtb.GroupMemberModel) error TakeGroup(ctx context.Context, groupID string) (group *relationtb.GroupModel, err error) FindGroup(ctx context.Context, groupIDs []string) (groups []*relationtb.GroupModel, err error) - FindNotDismissedGroup(ctx context.Context, groupIDs []string) (groups []*relationtb.GroupModel, err error) - SearchGroup(ctx context.Context, keyword string, pageNumber, showNumber int32) (uint32, []*relationtb.GroupModel, error) + SearchGroup(ctx context.Context, keyword string, pagination pagination.Pagination) (int64, []*relationtb.GroupModel, error) UpdateGroup(ctx context.Context, groupID string, data map[string]any) error DismissGroup(ctx context.Context, groupID string, deleteMember bool) error // 解散群,并删除群成员 - GetGroupIDsByGroupType(ctx context.Context, groupType int) (groupIDs []string, err error) - // GroupMember + TakeGroupMember(ctx context.Context, groupID string, userID string) (groupMember *relationtb.GroupMemberModel, err error) TakeGroupOwner(ctx context.Context, groupID string) (*relationtb.GroupMemberModel, error) - FindGroupMember(ctx context.Context, groupIDs []string, userIDs []string, roleLevels []int32) ([]*relationtb.GroupMemberModel, error) + FindGroupMembers(ctx context.Context, groupID string, userIDs []string) (groupMembers []*relationtb.GroupMemberModel, err error) // * + FindGroupMemberUser(ctx context.Context, groupIDs []string, userID string) (groupMembers []*relationtb.GroupMemberModel, err error) // * + FindGroupMemberRoleLevels(ctx context.Context, groupID string, roleLevels []int32) (groupMembers []*relationtb.GroupMemberModel, err error) // * + FindGroupMemberAll(ctx context.Context, groupID string) (groupMembers []*relationtb.GroupMemberModel, err error) // * + FindGroupsOwner(ctx context.Context, groupIDs []string) ([]*relationtb.GroupMemberModel, error) FindGroupMemberUserID(ctx context.Context, groupID string) ([]string, error) FindGroupMemberNum(ctx context.Context, groupID string) (uint32, error) FindUserManagedGroupID(ctx context.Context, userID string) (groupIDs []string, err error) - PageGroupRequest(ctx context.Context, groupIDs []string, pageNumber, showNumber int32) (uint32, []*relationtb.GroupRequestModel, error) + PageGroupRequest(ctx context.Context, groupIDs []string, pagination pagination.Pagination) (int64, []*relationtb.GroupRequestModel, error) - PageGetJoinGroup(ctx context.Context, userID string, pageNumber, showNumber int32) (total uint32, totalGroupMembers []*relationtb.GroupMemberModel, err error) - PageGetGroupMember(ctx context.Context, groupID string, pageNumber, showNumber int32) (total uint32, totalGroupMembers []*relationtb.GroupMemberModel, err error) - SearchGroupMember(ctx context.Context, keyword string, groupIDs []string, userIDs []string, roleLevels []int32, pageNumber, showNumber int32) (uint32, []*relationtb.GroupMemberModel, error) + PageGetJoinGroup(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, totalGroupMembers []*relationtb.GroupMemberModel, err error) + PageGetGroupMember(ctx context.Context, groupID string, pagination pagination.Pagination) (total int64, totalGroupMembers []*relationtb.GroupMemberModel, err error) + SearchGroupMember(ctx context.Context, keyword string, groupID string, pagination pagination.Pagination) (int64, []*relationtb.GroupMemberModel, error) HandlerGroupRequest(ctx context.Context, groupID string, userID string, handledMsg string, handleResult int32, member *relationtb.GroupMemberModel) error DeleteGroupMember(ctx context.Context, groupID string, userIDs []string) error MapGroupMemberUserID(ctx context.Context, groupIDs []string) (map[string]*relationtb.GroupSimpleUserID, error) @@ -67,15 +63,8 @@ type GroupDatabase interface { // GroupRequest CreateGroupRequest(ctx context.Context, requests []*relationtb.GroupRequestModel) error TakeGroupRequest(ctx context.Context, groupID string, userID string) (*relationtb.GroupRequestModel, error) - FindGroupRequests(ctx context.Context, groupID string, userIDs []string) (int64, []*relationtb.GroupRequestModel, error) - PageGroupRequestUser(ctx context.Context, userID string, pageNumber, showNumber int32) (uint32, []*relationtb.GroupRequestModel, error) - // SuperGroupModelInterface - FindSuperGroup(ctx context.Context, groupIDs []string) ([]*unrelationtb.SuperGroupModel, error) - FindJoinSuperGroup(ctx context.Context, userID string) ([]string, error) - CreateSuperGroup(ctx context.Context, groupID string, initMemberIDList []string) error - DeleteSuperGroup(ctx context.Context, groupID string) error - DeleteSuperGroupMember(ctx context.Context, groupID string, userIDs []string) error - CreateSuperGroupMember(ctx context.Context, groupID string, userIDs []string) error + FindGroupRequests(ctx context.Context, groupID string, userIDs []string) ([]*relationtb.GroupRequestModel, error) + PageGroupRequestUser(ctx context.Context, userID string, pagination pagination.Pagination) (int64, []*relationtb.GroupRequestModel, error) // 获取群总数 CountTotal(ctx context.Context, before *time.Time) (count int64, err error) @@ -84,127 +73,105 @@ type GroupDatabase interface { DeleteGroupMemberHash(ctx context.Context, groupIDs []string) error } -func NewGroupDatabase( - group relationtb.GroupModelInterface, - member relationtb.GroupMemberModelInterface, - request relationtb.GroupRequestModelInterface, - tx tx.Tx, - ctxTx tx.CtxTx, - superGroup unrelationtb.SuperGroupModelInterface, - cache cache.GroupCache, -) GroupDatabase { - database := &groupDatabase{ - groupDB: group, - groupMemberDB: member, - groupRequestDB: request, - tx: tx, - ctxTx: ctxTx, - cache: cache, - mongoDB: superGroup, - } - return database -} - -func InitGroupDatabase(db *gorm.DB, rdb redis.UniversalClient, database *mongo.Database, hashCode func(ctx context.Context, groupID string) (uint64, error)) GroupDatabase { +func NewGroupDatabase(rdb redis.UniversalClient, groupDB relationtb.GroupModelInterface, groupMemberDB relationtb.GroupMemberModelInterface, groupRequestDB relationtb.GroupRequestModelInterface, ctxTx tx.CtxTx, groupHash cache.GroupHash) GroupDatabase { rcOptions := rockscache.NewDefaultOptions() rcOptions.StrongConsistency = true rcOptions.RandomExpireAdjustment = 0.2 - return NewGroupDatabase( - relation.NewGroupDB(db), - relation.NewGroupMemberDB(db), - relation.NewGroupRequest(db), - tx.NewGorm(db), - tx.NewMongo(database.Client()), - unrelation.NewSuperGroupMongoDriver(database), - cache.NewGroupCacheRedis( - rdb, - relation.NewGroupDB(db), - relation.NewGroupMemberDB(db), - relation.NewGroupRequest(db), - unrelation.NewSuperGroupMongoDriver(database), - hashCode, - rcOptions, - ), - ) + return &groupDatabase{ + groupDB: groupDB, + groupMemberDB: groupMemberDB, + groupRequestDB: groupRequestDB, + ctxTx: ctxTx, + cache: cache.NewGroupCacheRedis(rdb, groupDB, groupMemberDB, groupRequestDB, groupHash, rcOptions), + } } type groupDatabase struct { groupDB relationtb.GroupModelInterface groupMemberDB relationtb.GroupMemberModelInterface groupRequestDB relationtb.GroupRequestModelInterface - tx tx.Tx ctxTx tx.CtxTx cache cache.GroupCache - mongoDB unrelationtb.SuperGroupModelInterface } -func (g *groupDatabase) GetGroupIDsByGroupType(ctx context.Context, groupType int) (groupIDs []string, err error) { - return g.groupDB.GetGroupIDsByGroupType(ctx, groupType) +func (g *groupDatabase) FindGroupMembers(ctx context.Context, groupID string, userIDs []string) ([]*relationtb.GroupMemberModel, error) { + return g.cache.GetGroupMembersInfo(ctx, groupID, userIDs) } -func (g *groupDatabase) FindGroupMemberUserID(ctx context.Context, groupID string) ([]string, error) { - return g.cache.GetGroupMemberIDs(ctx, groupID) +func (g *groupDatabase) FindGroupMemberUser(ctx context.Context, groupIDs []string, userID string) ([]*relationtb.GroupMemberModel, error) { + return g.cache.FindGroupMemberUser(ctx, groupIDs, userID) } -func (g *groupDatabase) FindGroupMemberNum(ctx context.Context, groupID string) (uint32, error) { - num, err := g.cache.GetGroupMemberNum(ctx, groupID) - if err != nil { - return 0, err - } - return uint32(num), nil +func (g *groupDatabase) FindGroupMemberRoleLevels(ctx context.Context, groupID string, roleLevels []int32) ([]*relationtb.GroupMemberModel, error) { + return g.cache.GetGroupRolesLevelMemberInfo(ctx, groupID, roleLevels) } -func (g *groupDatabase) CreateGroup( - ctx context.Context, - groups []*relationtb.GroupModel, - groupMembers []*relationtb.GroupMemberModel, -) error { - cache := g.cache.NewCache() - if err := g.tx.Transaction(func(tx any) error { +func (g *groupDatabase) FindGroupMemberAll(ctx context.Context, groupID string) ([]*relationtb.GroupMemberModel, error) { + return g.cache.GetAllGroupMembersInfo(ctx, groupID) +} + +func (g *groupDatabase) FindGroupsOwner(ctx context.Context, groupIDs []string) ([]*relationtb.GroupMemberModel, error) { + return g.cache.GetGroupsOwner(ctx, groupIDs) +} + +func (g *groupDatabase) CreateGroup(ctx context.Context, groups []*relationtb.GroupModel, groupMembers []*relationtb.GroupMemberModel) error { + if len(groups)+len(groupMembers) == 0 { + return nil + } + return g.ctxTx.Transaction(ctx, func(ctx context.Context) error { + c := g.cache.NewCache() if len(groups) > 0 { - if err := g.groupDB.NewTx(tx).Create(ctx, groups); err != nil { + if err := g.groupDB.Create(ctx, groups); err != nil { return err } + for _, group := range groups { + c = c.DelGroupsInfo(group.GroupID). + DelGroupMembersHash(group.GroupID). + DelGroupMembersHash(group.GroupID). + DelGroupsMemberNum(group.GroupID). + DelGroupMemberIDs(group.GroupID). + DelGroupAllRoleLevel(group.GroupID) + } } if len(groupMembers) > 0 { - if err := g.groupMemberDB.NewTx(tx).Create(ctx, groupMembers); err != nil { + if err := g.groupMemberDB.Create(ctx, groupMembers); err != nil { return err } - } - createGroupIDs := utils.DistinctAnyGetComparable(groups, func(group *relationtb.GroupModel) string { - return group.GroupID - }) - m := make(map[string]struct{}) - - for _, groupMember := range groupMembers { - if _, ok := m[groupMember.GroupID]; !ok { - m[groupMember.GroupID] = struct{}{} - cache = cache.DelGroupMemberIDs(groupMember.GroupID).DelGroupMembersHash(groupMember.GroupID).DelGroupsMemberNum(groupMember.GroupID) + for _, groupMember := range groupMembers { + c = c.DelGroupMembersHash(groupMember.GroupID). + DelGroupsMemberNum(groupMember.GroupID). + DelGroupMemberIDs(groupMember.GroupID). + DelJoinedGroupID(groupMember.UserID). + DelGroupMembersInfo(groupMember.GroupID, groupMember.UserID). + DelGroupAllRoleLevel(groupMember.GroupID) } - cache = cache.DelJoinedGroupID(groupMember.UserID).DelGroupMembersInfo(groupMember.GroupID, groupMember.UserID) } - cache = cache.DelGroupsInfo(createGroupIDs...) - return nil - }); err != nil { - return err + return c.ExecDel(ctx, true) + }) +} + +func (g *groupDatabase) FindGroupMemberUserID(ctx context.Context, groupID string) ([]string, error) { + return g.cache.GetGroupMemberIDs(ctx, groupID) +} + +func (g *groupDatabase) FindGroupMemberNum(ctx context.Context, groupID string) (uint32, error) { + num, err := g.cache.GetGroupMemberNum(ctx, groupID) + if err != nil { + return 0, err } - return cache.ExecDel(ctx) + return uint32(num), nil } -func (g *groupDatabase) TakeGroup(ctx context.Context, groupID string) (group *relationtb.GroupModel, err error) { +func (g *groupDatabase) TakeGroup(ctx context.Context, groupID string) (*relationtb.GroupModel, error) { return g.cache.GetGroupInfo(ctx, groupID) } -func (g *groupDatabase) FindGroup(ctx context.Context, groupIDs []string) (groups []*relationtb.GroupModel, err error) { +func (g *groupDatabase) FindGroup(ctx context.Context, groupIDs []string) ([]*relationtb.GroupModel, error) { return g.cache.GetGroupsInfo(ctx, groupIDs) } -func (g *groupDatabase) SearchGroup( - ctx context.Context, - keyword string, - pageNumber, showNumber int32, -) (uint32, []*relationtb.GroupModel, error) { - return g.groupDB.Search(ctx, keyword, pageNumber, showNumber) +func (g *groupDatabase) SearchGroup(ctx context.Context, keyword string, pagination pagination.Pagination) (int64, []*relationtb.GroupModel, error) { + return g.groupDB.Search(ctx, keyword, pagination) } func (g *groupDatabase) UpdateGroup(ctx context.Context, groupID string, data map[string]any) error { @@ -215,166 +182,97 @@ func (g *groupDatabase) UpdateGroup(ctx context.Context, groupID string, data ma } func (g *groupDatabase) DismissGroup(ctx context.Context, groupID string, deleteMember bool) error { - cache := g.cache.NewCache() - if err := g.tx.Transaction(func(tx any) error { - if err := g.groupDB.NewTx(tx).UpdateStatus(ctx, groupID, constant.GroupStatusDismissed); err != nil { + return g.ctxTx.Transaction(ctx, func(ctx context.Context) error { + c := g.cache.NewCache() + if err := g.groupDB.UpdateState(ctx, groupID, constant.GroupStatusDismissed); err != nil { return err } if deleteMember { - if err := g.groupMemberDB.NewTx(tx).DeleteGroup(ctx, []string{groupID}); err != nil { - return err - } userIDs, err := g.cache.GetGroupMemberIDs(ctx, groupID) if err != nil { return err } - cache = cache.DelJoinedGroupID(userIDs...).DelGroupMemberIDs(groupID).DelGroupsMemberNum(groupID).DelGroupMembersHash(groupID) + if err := g.groupMemberDB.Delete(ctx, groupID, nil); err != nil { + return err + } + c = c.DelJoinedGroupID(userIDs...). + DelGroupMemberIDs(groupID). + DelGroupsMemberNum(groupID). + DelGroupMembersHash(groupID). + DelGroupAllRoleLevel(groupID). + DelGroupMembersInfo(groupID, userIDs...) } - cache = cache.DelGroupsInfo(groupID) - return nil - }); err != nil { - return err - } - return cache.ExecDel(ctx) + return c.DelGroupsInfo(groupID).ExecDel(ctx) + }) } -func (g *groupDatabase) TakeGroupMember( - ctx context.Context, - groupID string, - userID string, -) (groupMember *relationtb.GroupMemberModel, err error) { +func (g *groupDatabase) TakeGroupMember(ctx context.Context, groupID string, userID string) (*relationtb.GroupMemberModel, error) { return g.cache.GetGroupMemberInfo(ctx, groupID, userID) } func (g *groupDatabase) TakeGroupOwner(ctx context.Context, groupID string) (*relationtb.GroupMemberModel, error) { - return g.groupMemberDB.TakeOwner(ctx, groupID) // todo cache group owner + return g.cache.GetGroupOwner(ctx, groupID) } func (g *groupDatabase) FindUserManagedGroupID(ctx context.Context, userID string) (groupIDs []string, err error) { return g.groupMemberDB.FindUserManagedGroupID(ctx, userID) } -func (g *groupDatabase) PageGroupRequest( - ctx context.Context, - groupIDs []string, - pageNumber, showNumber int32, -) (uint32, []*relationtb.GroupRequestModel, error) { - return g.groupRequestDB.PageGroup(ctx, groupIDs, pageNumber, showNumber) +func (g *groupDatabase) PageGroupRequest(ctx context.Context, groupIDs []string, pagination pagination.Pagination) (int64, []*relationtb.GroupRequestModel, error) { + return g.groupRequestDB.PageGroup(ctx, groupIDs, pagination) } -func (g *groupDatabase) FindGroupMember(ctx context.Context, groupIDs []string, userIDs []string, roleLevels []int32) (totalGroupMembers []*relationtb.GroupMemberModel, err error) { - if len(groupIDs) == 0 && len(roleLevels) == 0 && len(userIDs) == 1 { - gIDs, err := g.cache.GetJoinedGroupIDs(ctx, userIDs[0]) - if err != nil { - return nil, err - } - var res []*relationtb.GroupMemberModel - for _, groupID := range gIDs { - v, err := g.cache.GetGroupMemberInfo(ctx, groupID, userIDs[0]) - if err != nil { - return nil, err - } - res = append(res, v) - } - return res, nil - } - if len(roleLevels) == 0 { - for _, groupID := range groupIDs { - groupMembers, err := g.cache.GetGroupMembersInfo(ctx, groupID, userIDs) - if err != nil { - return nil, err - } - totalGroupMembers = append(totalGroupMembers, groupMembers...) - } - return totalGroupMembers, nil - } - return g.groupMemberDB.Find(ctx, groupIDs, userIDs, roleLevels) -} - -func (g *groupDatabase) PageGetJoinGroup( - ctx context.Context, - userID string, - pageNumber, showNumber int32, -) (total uint32, totalGroupMembers []*relationtb.GroupMemberModel, err error) { +func (g *groupDatabase) PageGetJoinGroup(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, totalGroupMembers []*relationtb.GroupMemberModel, err error) { groupIDs, err := g.cache.GetJoinedGroupIDs(ctx, userID) if err != nil { return 0, nil, err } - for _, groupID := range utils.Paginate(groupIDs, int(pageNumber), int(showNumber)) { + for _, groupID := range utils.Paginate(groupIDs, int(pagination.GetPageNumber()), int(pagination.GetShowNumber())) { groupMembers, err := g.cache.GetGroupMembersInfo(ctx, groupID, []string{userID}) if err != nil { return 0, nil, err } totalGroupMembers = append(totalGroupMembers, groupMembers...) } - return uint32(len(groupIDs)), totalGroupMembers, nil + return int64(len(groupIDs)), totalGroupMembers, nil } -func (g *groupDatabase) PageGetGroupMember( - ctx context.Context, - groupID string, - pageNumber, showNumber int32, -) (total uint32, totalGroupMembers []*relationtb.GroupMemberModel, err error) { +func (g *groupDatabase) PageGetGroupMember(ctx context.Context, groupID string, pagination pagination.Pagination) (total int64, totalGroupMembers []*relationtb.GroupMemberModel, err error) { groupMemberIDs, err := g.cache.GetGroupMemberIDs(ctx, groupID) if err != nil { return 0, nil, err } - pageIDs := utils.Paginate(groupMemberIDs, int(pageNumber), int(showNumber)) + pageIDs := utils.Paginate(groupMemberIDs, int(pagination.GetPageNumber()), int(pagination.GetShowNumber())) if len(pageIDs) == 0 { - return uint32(len(groupMemberIDs)), nil, nil + return int64(len(groupMemberIDs)), nil, nil } members, err := g.cache.GetGroupMembersInfo(ctx, groupID, pageIDs) if err != nil { return 0, nil, err } - return uint32(len(groupMemberIDs)), members, nil + return int64(len(groupMemberIDs)), members, nil } -func (g *groupDatabase) SearchGroupMember( - ctx context.Context, - keyword string, - groupIDs []string, - userIDs []string, - roleLevels []int32, - pageNumber, showNumber int32, -) (uint32, []*relationtb.GroupMemberModel, error) { - return g.groupMemberDB.SearchMember(ctx, keyword, groupIDs, userIDs, roleLevels, pageNumber, showNumber) +func (g *groupDatabase) SearchGroupMember(ctx context.Context, keyword string, groupID string, pagination pagination.Pagination) (int64, []*relationtb.GroupMemberModel, error) { + return g.groupMemberDB.SearchMember(ctx, keyword, groupID, pagination) } -func (g *groupDatabase) HandlerGroupRequest( - ctx context.Context, - groupID string, - userID string, - handledMsg string, - handleResult int32, - member *relationtb.GroupMemberModel, -) error { - //cache := g.cache.NewCache() - //if err := g.tx.Transaction(func(tx any) error { - // if err := g.groupRequestDB.NewTx(tx).UpdateHandler(ctx, groupID, userID, handledMsg, handleResult); err != nil { - // return err - // } - // if member != nil { - // if err := g.groupMemberDB.NewTx(tx).Create(ctx, []*relationtb.GroupMemberModel{member}); err != nil { - // return err - // } - // cache = cache.DelGroupMembersHash(groupID).DelGroupMemberIDs(groupID).DelGroupsMemberNum(groupID).DelJoinedGroupID(member.UserID) - // } - // return nil - //}); err != nil { - // return err - //} - //return cache.ExecDel(ctx) - - return g.tx.Transaction(func(tx any) error { - if err := g.groupRequestDB.NewTx(tx).UpdateHandler(ctx, groupID, userID, handledMsg, handleResult); err != nil { +func (g *groupDatabase) HandlerGroupRequest(ctx context.Context, groupID string, userID string, handledMsg string, handleResult int32, member *relationtb.GroupMemberModel) error { + return g.ctxTx.Transaction(ctx, func(ctx context.Context) error { + if err := g.groupRequestDB.UpdateHandler(ctx, groupID, userID, handledMsg, handleResult); err != nil { return err } if member != nil { - if err := g.groupMemberDB.NewTx(tx).Create(ctx, []*relationtb.GroupMemberModel{member}); err != nil { + if err := g.groupMemberDB.Create(ctx, []*relationtb.GroupMemberModel{member}); err != nil { return err } - if err := g.cache.NewCache().DelGroupMembersHash(groupID).DelGroupMembersInfo(groupID, member.UserID).DelGroupMemberIDs(groupID).DelGroupsMemberNum(groupID).DelJoinedGroupID(member.UserID).ExecDel(ctx); err != nil { + c := g.cache.DelGroupMembersHash(groupID). + DelGroupMembersInfo(groupID, member.UserID). + DelGroupMemberIDs(groupID). + DelGroupsMemberNum(groupID). + DelJoinedGroupID(member.UserID). + DelGroupRoleLevel(groupID, []int32{member.RoleLevel}) + if err := c.ExecDel(ctx); err != nil { return err } } @@ -391,13 +289,11 @@ func (g *groupDatabase) DeleteGroupMember(ctx context.Context, groupID string, u DelGroupsMemberNum(groupID). DelJoinedGroupID(userIDs...). DelGroupMembersInfo(groupID, userIDs...). + DelGroupAllRoleLevel(groupID). ExecDel(ctx) } -func (g *groupDatabase) MapGroupMemberUserID( - ctx context.Context, - groupIDs []string, -) (map[string]*relationtb.GroupSimpleUserID, error) { +func (g *groupDatabase) MapGroupMemberUserID(ctx context.Context, groupIDs []string) (map[string]*relationtb.GroupSimpleUserID, error) { return g.cache.GetGroupMemberHashMap(ctx, groupIDs) } @@ -414,62 +310,54 @@ func (g *groupDatabase) MapGroupMemberNum(ctx context.Context, groupIDs []string } func (g *groupDatabase) TransferGroupOwner(ctx context.Context, groupID string, oldOwnerUserID, newOwnerUserID string, roleLevel int32) error { - return g.tx.Transaction(func(tx any) error { - rowsAffected, err := g.groupMemberDB.NewTx(tx).UpdateRoleLevel(ctx, groupID, oldOwnerUserID, roleLevel) - if err != nil { + return g.ctxTx.Transaction(ctx, func(ctx context.Context) error { + if err := g.groupMemberDB.UpdateRoleLevel(ctx, groupID, oldOwnerUserID, roleLevel); err != nil { return err } - if rowsAffected != 1 { - return utils.Wrap(fmt.Errorf("oldOwnerUserID %s rowsAffected = %d", oldOwnerUserID, rowsAffected), "") - } - rowsAffected, err = g.groupMemberDB.NewTx(tx).UpdateRoleLevel(ctx, groupID, newOwnerUserID, constant.GroupOwner) - if err != nil { + if err := g.groupMemberDB.UpdateRoleLevel(ctx, groupID, newOwnerUserID, constant.GroupOwner); err != nil { return err } - if rowsAffected != 1 { - return utils.Wrap(fmt.Errorf("newOwnerUserID %s rowsAffected = %d", newOwnerUserID, rowsAffected), "") - } - return g.cache.DelGroupMembersInfo(groupID, oldOwnerUserID, newOwnerUserID).DelGroupMembersHash(groupID).ExecDel(ctx) + return g.cache.DelGroupMembersInfo(groupID, oldOwnerUserID, newOwnerUserID). + DelGroupAllRoleLevel(groupID). + DelGroupMembersHash(groupID).ExecDel(ctx) }) } -func (g *groupDatabase) UpdateGroupMember( - ctx context.Context, - groupID string, - userID string, - data map[string]any, -) error { +func (g *groupDatabase) UpdateGroupMember(ctx context.Context, groupID string, userID string, data map[string]any) error { if err := g.groupMemberDB.Update(ctx, groupID, userID, data); err != nil { return err } - return g.cache.DelGroupMembersInfo(groupID, userID).ExecDel(ctx) + c := g.cache.DelGroupMembersInfo(groupID, userID) + if g.groupMemberDB.IsUpdateRoleLevel(data) { + c = c.DelGroupAllRoleLevel(groupID) + } + return c.ExecDel(ctx) } func (g *groupDatabase) UpdateGroupMembers(ctx context.Context, data []*relationtb.BatchUpdateGroupMember) error { - cache := g.cache.NewCache() - if err := g.tx.Transaction(func(tx any) error { + return g.ctxTx.Transaction(ctx, func(ctx context.Context) error { + c := g.cache.NewCache() for _, item := range data { - if err := g.groupMemberDB.NewTx(tx).Update(ctx, item.GroupID, item.UserID, item.Map); err != nil { + if err := g.groupMemberDB.Update(ctx, item.GroupID, item.UserID, item.Map); err != nil { return err } - cache = cache.DelGroupMembersInfo(item.GroupID, item.UserID) + if g.groupMemberDB.IsUpdateRoleLevel(item.Map) { + c = c.DelGroupAllRoleLevel(item.GroupID) + } + c = c.DelGroupMembersInfo(item.GroupID, item.UserID).DelGroupMembersHash(item.GroupID) } - return nil - }); err != nil { - return err - } - return cache.ExecDel(ctx) + return c.ExecDel(ctx, true) + }) } func (g *groupDatabase) CreateGroupRequest(ctx context.Context, requests []*relationtb.GroupRequestModel) error { - return g.tx.Transaction(func(tx any) error { - db := g.groupRequestDB.NewTx(tx) + return g.ctxTx.Transaction(ctx, func(ctx context.Context) error { for _, request := range requests { - if err := db.Delete(ctx, request.GroupID, request.UserID); err != nil { + if err := g.groupRequestDB.Delete(ctx, request.GroupID, request.UserID); err != nil { return err } } - return db.Create(ctx, requests) + return g.groupRequestDB.Create(ctx, requests) }) } @@ -481,65 +369,8 @@ func (g *groupDatabase) TakeGroupRequest( return g.groupRequestDB.Take(ctx, groupID, userID) } -func (g *groupDatabase) PageGroupRequestUser( - ctx context.Context, - userID string, - pageNumber, showNumber int32, -) (uint32, []*relationtb.GroupRequestModel, error) { - return g.groupRequestDB.Page(ctx, userID, pageNumber, showNumber) -} - -func (g *groupDatabase) FindSuperGroup( - ctx context.Context, - groupIDs []string, -) (models []*unrelationtb.SuperGroupModel, err error) { - return g.cache.GetSuperGroupMemberIDs(ctx, groupIDs...) -} - -func (g *groupDatabase) FindJoinSuperGroup(ctx context.Context, userID string) ([]string, error) { - return g.cache.GetJoinedSuperGroupIDs(ctx, userID) -} - -func (g *groupDatabase) CreateSuperGroup(ctx context.Context, groupID string, initMemberIDs []string) error { - if err := g.mongoDB.CreateSuperGroup(ctx, groupID, initMemberIDs); err != nil { - return err - } - return g.cache.DelSuperGroupMemberIDs(groupID).DelJoinedSuperGroupIDs(initMemberIDs...).ExecDel(ctx) -} - -func (g *groupDatabase) DeleteSuperGroup(ctx context.Context, groupID string) error { - cache := g.cache.NewCache() - if err := g.ctxTx.Transaction(ctx, func(ctx context.Context) error { - if err := g.mongoDB.DeleteSuperGroup(ctx, groupID); err != nil { - return err - } - models, err := g.cache.GetSuperGroupMemberIDs(ctx, groupID) - if err != nil { - return err - } - cache = cache.DelSuperGroupMemberIDs(groupID) - if len(models) > 0 { - cache = cache.DelJoinedSuperGroupIDs(models[0].MemberIDs...) - } - return nil - }); err != nil { - return err - } - return cache.ExecDel(ctx) -} - -func (g *groupDatabase) DeleteSuperGroupMember(ctx context.Context, groupID string, userIDs []string) error { - if err := g.mongoDB.RemoverUserFromSuperGroup(ctx, groupID, userIDs); err != nil { - return err - } - return g.cache.DelSuperGroupMemberIDs(groupID).DelJoinedSuperGroupIDs(userIDs...).ExecDel(ctx) -} - -func (g *groupDatabase) CreateSuperGroupMember(ctx context.Context, groupID string, userIDs []string) error { - if err := g.mongoDB.AddUserToSuperGroup(ctx, groupID, userIDs); err != nil { - return err - } - return g.cache.DelSuperGroupMemberIDs(groupID).DelJoinedSuperGroupIDs(userIDs...).ExecDel(ctx) +func (g *groupDatabase) PageGroupRequestUser(ctx context.Context, userID string, pagination pagination.Pagination) (int64, []*relationtb.GroupRequestModel, error) { + return g.groupRequestDB.Page(ctx, userID, pagination) } func (g *groupDatabase) CountTotal(ctx context.Context, before *time.Time) (count int64, err error) { @@ -550,14 +381,10 @@ func (g *groupDatabase) CountRangeEverydayTotal(ctx context.Context, start time. return g.groupDB.CountRangeEverydayTotal(ctx, start, end) } -func (g *groupDatabase) FindGroupRequests(ctx context.Context, groupID string, userIDs []string) (int64, []*relationtb.GroupRequestModel, error) { +func (g *groupDatabase) FindGroupRequests(ctx context.Context, groupID string, userIDs []string) ([]*relationtb.GroupRequestModel, error) { return g.groupRequestDB.FindGroupRequests(ctx, groupID, userIDs) } -func (g *groupDatabase) FindNotDismissedGroup(ctx context.Context, groupIDs []string) (groups []*relationtb.GroupModel, err error) { - return g.groupDB.FindNotDismissedGroup(ctx, groupIDs) -} - func (g *groupDatabase) DeleteGroupMemberHash(ctx context.Context, groupIDs []string) error { if len(groupIDs) == 0 { return nil @@ -566,6 +393,5 @@ func (g *groupDatabase) DeleteGroupMemberHash(ctx context.Context, groupIDs []st for _, groupID := range groupIDs { c = c.DelGroupMembersHash(groupID) } - return c.ExecDel(ctx) } diff --git a/pkg/common/db/controller/msg_test.go b/pkg/common/db/controller/msg_test.go index ba5aecd25..cfb969b3e 100644 --- a/pkg/common/db/controller/msg_test.go +++ b/pkg/common/db/controller/msg_test.go @@ -235,7 +235,7 @@ func Test_FindBySeq(t *testing.T) { func TestName(t *testing.T) { db := GetDB() var seqs []int64 - for i := int64(1); i <= 4; i++ { + for i := int64(1); i <= 50; i++ { seqs = append(seqs, i) } msgs, err := db.getMsgBySeqsRange(context.Background(), "4931176757", "si_3866692501_4931176757", seqs, seqs[0], seqs[len(seqs)-1]) diff --git a/pkg/common/db/controller/s3.go b/pkg/common/db/controller/s3.go index ddbd5d27f..6916a7d30 100644 --- a/pkg/common/db/controller/s3.go +++ b/pkg/common/db/controller/s3.go @@ -72,14 +72,15 @@ func (s *s3Database) CompleteMultipartUpload(ctx context.Context, uploadID strin } func (s *s3Database) SetObject(ctx context.Context, info *relation.ObjectModel) error { + info.Engine = s.s3.Engine() if err := s.db.SetObject(ctx, info); err != nil { return err } - return s.cache.DelObjectName(info.Name).ExecDel(ctx) + return s.cache.DelObjectName(info.Engine, info.Name).ExecDel(ctx) } func (s *s3Database) AccessURL(ctx context.Context, name string, expire time.Duration, opt *s3.AccessURLOption) (time.Time, string, error) { - obj, err := s.cache.GetName(ctx, name) + obj, err := s.cache.GetName(ctx, s.s3.Engine(), name) if err != nil { return time.Time{}, "", err } diff --git a/pkg/common/db/controller/third.go b/pkg/common/db/controller/third.go index 971719b1f..27481f78d 100644 --- a/pkg/common/db/controller/third.go +++ b/pkg/common/db/controller/third.go @@ -16,12 +16,10 @@ package controller import ( "context" + "github.com/openimsdk/open-im-server/v3/pkg/common/pagination" "time" - "gorm.io/gorm" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/cache" - dbimpl "github.com/openimsdk/open-im-server/v3/pkg/common/db/relation" "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" ) @@ -31,20 +29,13 @@ type ThirdDatabase interface { // about log for debug UploadLogs(ctx context.Context, logs []*relation.Log) error DeleteLogs(ctx context.Context, logID []string, userID string) error - SearchLogs(ctx context.Context, keyword string, start time.Time, end time.Time, pageNumber int32, showNumber int32) (uint32, []*relation.Log, error) + SearchLogs(ctx context.Context, keyword string, start time.Time, end time.Time, pagination pagination.Pagination) (int64, []*relation.Log, error) GetLogs(ctx context.Context, LogIDs []string, userID string) ([]*relation.Log, error) - FindUsers(ctx context.Context, userIDs []string) ([]*relation.UserModel, error) } type thirdDatabase struct { - cache cache.MsgModel - logdb relation.LogInterface - userdb relation.UserModelInterface -} - -// FindUsers implements ThirdDatabase. -func (t *thirdDatabase) FindUsers(ctx context.Context, userIDs []string) ([]*relation.UserModel, error) { - return t.userdb.Find(ctx, userIDs) + cache cache.MsgModel + logdb relation.LogInterface } // DeleteLogs implements ThirdDatabase. @@ -58,8 +49,8 @@ func (t *thirdDatabase) GetLogs(ctx context.Context, LogIDs []string, userID str } // SearchLogs implements ThirdDatabase. -func (t *thirdDatabase) SearchLogs(ctx context.Context, keyword string, start time.Time, end time.Time, pageNumber int32, showNumber int32) (uint32, []*relation.Log, error) { - return t.logdb.Search(ctx, keyword, start, end, pageNumber, showNumber) +func (t *thirdDatabase) SearchLogs(ctx context.Context, keyword string, start time.Time, end time.Time, pagination pagination.Pagination) (int64, []*relation.Log, error) { + return t.logdb.Search(ctx, keyword, start, end, pagination) } // UploadLogs implements ThirdDatabase. @@ -67,8 +58,8 @@ func (t *thirdDatabase) UploadLogs(ctx context.Context, logs []*relation.Log) er return t.logdb.Create(ctx, logs) } -func NewThirdDatabase(cache cache.MsgModel, db *gorm.DB) ThirdDatabase { - return &thirdDatabase{cache: cache, logdb: dbimpl.NewLogGorm(db), userdb: dbimpl.NewUserGorm(db)} +func NewThirdDatabase(cache cache.MsgModel, logdb relation.LogInterface) ThirdDatabase { + return &thirdDatabase{cache: cache, logdb: logdb} } func (t *thirdDatabase) FcmUpdateToken( diff --git a/pkg/common/db/controller/user.go b/pkg/common/db/controller/user.go index 9c6fdc5c4..6299e7e87 100644 --- a/pkg/common/db/controller/user.go +++ b/pkg/common/db/controller/user.go @@ -16,6 +16,9 @@ package controller import ( "context" + "github.com/OpenIMSDK/tools/tx" + "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" + "github.com/openimsdk/open-im-server/v3/pkg/common/pagination" "time" "github.com/OpenIMSDK/protocol/user" @@ -23,11 +26,9 @@ import ( unrelationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/unrelation" "github.com/OpenIMSDK/tools/errs" - "github.com/OpenIMSDK/tools/tx" "github.com/OpenIMSDK/tools/utils" "github.com/openimsdk/open-im-server/v3/pkg/common/db/cache" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" ) type UserDatabase interface { @@ -38,15 +39,15 @@ type UserDatabase interface { // Create Insert multiple external guarantees that the userID is not repeated and does not exist in the db Create(ctx context.Context, users []*relation.UserModel) (err error) // Update update (non-zero value) external guarantee userID exists - Update(ctx context.Context, user *relation.UserModel) (err error) + //Update(ctx context.Context, user *relation.UserModel) (err error) // UpdateByMap update (zero value) external guarantee userID exists - UpdateByMap(ctx context.Context, userID string, args map[string]interface{}) (err error) + UpdateByMap(ctx context.Context, userID string, args map[string]any) (err error) // Page If not found, no error is returned - Page(ctx context.Context, pageNumber, showNumber int32) (users []*relation.UserModel, count int64, err error) + Page(ctx context.Context, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) // IsExist true as long as one exists IsExist(ctx context.Context, userIDs []string) (exist bool, err error) // GetAllUserID Get all user IDs - GetAllUserID(ctx context.Context, pageNumber, showNumber int32) ([]string, error) + GetAllUserID(ctx context.Context, pagination pagination.Pagination) (int64, []string, error) // InitOnce Inside the function, first query whether it exists in the db, if it exists, do nothing; if it does not exist, insert it InitOnce(ctx context.Context, users []*relation.UserModel) (err error) // CountTotal Get the total number of users @@ -68,31 +69,45 @@ type UserDatabase interface { } type userDatabase struct { + tx tx.CtxTx userDB relation.UserModelInterface cache cache.UserCache - tx tx.Tx mongoDB unrelationtb.UserModelInterface } -func NewUserDatabase(userDB relation.UserModelInterface, cache cache.UserCache, tx tx.Tx, mongoDB unrelationtb.UserModelInterface) UserDatabase { +func NewUserDatabase(userDB relation.UserModelInterface, cache cache.UserCache, tx tx.CtxTx, mongoDB unrelationtb.UserModelInterface) UserDatabase { return &userDatabase{userDB: userDB, cache: cache, tx: tx, mongoDB: mongoDB} } -func (u *userDatabase) InitOnce(ctx context.Context, users []*relation.UserModel) (err error) { - userIDs := utils.Slice(users, func(e *relation.UserModel) string { - return e.UserID - }) - result, err := u.userDB.Find(ctx, userIDs) - if err != nil { - return err - } - miss := utils.SliceAnySub(users, result, func(e *relation.UserModel) string { return e.UserID }) - if len(miss) > 0 { - _ = u.userDB.Create(ctx, miss) - } - return nil + +func (u *userDatabase) InitOnce(ctx context.Context, users []*relation.UserModel) error { + // Extract user IDs from the given user models. + userIDs := utils.Slice(users, func(e *relation.UserModel) string { + return e.UserID + }) + + // Find existing users in the database. + existingUsers, err := u.userDB.Find(ctx, userIDs) + if err != nil { + return err + } + + // Determine which users are missing from the database. + missingUsers := utils.SliceAnySub(users, existingUsers, func(e *relation.UserModel) string { + return e.UserID + }) + + // Create records for missing users. + if len(missingUsers) > 0 { + if err := u.userDB.Create(ctx, missingUsers); err != nil { + return err + } + } + + return nil } + // FindWithError Get the information of the specified user and return an error if the userID is not found. func (u *userDatabase) FindWithError(ctx context.Context, userIDs []string) (users []*relation.UserModel, err error) { users, err = u.cache.GetUsersInfo(ctx, userIDs) @@ -107,50 +122,42 @@ func (u *userDatabase) FindWithError(ctx context.Context, userIDs []string) (use // Find Get the information of the specified user. If the userID is not found, no error will be returned. func (u *userDatabase) Find(ctx context.Context, userIDs []string) (users []*relation.UserModel, err error) { - users, err = u.cache.GetUsersInfo(ctx, userIDs) - return + return u.cache.GetUsersInfo(ctx, userIDs) } // Create Insert multiple external guarantees that the userID is not repeated and does not exist in the db. func (u *userDatabase) Create(ctx context.Context, users []*relation.UserModel) (err error) { - if err := u.tx.Transaction(func(tx any) error { - err = u.userDB.Create(ctx, users) - if err != nil { + return u.tx.Transaction(ctx, func(ctx context.Context) error { + if err = u.userDB.Create(ctx, users); err != nil { return err } - return nil - }); err != nil { - return err - } - var userIDs []string - for _, user := range users { - userIDs = append(userIDs, user.UserID) - } - return u.cache.DelUsersInfo(userIDs...).ExecDel(ctx) + return u.cache.DelUsersInfo(utils.Slice(users, func(e *relation.UserModel) string { + return e.UserID + })...).ExecDel(ctx) + }) } -// Update (non-zero value) externally guarantees that userID exists. -func (u *userDatabase) Update(ctx context.Context, user *relation.UserModel) (err error) { - if err := u.userDB.Update(ctx, user); err != nil { - return err - } - return u.cache.DelUsersInfo(user.UserID).ExecDel(ctx) -} +//// Update (non-zero value) externally guarantees that userID exists. +//func (u *userDatabase) Update(ctx context.Context, user *relation.UserModel) (err error) { +// if err := u.userDB.Update(ctx, user); err != nil { +// return err +// } +// return u.cache.DelUsersInfo(user.UserID).ExecDel(ctx) +//} // UpdateByMap update (zero value) externally guarantees that userID exists. -func (u *userDatabase) UpdateByMap(ctx context.Context, userID string, args map[string]interface{}) (err error) { - if err := u.userDB.UpdateByMap(ctx, userID, args); err != nil { - return err - } - return u.cache.DelUsersInfo(userID).ExecDel(ctx) +func (u *userDatabase) UpdateByMap(ctx context.Context, userID string, args map[string]any) (err error) { + return u.tx.Transaction(ctx, func(ctx context.Context) error { + if err := u.userDB.UpdateByMap(ctx, userID, args); err != nil { + return err + } + return u.cache.DelUsersInfo(userID).ExecDel(ctx) + }) } // Page Gets, returns no error if not found. -func (u *userDatabase) Page( - ctx context.Context, - pageNumber, showNumber int32, -) (users []*relation.UserModel, count int64, err error) { - return u.userDB.Page(ctx, pageNumber, showNumber) +func (u *userDatabase) Page(ctx context.Context, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) { + return u.userDB.Page(ctx, pagination) } // IsExist Does userIDs exist? As long as there is one, it will be true. @@ -166,8 +173,8 @@ func (u *userDatabase) IsExist(ctx context.Context, userIDs []string) (exist boo } // GetAllUserID Get all user IDs. -func (u *userDatabase) GetAllUserID(ctx context.Context, pageNumber, showNumber int32) (userIDs []string, err error) { - return u.userDB.GetAllUserID(ctx, pageNumber, showNumber) +func (u *userDatabase) GetAllUserID(ctx context.Context, pagination pagination.Pagination) (total int64, userIDs []string, err error) { + return u.userDB.GetAllUserID(ctx, pagination) } // CountTotal Get the total number of users. diff --git a/pkg/common/db/newmgo/conversation.go b/pkg/common/db/newmgo/conversation.go new file mode 100644 index 000000000..cfa22d08f --- /dev/null +++ b/pkg/common/db/newmgo/conversation.go @@ -0,0 +1,129 @@ +package newmgo + +import ( + "context" + "github.com/OpenIMSDK/protocol/constant" + "github.com/openimsdk/open-im-server/v3/pkg/common/db/newmgo/mgotool" + "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" + "github.com/openimsdk/open-im-server/v3/pkg/common/pagination" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" + "time" +) + +func NewConversationMongo(db *mongo.Database) (*ConversationMgo, error) { + return &ConversationMgo{ + coll: db.Collection("conversation"), + }, nil +} + +type ConversationMgo struct { + coll *mongo.Collection +} + +func (c *ConversationMgo) Create(ctx context.Context, conversations []*relation.ConversationModel) (err error) { + return mgotool.InsertMany(ctx, c.coll, conversations) +} + +func (c *ConversationMgo) Delete(ctx context.Context, groupIDs []string) (err error) { + return mgotool.DeleteMany(ctx, c.coll, bson.M{"group_id": bson.M{"$in": groupIDs}}) +} + +func (c *ConversationMgo) UpdateByMap(ctx context.Context, userIDs []string, conversationID string, args map[string]any) (rows int64, err error) { + res, err := mgotool.UpdateMany(ctx, c.coll, bson.M{"owner_user_id": bson.M{"$in": userIDs}, "conversation_id": conversationID}, bson.M{"$set": args}) + if err != nil { + return 0, err + } + return res.ModifiedCount, nil +} + +func (c *ConversationMgo) Update(ctx context.Context, conversation *relation.ConversationModel) (err error) { + return mgotool.UpdateOne(ctx, c.coll, bson.M{"owner_user_id": conversation.OwnerUserID, "conversation_id": conversation.ConversationID}, bson.M{"$set": conversation}, true) +} + +func (c *ConversationMgo) Find(ctx context.Context, ownerUserID string, conversationIDs []string) (conversations []*relation.ConversationModel, err error) { + return mgotool.Find[*relation.ConversationModel](ctx, c.coll, bson.M{"owner_user_id": ownerUserID, "conversation_id": bson.M{"$in": conversationIDs}}) +} + +func (c *ConversationMgo) FindUserID(ctx context.Context, userIDs []string, conversationIDs []string) ([]string, error) { + return mgotool.Find[string](ctx, c.coll, bson.M{"owner_user_id": bson.M{"$in": userIDs}, "conversation_id": bson.M{"$in": conversationIDs}}, options.Find().SetProjection(bson.M{"_id": 0, "owner_user_id": 1})) +} + +func (c *ConversationMgo) FindUserIDAllConversationID(ctx context.Context, userID string) ([]string, error) { + return mgotool.Find[string](ctx, c.coll, bson.M{"owner_user_id": userID}, options.Find().SetProjection(bson.M{"_id": 0, "conversation_id": 1})) +} + +func (c *ConversationMgo) Take(ctx context.Context, userID, conversationID string) (conversation *relation.ConversationModel, err error) { + return mgotool.FindOne[*relation.ConversationModel](ctx, c.coll, bson.M{"owner_user_id": userID, "conversation_id": conversationID}) +} + +func (c *ConversationMgo) FindConversationID(ctx context.Context, userID string, conversationIDs []string) (existConversationID []string, err error) { + return mgotool.Find[string](ctx, c.coll, bson.M{"owner_user_id": userID, "conversation_id": bson.M{"$in": conversationIDs}}, options.Find().SetProjection(bson.M{"_id": 0, "conversation_id": 1})) +} + +func (c *ConversationMgo) FindUserIDAllConversations(ctx context.Context, userID string) (conversations []*relation.ConversationModel, err error) { + return mgotool.Find[*relation.ConversationModel](ctx, c.coll, bson.M{"owner_user_id": userID}) +} + +func (c *ConversationMgo) FindRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) ([]string, error) { + return mgotool.Find[string](ctx, c.coll, bson.M{"group_id": groupID, "recv_msg_opt": constant.ReceiveNotNotifyMessage}, options.Find().SetProjection(bson.M{"_id": 0, "owner_user_id": 1})) +} + +func (c *ConversationMgo) GetUserRecvMsgOpt(ctx context.Context, ownerUserID, conversationID string) (opt int, err error) { + return mgotool.FindOne[int](ctx, c.coll, bson.M{"owner_user_id": ownerUserID, "conversation_id": conversationID}, options.FindOne().SetProjection(bson.M{"recv_msg_opt": 1})) +} + +func (c *ConversationMgo) GetAllConversationIDs(ctx context.Context) ([]string, error) { + return mgotool.Aggregate[string](ctx, c.coll, []bson.M{ + {"$group": bson.M{"_id": "$conversation_id"}}, + {"$project": bson.M{"_id": 0, "conversation_id": "$_id"}}, + }) +} + +func (c *ConversationMgo) GetAllConversationIDsNumber(ctx context.Context) (int64, error) { + counts, err := mgotool.Aggregate[int64](ctx, c.coll, []bson.M{ + {"$group": bson.M{"_id": "$conversation_id"}}, + {"$project": bson.M{"_id": 0, "conversation_id": "$_id"}}, + }) + if err != nil { + return 0, err + } + if len(counts) == 0 { + return 0, nil + } + return counts[0], nil +} + +func (c *ConversationMgo) PageConversationIDs(ctx context.Context, pagination pagination.Pagination) (conversationIDs []string, err error) { + return mgotool.FindPageOnly[string](ctx, c.coll, bson.M{}, pagination, options.Find().SetProjection(bson.M{"conversation_id": 1})) +} + +func (c *ConversationMgo) GetConversationsByConversationID(ctx context.Context, conversationIDs []string) ([]*relation.ConversationModel, error) { + return mgotool.Find[*relation.ConversationModel](ctx, c.coll, bson.M{"conversation_id": bson.M{"$in": conversationIDs}}) +} + +func (c *ConversationMgo) GetConversationIDsNeedDestruct(ctx context.Context) ([]*relation.ConversationModel, error) { + //"is_msg_destruct = 1 && msg_destruct_time != 0 && (UNIX_TIMESTAMP(NOW()) > (msg_destruct_time + UNIX_TIMESTAMP(latest_msg_destruct_time)) || latest_msg_destruct_time is NULL)" + return mgotool.Find[*relation.ConversationModel](ctx, c.coll, bson.M{ + "is_msg_destruct": 1, + "msg_destruct_time": bson.M{"$ne": 0}, + "$or": []bson.M{ + { + "$expr": bson.M{ + "$gt": []any{ + time.Now(), + bson.M{"$add": []any{"$msg_destruct_time", "$latest_msg_destruct_time"}}, + }, + }, + }, + { + "latest_msg_destruct_time": nil, + }, + }, + }) +} + +func (c *ConversationMgo) GetConversationNotReceiveMessageUserIDs(ctx context.Context, conversationID string) ([]string, error) { + return mgotool.Find[string](ctx, c.coll, bson.M{"conversation_id": conversationID, "recv_msg_opt": bson.M{"$ne": constant.ReceiveMessage}}, options.Find().SetProjection(bson.M{"_id": 0, "owner_user_id": 1})) +} diff --git a/pkg/common/db/newmgo/friend.go b/pkg/common/db/newmgo/friend.go new file mode 100644 index 000000000..b02cff7c0 --- /dev/null +++ b/pkg/common/db/newmgo/friend.go @@ -0,0 +1,169 @@ +package newmgo + +import ( + "context" + + "github.com/openimsdk/open-im-server/v3/pkg/common/db/newmgo/mgotool" + "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" + "github.com/openimsdk/open-im-server/v3/pkg/common/pagination" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" +) + +// FriendMgo implements FriendModelInterface using MongoDB as the storage backend. +type FriendMgo struct { + coll *mongo.Collection +} + +// NewFriendMongo creates a new instance of FriendMgo with the provided MongoDB database. +func NewFriendMongo(db *mongo.Database) (relation.FriendModelInterface, error) { + return &FriendMgo{ + coll: db.Collection(relation.FriendModelCollectionName), + }, nil +} + +// Create inserts multiple friend records. +func (f *FriendMgo) Create(ctx context.Context, friends []*relation.FriendModel) error { + return mgotool.InsertMany(ctx, f.coll, friends) +} + +// Delete removes specified friends of the owner user. +func (f *FriendMgo) Delete(ctx context.Context, ownerUserID string, friendUserIDs []string) error { + filter := bson.M{ + "owner_user_id": ownerUserID, + "friend_user_id": bson.M{"$in": friendUserIDs}, + } + _, err := f.coll.DeleteMany(ctx, filter) + if err != nil { + return err + } + return nil +} + +// UpdateByMap updates specific fields of a friend document using a map. +func (f *FriendMgo) UpdateByMap(ctx context.Context, ownerUserID string, friendUserID string, args map[string]interface{}) error { + if len(args) == 0 { + return nil + } + filter := bson.M{ + "owner_user_id": ownerUserID, + "friend_user_id": friendUserID, + } + update := bson.M{"$set": args} + err := mgotool.UpdateOne(ctx, f.coll, filter, update, true) + if err != nil { + return err + } + return nil +} + +// Update modifies multiple friend documents. +// func (f *FriendMgo) Update(ctx context.Context, friends []*relation.FriendModel) error { +// filter := bson.M{ +// "owner_user_id": ownerUserID, +// "friend_user_id": friendUserID, +// } +// return mgotool.UpdateMany(ctx, f.coll, filter, friends) +// } + +// UpdateRemark updates the remark for a specific friend. +func (f *FriendMgo) UpdateRemark(ctx context.Context, ownerUserID, friendUserID, remark string) error { + args := map[string]interface{}{"remark": remark} + return f.UpdateByMap(ctx, ownerUserID, friendUserID, args) +} + +// Take retrieves a single friend document. Returns an error if not found. +func (f *FriendMgo) Take(ctx context.Context, ownerUserID, friendUserID string) (*relation.FriendModel, error) { + filter := bson.M{ + "owner_user_id": ownerUserID, + "friend_user_id": friendUserID, + } + friend, err := mgotool.FindOne[*relation.FriendModel](ctx, f.coll, filter) + if err != nil { + return nil, err + } + return friend, nil +} + +// FindUserState finds the friendship status between two users. +func (f *FriendMgo) FindUserState(ctx context.Context, userID1, userID2 string) ([]*relation.FriendModel, error) { + filter := bson.M{ + "$or": []bson.M{ + {"owner_user_id": userID1, "friend_user_id": userID2}, + {"owner_user_id": userID2, "friend_user_id": userID1}, + }, + } + friends, err := mgotool.Find[*relation.FriendModel](ctx, f.coll, filter) + if err != nil { + return nil, err + } + return friends, nil +} + +// FindFriends retrieves a list of friends for a given owner. Missing friends do not cause an error. +func (f *FriendMgo) FindFriends(ctx context.Context, ownerUserID string, friendUserIDs []string) ([]*relation.FriendModel, error) { + filter := bson.M{ + "owner_user_id": ownerUserID, + "friend_user_id": bson.M{"$in": friendUserIDs}, + } + friends, err := mgotool.Find[*relation.FriendModel](ctx, f.coll, filter) + if err != nil { + return nil, err + } + return friends, nil +} + +// FindReversalFriends finds users who have added the specified user as a friend. +func (f *FriendMgo) FindReversalFriends(ctx context.Context, friendUserID string, ownerUserIDs []string) ([]*relation.FriendModel, error) { + filter := bson.M{ + "owner_user_id": bson.M{"$in": ownerUserIDs}, + "friend_user_id": friendUserID, + } + friends, err := mgotool.Find[*relation.FriendModel](ctx, f.coll, filter) + if err != nil { + return nil, err + } + return friends, nil +} + +// FindOwnerFriends retrieves a paginated list of friends for a given owner. +func (f *FriendMgo) FindOwnerFriends(ctx context.Context, ownerUserID string, pagination pagination.Pagination, showNumber int32) ([]*relation.FriendModel, int64, error) { + filter := bson.M{"owner_user_id": ownerUserID} + count, friends, err := mgotool.FindPage[*relation.FriendModel](ctx, f.coll, filter, pagination) + if err != nil { + return nil, 0, err + } + return friends, count, nil +} + +// FindInWhoseFriends finds users who have added the specified user as a friend, with pagination. +func (f *FriendMgo) FindInWhoseFriends(ctx context.Context, friendUserID string, pagination.Pagination, showNumber int32) ([]*relation.FriendModel, int64, error) { + filter := bson.M{"friend_user_id": friendUserID} + count, friends, err := mgotool.FindPage[*relation.FriendModel](ctx, f.coll, filter, pagination) + if err != nil { + return nil, 0, err + } + return friends, count, nil +} + +// FindFriendUserIDs retrieves a list of friend user IDs for a given owner. +func (f *FriendMgo) FindFriendUserIDs(ctx context.Context, ownerUserID string) ([]string, error) { + filter := bson.M{"owner_user_id": ownerUserID} + friends := []*relation.FriendModel{} + friends, err := mgotool.Find[*relation.FriendModel](ctx, f.coll, filter) + if err != nil { + return nil, err + } + + friendUserIDs := make([]string, len(friends)) + for i, friend := range friends { + friendUserIDs[i] = friend.FriendUserID + } + return friendUserIDs, nil +} + +// NewTx creates a new transaction. +func (f *FriendMgo) NewTx(tx any) relation.FriendModelInterface { + panic("not implemented") + return nil +} diff --git a/pkg/common/db/newmgo/friend_request.go b/pkg/common/db/newmgo/friend_request.go new file mode 100644 index 000000000..99f4dff56 --- /dev/null +++ b/pkg/common/db/newmgo/friend_request.go @@ -0,0 +1,48 @@ +package newmgo + +import ( + "context" + + "github.com/openimsdk/open-im-server/v3/pkg/common/db/newmgo/mgotool" + "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" +) + +type FriendRequestMgo struct { + coll *mongo.Collection +} + +func NewFriendRequestMongo(db *mongo.Database) (relation.FriendRequestModelInterface, error) { + return &FriendRequestMgo{ + coll: db.Collection(relation.FriendRequestModelCollectionName), + }, nil +} + +func (f *FriendRequestMgo) Create(ctx context.Context, friendRequests []*relation.FriendRequestModel) error { + return mgotool.InsertMany(ctx, f.coll, friendRequests) +} + +func (f *FriendRequestMgo) Delete(ctx context.Context, fromUserID, toUserID string) (err error) { + return mgotool.Delete[*relation.FriendRequestModel](ctx, f.coll, bson.M{"from_user_id": fromUserID, "to_user_id": toUserID}) +} + +func (f *FriendRequestMgo) UpdateByMap(ctx context.Context, formUserID, toUserID string, args map[string]any) (err error) { + if len(args) == 0 { + return nil + } + return mgotool.UpdateOne(ctx, f.coll, bson.M{"from_user_id": formUserID, "to_user_id": toUserID}, bson.M{"$set": args}, true) +} + +func (f *FriendRequestMgo) Update(ctx context.Context, friendRequest *relation.FriendRequestModel) (err error) { + return mgotool.UpdateOne(ctx, f.coll, bson.M{"_id": friendRequest.ID}, bson.M{"$set": friendRequest}, true) +} + +func (f *FriendRequestMgo) Find(ctx context.Context, fromUserID, toUserID string) (friendRequest *relation.FriendRequestModel, err error) { + return mgotool.FindOne[*relation.FriendRequestModel](ctx, f.coll, bson.M{"from_user_id": fromUserID, "to_user_id": toUserID}) +} + +func (f *FriendRequestMgo) Take(ctx context.Context, fromUserID, toUserID string) (friendRequest *relation.FriendRequestModel, err error) { + return f.Find(ctx, fromUserID, toUserID) +} + diff --git a/pkg/common/db/newmgo/group.go b/pkg/common/db/newmgo/group.go new file mode 100644 index 000000000..ff5807c0d --- /dev/null +++ b/pkg/common/db/newmgo/group.go @@ -0,0 +1,60 @@ +package newmgo + +import ( + "context" + "github.com/openimsdk/open-im-server/v3/pkg/common/db/newmgo/mgotool" + "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" + "github.com/openimsdk/open-im-server/v3/pkg/common/pagination" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" + "time" +) + +func NewGroupMongo(db *mongo.Database) (relation.GroupModelInterface, error) { + return &GroupMgo{ + coll: db.Collection("group"), + }, nil +} + +type GroupMgo struct { + coll *mongo.Collection +} + +func (g *GroupMgo) Create(ctx context.Context, groups []*relation.GroupModel) (err error) { + return mgotool.InsertMany(ctx, g.coll, groups) +} + +func (g *GroupMgo) UpdateState(ctx context.Context, groupID string, state int32) (err error) { + return g.UpdateMap(ctx, groupID, map[string]any{"state": state}) +} + +func (g *GroupMgo) UpdateMap(ctx context.Context, groupID string, args map[string]any) (err error) { + if len(args) == 0 { + return nil + } + return mgotool.UpdateOne(ctx, g.coll, bson.M{"group_id": groupID}, bson.M{"$set": args}, true) +} + +func (g *GroupMgo) Find(ctx context.Context, groupIDs []string) (groups []*relation.GroupModel, err error) { + return mgotool.Find[*relation.GroupModel](ctx, g.coll, bson.M{"group_id": bson.M{"$in": groupIDs}}) +} + +func (g *GroupMgo) Take(ctx context.Context, groupID string) (group *relation.GroupModel, err error) { + return mgotool.FindOne[*relation.GroupModel](ctx, g.coll, bson.M{"group_id": groupID}) +} + +func (g *GroupMgo) Search(ctx context.Context, keyword string, pagination pagination.Pagination) (total int64, groups []*relation.GroupModel, err error) { + return mgotool.FindPage[*relation.GroupModel](ctx, g.coll, bson.M{"group_name": bson.M{"$regex": keyword}}, pagination) +} + +func (g *GroupMgo) CountTotal(ctx context.Context, before *time.Time) (count int64, err error) { + if before == nil { + return mgotool.Count(ctx, g.coll, bson.M{}) + } + return mgotool.Count(ctx, g.coll, bson.M{"create_time": bson.M{"$lt": before}}) +} + +func (g *GroupMgo) CountRangeEverydayTotal(ctx context.Context, start time.Time, end time.Time) (map[string]int64, error) { + //TODO implement me + panic("implement me") +} diff --git a/pkg/common/db/newmgo/group_member.go b/pkg/common/db/newmgo/group_member.go new file mode 100644 index 000000000..dbc774e80 --- /dev/null +++ b/pkg/common/db/newmgo/group_member.go @@ -0,0 +1,88 @@ +package newmgo + +import ( + "context" + "github.com/OpenIMSDK/protocol/constant" + "github.com/openimsdk/open-im-server/v3/pkg/common/db/newmgo/mgotool" + "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" + "github.com/openimsdk/open-im-server/v3/pkg/common/pagination" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" +) + +func NewGroupMember(db *mongo.Database) (relation.GroupMemberModelInterface, error) { + return &GroupMemberMgo{coll: db.Collection("group_member")}, nil +} + +type GroupMemberMgo struct { + coll *mongo.Collection +} + +func (g *GroupMemberMgo) Create(ctx context.Context, groupMembers []*relation.GroupMemberModel) (err error) { + return mgotool.InsertMany(ctx, g.coll, groupMembers) +} + +func (g *GroupMemberMgo) Delete(ctx context.Context, groupID string, userIDs []string) (err error) { + return mgotool.DeleteMany(ctx, g.coll, bson.M{"group_id": groupID, "user_id": bson.M{"$in": userIDs}}) +} + +func (g *GroupMemberMgo) UpdateRoleLevel(ctx context.Context, groupID string, userID string, roleLevel int32) error { + return g.Update(ctx, groupID, userID, bson.M{"role_level": roleLevel}) +} + +func (g *GroupMemberMgo) Update(ctx context.Context, groupID string, userID string, data map[string]any) (err error) { + return mgotool.UpdateOne(ctx, g.coll, bson.M{"group_id": groupID, "user_id": userID}, bson.M{"$set": data}, true) +} + +func (g *GroupMemberMgo) Find(ctx context.Context, groupIDs []string, userIDs []string, roleLevels []int32) (groupMembers []*relation.GroupMemberModel, err error) { + //TODO implement me + panic("implement me") +} + +func (g *GroupMemberMgo) FindMemberUserID(ctx context.Context, groupID string) (userIDs []string, err error) { + return mgotool.Find[string](ctx, g.coll, bson.M{"group_id": groupID}, options.Find().SetProjection(bson.M{"_id": 0, "user_id": 1})) +} + +func (g *GroupMemberMgo) Take(ctx context.Context, groupID string, userID string) (groupMember *relation.GroupMemberModel, err error) { + return mgotool.FindOne[*relation.GroupMemberModel](ctx, g.coll, bson.M{"group_id": groupID, "user_id": userID}) +} + +func (g *GroupMemberMgo) TakeOwner(ctx context.Context, groupID string) (groupMember *relation.GroupMemberModel, err error) { + return mgotool.FindOne[*relation.GroupMemberModel](ctx, g.coll, bson.M{"group_id": groupID, "role_level": constant.GroupOwner}) +} + +func (g *GroupMemberMgo) FindRoleLevelUserIDs(ctx context.Context, groupID string, roleLevel int32) ([]string, error) { + return mgotool.Find[string](ctx, g.coll, bson.M{"group_id": groupID, "role_level": roleLevel}, options.Find().SetProjection(bson.M{"_id": 0, "user_id": 1})) +} + +func (g *GroupMemberMgo) SearchMember(ctx context.Context, keyword string, groupID string, pagination pagination.Pagination) (total int64, groupList []*relation.GroupMemberModel, err error) { + //TODO implement me + panic("implement me") +} + +func (g *GroupMemberMgo) FindUserJoinedGroupID(ctx context.Context, userID string) (groupIDs []string, err error) { + return mgotool.Find[string](ctx, g.coll, bson.M{"user_id": userID}, options.Find().SetProjection(bson.M{"_id": 0, "group_id": 1})) +} + +func (g *GroupMemberMgo) TakeGroupMemberNum(ctx context.Context, groupID string) (count int64, err error) { + return mgotool.Count(ctx, g.coll, bson.M{"group_id": groupID}) +} + +func (g *GroupMemberMgo) FindUserManagedGroupID(ctx context.Context, userID string) (groupIDs []string, err error) { + filter := bson.M{ + "user_id": userID, + "role_level": bson.M{ + "$in": []int{constant.GroupOwner, constant.GroupAdmin}, + }, + } + return mgotool.Find[string](ctx, g.coll, filter, options.Find().SetProjection(bson.M{"_id": 0, "group_id": 1})) +} + +func (g *GroupMemberMgo) IsUpdateRoleLevel(data map[string]any) bool { + if len(data) == 0 { + return false + } + _, ok := data["role_level"] + return ok +} diff --git a/pkg/common/db/newmgo/group_request.go b/pkg/common/db/newmgo/group_request.go new file mode 100644 index 000000000..ea367b653 --- /dev/null +++ b/pkg/common/db/newmgo/group_request.go @@ -0,0 +1,46 @@ +package newmgo + +import ( + "context" + "github.com/openimsdk/open-im-server/v3/pkg/common/db/newmgo/mgotool" + "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" + "github.com/openimsdk/open-im-server/v3/pkg/common/pagination" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" +) + +func NewGroupRequestMgo(db *mongo.Database) (relation.GroupRequestModelInterface, error) { + return &GroupRequestMgo{coll: db.Collection("group_request")}, nil +} + +type GroupRequestMgo struct { + coll *mongo.Collection +} + +func (g *GroupRequestMgo) Create(ctx context.Context, groupRequests []*relation.GroupRequestModel) (err error) { + return mgotool.InsertMany(ctx, g.coll, groupRequests) +} + +func (g *GroupRequestMgo) Delete(ctx context.Context, groupID string, userID string) (err error) { + return mgotool.DeleteOne(ctx, g.coll, bson.M{"group_id": groupID, "user_id": userID}) +} + +func (g *GroupRequestMgo) UpdateHandler(ctx context.Context, groupID string, userID string, handledMsg string, handleResult int32) (err error) { + return mgotool.UpdateOne(ctx, g.coll, bson.M{"group_id": groupID, "user_id": userID}, bson.M{"$set": bson.M{"handle_msg": handledMsg, "handle_result": handleResult}}, true) +} + +func (g *GroupRequestMgo) Take(ctx context.Context, groupID string, userID string) (groupRequest *relation.GroupRequestModel, err error) { + return mgotool.FindOne[*relation.GroupRequestModel](ctx, g.coll, bson.M{"group_id": groupID, "user_id": userID}) +} + +func (g *GroupRequestMgo) FindGroupRequests(ctx context.Context, groupID string, userIDs []string) ([]*relation.GroupRequestModel, error) { + return mgotool.Find[*relation.GroupRequestModel](ctx, g.coll, bson.M{"group_id": groupID, "user_id": bson.M{"$in": userIDs}}) +} + +func (g *GroupRequestMgo) Page(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, groups []*relation.GroupRequestModel, err error) { + return mgotool.FindPage[*relation.GroupRequestModel](ctx, g.coll, bson.M{"user_id": userID}, pagination) +} + +func (g *GroupRequestMgo) PageGroup(ctx context.Context, groupIDs []string, pagination pagination.Pagination) (total int64, groups []*relation.GroupRequestModel, err error) { + return mgotool.FindPage[*relation.GroupRequestModel](ctx, g.coll, bson.M{"group_id": bson.M{"$in": groupIDs}}, pagination) +} diff --git a/pkg/common/db/newmgo/log.go b/pkg/common/db/newmgo/log.go new file mode 100644 index 000000000..f42588745 --- /dev/null +++ b/pkg/common/db/newmgo/log.go @@ -0,0 +1,49 @@ +package newmgo + +import ( + "context" + "github.com/openimsdk/open-im-server/v3/pkg/common/db/newmgo/mgotool" + "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" + "github.com/openimsdk/open-im-server/v3/pkg/common/pagination" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" + "time" +) + +func NewLogMongo(db *mongo.Database) (relation.LogInterface, error) { + lm := &LogMgo{ + coll: db.Collection("log"), + } + return lm, nil +} + +type LogMgo struct { + coll *mongo.Collection +} + +func (l *LogMgo) Create(ctx context.Context, log []*relation.Log) error { + return mgotool.InsertMany(ctx, l.coll, log) +} + +func (l *LogMgo) Search(ctx context.Context, keyword string, start time.Time, end time.Time, pagination pagination.Pagination) (int64, []*relation.Log, error) { + filter := bson.M{"create_time": bson.M{"$gte": start, "$lte": end}} + if keyword != "" { + filter["user_id"] = bson.M{"$regex": keyword} + } + return mgotool.FindPage[*relation.Log](ctx, l.coll, filter, pagination, options.Find().SetSort(bson.M{"create_time": -1})) +} + +func (l *LogMgo) Delete(ctx context.Context, logID []string, userID string) error { + if userID == "" { + return mgotool.DeleteMany(ctx, l.coll, bson.M{"log_id": bson.M{"$in": logID}}) + } + return mgotool.DeleteMany(ctx, l.coll, bson.M{"log_id": bson.M{"$in": logID}, "user_id": userID}) +} + +func (l *LogMgo) Get(ctx context.Context, logIDs []string, userID string) ([]*relation.Log, error) { + if userID == "" { + return mgotool.Find[*relation.Log](ctx, l.coll, bson.M{"log_id": bson.M{"$in": logIDs}}) + } + return mgotool.Find[*relation.Log](ctx, l.coll, bson.M{"log_id": bson.M{"$in": logIDs}, "user_id": userID}) +} diff --git a/pkg/common/db/newmgo/mgotool/tool.go b/pkg/common/db/newmgo/mgotool/tool.go new file mode 100644 index 000000000..c2c05949c --- /dev/null +++ b/pkg/common/db/newmgo/mgotool/tool.go @@ -0,0 +1,198 @@ +package mgotool + +import ( + "context" + + "github.com/OpenIMSDK/tools/errs" + "github.com/openimsdk/open-im-server/v3/pkg/common/pagination" + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" +) + + +func basic[T any]() bool { + var t T + switch any(t).(type) { + case int: + case int8: + case int16: + case int32: + case int64: + case uint: + case uint8: + case uint16: + case uint32: + case uint64: + case float32: + case float64: + case string: + case []byte: + default: + return false + } + return true +} + +func anes[T any](ts []T) []any { + val := make([]any, len(ts)) + for i := range ts { + val[i] = ts[i] + } + return val +} + +func findOptionToCountOption(opts []*options.FindOptions) *options.CountOptions { + countOpt := options.Count() + for _, opt := range opts { + if opt.Skip != nil { + countOpt.SetSkip(*opt.Skip) + } + if opt.Limit != nil { + countOpt.SetLimit(*opt.Limit) + } + } + return countOpt +} + +func InsertMany[T any](ctx context.Context, coll *mongo.Collection, val []T, opts ...*options.InsertManyOptions) error { + _, err := coll.InsertMany(ctx, anes(val), opts...) + if err != nil { + return errs.Wrap(err) + } + return nil +} + +func UpdateOne(ctx context.Context, coll *mongo.Collection, filter any, update any, notMatchedErr bool, opts ...*options.UpdateOptions) error { + res, err := coll.UpdateOne(ctx, filter, update, opts...) + if err != nil { + return errs.Wrap(err) + } + if notMatchedErr && res.MatchedCount == 0 { + return errs.Wrap(mongo.ErrNoDocuments) + } + return nil +} + +func UpdateMany(ctx context.Context, coll *mongo.Collection, filter any, update any, opts ...*options.UpdateOptions) (*mongo.UpdateResult, error) { + res, err := coll.UpdateMany(ctx, filter, update, opts...) + if err != nil { + return nil, errs.Wrap(err) + } + return res, nil +} + +func Find[T any](ctx context.Context, coll *mongo.Collection, filter any, opts ...*options.FindOptions) ([]T, error) { + cur, err := coll.Find(ctx, filter, opts...) + if err != nil { + return nil, errs.Wrap(err) + } + defer cur.Close(ctx) + var res []T + if basic[T]() { + var temp []map[string]T + if err := cur.All(ctx, &temp); err != nil { + return nil, errs.Wrap(err) + } + res = make([]T, 0, len(temp)) + for _, m := range temp { + if len(m) != 1 { + return nil, errs.ErrInternalServer.Wrap("mongo find result len(m) != 1") + } + for _, t := range m { + res = append(res, t) + } + } + } else { + if err := cur.All(ctx, &res); err != nil { + return nil, errs.Wrap(err) + } + } + return res, nil +} + +func FindOne[T any](ctx context.Context, coll *mongo.Collection, filter any, opts ...*options.FindOneOptions) (res T, err error) { + cur := coll.FindOne(ctx, filter, opts...) + if err := cur.Err(); err != nil { + return res, errs.Wrap(err) + } + if err := cur.Decode(&res); err != nil { + return res, errs.Wrap(err) + } + return res, nil +} + +func FindPage[T any](ctx context.Context, coll *mongo.Collection, filter any, pagination pagination.Pagination, opts ...*options.FindOptions) (int64, []T, error) { + count, err := Count(ctx, coll, filter, findOptionToCountOption(opts)) + if err != nil { + return 0, nil, err + } + if count == 0 || pagination == nil { + return count, nil, nil + } + skip := int64(pagination.GetPageNumber()-1) * int64(pagination.GetShowNumber()) + if skip < 0 || skip >= count || pagination.GetShowNumber() <= 0 { + return count, nil, nil + } + opt := options.Find().SetSkip(skip).SetLimit(int64(pagination.GetShowNumber())) + res, err := Find[T](ctx, coll, filter, append(opts, opt)...) + if err != nil { + return 0, nil, err + } + return count, res, nil +} + +func FindPageOnly[T any](ctx context.Context, coll *mongo.Collection, filter any, pagination pagination.Pagination, opts ...*options.FindOptions) ([]T, error) { + skip := int64(pagination.GetPageNumber()-1) * int64(pagination.GetShowNumber()) + if skip < 0 || pagination.GetShowNumber() <= 0 { + return nil, nil + } + opt := options.Find().SetSkip(skip).SetLimit(int64(pagination.GetShowNumber())) + return Find[T](ctx, coll, filter, append(opts, opt)...) +} + +func Count(ctx context.Context, coll *mongo.Collection, filter any, opts ...*options.CountOptions) (int64, error) { + return coll.CountDocuments(ctx, filter, opts...) +} + +func Exist(ctx context.Context, coll *mongo.Collection, filter any, opts ...*options.CountOptions) (bool, error) { + opts = append(opts, options.Count().SetLimit(1)) + count, err := Count(ctx, coll, filter, opts...) + if err != nil { + return false, err + } + return count > 0, nil +} + +func DeleteOne(ctx context.Context, coll *mongo.Collection, filter any, opts ...*options.DeleteOptions) error { + if _, err := coll.DeleteOne(ctx, filter, opts...); err != nil { + return errs.Wrap(err) + } + return nil +} + +func DeleteMany(ctx context.Context, coll *mongo.Collection, filter any, opts ...*options.DeleteOptions) error { + if _, err := coll.DeleteMany(ctx, filter, opts...); err != nil { + return errs.Wrap(err) + } + return nil +} + +// TODO +func Delete[T any](ctx context.Context, coll *mongo.Collection, filter any, opts ...*options.DeleteOptions) error { + if _, err := coll.DeleteMany(ctx, filter, opts...); err != nil { + return errs.Wrap(err) + } + return nil +} + +func Aggregate[T any](ctx context.Context, coll *mongo.Collection, pipeline any, opts ...*options.AggregateOptions) ([]T, error) { + cur, err := coll.Aggregate(ctx, pipeline, opts...) + if err != nil { + return nil, err + } + var ts []T + if err := cur.All(ctx, &ts); err != nil { + return nil, err + } + return ts, nil +} diff --git a/pkg/common/db/newmgo/object.go b/pkg/common/db/newmgo/object.go new file mode 100644 index 000000000..32e3daa4f --- /dev/null +++ b/pkg/common/db/newmgo/object.go @@ -0,0 +1,45 @@ +package newmgo + +import ( + "context" + "github.com/openimsdk/open-im-server/v3/pkg/common/db/newmgo/mgotool" + "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" +) + +func NewS3Mongo(db *mongo.Database) (relation.ObjectInfoModelInterface, error) { + return &S3Mongo{ + coll: db.Collection("s3"), + }, nil +} + +type S3Mongo struct { + coll *mongo.Collection +} + +func (o *S3Mongo) SetObject(ctx context.Context, obj *relation.ObjectModel) error { + filter := bson.M{"name": obj.Name, "engine": obj.Engine} + update := bson.M{ + "name": obj.Name, + "engine": obj.Engine, + "key": obj.Key, + "size": obj.Size, + "content_type": obj.ContentType, + "group": obj.Group, + "create_time": obj.CreateTime, + } + return mgotool.UpdateOne(ctx, o.coll, filter, bson.M{"$set": update}, false, options.Update().SetUpsert(true)) +} + +func (o *S3Mongo) Take(ctx context.Context, engine string, name string) (*relation.ObjectModel, error) { + if engine == "" { + return mgotool.FindOne[*relation.ObjectModel](ctx, o.coll, bson.M{"name": name}) + } + return mgotool.FindOne[*relation.ObjectModel](ctx, o.coll, bson.M{"name": name, "engine": engine}) +} + +func (o *S3Mongo) Delete(ctx context.Context, engine string, name string) error { + return mgotool.DeleteOne(ctx, o.coll, bson.M{"name": name, "engine": engine}) +} diff --git a/pkg/common/db/newmgo/user.go b/pkg/common/db/newmgo/user.go new file mode 100644 index 000000000..6a9975dff --- /dev/null +++ b/pkg/common/db/newmgo/user.go @@ -0,0 +1,71 @@ +package newmgo + +import ( + "context" + "github.com/openimsdk/open-im-server/v3/pkg/common/db/newmgo/mgotool" + "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" + "github.com/openimsdk/open-im-server/v3/pkg/common/pagination" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" + "time" +) + +func NewUserMongo(db *mongo.Database) (relation.UserModelInterface, error) { + return &UserMgo{ + coll: db.Collection("user"), + }, nil +} + +type UserMgo struct { + coll *mongo.Collection +} + +func (u *UserMgo) Create(ctx context.Context, users []*relation.UserModel) error { + return mgotool.InsertMany(ctx, u.coll, users) +} + +func (u *UserMgo) UpdateByMap(ctx context.Context, userID string, args map[string]any) (err error) { + if len(args) == 0 { + return nil + } + return mgotool.UpdateOne(ctx, u.coll, bson.M{"user_id": userID}, bson.M{"$set": args}, true) +} + +func (u *UserMgo) Find(ctx context.Context, userIDs []string) (users []*relation.UserModel, err error) { + return mgotool.Find[*relation.UserModel](ctx, u.coll, bson.M{"user_id": bson.M{"$in": userIDs}}) +} + +func (u *UserMgo) Take(ctx context.Context, userID string) (user *relation.UserModel, err error) { + return mgotool.FindOne[*relation.UserModel](ctx, u.coll, bson.M{"user_id": userID}) +} + +func (u *UserMgo) Page(ctx context.Context, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) { + return mgotool.FindPage[*relation.UserModel](ctx, u.coll, bson.M{}, pagination) +} + +func (u *UserMgo) GetAllUserID(ctx context.Context, pagination pagination.Pagination) (int64, []string, error) { + return mgotool.FindPage[string](ctx, u.coll, bson.M{}, pagination, options.Find().SetProjection(bson.M{"user_id": 1})) +} + +func (u *UserMgo) Exist(ctx context.Context, userID string) (exist bool, err error) { + return mgotool.Exist(ctx, u.coll, bson.M{"user_id": userID}) +} + +func (u *UserMgo) GetUserGlobalRecvMsgOpt(ctx context.Context, userID string) (opt int, err error) { + return mgotool.FindOne[int](ctx, u.coll, bson.M{"user_id": userID}, options.FindOne().SetProjection(bson.M{"global_recv_msg_opt": 1})) +} + +func (u *UserMgo) CountTotal(ctx context.Context, before *time.Time) (count int64, err error) { + return mgotool.Count(ctx, u.coll, bson.M{"create_time": bson.M{"$lt": before}}) +} + +func (u *UserMgo) CountRangeEverydayTotal(ctx context.Context, start time.Time, end time.Time) (map[string]int64, error) { + //type Temp struct { + // CreateTime time.Time `bson:"create_time"` + // Number int64 `bson:"number"` + //} + //mgotool.Find(ctx, u.coll, bson.M{"create_time": bson.M{"$gte": start, "$lt": end}}, options.Find().SetProjection(bson.M{"create_time": 1})) + panic("implement me") + return nil, nil +} diff --git a/pkg/common/db/relation/black_model.go b/pkg/common/db/relation/black_model.go index 34123c7a3..458012d15 100644 --- a/pkg/common/db/relation/black_model.go +++ b/pkg/common/db/relation/black_model.go @@ -47,7 +47,7 @@ func (b *BlackGorm) Delete(ctx context.Context, blacks []*relation.BlackModel) ( func (b *BlackGorm) UpdateByMap( ctx context.Context, ownerUserID, blockUserID string, - args map[string]interface{}, + args map[string]any, ) (err error) { return utils.Wrap( b.db(ctx).Where("block_user_id = ? and block_user_id = ?", ownerUserID, blockUserID).Updates(args).Error, @@ -63,9 +63,9 @@ func (b *BlackGorm) Find( ctx context.Context, blacks []*relation.BlackModel, ) (blackList []*relation.BlackModel, err error) { - var where [][]interface{} + var where [][]any for _, black := range blacks { - where = append(where, []interface{}{black.OwnerUserID, black.BlockUserID}) + where = append(where, []any{black.OwnerUserID, black.BlockUserID}) } return blackList, utils.Wrap( b.db(ctx).Where("(owner_user_id, block_user_id) in ?", where).Find(&blackList).Error, diff --git a/pkg/common/db/relation/conversation_model.go b/pkg/common/db/relation/conversation_model.go index f39047bf6..73cf1a80e 100644 --- a/pkg/common/db/relation/conversation_model.go +++ b/pkg/common/db/relation/conversation_model.go @@ -14,237 +14,231 @@ package relation -import ( - "context" - - "github.com/OpenIMSDK/tools/errs" - "gorm.io/gorm" - - "github.com/OpenIMSDK/protocol/constant" - "github.com/OpenIMSDK/tools/utils" - - "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" -) - -type ConversationGorm struct { - *MetaDB -} - -func NewConversationGorm(db *gorm.DB) relation.ConversationModelInterface { - return &ConversationGorm{NewMetaDB(db, &relation.ConversationModel{})} -} - -func (c *ConversationGorm) NewTx(tx any) relation.ConversationModelInterface { - return &ConversationGorm{NewMetaDB(tx.(*gorm.DB), &relation.ConversationModel{})} -} - -func (c *ConversationGorm) Create(ctx context.Context, conversations []*relation.ConversationModel) (err error) { - return utils.Wrap(c.db(ctx).Create(&conversations).Error, "") -} - -func (c *ConversationGorm) Delete(ctx context.Context, groupIDs []string) (err error) { - return utils.Wrap(c.db(ctx).Where("group_id in (?)", groupIDs).Delete(&relation.ConversationModel{}).Error, "") -} - -func (c *ConversationGorm) UpdateByMap( - ctx context.Context, - userIDList []string, - conversationID string, - args map[string]interface{}, -) (rows int64, err error) { - result := c.db(ctx).Where("owner_user_id IN (?) and conversation_id=?", userIDList, conversationID).Updates(args) - return result.RowsAffected, utils.Wrap(result.Error, "") -} - -func (c *ConversationGorm) Update(ctx context.Context, conversation *relation.ConversationModel) (err error) { - return utils.Wrap( - c.db(ctx). - Where("owner_user_id = ? and conversation_id = ?", conversation.OwnerUserID, conversation.ConversationID). - Updates(conversation). - Error, - "", - ) -} - -func (c *ConversationGorm) Find( - ctx context.Context, - ownerUserID string, - conversationIDs []string, -) (conversations []*relation.ConversationModel, err error) { - err = utils.Wrap( - c.db(ctx). - Where("owner_user_id=? and conversation_id IN (?)", ownerUserID, conversationIDs). - Find(&conversations). - Error, - "", - ) - return conversations, err -} - -func (c *ConversationGorm) Take( - ctx context.Context, - userID, conversationID string, -) (conversation *relation.ConversationModel, err error) { - cc := &relation.ConversationModel{} - return cc, utils.Wrap( - c.db(ctx).Where("conversation_id = ? And owner_user_id = ?", conversationID, userID).Take(cc).Error, - "", - ) -} - -func (c *ConversationGorm) FindUserID( - ctx context.Context, - userIDs []string, - conversationIDs []string, -) (existUserID []string, err error) { - return existUserID, utils.Wrap( - c.db(ctx). - Where(" owner_user_id IN (?) and conversation_id in (?)", userIDs, conversationIDs). - Pluck("owner_user_id", &existUserID). - Error, - "", - ) -} - -func (c *ConversationGorm) FindConversationID( - ctx context.Context, - userID string, - conversationIDList []string, -) (existConversationID []string, err error) { - return existConversationID, utils.Wrap( - c.db(ctx). - Where(" conversation_id IN (?) and owner_user_id=?", conversationIDList, userID). - Pluck("conversation_id", &existConversationID). - Error, - "", - ) -} - -func (c *ConversationGorm) FindUserIDAllConversationID( - ctx context.Context, - userID string, -) (conversationIDList []string, err error) { - return conversationIDList, utils.Wrap( - c.db(ctx).Where("owner_user_id=?", userID).Pluck("conversation_id", &conversationIDList).Error, - "", - ) -} - -func (c *ConversationGorm) FindUserIDAllConversations( - ctx context.Context, - userID string, -) (conversations []*relation.ConversationModel, err error) { - return conversations, utils.Wrap(c.db(ctx).Where("owner_user_id=?", userID).Find(&conversations).Error, "") -} - -func (c *ConversationGorm) FindRecvMsgNotNotifyUserIDs( - ctx context.Context, - groupID string, -) (userIDs []string, err error) { - return userIDs, utils.Wrap( - c.db(ctx). - Where("group_id = ? and recv_msg_opt = ?", groupID, constant.ReceiveNotNotifyMessage). - Pluck("owner_user_id", &userIDs). - Error, - "", - ) -} - -func (c *ConversationGorm) FindSuperGroupRecvMsgNotNotifyUserIDs( - ctx context.Context, - groupID string, -) (userIDs []string, err error) { - return userIDs, utils.Wrap( - c.db(ctx). - Where("group_id = ? and recv_msg_opt = ? and conversation_type = ?", groupID, constant.ReceiveNotNotifyMessage, constant.SuperGroupChatType). - Pluck("owner_user_id", &userIDs). - Error, - "", - ) -} - -func (c *ConversationGorm) GetUserRecvMsgOpt( - ctx context.Context, - ownerUserID, conversationID string, -) (opt int, err error) { - var conversation relation.ConversationModel - return int( - conversation.RecvMsgOpt, - ), utils.Wrap( - c.db(ctx). - Where("conversation_id = ? And owner_user_id = ?", conversationID, ownerUserID). - Select("recv_msg_opt"). - Find(&conversation). - Error, - "", - ) -} - -func (c *ConversationGorm) GetAllConversationIDs(ctx context.Context) (conversationIDs []string, err error) { - return conversationIDs, utils.Wrap( - c.db(ctx).Distinct("conversation_id").Pluck("conversation_id", &conversationIDs).Error, - "", - ) -} - -func (c *ConversationGorm) GetAllConversationIDsNumber(ctx context.Context) (int64, error) { - var num int64 - err := c.db(ctx).Select("COUNT(DISTINCT conversation_id)").Model(&relation.ConversationModel{}).Count(&num).Error - return num, errs.Wrap(err) -} - -func (c *ConversationGorm) PageConversationIDs(ctx context.Context, pageNumber, showNumber int32) (conversationIDs []string, err error) { - err = c.db(ctx).Distinct("conversation_id").Limit(int(showNumber)).Offset(int((pageNumber-1)*showNumber)).Pluck("conversation_id", &conversationIDs).Error - err = errs.Wrap(err) - return -} - -func (c *ConversationGorm) GetUserAllHasReadSeqs( - ctx context.Context, - ownerUserID string, -) (hasReadSeqs map[string]int64, err error) { - return nil, nil -} - -func (c *ConversationGorm) GetConversationsByConversationID( - ctx context.Context, - conversationIDs []string, -) (conversations []*relation.ConversationModel, err error) { - return conversations, utils.Wrap( - c.db(ctx).Where("conversation_id IN (?)", conversationIDs).Find(&conversations).Error, - "", - ) -} - -func (c *ConversationGorm) GetConversationIDsNeedDestruct( - ctx context.Context, -) (conversations []*relation.ConversationModel, err error) { - return conversations, utils.Wrap( - c.db(ctx). - Where("is_msg_destruct = 1 && msg_destruct_time != 0 && (UNIX_TIMESTAMP(NOW()) > (msg_destruct_time + UNIX_TIMESTAMP(latest_msg_destruct_time)) || latest_msg_destruct_time is NULL)"). - Find(&conversations). - Error, - "", - ) -} - -func (c *ConversationGorm) GetConversationRecvMsgOpt(ctx context.Context, userID string, conversationID string) (int32, error) { - var recvMsgOpt int32 - return recvMsgOpt, errs.Wrap( - c.db(ctx). - Model(&relation.ConversationModel{}). - Where("conversation_id = ? and owner_user_id in ?", conversationID, userID). - Pluck("recv_msg_opt", &recvMsgOpt). - Error, - ) -} - -func (c *ConversationGorm) GetConversationNotReceiveMessageUserIDs(ctx context.Context, conversationID string) ([]string, error) { - var userIDs []string - return userIDs, errs.Wrap( - c.db(ctx). - Model(&relation.ConversationModel{}). - Where("conversation_id = ? and recv_msg_opt <> ?", conversationID, constant.ReceiveMessage). - Pluck("owner_user_id", &userIDs).Error, - ) -} +// +//import ( +// "context" +// +// "github.com/OpenIMSDK/tools/errs" +// "gorm.io/gorm" +// +// "github.com/OpenIMSDK/protocol/constant" +// "github.com/OpenIMSDK/tools/utils" +// +// "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" +//) +// +//type ConversationGorm struct { +// *MetaDB +//} +// +//func NewConversationGorm(db *gorm.DB) relation.ConversationModelInterface { +// return &ConversationGorm{NewMetaDB(db, &relation.ConversationModel{})} +//} +// +//func (c *ConversationGorm) NewTx(tx any) relation.ConversationModelInterface { +// return &ConversationGorm{NewMetaDB(tx.(*gorm.DB), &relation.ConversationModel{})} +//} +// +//func (c *ConversationGorm) Create(ctx context.Context, conversations []*relation.ConversationModel) (err error) { +// return utils.Wrap(c.db(ctx).Create(&conversations).Error, "") +//} +// +//func (c *ConversationGorm) Delete(ctx context.Context, groupIDs []string) (err error) { +// return utils.Wrap(c.db(ctx).Where("group_id in (?)", groupIDs).Delete(&relation.ConversationModel{}).Error, "") +//} +// +//func (c *ConversationGorm) UpdateByMap( +// ctx context.Context, +// userIDList []string, +// conversationID string, +// args map[string]any, +//) (rows int64, err error) { +// result := c.db(ctx).Where("owner_user_id IN (?) and conversation_id=?", userIDList, conversationID).Updates(args) +// return result.RowsAffected, utils.Wrap(result.Error, "") +//} +// +//func (c *ConversationGorm) Update(ctx context.Context, conversation *relation.ConversationModel) (err error) { +// return utils.Wrap( +// c.db(ctx). +// Where("owner_user_id = ? and conversation_id = ?", conversation.OwnerUserID, conversation.ConversationID). +// Updates(conversation). +// Error, +// "", +// ) +//} +// +//func (c *ConversationGorm) Find( +// ctx context.Context, +// ownerUserID string, +// conversationIDs []string, +//) (conversations []*relation.ConversationModel, err error) { +// err = utils.Wrap( +// c.db(ctx). +// Where("owner_user_id=? and conversation_id IN (?)", ownerUserID, conversationIDs). +// Find(&conversations). +// Error, +// "", +// ) +// return conversations, err +//} +// +//func (c *ConversationGorm) Take( +// ctx context.Context, +// userID, conversationID string, +//) (conversation *relation.ConversationModel, err error) { +// cc := &relation.ConversationModel{} +// return cc, utils.Wrap( +// c.db(ctx).Where("conversation_id = ? And owner_user_id = ?", conversationID, userID).Take(cc).Error, +// "", +// ) +//} +// +//func (c *ConversationGorm) FindUserID( +// ctx context.Context, +// userIDs []string, +// conversationIDs []string, +//) (existUserID []string, err error) { +// return existUserID, utils.Wrap( +// c.db(ctx). +// Where(" owner_user_id IN (?) and conversation_id in (?)", userIDs, conversationIDs). +// Pluck("owner_user_id", &existUserID). +// Error, +// "", +// ) +//} +// +//func (c *ConversationGorm) FindConversationID( +// ctx context.Context, +// userID string, +// conversationIDList []string, +//) (existConversationID []string, err error) { +// return existConversationID, utils.Wrap( +// c.db(ctx). +// Where(" conversation_id IN (?) and owner_user_id=?", conversationIDList, userID). +// Pluck("conversation_id", &existConversationID). +// Error, +// "", +// ) +//} +// +//func (c *ConversationGorm) FindUserIDAllConversationID( +// ctx context.Context, +// userID string, +//) (conversationIDList []string, err error) { +// return conversationIDList, utils.Wrap( +// c.db(ctx).Where("owner_user_id=?", userID).Pluck("conversation_id", &conversationIDList).Error, +// "", +// ) +//} +// +//func (c *ConversationGorm) FindUserIDAllConversations( +// ctx context.Context, +// userID string, +//) (conversations []*relation.ConversationModel, err error) { +// return conversations, utils.Wrap(c.db(ctx).Where("owner_user_id=?", userID).Find(&conversations).Error, "") +//} +// +//func (c *ConversationGorm) FindRecvMsgNotNotifyUserIDs( +// ctx context.Context, +// groupID string, +//) (userIDs []string, err error) { +// return userIDs, utils.Wrap( +// c.db(ctx). +// Where("group_id = ? and recv_msg_opt = ?", groupID, constant.ReceiveNotNotifyMessage). +// Pluck("owner_user_id", &userIDs). +// Error, +// "", +// ) +//} +// +//func (c *ConversationGorm) FindSuperGroupRecvMsgNotNotifyUserIDs( +// ctx context.Context, +// groupID string, +//) (userIDs []string, err error) { +// return userIDs, utils.Wrap( +// c.db(ctx). +// Where("group_id = ? and recv_msg_opt = ? and conversation_type = ?", groupID, constant.ReceiveNotNotifyMessage, constant.SuperGroupChatType). +// Pluck("owner_user_id", &userIDs). +// Error, +// "", +// ) +//} +// +//func (c *ConversationGorm) GetUserRecvMsgOpt( +// ctx context.Context, +// ownerUserID, conversationID string, +//) (opt int, err error) { +// var conversation relation.ConversationModel +// return int( +// conversation.RecvMsgOpt, +// ), utils.Wrap( +// c.db(ctx). +// Where("conversation_id = ? And owner_user_id = ?", conversationID, ownerUserID). +// Select("recv_msg_opt"). +// Find(&conversation). +// Error, +// "", +// ) +//} +// +//func (c *ConversationGorm) GetAllConversationIDs(ctx context.Context) (conversationIDs []string, err error) { +// return conversationIDs, utils.Wrap( +// c.db(ctx).Distinct("conversation_id").Pluck("conversation_id", &conversationIDs).Error, +// "", +// ) +//} +// +//func (c *ConversationGorm) GetAllConversationIDsNumber(ctx context.Context) (int64, error) { +// var num int64 +// err := c.db(ctx).Select("COUNT(DISTINCT conversation_id)").Model(&relation.ConversationModel{}).Count(&num).Error +// return num, errs.Wrap(err) +//} +// +//func (c *ConversationGorm) PageConversationIDs(ctx context.Context, pageNumber, showNumber int32) (conversationIDs []string, err error) { +// err = c.db(ctx).Distinct("conversation_id").Limit(int(showNumber)).Offset(int((pageNumber-1)*showNumber)).Pluck("conversation_id", &conversationIDs).Error +// err = errs.Wrap(err) +// return +//} +// +//func (c *ConversationGorm) GetConversationsByConversationID( +// ctx context.Context, +// conversationIDs []string, +//) (conversations []*relation.ConversationModel, err error) { +// return conversations, utils.Wrap( +// c.db(ctx).Where("conversation_id IN (?)", conversationIDs).Find(&conversations).Error, +// "", +// ) +//} +// +//func (c *ConversationGorm) GetConversationIDsNeedDestruct( +// ctx context.Context, +//) (conversations []*relation.ConversationModel, err error) { +// return conversations, utils.Wrap( +// c.db(ctx). +// Where("is_msg_destruct = 1 && msg_destruct_time != 0 && (UNIX_TIMESTAMP(NOW()) > (msg_destruct_time + UNIX_TIMESTAMP(latest_msg_destruct_time)) || latest_msg_destruct_time is NULL)"). +// Find(&conversations). +// Error, +// "", +// ) +//} +// +//func (c *ConversationGorm) GetConversationRecvMsgOpt(ctx context.Context, userID string, conversationID string) (int32, error) { +// var recvMsgOpt int32 +// return recvMsgOpt, errs.Wrap( +// c.db(ctx). +// Model(&relation.ConversationModel{}). +// Where("conversation_id = ? and owner_user_id in ?", conversationID, userID). +// Pluck("recv_msg_opt", &recvMsgOpt). +// Error, +// ) +//} +// +//func (c *ConversationGorm) GetConversationNotReceiveMessageUserIDs(ctx context.Context, conversationID string) ([]string, error) { +// var userIDs []string +// return userIDs, errs.Wrap( +// c.db(ctx). +// Model(&relation.ConversationModel{}). +// Where("conversation_id = ? and recv_msg_opt <> ?", conversationID, constant.ReceiveMessage). +// Pluck("owner_user_id", &userIDs).Error, +// ) +//} diff --git a/pkg/common/db/relation/friend_model.go b/pkg/common/db/relation/friend_model.go index 869254455..50f4451b5 100644 --- a/pkg/common/db/relation/friend_model.go +++ b/pkg/common/db/relation/friend_model.go @@ -58,7 +58,7 @@ func (f *FriendGorm) UpdateByMap( ctx context.Context, ownerUserID string, friendUserID string, - args map[string]interface{}, + args map[string]any, ) (err error) { return utils.Wrap( f.db(ctx).Where("owner_user_id = ? AND friend_user_id = ? ", ownerUserID, friendUserID).Updates(args).Error, @@ -82,7 +82,7 @@ func (f *FriendGorm) UpdateRemark(ctx context.Context, ownerUserID, friendUserID "", ) } - m := make(map[string]interface{}, 1) + m := make(map[string]any, 1) m["remark"] = "" return utils.Wrap(f.db(ctx).Where("owner_user_id = ?", ownerUserID).Updates(m).Error, "") } diff --git a/pkg/common/db/relation/friend_request_model.go b/pkg/common/db/relation/friend_request_model.go index 5678f7b7b..e215f8850 100644 --- a/pkg/common/db/relation/friend_request_model.go +++ b/pkg/common/db/relation/friend_request_model.go @@ -14,151 +14,141 @@ package relation -import ( - "context" - - "gorm.io/gorm" - - "github.com/OpenIMSDK/tools/utils" - - "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" -) - -type FriendRequestGorm struct { - *MetaDB -} - -func NewFriendRequestGorm(db *gorm.DB) relation.FriendRequestModelInterface { - return &FriendRequestGorm{NewMetaDB(db, &relation.FriendRequestModel{})} -} - -func (f *FriendRequestGorm) NewTx(tx any) relation.FriendRequestModelInterface { - return &FriendRequestGorm{NewMetaDB(tx.(*gorm.DB), &relation.FriendRequestModel{})} -} - -// 插入多条记录. -func (f *FriendRequestGorm) Create(ctx context.Context, friendRequests []*relation.FriendRequestModel) (err error) { - return utils.Wrap(f.db(ctx).Create(&friendRequests).Error, "") -} - -// 删除记录. -func (f *FriendRequestGorm) Delete(ctx context.Context, fromUserID, toUserID string) (err error) { - return utils.Wrap( - f.db(ctx). - Where("from_user_id = ? AND to_user_id = ?", fromUserID, toUserID). - Delete(&relation.FriendRequestModel{}). - Error, - "", - ) -} - -// 更新零值. -func (f *FriendRequestGorm) UpdateByMap( - ctx context.Context, - fromUserID string, - toUserID string, - args map[string]interface{}, -) (err error) { - return utils.Wrap( - f.db(ctx). - Model(&relation.FriendRequestModel{}). - Where("from_user_id = ? AND to_user_id =?", fromUserID, toUserID). - Updates(args). - Error, - "", - ) -} - -// 更新记录 (非零值). -func (f *FriendRequestGorm) Update(ctx context.Context, friendRequest *relation.FriendRequestModel) (err error) { - fr2 := *friendRequest - fr2.FromUserID = "" - fr2.ToUserID = "" - return utils.Wrap( - f.db(ctx). - Where("from_user_id = ? AND to_user_id =?", friendRequest.FromUserID, friendRequest.ToUserID). - Updates(fr2). - Error, - "", - ) -} - -// 获取来指定用户的好友申请 未找到 不返回错误. -func (f *FriendRequestGorm) Find( - ctx context.Context, - fromUserID, toUserID string, -) (friendRequest *relation.FriendRequestModel, err error) { - friendRequest = &relation.FriendRequestModel{} - err = utils.Wrap( - f.db(ctx).Where("from_user_id = ? and to_user_id = ?", fromUserID, toUserID).Find(friendRequest).Error, - "", - ) - return friendRequest, err -} - -func (f *FriendRequestGorm) Take( - ctx context.Context, - fromUserID, toUserID string, -) (friendRequest *relation.FriendRequestModel, err error) { - friendRequest = &relation.FriendRequestModel{} - err = utils.Wrap( - f.db(ctx).Where("from_user_id = ? and to_user_id = ?", fromUserID, toUserID).Take(friendRequest).Error, - "", - ) - return friendRequest, err -} - -// 获取toUserID收到的好友申请列表. -func (f *FriendRequestGorm) FindToUserID( - ctx context.Context, - toUserID string, - pageNumber, showNumber int32, -) (friendRequests []*relation.FriendRequestModel, total int64, err error) { - err = f.db(ctx).Model(&relation.FriendRequestModel{}).Where("to_user_id = ? ", toUserID).Count(&total).Error - if err != nil { - return nil, 0, utils.Wrap(err, "") - } - err = utils.Wrap( - f.db(ctx). - Where("to_user_id = ? ", toUserID). - Limit(int(showNumber)). - Offset(int(pageNumber-1)*int(showNumber)). - Find(&friendRequests). - Error, - "", - ) - return -} - -// 获取fromUserID发出去的好友申请列表. -func (f *FriendRequestGorm) FindFromUserID( - ctx context.Context, - fromUserID string, - pageNumber, showNumber int32, -) (friendRequests []*relation.FriendRequestModel, total int64, err error) { - err = f.db(ctx).Model(&relation.FriendRequestModel{}).Where("from_user_id = ? ", fromUserID).Count(&total).Error - if err != nil { - return nil, 0, utils.Wrap(err, "") - } - err = utils.Wrap( - f.db(ctx). - Where("from_user_id = ? ", fromUserID). - Limit(int(showNumber)). - Offset(int(pageNumber-1)*int(showNumber)). - Find(&friendRequests). - Error, - "", - ) - return -} - -func (f *FriendRequestGorm) FindBothFriendRequests(ctx context.Context, fromUserID, toUserID string) (friends []*relation.FriendRequestModel, err error) { - err = utils.Wrap( - f.db(ctx). - Where("(from_user_id = ? AND to_user_id = ?) OR (from_user_id = ? AND to_user_id = ?)", fromUserID, toUserID, toUserID, fromUserID). - Find(&friends). - Error, - "", - ) - return -} +// type FriendRequestGorm struct { +// *MetaDB +// } + +// func NewFriendRequestGorm(db *gorm.DB) relation.FriendRequestModelInterface { +// return &FriendRequestGorm{NewMetaDB(db, &relation.FriendRequestModel{})} +// } + +// func (f *FriendRequestGorm) NewTx(tx any) relation.FriendRequestModelInterface { +// return &FriendRequestGorm{NewMetaDB(tx.(*gorm.DB), &relation.FriendRequestModel{})} +// } + +// // 插入多条记录. +// func (f *FriendRequestGorm) Create(ctx context.Context, friendRequests []*relation.FriendRequestModel) (err error) { +// return utils.Wrap(f.db(ctx).Create(&friendRequests).Error, "") +// } + +// // 删除记录. +// func (f *FriendRequestGorm) Delete(ctx context.Context, fromUserID, toUserID string) (err error) { +// return utils.Wrap( +// f.db(ctx). +// Where("from_user_id = ? AND to_user_id = ?", fromUserID, toUserID). +// Delete(&relation.FriendRequestModel{}). +// Error, +// "", +// ) +// } + +// // 更新零值. +// func (f *FriendRequestGorm) UpdateByMap( +// ctx context.Context, +// fromUserID string, +// toUserID string, +// args map[string]any, +// ) (err error) { +// return utils.Wrap( +// f.db(ctx). +// Model(&relation.FriendRequestModel{}). +// Where("from_user_id = ? AND to_user_id =?", fromUserID, toUserID). +// Updates(args). +// Error, +// "", +// ) +// } + +// // 更新记录 (非零值). +// func (f *FriendRequestGorm) Update(ctx context.Context, friendRequest *relation.FriendRequestModel) (err error) { +// fr2 := *friendRequest +// fr2.FromUserID = "" +// fr2.ToUserID = "" +// return utils.Wrap( +// f.db(ctx). +// Where("from_user_id = ? AND to_user_id =?", friendRequest.FromUserID, friendRequest.ToUserID). +// Updates(fr2). +// Error, +// "", +// ) +// } + +// // 获取来指定用户的好友申请 未找到 不返回错误. +// func (f *FriendRequestGorm) Find( +// ctx context.Context, +// fromUserID, toUserID string, +// ) (friendRequest *relation.FriendRequestModel, err error) { +// friendRequest = &relation.FriendRequestModel{} +// err = utils.Wrap( +// f.db(ctx).Where("from_user_id = ? and to_user_id = ?", fromUserID, toUserID).Find(friendRequest).Error, +// "", +// ) +// return friendRequest, err +// } + +// func (f *FriendRequestGorm) Take( +// ctx context.Context, +// fromUserID, toUserID string, +// ) (friendRequest *relation.FriendRequestModel, err error) { +// friendRequest = &relation.FriendRequestModel{} +// err = utils.Wrap( +// f.db(ctx).Where("from_user_id = ? and to_user_id = ?", fromUserID, toUserID).Take(friendRequest).Error, +// "", +// ) +// return friendRequest, err +// } + +// // 获取toUserID收到的好友申请列表. +// func (f *FriendRequestGorm) FindToUserID( +// ctx context.Context, +// toUserID string, +// pageNumber, showNumber int32, +// ) (friendRequests []*relation.FriendRequestModel, total int64, err error) { +// err = f.db(ctx).Model(&relation.FriendRequestModel{}).Where("to_user_id = ? ", toUserID).Count(&total).Error +// if err != nil { +// return nil, 0, utils.Wrap(err, "") +// } +// err = utils.Wrap( +// f.db(ctx). +// Where("to_user_id = ? ", toUserID). +// Limit(int(showNumber)). +// Offset(int(pageNumber-1)*int(showNumber)). +// Find(&friendRequests). +// Error, +// "", +// ) +// return +// } + +// // 获取fromUserID发出去的好友申请列表. +// func (f *FriendRequestGorm) FindFromUserID( +// ctx context.Context, +// fromUserID string, +// pageNumber, showNumber int32, +// ) (friendRequests []*relation.FriendRequestModel, total int64, err error) { +// err = f.db(ctx).Model(&relation.FriendRequestModel{}).Where("from_user_id = ? ", fromUserID).Count(&total).Error +// if err != nil { +// return nil, 0, utils.Wrap(err, "") +// } +// err = utils.Wrap( +// f.db(ctx). +// Where("from_user_id = ? ", fromUserID). +// Limit(int(showNumber)). +// Offset(int(pageNumber-1)*int(showNumber)). +// Find(&friendRequests). +// Error, +// "", +// ) +// return +// } + +// func (f *FriendRequestGorm) FindBothFriendRequests(ctx context.Context, fromUserID, toUserID string) (friends []*relation.FriendRequestModel, err error) { +// err = utils.Wrap( +// f.db(ctx). +// Where("(from_user_id = ? AND to_user_id = ?) OR (from_user_id = ? AND to_user_id = ?)", fromUserID, toUserID, toUserID, fromUserID). +// Find(&friends). +// Error, +// "", +// ) +// return +// } diff --git a/pkg/common/db/relation/group_member_model.go b/pkg/common/db/relation/group_member_model.go index 312e32054..93885760c 100644 --- a/pkg/common/db/relation/group_member_model.go +++ b/pkg/common/db/relation/group_member_model.go @@ -14,184 +14,185 @@ package relation -import ( - "context" - - "gorm.io/gorm" - - "github.com/OpenIMSDK/protocol/constant" - "github.com/OpenIMSDK/tools/ormutil" - "github.com/OpenIMSDK/tools/utils" - - "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" -) - -var _ relation.GroupMemberModelInterface = (*GroupMemberGorm)(nil) - -type GroupMemberGorm struct { - *MetaDB -} - -func NewGroupMemberDB(db *gorm.DB) relation.GroupMemberModelInterface { - return &GroupMemberGorm{NewMetaDB(db, &relation.GroupMemberModel{})} -} - -func (g *GroupMemberGorm) NewTx(tx any) relation.GroupMemberModelInterface { - return &GroupMemberGorm{NewMetaDB(tx.(*gorm.DB), &relation.GroupMemberModel{})} -} - -func (g *GroupMemberGorm) Create(ctx context.Context, groupMemberList []*relation.GroupMemberModel) (err error) { - return utils.Wrap(g.db(ctx).Create(&groupMemberList).Error, "") -} - -func (g *GroupMemberGorm) Delete(ctx context.Context, groupID string, userIDs []string) (err error) { - return utils.Wrap( - g.db(ctx).Where("group_id = ? and user_id in (?)", groupID, userIDs).Delete(&relation.GroupMemberModel{}).Error, - "", - ) -} - -func (g *GroupMemberGorm) DeleteGroup(ctx context.Context, groupIDs []string) (err error) { - return utils.Wrap(g.db(ctx).Where("group_id in (?)", groupIDs).Delete(&relation.GroupMemberModel{}).Error, "") -} - -func (g *GroupMemberGorm) Update(ctx context.Context, groupID string, userID string, data map[string]any) (err error) { - return utils.Wrap(g.db(ctx).Where("group_id = ? and user_id = ?", groupID, userID).Updates(data).Error, "") -} - -func (g *GroupMemberGorm) UpdateRoleLevel( - ctx context.Context, - groupID string, - userID string, - roleLevel int32, -) (rowsAffected int64, err error) { - db := g.db(ctx).Where("group_id = ? and user_id = ?", groupID, userID).Updates(map[string]any{ - "role_level": roleLevel, - }) - return db.RowsAffected, utils.Wrap(db.Error, "") -} - -func (g *GroupMemberGorm) Find( - ctx context.Context, - groupIDs []string, - userIDs []string, - roleLevels []int32, -) (groupMembers []*relation.GroupMemberModel, err error) { - db := g.db(ctx) - if len(groupIDs) > 0 { - db = db.Where("group_id in (?)", groupIDs) - } - if len(userIDs) > 0 { - db = db.Where("user_id in (?)", userIDs) - } - if len(roleLevels) > 0 { - db = db.Where("role_level in (?)", roleLevels) - } - return groupMembers, utils.Wrap(db.Find(&groupMembers).Error, "") -} - -func (g *GroupMemberGorm) Take( - ctx context.Context, - groupID string, - userID string, -) (groupMember *relation.GroupMemberModel, err error) { - groupMember = &relation.GroupMemberModel{} - return groupMember, utils.Wrap( - g.db(ctx).Where("group_id = ? and user_id = ?", groupID, userID).Take(groupMember).Error, - "", - ) -} - -func (g *GroupMemberGorm) TakeOwner( - ctx context.Context, - groupID string, -) (groupMember *relation.GroupMemberModel, err error) { - groupMember = &relation.GroupMemberModel{} - return groupMember, utils.Wrap( - g.db(ctx).Where("group_id = ? and role_level = ?", groupID, constant.GroupOwner).Take(groupMember).Error, - "", - ) -} - -func (g *GroupMemberGorm) SearchMember( - ctx context.Context, - keyword string, - groupIDs []string, - userIDs []string, - roleLevels []int32, - pageNumber, showNumber int32, -) (total uint32, groupList []*relation.GroupMemberModel, err error) { - db := g.db(ctx) - ormutil.GormIn(&db, "group_id", groupIDs) - ormutil.GormIn(&db, "user_id", userIDs) - ormutil.GormIn(&db, "role_level", roleLevels) - return ormutil.GormSearch[relation.GroupMemberModel](db, []string{"nickname"}, keyword, pageNumber, showNumber) -} - -func (g *GroupMemberGorm) MapGroupMemberNum( - ctx context.Context, - groupIDs []string, -) (count map[string]uint32, err error) { - return ormutil.MapCount(g.db(ctx).Where("group_id in (?)", groupIDs), "group_id") -} - -func (g *GroupMemberGorm) FindJoinUserID( - ctx context.Context, - groupIDs []string, -) (groupUsers map[string][]string, err error) { - var groupMembers []*relation.GroupMemberModel - if err := g.db(ctx).Select("group_id, user_id").Where("group_id in (?)", groupIDs).Find(&groupMembers).Error; err != nil { - return nil, utils.Wrap(err, "") - } - groupUsers = make(map[string][]string) - for _, item := range groupMembers { - v, ok := groupUsers[item.GroupID] - if !ok { - groupUsers[item.GroupID] = []string{item.UserID} - } else { - groupUsers[item.GroupID] = append(v, item.UserID) - } - } - return groupUsers, nil -} - -func (g *GroupMemberGorm) FindMemberUserID(ctx context.Context, groupID string) (userIDs []string, err error) { - return userIDs, utils.Wrap(g.db(ctx).Where("group_id = ?", groupID).Pluck("user_id", &userIDs).Error, "") -} - -func (g *GroupMemberGorm) FindUserJoinedGroupID(ctx context.Context, userID string) (groupIDs []string, err error) { - return groupIDs, utils.Wrap(g.db(ctx).Where("user_id = ?", userID).Pluck("group_id", &groupIDs).Error, "") -} - -func (g *GroupMemberGorm) TakeGroupMemberNum(ctx context.Context, groupID string) (count int64, err error) { - return count, utils.Wrap(g.db(ctx).Where("group_id = ?", groupID).Count(&count).Error, "") -} - -func (g *GroupMemberGorm) FindUsersJoinedGroupID(ctx context.Context, userIDs []string) (map[string][]string, error) { - var groupMembers []*relation.GroupMemberModel - err := g.db(ctx).Select("group_id, user_id").Where("user_id IN (?)", userIDs).Find(&groupMembers).Error - if err != nil { - return nil, err - } - result := make(map[string][]string) - for _, groupMember := range groupMembers { - v, ok := result[groupMember.UserID] - if !ok { - result[groupMember.UserID] = []string{groupMember.GroupID} - } else { - result[groupMember.UserID] = append(v, groupMember.GroupID) - } - } - return result, nil -} - -func (g *GroupMemberGorm) FindUserManagedGroupID(ctx context.Context, userID string) (groupIDs []string, err error) { - return groupIDs, utils.Wrap( - g.db(ctx). - Model(&relation.GroupMemberModel{}). - Where("user_id = ? and (role_level = ? or role_level = ?)", userID, constant.GroupOwner, constant.GroupAdmin). - Pluck("group_id", &groupIDs). - Error, - "", - ) -} +// +//import ( +// "context" +// +// "gorm.io/gorm" +// +// "github.com/OpenIMSDK/protocol/constant" +// "github.com/OpenIMSDK/tools/ormutil" +// "github.com/OpenIMSDK/tools/utils" +// +// "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" +//) +// +//var _ relation.GroupMemberModelInterface = (*GroupMemberGorm)(nil) +// +//type GroupMemberGorm struct { +// *MetaDB +//} +// +//func NewGroupMemberDB(db *gorm.DB) relation.GroupMemberModelInterface { +// return &GroupMemberGorm{NewMetaDB(db, &relation.GroupMemberModel{})} +//} +// +//func (g *GroupMemberGorm) NewTx(tx any) relation.GroupMemberModelInterface { +// return &GroupMemberGorm{NewMetaDB(tx.(*gorm.DB), &relation.GroupMemberModel{})} +//} +// +//func (g *GroupMemberGorm) Create(ctx context.Context, groupMemberList []*relation.GroupMemberModel) (err error) { +// return utils.Wrap(g.db(ctx).Create(&groupMemberList).Error, "") +//} +// +//func (g *GroupMemberGorm) Delete(ctx context.Context, groupID string, userIDs []string) (err error) { +// return utils.Wrap( +// g.db(ctx).Where("group_id = ? and user_id in (?)", groupID, userIDs).Delete(&relation.GroupMemberModel{}).Error, +// "", +// ) +//} +// +//func (g *GroupMemberGorm) DeleteGroup(ctx context.Context, groupIDs []string) (err error) { +// return utils.Wrap(g.db(ctx).Where("group_id in (?)", groupIDs).Delete(&relation.GroupMemberModel{}).Error, "") +//} +// +//func (g *GroupMemberGorm) Update(ctx context.Context, groupID string, userID string, data map[string]any) (err error) { +// return utils.Wrap(g.db(ctx).Where("group_id = ? and user_id = ?", groupID, userID).Updates(data).Error, "") +//} +// +//func (g *GroupMemberGorm) UpdateRoleLevel( +// ctx context.Context, +// groupID string, +// userID string, +// roleLevel int32, +//) (rowsAffected int64, err error) { +// db := g.db(ctx).Where("group_id = ? and user_id = ?", groupID, userID).Updates(map[string]any{ +// "role_level": roleLevel, +// }) +// return db.RowsAffected, utils.Wrap(db.Error, "") +//} +// +//func (g *GroupMemberGorm) Find( +// ctx context.Context, +// groupIDs []string, +// userIDs []string, +// roleLevels []int32, +//) (groupMembers []*relation.GroupMemberModel, err error) { +// db := g.db(ctx) +// if len(groupIDs) > 0 { +// db = db.Where("group_id in (?)", groupIDs) +// } +// if len(userIDs) > 0 { +// db = db.Where("user_id in (?)", userIDs) +// } +// if len(roleLevels) > 0 { +// db = db.Where("role_level in (?)", roleLevels) +// } +// return groupMembers, utils.Wrap(db.Find(&groupMembers).Error, "") +//} +// +//func (g *GroupMemberGorm) Take( +// ctx context.Context, +// groupID string, +// userID string, +//) (groupMember *relation.GroupMemberModel, err error) { +// groupMember = &relation.GroupMemberModel{} +// return groupMember, utils.Wrap( +// g.db(ctx).Where("group_id = ? and user_id = ?", groupID, userID).Take(groupMember).Error, +// "", +// ) +//} +// +//func (g *GroupMemberGorm) TakeOwner( +// ctx context.Context, +// groupID string, +//) (groupMember *relation.GroupMemberModel, err error) { +// groupMember = &relation.GroupMemberModel{} +// return groupMember, utils.Wrap( +// g.db(ctx).Where("group_id = ? and role_level = ?", groupID, constant.GroupOwner).Take(groupMember).Error, +// "", +// ) +//} +// +//func (g *GroupMemberGorm) SearchMember( +// ctx context.Context, +// keyword string, +// groupIDs []string, +// userIDs []string, +// roleLevels []int32, +// pageNumber, showNumber int32, +//) (total uint32, groupList []*relation.GroupMemberModel, err error) { +// db := g.db(ctx) +// ormutil.GormIn(&db, "group_id", groupIDs) +// ormutil.GormIn(&db, "user_id", userIDs) +// ormutil.GormIn(&db, "role_level", roleLevels) +// return ormutil.GormSearch[relation.GroupMemberModel](db, []string{"nickname"}, keyword, pageNumber, showNumber) +//} +// +//func (g *GroupMemberGorm) MapGroupMemberNum( +// ctx context.Context, +// groupIDs []string, +//) (count map[string]uint32, err error) { +// return ormutil.MapCount(g.db(ctx).Where("group_id in (?)", groupIDs), "group_id") +//} +// +//func (g *GroupMemberGorm) FindJoinUserID( +// ctx context.Context, +// groupIDs []string, +//) (groupUsers map[string][]string, err error) { +// var groupMembers []*relation.GroupMemberModel +// if err := g.db(ctx).Select("group_id, user_id").Where("group_id in (?)", groupIDs).Find(&groupMembers).Error; err != nil { +// return nil, utils.Wrap(err, "") +// } +// groupUsers = make(map[string][]string) +// for _, item := range groupMembers { +// v, ok := groupUsers[item.GroupID] +// if !ok { +// groupUsers[item.GroupID] = []string{item.UserID} +// } else { +// groupUsers[item.GroupID] = append(v, item.UserID) +// } +// } +// return groupUsers, nil +//} +// +//func (g *GroupMemberGorm) FindMemberUserID(ctx context.Context, groupID string) (userIDs []string, err error) { +// return userIDs, utils.Wrap(g.db(ctx).Where("group_id = ?", groupID).Pluck("user_id", &userIDs).Error, "") +//} +// +//func (g *GroupMemberGorm) FindUserJoinedGroupID(ctx context.Context, userID string) (groupIDs []string, err error) { +// return groupIDs, utils.Wrap(g.db(ctx).Where("user_id = ?", userID).Pluck("group_id", &groupIDs).Error, "") +//} +// +//func (g *GroupMemberGorm) TakeGroupMemberNum(ctx context.Context, groupID string) (count int64, err error) { +// return count, utils.Wrap(g.db(ctx).Where("group_id = ?", groupID).Count(&count).Error, "") +//} +// +//func (g *GroupMemberGorm) FindUsersJoinedGroupID(ctx context.Context, userIDs []string) (map[string][]string, error) { +// var groupMembers []*relation.GroupMemberModel +// err := g.db(ctx).Select("group_id, user_id").Where("user_id IN (?)", userIDs).Find(&groupMembers).Error +// if err != nil { +// return nil, err +// } +// result := make(map[string][]string) +// for _, groupMember := range groupMembers { +// v, ok := result[groupMember.UserID] +// if !ok { +// result[groupMember.UserID] = []string{groupMember.GroupID} +// } else { +// result[groupMember.UserID] = append(v, groupMember.GroupID) +// } +// } +// return result, nil +//} +// +//func (g *GroupMemberGorm) FindUserManagedGroupID(ctx context.Context, userID string) (groupIDs []string, err error) { +// return groupIDs, utils.Wrap( +// g.db(ctx). +// Model(&relation.GroupMemberModel{}). +// Where("user_id = ? and (role_level = ? or role_level = ?)", userID, constant.GroupOwner, constant.GroupAdmin). +// Pluck("group_id", &groupIDs). +// Error, +// "", +// ) +//} diff --git a/pkg/common/db/relation/group_model.go b/pkg/common/db/relation/group_model.go index 7a8eee9f0..1b07a4072 100644 --- a/pkg/common/db/relation/group_model.go +++ b/pkg/common/db/relation/group_model.go @@ -14,93 +14,93 @@ package relation -import ( - "context" - "time" - - "github.com/OpenIMSDK/protocol/constant" - - "gorm.io/gorm" - - "github.com/OpenIMSDK/tools/errs" - "github.com/OpenIMSDK/tools/ormutil" - "github.com/OpenIMSDK/tools/utils" - - "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" -) - -var _ relation.GroupModelInterface = (*GroupGorm)(nil) - -type GroupGorm struct { - *MetaDB -} - -func NewGroupDB(db *gorm.DB) relation.GroupModelInterface { - return &GroupGorm{NewMetaDB(db, &relation.GroupModel{})} -} - -func (g *GroupGorm) NewTx(tx any) relation.GroupModelInterface { - return &GroupGorm{NewMetaDB(tx.(*gorm.DB), &relation.GroupModel{})} -} - -func (g *GroupGorm) Create(ctx context.Context, groups []*relation.GroupModel) (err error) { - return utils.Wrap(g.DB.Create(&groups).Error, "") -} - -func (g *GroupGorm) UpdateMap(ctx context.Context, groupID string, args map[string]interface{}) (err error) { - return utils.Wrap(g.DB.Where("group_id = ?", groupID).Model(&relation.GroupModel{}).Updates(args).Error, "") -} - -func (g *GroupGorm) UpdateStatus(ctx context.Context, groupID string, status int32) (err error) { - return utils.Wrap(g.DB.Where("group_id = ?", groupID).Model(&relation.GroupModel{}).Updates(map[string]any{"status": status}).Error, "") -} - -func (g *GroupGorm) Find(ctx context.Context, groupIDs []string) (groups []*relation.GroupModel, err error) { - return groups, utils.Wrap(g.DB.Where("group_id in (?)", groupIDs).Find(&groups).Error, "") -} - -func (g *GroupGorm) Take(ctx context.Context, groupID string) (group *relation.GroupModel, err error) { - group = &relation.GroupModel{} - return group, utils.Wrap(g.DB.Where("group_id = ?", groupID).Take(group).Error, "") -} - -func (g *GroupGorm) Search(ctx context.Context, keyword string, pageNumber, showNumber int32) (total uint32, groups []*relation.GroupModel, err error) { - db := g.DB - db = db.WithContext(ctx).Where("status!=?", constant.GroupStatusDismissed) - return ormutil.GormSearch[relation.GroupModel](db, []string{"name"}, keyword, pageNumber, showNumber) -} - -func (g *GroupGorm) GetGroupIDsByGroupType(ctx context.Context, groupType int) (groupIDs []string, err error) { - return groupIDs, utils.Wrap(g.DB.Model(&relation.GroupModel{}).Where("group_type = ? ", groupType).Pluck("group_id", &groupIDs).Error, "") -} - -func (g *GroupGorm) CountTotal(ctx context.Context, before *time.Time) (count int64, err error) { - db := g.db(ctx).Model(&relation.GroupModel{}) - if before != nil { - db = db.Where("create_time < ?", before) - } - if err := db.Count(&count).Error; err != nil { - return 0, err - } - return count, nil -} - -func (g *GroupGorm) CountRangeEverydayTotal(ctx context.Context, start time.Time, end time.Time) (map[string]int64, error) { - var res []struct { - Date time.Time `gorm:"column:date"` - Count int64 `gorm:"column:count"` - } - err := g.db(ctx).Model(&relation.GroupModel{}).Select("DATE(create_time) AS date, count(1) AS count").Where("create_time >= ? and create_time < ?", start, end).Group("date").Find(&res).Error - if err != nil { - return nil, errs.Wrap(err) - } - v := make(map[string]int64) - for _, r := range res { - v[r.Date.Format("2006-01-02")] = r.Count - } - return v, nil -} - -func (g *GroupGorm) FindNotDismissedGroup(ctx context.Context, groupIDs []string) (groups []*relation.GroupModel, err error) { - return groups, utils.Wrap(g.DB.Where("group_id in (?) and status != ?", groupIDs, constant.GroupStatusDismissed).Find(&groups).Error, "") -} +//import ( +// "context" +// "time" +// +// "github.com/OpenIMSDK/protocol/constant" +// +// "gorm.io/gorm" +// +// "github.com/OpenIMSDK/tools/errs" +// "github.com/OpenIMSDK/tools/ormutil" +// "github.com/OpenIMSDK/tools/utils" +// +// "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" +//) +// +//var _ relation.GroupModelInterface = (*GroupGorm)(nil) +// +//type GroupGorm struct { +// *MetaDB +//} +// +//func NewGroupDB(db *gorm.DB) relation.GroupModelInterface { +// return &GroupGorm{NewMetaDB(db, &relation.GroupModel{})} +//} +// +//func (g *GroupGorm) NewTx(tx any) relation.GroupModelInterface { +// return &GroupGorm{NewMetaDB(tx.(*gorm.DB), &relation.GroupModel{})} +//} +// +//func (g *GroupGorm) Create(ctx context.Context, groups []*relation.GroupModel) (err error) { +// return utils.Wrap(g.DB.Create(&groups).Error, "") +//} +// +//func (g *GroupGorm) UpdateMap(ctx context.Context, groupID string, args map[string]any) (err error) { +// return utils.Wrap(g.DB.Where("group_id = ?", groupID).Model(&relation.GroupModel{}).Updates(args).Error, "") +//} +// +//func (g *GroupGorm) UpdateStatus(ctx context.Context, groupID string, status int32) (err error) { +// return utils.Wrap(g.DB.Where("group_id = ?", groupID).Model(&relation.GroupModel{}).Updates(map[string]any{"status": status}).Error, "") +//} +// +//func (g *GroupGorm) Find(ctx context.Context, groupIDs []string) (groups []*relation.GroupModel, err error) { +// return groups, utils.Wrap(g.DB.Where("group_id in (?)", groupIDs).Find(&groups).Error, "") +//} +// +//func (g *GroupGorm) Take(ctx context.Context, groupID string) (group *relation.GroupModel, err error) { +// group = &relation.GroupModel{} +// return group, utils.Wrap(g.DB.Where("group_id = ?", groupID).Take(group).Error, "") +//} +// +//func (g *GroupGorm) Search(ctx context.Context, keyword string, pageNumber, showNumber int32) (total uint32, groups []*relation.GroupModel, err error) { +// db := g.DB +// db = db.WithContext(ctx).Where("status!=?", constant.GroupStatusDismissed) +// return ormutil.GormSearch[relation.GroupModel](db, []string{"name"}, keyword, pageNumber, showNumber) +//} +// +//func (g *GroupGorm) GetGroupIDsByGroupType(ctx context.Context, groupType int) (groupIDs []string, err error) { +// return groupIDs, utils.Wrap(g.DB.Model(&relation.GroupModel{}).Where("group_type = ? ", groupType).Pluck("group_id", &groupIDs).Error, "") +//} +// +//func (g *GroupGorm) CountTotal(ctx context.Context, before *time.Time) (count int64, err error) { +// db := g.db(ctx).Model(&relation.GroupModel{}) +// if before != nil { +// db = db.Where("create_time < ?", before) +// } +// if err := db.Count(&count).Error; err != nil { +// return 0, err +// } +// return count, nil +//} +// +//func (g *GroupGorm) CountRangeEverydayTotal(ctx context.Context, start time.Time, end time.Time) (map[string]int64, error) { +// var res []struct { +// Date time.Time `gorm:"column:date"` +// Count int64 `gorm:"column:count"` +// } +// err := g.db(ctx).Model(&relation.GroupModel{}).Select("DATE(create_time) AS date, count(1) AS count").Where("create_time >= ? and create_time < ?", start, end).Group("date").Find(&res).Error +// if err != nil { +// return nil, errs.Wrap(err) +// } +// v := make(map[string]int64) +// for _, r := range res { +// v[r.Date.Format("2006-01-02")] = r.Count +// } +// return v, nil +//} +// +//func (g *GroupGorm) FindNotDismissedGroup(ctx context.Context, groupIDs []string) (groups []*relation.GroupModel, err error) { +// return groups, utils.Wrap(g.DB.Where("group_id in (?) and status != ?", groupIDs, constant.GroupStatusDismissed).Find(&groups).Error, "") +//} diff --git a/pkg/common/db/relation/group_request_model.go b/pkg/common/db/relation/group_request_model.go index af3f277e8..aa601aaba 100644 --- a/pkg/common/db/relation/group_request_model.go +++ b/pkg/common/db/relation/group_request_model.go @@ -14,105 +14,106 @@ package relation -import ( - "context" - - "github.com/OpenIMSDK/tools/ormutil" - - "gorm.io/gorm" - - "github.com/OpenIMSDK/tools/utils" - - "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" -) - -type GroupRequestGorm struct { - *MetaDB -} - -func NewGroupRequest(db *gorm.DB) relation.GroupRequestModelInterface { - return &GroupRequestGorm{ - NewMetaDB(db, &relation.GroupRequestModel{}), - } -} - -func (g *GroupRequestGorm) NewTx(tx any) relation.GroupRequestModelInterface { - return &GroupRequestGorm{NewMetaDB(tx.(*gorm.DB), &relation.GroupRequestModel{})} -} - -func (g *GroupRequestGorm) Create(ctx context.Context, groupRequests []*relation.GroupRequestModel) (err error) { - return utils.Wrap(g.DB.WithContext(ctx).Create(&groupRequests).Error, utils.GetSelfFuncName()) -} - -func (g *GroupRequestGorm) Delete(ctx context.Context, groupID string, userID string) (err error) { - return utils.Wrap( - g.DB.WithContext(ctx). - Where("group_id = ? and user_id = ? ", groupID, userID). - Delete(&relation.GroupRequestModel{}). - Error, - utils.GetSelfFuncName(), - ) -} - -func (g *GroupRequestGorm) UpdateHandler( - ctx context.Context, - groupID string, - userID string, - handledMsg string, - handleResult int32, -) (err error) { - return utils.Wrap( - g.DB.WithContext(ctx). - Model(&relation.GroupRequestModel{}). - Where("group_id = ? and user_id = ? ", groupID, userID). - Updates(map[string]any{ - "handle_msg": handledMsg, - "handle_result": handleResult, - }). - Error, - utils.GetSelfFuncName(), - ) -} - -func (g *GroupRequestGorm) Take( - ctx context.Context, - groupID string, - userID string, -) (groupRequest *relation.GroupRequestModel, err error) { - groupRequest = &relation.GroupRequestModel{} - return groupRequest, utils.Wrap( - g.DB.WithContext(ctx).Where("group_id = ? and user_id = ? ", groupID, userID).Take(groupRequest).Error, - utils.GetSelfFuncName(), - ) -} - -func (g *GroupRequestGorm) Page( - ctx context.Context, - userID string, - pageNumber, showNumber int32, -) (total uint32, groups []*relation.GroupRequestModel, err error) { - return ormutil.GormSearch[relation.GroupRequestModel]( - g.DB.WithContext(ctx).Where("user_id = ?", userID), - nil, - "", - pageNumber, - showNumber, - ) -} - -func (g *GroupRequestGorm) PageGroup( - ctx context.Context, - groupIDs []string, - pageNumber, showNumber int32, -) (total uint32, groups []*relation.GroupRequestModel, err error) { - return ormutil.GormPage[relation.GroupRequestModel]( - g.DB.WithContext(ctx).Where("group_id in ?", groupIDs), - pageNumber, - showNumber, - ) -} - -func (g *GroupRequestGorm) FindGroupRequests(ctx context.Context, groupID string, userIDs []string) (total int64, groupRequests []*relation.GroupRequestModel, err error) { - err = g.DB.WithContext(ctx).Where("group_id = ? and user_id in ?", groupID, userIDs).Find(&groupRequests).Error - return int64(len(groupRequests)), groupRequests, utils.Wrap(err, utils.GetSelfFuncName()) -} +// +//import ( +// "context" +// +// "github.com/OpenIMSDK/tools/ormutil" +// +// "gorm.io/gorm" +// +// "github.com/OpenIMSDK/tools/utils" +// +// "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" +//) +// +//type GroupRequestGorm struct { +// *MetaDB +//} +// +//func NewGroupRequest(db *gorm.DB) relation.GroupRequestModelInterface { +// return &GroupRequestGorm{ +// NewMetaDB(db, &relation.GroupRequestModel{}), +// } +//} +// +//func (g *GroupRequestGorm) NewTx(tx any) relation.GroupRequestModelInterface { +// return &GroupRequestGorm{NewMetaDB(tx.(*gorm.DB), &relation.GroupRequestModel{})} +//} +// +//func (g *GroupRequestGorm) Create(ctx context.Context, groupRequests []*relation.GroupRequestModel) (err error) { +// return utils.Wrap(g.DB.WithContext(ctx).Create(&groupRequests).Error, utils.GetSelfFuncName()) +//} +// +//func (g *GroupRequestGorm) Delete(ctx context.Context, groupID string, userID string) (err error) { +// return utils.Wrap( +// g.DB.WithContext(ctx). +// Where("group_id = ? and user_id = ? ", groupID, userID). +// Delete(&relation.GroupRequestModel{}). +// Error, +// utils.GetSelfFuncName(), +// ) +//} +// +//func (g *GroupRequestGorm) UpdateHandler( +// ctx context.Context, +// groupID string, +// userID string, +// handledMsg string, +// handleResult int32, +//) (err error) { +// return utils.Wrap( +// g.DB.WithContext(ctx). +// Model(&relation.GroupRequestModel{}). +// Where("group_id = ? and user_id = ? ", groupID, userID). +// Updates(map[string]any{ +// "handle_msg": handledMsg, +// "handle_result": handleResult, +// }). +// Error, +// utils.GetSelfFuncName(), +// ) +//} +// +//func (g *GroupRequestGorm) Take( +// ctx context.Context, +// groupID string, +// userID string, +//) (groupRequest *relation.GroupRequestModel, err error) { +// groupRequest = &relation.GroupRequestModel{} +// return groupRequest, utils.Wrap( +// g.DB.WithContext(ctx).Where("group_id = ? and user_id = ? ", groupID, userID).Take(groupRequest).Error, +// utils.GetSelfFuncName(), +// ) +//} +// +//func (g *GroupRequestGorm) Page( +// ctx context.Context, +// userID string, +// pageNumber, showNumber int32, +//) (total uint32, groups []*relation.GroupRequestModel, err error) { +// return ormutil.GormSearch[relation.GroupRequestModel]( +// g.DB.WithContext(ctx).Where("user_id = ?", userID), +// nil, +// "", +// pageNumber, +// showNumber, +// ) +//} +// +//func (g *GroupRequestGorm) PageGroup( +// ctx context.Context, +// groupIDs []string, +// pageNumber, showNumber int32, +//) (total uint32, groups []*relation.GroupRequestModel, err error) { +// return ormutil.GormPage[relation.GroupRequestModel]( +// g.DB.WithContext(ctx).Where("group_id in ?", groupIDs), +// pageNumber, +// showNumber, +// ) +//} +// +//func (g *GroupRequestGorm) FindGroupRequests(ctx context.Context, groupID string, userIDs []string) (total int64, groupRequests []*relation.GroupRequestModel, err error) { +// err = g.DB.WithContext(ctx).Where("group_id = ? and user_id in ?", groupID, userIDs).Find(&groupRequests).Error +// return int64(len(groupRequests)), groupRequests, utils.Wrap(err, utils.GetSelfFuncName()) +//} diff --git a/pkg/common/db/relation/log_model.go b/pkg/common/db/relation/log_model.go index 53365ca5b..f5d8a9fae 100644 --- a/pkg/common/db/relation/log_model.go +++ b/pkg/common/db/relation/log_model.go @@ -1,49 +1,49 @@ package relation -import ( - "context" - "time" - - "github.com/OpenIMSDK/tools/errs" - "github.com/OpenIMSDK/tools/ormutil" - "gorm.io/gorm" - - relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" -) - -type LogGorm struct { - db *gorm.DB -} - -func (l *LogGorm) Create(ctx context.Context, log []*relationtb.Log) error { - return errs.Wrap(l.db.WithContext(ctx).Create(log).Error) -} - -func (l *LogGorm) Search(ctx context.Context, keyword string, start time.Time, end time.Time, pageNumber int32, showNumber int32) (uint32, []*relationtb.Log, error) { - db := l.db.WithContext(ctx).Where("create_time >= ?", start) - if end.UnixMilli() != 0 { - db = l.db.WithContext(ctx).Where("create_time <= ?", end) - } - db = db.Order("create_time desc") - return ormutil.GormSearch[relationtb.Log](db, []string{"user_id"}, keyword, pageNumber, showNumber) -} - -func (l *LogGorm) Delete(ctx context.Context, logIDs []string, userID string) error { - if userID == "" { - return errs.Wrap(l.db.WithContext(ctx).Where("log_id in ?", logIDs).Delete(&relationtb.Log{}).Error) - } - return errs.Wrap(l.db.WithContext(ctx).Where("log_id in ? and user_id=?", logIDs, userID).Delete(&relationtb.Log{}).Error) -} - -func (l *LogGorm) Get(ctx context.Context, logIDs []string, userID string) ([]*relationtb.Log, error) { - var logs []*relationtb.Log - if userID == "" { - return logs, errs.Wrap(l.db.WithContext(ctx).Where("log_id in ?", logIDs).Find(&logs).Error) - } - return logs, errs.Wrap(l.db.WithContext(ctx).Where("log_id in ? and user_id=?", logIDs, userID).Find(&logs).Error) -} - -func NewLogGorm(db *gorm.DB) relationtb.LogInterface { - db.AutoMigrate(&relationtb.Log{}) - return &LogGorm{db: db} -} +//import ( +// "context" +// "time" +// +// "github.com/OpenIMSDK/tools/errs" +// "github.com/OpenIMSDK/tools/ormutil" +// "gorm.io/gorm" +// +// relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" +//) +// +//type LogGorm struct { +// db *gorm.DB +//} +// +//func (l *LogGorm) Create(ctx context.Context, log []*relationtb.Log) error { +// return errs.Wrap(l.db.WithContext(ctx).Create(log).Error) +//} +// +//func (l *LogGorm) Search(ctx context.Context, keyword string, start time.Time, end time.Time, pageNumber int32, showNumber int32) (uint32, []*relationtb.Log, error) { +// db := l.db.WithContext(ctx).Where("create_time >= ?", start) +// if end.UnixMilli() != 0 { +// db = l.db.WithContext(ctx).Where("create_time <= ?", end) +// } +// db = db.Order("create_time desc") +// return ormutil.GormSearch[relationtb.Log](db, []string{"user_id"}, keyword, pageNumber, showNumber) +//} +// +//func (l *LogGorm) Delete(ctx context.Context, logIDs []string, userID string) error { +// if userID == "" { +// return errs.Wrap(l.db.WithContext(ctx).Where("log_id in ?", logIDs).Delete(&relationtb.Log{}).Error) +// } +// return errs.Wrap(l.db.WithContext(ctx).Where("log_id in ? and user_id=?", logIDs, userID).Delete(&relationtb.Log{}).Error) +//} +// +//func (l *LogGorm) Get(ctx context.Context, logIDs []string, userID string) ([]*relationtb.Log, error) { +// var logs []*relationtb.Log +// if userID == "" { +// return logs, errs.Wrap(l.db.WithContext(ctx).Where("log_id in ?", logIDs).Find(&logs).Error) +// } +// return logs, errs.Wrap(l.db.WithContext(ctx).Where("log_id in ? and user_id=?", logIDs, userID).Find(&logs).Error) +//} +// +//func NewLogGorm(db *gorm.DB) relationtb.LogInterface { +// db.AutoMigrate(&relationtb.Log{}) +// return &LogGorm{db: db} +//} diff --git a/pkg/common/db/relation/object_model.go b/pkg/common/db/relation/object_model.go index c5624a8d4..67b59969b 100644 --- a/pkg/common/db/relation/object_model.go +++ b/pkg/common/db/relation/object_model.go @@ -14,40 +14,41 @@ package relation -import ( - "context" - - "gorm.io/gorm" - - "github.com/OpenIMSDK/tools/errs" - - "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" -) - -type ObjectInfoGorm struct { - *MetaDB -} - -func NewObjectInfo(db *gorm.DB) relation.ObjectInfoModelInterface { - return &ObjectInfoGorm{ - NewMetaDB(db, &relation.ObjectModel{}), - } -} - -func (o *ObjectInfoGorm) NewTx(tx any) relation.ObjectInfoModelInterface { - return &ObjectInfoGorm{ - NewMetaDB(tx.(*gorm.DB), &relation.ObjectModel{}), - } -} - -func (o *ObjectInfoGorm) SetObject(ctx context.Context, obj *relation.ObjectModel) (err error) { - if err := o.DB.WithContext(ctx).Where("name = ?", obj.Name).FirstOrCreate(obj).Error; err != nil { - return errs.Wrap(err) - } - return nil -} - -func (o *ObjectInfoGorm) Take(ctx context.Context, name string) (info *relation.ObjectModel, err error) { - info = &relation.ObjectModel{} - return info, errs.Wrap(o.DB.WithContext(ctx).Where("name = ?", name).Take(info).Error) -} +// +//import ( +// "context" +// +// "gorm.io/gorm" +// +// "github.com/OpenIMSDK/tools/errs" +// +// "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" +//) +// +//type ObjectInfoGorm struct { +// *MetaDB +//} +// +//func NewObjectInfo(db *gorm.DB) relation.ObjectInfoModelInterface { +// return &ObjectInfoGorm{ +// NewMetaDB(db, &relation.ObjectModel{}), +// } +//} +// +//func (o *ObjectInfoGorm) NewTx(tx any) relation.ObjectInfoModelInterface { +// return &ObjectInfoGorm{ +// NewMetaDB(tx.(*gorm.DB), &relation.ObjectModel{}), +// } +//} +// +//func (o *ObjectInfoGorm) SetObject(ctx context.Context, obj *relation.ObjectModel) (err error) { +// if err := o.DB.WithContext(ctx).Where("name = ?", obj.Name).FirstOrCreate(obj).Error; err != nil { +// return errs.Wrap(err) +// } +// return nil +//} +// +//func (o *ObjectInfoGorm) Take(ctx context.Context, name string) (info *relation.ObjectModel, err error) { +// info = &relation.ObjectModel{} +// return info, errs.Wrap(o.DB.WithContext(ctx).Where("name = ?", name).Take(info).Error) +//} diff --git a/pkg/common/db/relation/user_model.go b/pkg/common/db/relation/user_model.go index b04c29816..100bfcf13 100644 --- a/pkg/common/db/relation/user_model.go +++ b/pkg/common/db/relation/user_model.go @@ -14,123 +14,125 @@ package relation -import ( - "context" - "time" - - "github.com/OpenIMSDK/tools/errs" - - "gorm.io/gorm" - - "github.com/OpenIMSDK/tools/utils" - - "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" -) - -type UserGorm struct { - *MetaDB -} - -func NewUserGorm(db *gorm.DB) relation.UserModelInterface { - return &UserGorm{NewMetaDB(db, &relation.UserModel{})} -} - -// 插入多条. -func (u *UserGorm) Create(ctx context.Context, users []*relation.UserModel) (err error) { - return utils.Wrap(u.db(ctx).Create(&users).Error, "") -} - -// 更新用户信息 零值. -func (u *UserGorm) UpdateByMap(ctx context.Context, userID string, args map[string]interface{}) (err error) { - return utils.Wrap(u.db(ctx).Model(&relation.UserModel{}).Where("user_id = ?", userID).Updates(args).Error, "") -} - -// 更新多个用户信息 非零值. -func (u *UserGorm) Update(ctx context.Context, user *relation.UserModel) (err error) { - return utils.Wrap(u.db(ctx).Model(user).Updates(user).Error, "") -} - -// 获取指定用户信息 不存在,也不返回错误. -func (u *UserGorm) Find(ctx context.Context, userIDs []string) (users []*relation.UserModel, err error) { - err = utils.Wrap(u.db(ctx).Where("user_id in (?)", userIDs).Find(&users).Error, "") - return users, err -} - -// 获取某个用户信息 不存在,则返回错误. -func (u *UserGorm) Take(ctx context.Context, userID string) (user *relation.UserModel, err error) { - user = &relation.UserModel{} - err = utils.Wrap(u.db(ctx).Where("user_id = ?", userID).Take(&user).Error, "") - return user, err -} - -// 获取用户信息 不存在,不返回错误. -func (u *UserGorm) Page( - ctx context.Context, - pageNumber, showNumber int32, -) (users []*relation.UserModel, count int64, err error) { - err = utils.Wrap(u.db(ctx).Count(&count).Error, "") - if err != nil { - return - } - err = utils.Wrap( - u.db(ctx). - Limit(int(showNumber)). - Offset(int((pageNumber-1)*showNumber)). - Find(&users). - Order("create_time DESC"). - Error, - "", - ) - return -} - -// 获取所有用户ID. -func (u *UserGorm) GetAllUserID(ctx context.Context, pageNumber, showNumber int32) (userIDs []string, err error) { - if pageNumber == 0 || showNumber == 0 { - return userIDs, errs.Wrap(u.db(ctx).Pluck("user_id", &userIDs).Error) - } else { - return userIDs, errs.Wrap(u.db(ctx).Limit(int(showNumber)).Offset(int((pageNumber-1)*showNumber)).Pluck("user_id", &userIDs).Error) - } -} - -func (u *UserGorm) GetUserGlobalRecvMsgOpt(ctx context.Context, userID string) (opt int, err error) { - err = u.db(ctx).Model(&relation.UserModel{}).Where("user_id = ?", userID).Pluck("global_recv_msg_opt", &opt).Error - return opt, err -} - -func (u *UserGorm) CountTotal(ctx context.Context, before *time.Time) (count int64, err error) { - db := u.db(ctx).Model(&relation.UserModel{}) - if before != nil { - db = db.Where("create_time < ?", before) - } - if err := db.Count(&count).Error; err != nil { - return 0, err - } - return count, nil -} - -func (u *UserGorm) CountRangeEverydayTotal( - ctx context.Context, - start time.Time, - end time.Time, -) (map[string]int64, error) { - var res []struct { - Date time.Time `gorm:"column:date"` - Count int64 `gorm:"column:count"` - } - err := u.db(ctx). - Model(&relation.UserModel{}). - Select("DATE(create_time) AS date, count(1) AS count"). - Where("create_time >= ? and create_time < ?", start, end). - Group("date"). - Find(&res). - Error - if err != nil { - return nil, errs.Wrap(err) - } - v := make(map[string]int64) - for _, r := range res { - v[r.Date.Format("2006-01-02")] = r.Count - } - return v, nil -} +// +//import ( +// "context" +// "time" +// +// "github.com/OpenIMSDK/tools/errs" +// +// "gorm.io/gorm" +// +// "github.com/OpenIMSDK/tools/utils" +// +// "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" +//) +// +//type UserGorm struct { +// *MetaDB +//} +// +//func NewUserGorm(db *gorm.DB) relation.UserModelInterface { +// //return &UserGorm{NewMetaDB(db, &relation.UserModel{})} +// return nil +//} +// +//// 插入多条. +//func (u *UserGorm) Create(ctx context.Context, users []*relation.UserModel) (err error) { +// return utils.Wrap(u.db(ctx).Create(&users).Error, "") +//} +// +//// 更新用户信息 零值. +//func (u *UserGorm) UpdateByMap(ctx context.Context, userID string, args map[string]any) (err error) { +// return utils.Wrap(u.db(ctx).Model(&relation.UserModel{}).Where("user_id = ?", userID).Updates(args).Error, "") +//} +// +//// 更新多个用户信息 非零值. +//func (u *UserGorm) Update(ctx context.Context, user *relation.UserModel) (err error) { +// return utils.Wrap(u.db(ctx).Model(user).Updates(user).Error, "") +//} +// +//// 获取指定用户信息 不存在,也不返回错误. +//func (u *UserGorm) Find(ctx context.Context, userIDs []string) (users []*relation.UserModel, err error) { +// err = utils.Wrap(u.db(ctx).Where("user_id in (?)", userIDs).Find(&users).Error, "") +// return users, err +//} +// +//// 获取某个用户信息 不存在,则返回错误. +//func (u *UserGorm) Take(ctx context.Context, userID string) (user *relation.UserModel, err error) { +// user = &relation.UserModel{} +// err = utils.Wrap(u.db(ctx).Where("user_id = ?", userID).Take(&user).Error, "") +// return user, err +//} +// +//// 获取用户信息 不存在,不返回错误. +//func (u *UserGorm) Page( +// ctx context.Context, +// pageNumber, showNumber int32, +//) (users []*relation.UserModel, count int64, err error) { +// err = utils.Wrap(u.db(ctx).Count(&count).Error, "") +// if err != nil { +// return +// } +// err = utils.Wrap( +// u.db(ctx). +// Limit(int(showNumber)). +// Offset(int((pageNumber-1)*showNumber)). +// Find(&users). +// Order("create_time DESC"). +// Error, +// "", +// ) +// return +//} +// +//// 获取所有用户ID. +//func (u *UserGorm) GetAllUserID(ctx context.Context, pageNumber, showNumber int32) (userIDs []string, err error) { +// if pageNumber == 0 || showNumber == 0 { +// return userIDs, errs.Wrap(u.db(ctx).Pluck("user_id", &userIDs).Error) +// } else { +// return userIDs, errs.Wrap(u.db(ctx).Limit(int(showNumber)).Offset(int((pageNumber-1)*showNumber)).Pluck("user_id", &userIDs).Error) +// } +//} +// +//func (u *UserGorm) GetUserGlobalRecvMsgOpt(ctx context.Context, userID string) (opt int, err error) { +// err = u.db(ctx).Model(&relation.UserModel{}).Where("user_id = ?", userID).Pluck("global_recv_msg_opt", &opt).Error +// return opt, err +//} +// +//func (u *UserGorm) CountTotal(ctx context.Context, before *time.Time) (count int64, err error) { +// db := u.db(ctx).Model(&relation.UserModel{}) +// if before != nil { +// db = db.Where("create_time < ?", before) +// } +// if err := db.Count(&count).Error; err != nil { +// return 0, err +// } +// return count, nil +//} +// +//func (u *UserGorm) CountRangeEverydayTotal( +// ctx context.Context, +// start time.Time, +// end time.Time, +//) (map[string]int64, error) { +// var res []struct { +// Date time.Time `gorm:"column:date"` +// Count int64 `gorm:"column:count"` +// } +// err := u.db(ctx). +// Model(&relation.UserModel{}). +// Select("DATE(create_time) AS date, count(1) AS count"). +// Where("create_time >= ? and create_time < ?", start, end). +// Group("date"). +// Find(&res). +// Error +// if err != nil { +// return nil, errs.Wrap(err) +// } +// v := make(map[string]int64) +// for _, r := range res { +// v[r.Date.Format("2006-01-02")] = r.Count +// } +// return v, nil +//} diff --git a/pkg/common/db/s3/cont/controller.go b/pkg/common/db/s3/cont/controller.go index 7040c7306..1bf1a4b12 100644 --- a/pkg/common/db/s3/cont/controller.go +++ b/pkg/common/db/s3/cont/controller.go @@ -46,6 +46,10 @@ type Controller struct { impl s3.Interface } +func (c *Controller) Engine() string { + return c.impl.Engine() +} + func (c *Controller) HashPath(md5 string) string { return path.Join(hashPath, md5) } diff --git a/pkg/common/db/s3/cos/internal.go b/pkg/common/db/s3/cos/internal.go index 0e58a851c..02afde684 100644 --- a/pkg/common/db/s3/cos/internal.go +++ b/pkg/common/db/s3/cos/internal.go @@ -10,4 +10,4 @@ import ( ) //go:linkname newRequest github.com/tencentyun/cos-go-sdk-v5.(*Client).newRequest -func newRequest(c *cos.Client, ctx context.Context, baseURL *url.URL, uri, method string, body interface{}, optQuery interface{}, optHeader interface{}) (req *http.Request, err error) +func newRequest(c *cos.Client, ctx context.Context, baseURL *url.URL, uri, method string, body any, optQuery any, optHeader any) (req *http.Request, err error) diff --git a/pkg/common/db/s3/oss/internal.go b/pkg/common/db/s3/oss/internal.go index 4ca1acc47..155708ffd 100644 --- a/pkg/common/db/s3/oss/internal.go +++ b/pkg/common/db/s3/oss/internal.go @@ -26,7 +26,7 @@ import ( func signHeader(c oss.Conn, req *http.Request, canonicalizedResource string) //go:linkname getURLParams github.com/aliyun/aliyun-oss-go-sdk/oss.Conn.getURLParams -func getURLParams(c oss.Conn, params map[string]interface{}) string +func getURLParams(c oss.Conn, params map[string]any) string //go:linkname getURL github.com/aliyun/aliyun-oss-go-sdk/oss.urlMaker.getURL func getURL(um urlMaker, bucket, object, params string) *url.URL diff --git a/pkg/common/db/table/relation/black.go b/pkg/common/db/table/relation/black.go index 59dd12122..1697eaec6 100644 --- a/pkg/common/db/table/relation/black.go +++ b/pkg/common/db/table/relation/black.go @@ -39,7 +39,7 @@ func (BlackModel) TableName() string { type BlackModelInterface interface { Create(ctx context.Context, blacks []*BlackModel) (err error) Delete(ctx context.Context, blacks []*BlackModel) (err error) - UpdateByMap(ctx context.Context, ownerUserID, blockUserID string, args map[string]interface{}) (err error) + UpdateByMap(ctx context.Context, ownerUserID, blockUserID string, args map[string]any) (err error) Update(ctx context.Context, blacks []*BlackModel) (err error) Find(ctx context.Context, blacks []*BlackModel) (blackList []*BlackModel, err error) Take(ctx context.Context, ownerUserID, blockUserID string) (black *BlackModel, err error) diff --git a/pkg/common/db/table/relation/conversation.go b/pkg/common/db/table/relation/conversation.go index e9680873f..ffc82f244 100644 --- a/pkg/common/db/table/relation/conversation.go +++ b/pkg/common/db/table/relation/conversation.go @@ -16,6 +16,7 @@ package relation import ( "context" + "github.com/openimsdk/open-im-server/v3/pkg/common/pagination" "time" ) @@ -23,25 +24,46 @@ const ( conversationModelTableName = "conversations" ) +//type ConversationModel struct { +// OwnerUserID string `gorm:"column:owner_user_id;primary_key;type:char(128)" json:"OwnerUserID"` +// ConversationID string `gorm:"column:conversation_id;primary_key;type:char(128)" json:"conversationID"` +// ConversationType int32 `gorm:"column:conversation_type" json:"conversationType"` +// UserID string `gorm:"column:user_id;type:char(64)" json:"userID"` +// GroupID string `gorm:"column:group_id;type:char(128)" json:"groupID"` +// RecvMsgOpt int32 `gorm:"column:recv_msg_opt" json:"recvMsgOpt"` +// IsPinned bool `gorm:"column:is_pinned" json:"isPinned"` +// IsPrivateChat bool `gorm:"column:is_private_chat" json:"isPrivateChat"` +// BurnDuration int32 `gorm:"column:burn_duration;default:30" json:"burnDuration"` +// GroupAtType int32 `gorm:"column:group_at_type" json:"groupAtType"` +// AttachedInfo string `gorm:"column:attached_info;type:varchar(1024)" json:"attachedInfo"` +// Ex string `gorm:"column:ex;type:varchar(1024)" json:"ex"` +// MaxSeq int64 `gorm:"column:max_seq" json:"maxSeq"` +// MinSeq int64 `gorm:"column:min_seq" json:"minSeq"` +// CreateTime time.Time `gorm:"column:create_time;index:create_time;autoCreateTime"` +// IsMsgDestruct bool `gorm:"column:is_msg_destruct;default:false"` +// MsgDestructTime int64 `gorm:"column:msg_destruct_time;default:604800"` +// LatestMsgDestructTime time.Time `gorm:"column:latest_msg_destruct_time;autoCreateTime"` +//} + type ConversationModel struct { - OwnerUserID string `gorm:"column:owner_user_id;primary_key;type:char(128)" json:"OwnerUserID"` - ConversationID string `gorm:"column:conversation_id;primary_key;type:char(128)" json:"conversationID"` - ConversationType int32 `gorm:"column:conversation_type" json:"conversationType"` - UserID string `gorm:"column:user_id;type:char(64)" json:"userID"` - GroupID string `gorm:"column:group_id;type:char(128)" json:"groupID"` - RecvMsgOpt int32 `gorm:"column:recv_msg_opt" json:"recvMsgOpt"` - IsPinned bool `gorm:"column:is_pinned" json:"isPinned"` - IsPrivateChat bool `gorm:"column:is_private_chat" json:"isPrivateChat"` - BurnDuration int32 `gorm:"column:burn_duration;default:30" json:"burnDuration"` - GroupAtType int32 `gorm:"column:group_at_type" json:"groupAtType"` - AttachedInfo string `gorm:"column:attached_info;type:varchar(1024)" json:"attachedInfo"` - Ex string `gorm:"column:ex;type:varchar(1024)" json:"ex"` - MaxSeq int64 `gorm:"column:max_seq" json:"maxSeq"` - MinSeq int64 `gorm:"column:min_seq" json:"minSeq"` - CreateTime time.Time `gorm:"column:create_time;index:create_time;autoCreateTime"` - IsMsgDestruct bool `gorm:"column:is_msg_destruct;default:false"` - MsgDestructTime int64 `gorm:"column:msg_destruct_time;default:604800"` - LatestMsgDestructTime time.Time `gorm:"column:latest_msg_destruct_time;autoCreateTime"` + OwnerUserID string `bson:"owner_user_id"` + ConversationID string `bson:"conversation_id"` + ConversationType int32 `bson:"conversation_type"` + UserID string `bson:"user_id"` + GroupID string `bson:"group_id"` + RecvMsgOpt int32 `bson:"recv_msg_opt"` + IsPinned bool `bson:"is_pinned"` + IsPrivateChat bool `bson:"is_private_chat"` + BurnDuration int32 `bson:"burn_duration"` + GroupAtType int32 `bson:"group_at_type"` + AttachedInfo string `bson:"attached_info"` + Ex string `bson:"ex"` + MaxSeq int64 `bson:"max_seq"` + MinSeq int64 `bson:"min_seq"` + CreateTime time.Time `bson:"create_time"` + IsMsgDestruct bool `bson:"is_msg_destruct"` + MsgDestructTime int64 `bson:"msg_destruct_time"` + LatestMsgDestructTime time.Time `bson:"latest_msg_destruct_time"` } func (ConversationModel) TableName() string { @@ -51,7 +73,7 @@ func (ConversationModel) TableName() string { type ConversationModelInterface interface { Create(ctx context.Context, conversations []*ConversationModel) (err error) Delete(ctx context.Context, groupIDs []string) (err error) - UpdateByMap(ctx context.Context, userIDs []string, conversationID string, args map[string]interface{}) (rows int64, err error) + UpdateByMap(ctx context.Context, userIDs []string, conversationID string, args map[string]any) (rows int64, err error) Update(ctx context.Context, conversation *ConversationModel) (err error) Find(ctx context.Context, ownerUserID string, conversationIDs []string) (conversations []*ConversationModel, err error) FindUserID(ctx context.Context, userIDs []string, conversationIDs []string) ([]string, error) @@ -61,13 +83,12 @@ type ConversationModelInterface interface { FindUserIDAllConversations(ctx context.Context, userID string) (conversations []*ConversationModel, err error) FindRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) ([]string, error) GetUserRecvMsgOpt(ctx context.Context, ownerUserID, conversationID string) (opt int, err error) - FindSuperGroupRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) ([]string, error) + //FindSuperGroupRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) ([]string, error) GetAllConversationIDs(ctx context.Context) ([]string, error) GetAllConversationIDsNumber(ctx context.Context) (int64, error) - PageConversationIDs(ctx context.Context, pageNumber, showNumber int32) (conversationIDs []string, err error) - GetUserAllHasReadSeqs(ctx context.Context, ownerUserID string) (hashReadSeqs map[string]int64, err error) + PageConversationIDs(ctx context.Context, pagination pagination.Pagination) (conversationIDs []string, err error) + //GetUserAllHasReadSeqs(ctx context.Context, ownerUserID string) (hashReadSeqs map[string]int64, err error) GetConversationsByConversationID(ctx context.Context, conversationIDs []string) ([]*ConversationModel, error) GetConversationIDsNeedDestruct(ctx context.Context) ([]*ConversationModel, error) GetConversationNotReceiveMessageUserIDs(ctx context.Context, conversationID string) ([]string, error) - NewTx(tx any) ConversationModelInterface } diff --git a/pkg/common/db/table/relation/friend.go b/pkg/common/db/table/relation/friend.go index 58d8d1d34..481b23525 100644 --- a/pkg/common/db/table/relation/friend.go +++ b/pkg/common/db/table/relation/friend.go @@ -17,62 +17,65 @@ package relation import ( "context" "time" + + "go.mongodb.org/mongo-driver/bson/primitive" ) const ( - FriendModelTableName = "friends" + FriendModelCollectionName = "friends" ) +// OwnerUserID string `gorm:"column:owner_user_id;primary_key;size:64"` +// FriendUserID string `gorm:"column:friend_user_id;primary_key;size:64"` +// Remark string `gorm:"column:remark;size:255"` +// CreateTime time.Time `gorm:"column:create_time;autoCreateTime"` +// AddSource int32 `gorm:"column:add_source"` +// OperatorUserID string `gorm:"column:operator_user_id;size:64"` +// Ex string `gorm:"column:ex;size:1024"` + +// FriendModel represents the data structure for a friend relationship in MongoDB. type FriendModel struct { - OwnerUserID string `gorm:"column:owner_user_id;primary_key;size:64"` - FriendUserID string `gorm:"column:friend_user_id;primary_key;size:64"` - Remark string `gorm:"column:remark;size:255"` - CreateTime time.Time `gorm:"column:create_time;autoCreateTime"` - AddSource int32 `gorm:"column:add_source"` - OperatorUserID string `gorm:"column:operator_user_id;size:64"` - Ex string `gorm:"column:ex;size:1024"` + ID primitive.ObjectID `bson:"_id,omitempty"` + OwnerUserID string `bson:"owner_user_id"` + FriendUserID string `bson:"friend_user_id"` + Remark string `bson:"remark"` + CreateTime time.Time `bson:"create_time"` + AddSource int32 `bson:"add_source"` + OperatorUserID string `bson:"operator_user_id"` + Ex string `bson:"ex"` } -func (FriendModel) TableName() string { - return FriendModelTableName +// CollectionName returns the name of the MongoDB collection. +func (FriendModel) CollectionName() string { + return FriendModelCollectionName } +// FriendModelInterface defines the operations for managing friends in MongoDB. type FriendModelInterface interface { - // 插入多条记录 + // Create inserts multiple friend records. Create(ctx context.Context, friends []*FriendModel) (err error) - // 删除ownerUserID指定的好友 + // Delete removes specified friends of the owner user. Delete(ctx context.Context, ownerUserID string, friendUserIDs []string) (err error) - // 更新ownerUserID单个好友信息 更新零值 - UpdateByMap(ctx context.Context, ownerUserID string, friendUserID string, args map[string]interface{}) (err error) - // 更新好友信息的非零值 - Update(ctx context.Context, friends []*FriendModel) (err error) - // 更新好友备注(也支持零值 ) + // UpdateByMap updates specific fields of a friend document using a map. + UpdateByMap(ctx context.Context, ownerUserID string, friendUserID string, args map[string]any) (err error) + // Update modifies multiple friend documents. + // Update(ctx context.Context, friends []*FriendModel) (err error) + // UpdateRemark updates the remark for a specific friend. UpdateRemark(ctx context.Context, ownerUserID, friendUserID, remark string) (err error) - // 获取单个好友信息,如没找到 返回错误 + // Take retrieves a single friend document. Returns an error if not found. Take(ctx context.Context, ownerUserID, friendUserID string) (friend *FriendModel, err error) - // 查找好友关系,如果是双向关系,则都返回 + // FindUserState finds the friendship status between two users. FindUserState(ctx context.Context, userID1, userID2 string) (friends []*FriendModel, err error) - // 获取 owner指定的好友列表 如果有friendUserIDs不存在,也不返回错误 + // FindFriends retrieves a list of friends for a given owner. Missing friends do not cause an error. FindFriends(ctx context.Context, ownerUserID string, friendUserIDs []string) (friends []*FriendModel, err error) - // 获取哪些人添加了friendUserID 如果有ownerUserIDs不存在,也不返回错误 - FindReversalFriends( - ctx context.Context, - friendUserID string, - ownerUserIDs []string, - ) (friends []*FriendModel, err error) - // 获取ownerUserID好友列表 支持翻页 - FindOwnerFriends( - ctx context.Context, - ownerUserID string, - pageNumber, showNumber int32, - ) (friends []*FriendModel, total int64, err error) - // 获取哪些人添加了friendUserID 支持翻页 - FindInWhoseFriends( - ctx context.Context, - friendUserID string, - pageNumber, showNumber int32, - ) (friends []*FriendModel, total int64, err error) - // 获取好友UserID列表 + // FindReversalFriends finds users who have added the specified user as a friend. + FindReversalFriends(ctx context.Context, friendUserID string, ownerUserIDs []string) (friends []*FriendModel, err error) + // FindOwnerFriends retrieves a paginated list of friends for a given owner. + FindOwnerFriends(ctx context.Context, ownerUserID string, pageNumber, showNumber int32) (friends []*FriendModel, total int64, err error) + // FindInWhoseFriends finds users who have added the specified user as a friend, with pagination. + FindInWhoseFriends(ctx context.Context, friendUserID string, pageNumber, showNumber int32) (friends []*FriendModel, total int64, err error) + // FindFriendUserIDs retrieves a list of friend user IDs for a given owner. FindFriendUserIDs(ctx context.Context, ownerUserID string) (friendUserIDs []string, err error) + // NewTx creates a new transaction. NewTx(tx any) FriendModelInterface } diff --git a/pkg/common/db/table/relation/friend_request.go b/pkg/common/db/table/relation/friend_request.go index 51ea0ef6e..90d4a7b72 100644 --- a/pkg/common/db/table/relation/friend_request.go +++ b/pkg/common/db/table/relation/friend_request.go @@ -17,50 +17,47 @@ package relation import ( "context" "time" + + "go.mongodb.org/mongo-driver/bson/primitive" ) -const FriendRequestModelTableName = "friend_requests" +const FriendRequestModelCollectionName = "friend_requests" type FriendRequestModel struct { - FromUserID string `gorm:"column:from_user_id;primary_key;size:64"` - ToUserID string `gorm:"column:to_user_id;primary_key;size:64"` - HandleResult int32 `gorm:"column:handle_result"` - ReqMsg string `gorm:"column:req_msg;size:255"` - CreateTime time.Time `gorm:"column:create_time; autoCreateTime"` - HandlerUserID string `gorm:"column:handler_user_id;size:64"` - HandleMsg string `gorm:"column:handle_msg;size:255"` - HandleTime time.Time `gorm:"column:handle_time"` - Ex string `gorm:"column:ex;size:1024"` + ID primitive.ObjectID `bson:"_id,omitempty"` + FromUserID string `bson:"from_user_id"` + ToUserID string `bson:"to_user_id"` + HandleResult int32 `bson:"handle_result"` + ReqMsg string `bson:"req_msg"` + CreateTime time.Time `bson:"create_time"` + HandlerUserID string `bson:"handler_user_id"` + HandleMsg string `bson:"handle_msg"` + HandleTime time.Time `bson:"handle_time"` + Ex string `bson:"ex"` } -func (FriendRequestModel) TableName() string { - return FriendRequestModelTableName +func (FriendRequestModel) CollectionName() string { + return FriendRequestModelCollectionName } type FriendRequestModelInterface interface { - // 插入多条记录 + // Insert multiple records Create(ctx context.Context, friendRequests []*FriendRequestModel) (err error) - // 删除记录 + // Delete record Delete(ctx context.Context, fromUserID, toUserID string) (err error) - // 更新零值 - UpdateByMap(ctx context.Context, formUserID string, toUserID string, args map[string]interface{}) (err error) - // 更新多条记录 (非零值) + // Update with zero values + UpdateByMap(ctx context.Context, formUserID string, toUserID string, args map[string]any) (err error) + // Update multiple records (non-zero values) Update(ctx context.Context, friendRequest *FriendRequestModel) (err error) - // 获取来指定用户的好友申请 未找到 不返回错误 + // Get friend requests sent to a specific user, no error returned if not found Find(ctx context.Context, fromUserID, toUserID string) (friendRequest *FriendRequestModel, err error) Take(ctx context.Context, fromUserID, toUserID string) (friendRequest *FriendRequestModel, err error) - // 获取toUserID收到的好友申请列表 - FindToUserID( - ctx context.Context, - toUserID string, - pageNumber, showNumber int32, - ) (friendRequests []*FriendRequestModel, total int64, err error) - // 获取fromUserID发出去的好友申请列表 - FindFromUserID( - ctx context.Context, - fromUserID string, - pageNumber, showNumber int32, - ) (friendRequests []*FriendRequestModel, total int64, err error) + // Get list of friend requests received by toUserID + FindToUserID(ctx context.Context,toUserID string,pageNumber, showNumber int32,) (friendRequests []*FriendRequestModel, total int64, err error) + // Get list of friend requests sent by fromUserID + FindFromUserID(ctx context.Context,fromUserID string,pageNumber, showNumber int32,) (friendRequests []*FriendRequestModel, total int64, err error) FindBothFriendRequests(ctx context.Context, fromUserID, toUserID string) (friends []*FriendRequestModel, err error) NewTx(tx any) FriendRequestModelInterface + // Check if the record exists + Exist(ctx context.Context, userID string) (exist bool, err error) } diff --git a/pkg/common/db/table/relation/group.go b/pkg/common/db/table/relation/group.go index 6759e0d35..f9afc06b0 100644 --- a/pkg/common/db/table/relation/group.go +++ b/pkg/common/db/table/relation/group.go @@ -16,6 +16,7 @@ package relation import ( "context" + "github.com/openimsdk/open-im-server/v3/pkg/common/pagination" "time" ) @@ -23,22 +24,40 @@ const ( GroupModelTableName = "groups" ) +//type GroupModel struct { +// GroupID string `gorm:"column:group_id;primary_key;size:64" json:"groupID" binding:"required"` +// GroupName string `gorm:"column:name;size:255" json:"groupName"` +// Notification string `gorm:"column:notification;size:255" json:"notification"` +// Introduction string `gorm:"column:introduction;size:255" json:"introduction"` +// FaceURL string `gorm:"column:face_url;size:255" json:"faceURL"` +// CreateTime time.Time `gorm:"column:create_time;index:create_time;autoCreateTime"` +// Ex string `gorm:"column:ex" json:"ex;size:1024"` +// Status int32 `gorm:"column:status"` +// CreatorUserID string `gorm:"column:creator_user_id;size:64"` +// GroupType int32 `gorm:"column:group_type"` +// NeedVerification int32 `gorm:"column:need_verification"` +// LookMemberInfo int32 `gorm:"column:look_member_info" json:"lookMemberInfo"` +// ApplyMemberFriend int32 `gorm:"column:apply_member_friend" json:"applyMemberFriend"` +// NotificationUpdateTime time.Time `gorm:"column:notification_update_time"` +// NotificationUserID string `gorm:"column:notification_user_id;size:64"` +//} + type GroupModel struct { - GroupID string `gorm:"column:group_id;primary_key;size:64" json:"groupID" binding:"required"` - GroupName string `gorm:"column:name;size:255" json:"groupName"` - Notification string `gorm:"column:notification;size:255" json:"notification"` - Introduction string `gorm:"column:introduction;size:255" json:"introduction"` - FaceURL string `gorm:"column:face_url;size:255" json:"faceURL"` - CreateTime time.Time `gorm:"column:create_time;index:create_time;autoCreateTime"` - Ex string `gorm:"column:ex" json:"ex;size:1024"` - Status int32 `gorm:"column:status"` - CreatorUserID string `gorm:"column:creator_user_id;size:64"` - GroupType int32 `gorm:"column:group_type"` - NeedVerification int32 `gorm:"column:need_verification"` - LookMemberInfo int32 `gorm:"column:look_member_info" json:"lookMemberInfo"` - ApplyMemberFriend int32 `gorm:"column:apply_member_friend" json:"applyMemberFriend"` - NotificationUpdateTime time.Time `gorm:"column:notification_update_time"` - NotificationUserID string `gorm:"column:notification_user_id;size:64"` + GroupID string `bson:"group_id"` + GroupName string `bson:"group_name"` + Notification string `bson:"notification"` + Introduction string `bson:"introduction"` + FaceURL string `bson:"face_url"` + CreateTime time.Time `bson:"create_time"` + Ex string `bson:"ex"` + Status int32 `bson:"status"` + CreatorUserID string `bson:"creator_user_id"` + GroupType int32 `bson:"group_type"` + NeedVerification int32 `bson:"need_verification"` + LookMemberInfo int32 `bson:"look_member_info"` + ApplyMemberFriend int32 `bson:"apply_member_friend"` + NotificationUpdateTime time.Time `bson:"notification_update_time"` + NotificationUserID string `bson:"notification_user_id"` } func (GroupModel) TableName() string { @@ -46,19 +65,12 @@ func (GroupModel) TableName() string { } type GroupModelInterface interface { - NewTx(tx any) GroupModelInterface Create(ctx context.Context, groups []*GroupModel) (err error) - UpdateMap(ctx context.Context, groupID string, args map[string]interface{}) (err error) - UpdateStatus(ctx context.Context, groupID string, status int32) (err error) + UpdateMap(ctx context.Context, groupID string, args map[string]any) (err error) + UpdateState(ctx context.Context, groupID string, state int32) (err error) Find(ctx context.Context, groupIDs []string) (groups []*GroupModel, err error) - FindNotDismissedGroup(ctx context.Context, groupIDs []string) (groups []*GroupModel, err error) Take(ctx context.Context, groupID string) (group *GroupModel, err error) - Search( - ctx context.Context, - keyword string, - pageNumber, showNumber int32, - ) (total uint32, groups []*GroupModel, err error) - GetGroupIDsByGroupType(ctx context.Context, groupType int) (groupIDs []string, err error) + Search(ctx context.Context, keyword string, pagination pagination.Pagination) (total int64, groups []*GroupModel, err error) // 获取群总数 CountTotal(ctx context.Context, before *time.Time) (count int64, err error) // 获取范围内群增量 diff --git a/pkg/common/db/table/relation/group_member.go b/pkg/common/db/table/relation/group_member.go index bfde72834..e35f2dd84 100644 --- a/pkg/common/db/table/relation/group_member.go +++ b/pkg/common/db/table/relation/group_member.go @@ -16,6 +16,7 @@ package relation import ( "context" + "github.com/openimsdk/open-im-server/v3/pkg/common/pagination" "time" ) @@ -23,18 +24,32 @@ const ( GroupMemberModelTableName = "group_members" ) +//type GroupMemberModel struct { +// GroupID string `gorm:"column:group_id;primary_key;size:64"` +// UserID string `gorm:"column:user_id;primary_key;size:64"` +// Nickname string `gorm:"column:nickname;size:255"` +// FaceURL string `gorm:"column:user_group_face_url;size:255"` +// RoleLevel int32 `gorm:"column:role_level"` +// JoinTime time.Time `gorm:"column:join_time"` +// JoinSource int32 `gorm:"column:join_source"` +// InviterUserID string `gorm:"column:inviter_user_id;size:64"` +// OperatorUserID string `gorm:"column:operator_user_id;size:64"` +// MuteEndTime time.Time `gorm:"column:mute_end_time"` +// Ex string `gorm:"column:ex;size:1024"` +//} + type GroupMemberModel struct { - GroupID string `gorm:"column:group_id;primary_key;size:64"` - UserID string `gorm:"column:user_id;primary_key;size:64"` - Nickname string `gorm:"column:nickname;size:255"` - FaceURL string `gorm:"column:user_group_face_url;size:255"` - RoleLevel int32 `gorm:"column:role_level"` - JoinTime time.Time `gorm:"column:join_time"` - JoinSource int32 `gorm:"column:join_source"` - InviterUserID string `gorm:"column:inviter_user_id;size:64"` - OperatorUserID string `gorm:"column:operator_user_id;size:64"` - MuteEndTime time.Time `gorm:"column:mute_end_time"` - Ex string `gorm:"column:ex;size:1024"` + GroupID string `bson:"group_id"` + UserID string `bson:"user_id"` + Nickname string `bson:"nickname"` + FaceURL string `bson:"face_url"` + RoleLevel int32 `bson:"role_level"` + JoinTime time.Time `bson:"join_time"` + JoinSource int32 `bson:"join_source"` + InviterUserID string `bson:"inviter_user_id"` + OperatorUserID string `bson:"operator_user_id"` + MuteEndTime time.Time `bson:"mute_end_time"` + Ex string `bson:"ex"` } func (GroupMemberModel) TableName() string { @@ -42,33 +57,22 @@ func (GroupMemberModel) TableName() string { } type GroupMemberModelInterface interface { - NewTx(tx any) GroupMemberModelInterface + //NewTx(tx any) GroupMemberModelInterface Create(ctx context.Context, groupMembers []*GroupMemberModel) (err error) Delete(ctx context.Context, groupID string, userIDs []string) (err error) - DeleteGroup(ctx context.Context, groupIDs []string) (err error) + //DeleteGroup(ctx context.Context, groupIDs []string) (err error) Update(ctx context.Context, groupID string, userID string, data map[string]any) (err error) - UpdateRoleLevel(ctx context.Context, groupID string, userID string, roleLevel int32) (rowsAffected int64, err error) - Find( - ctx context.Context, - groupIDs []string, - userIDs []string, - roleLevels []int32, - ) (groupMembers []*GroupMemberModel, err error) + UpdateRoleLevel(ctx context.Context, groupID string, userID string, roleLevel int32) error FindMemberUserID(ctx context.Context, groupID string) (userIDs []string, err error) Take(ctx context.Context, groupID string, userID string) (groupMember *GroupMemberModel, err error) TakeOwner(ctx context.Context, groupID string) (groupMember *GroupMemberModel, err error) - SearchMember( - ctx context.Context, - keyword string, - groupIDs []string, - userIDs []string, - roleLevels []int32, - pageNumber, showNumber int32, - ) (total uint32, groupList []*GroupMemberModel, err error) - MapGroupMemberNum(ctx context.Context, groupIDs []string) (count map[string]uint32, err error) - FindJoinUserID(ctx context.Context, groupIDs []string) (groupUsers map[string][]string, err error) + SearchMember(ctx context.Context, keyword string, groupID string, pagination pagination.Pagination) (total int64, groupList []*GroupMemberModel, err error) + FindRoleLevelUserIDs(ctx context.Context, groupID string, roleLevel int32) ([]string, error) + //MapGroupMemberNum(ctx context.Context, groupIDs []string) (count map[string]uint32, err error) + //FindJoinUserID(ctx context.Context, groupIDs []string) (groupUsers map[string][]string, err error) FindUserJoinedGroupID(ctx context.Context, userID string) (groupIDs []string, err error) TakeGroupMemberNum(ctx context.Context, groupID string) (count int64, err error) - FindUsersJoinedGroupID(ctx context.Context, userIDs []string) (map[string][]string, error) + //FindUsersJoinedGroupID(ctx context.Context, userIDs []string) (map[string][]string, error) FindUserManagedGroupID(ctx context.Context, userID string) (groupIDs []string, err error) + IsUpdateRoleLevel(data map[string]any) bool } diff --git a/pkg/common/db/table/relation/group_request.go b/pkg/common/db/table/relation/group_request.go index 063b83938..83c0cf5bd 100644 --- a/pkg/common/db/table/relation/group_request.go +++ b/pkg/common/db/table/relation/group_request.go @@ -16,6 +16,7 @@ package relation import ( "context" + "github.com/openimsdk/open-im-server/v3/pkg/common/pagination" "time" ) @@ -23,18 +24,32 @@ const ( GroupRequestModelTableName = "group_requests" ) +//type GroupRequestModel struct { +// UserID string `gorm:"column:user_id;primary_key;size:64"` +// GroupID string `gorm:"column:group_id;primary_key;size:64"` +// HandleResult int32 `gorm:"column:handle_result"` +// ReqMsg string `gorm:"column:req_msg;size:1024"` +// HandledMsg string `gorm:"column:handle_msg;size:1024"` +// ReqTime time.Time `gorm:"column:req_time"` +// HandleUserID string `gorm:"column:handle_user_id;size:64"` +// HandledTime time.Time `gorm:"column:handle_time"` +// JoinSource int32 `gorm:"column:join_source"` +// InviterUserID string `gorm:"column:inviter_user_id;size:64"` +// Ex string `gorm:"column:ex;size:1024"` +//} + type GroupRequestModel struct { - UserID string `gorm:"column:user_id;primary_key;size:64"` - GroupID string `gorm:"column:group_id;primary_key;size:64"` - HandleResult int32 `gorm:"column:handle_result"` - ReqMsg string `gorm:"column:req_msg;size:1024"` - HandledMsg string `gorm:"column:handle_msg;size:1024"` - ReqTime time.Time `gorm:"column:req_time"` - HandleUserID string `gorm:"column:handle_user_id;size:64"` - HandledTime time.Time `gorm:"column:handle_time"` - JoinSource int32 `gorm:"column:join_source"` - InviterUserID string `gorm:"column:inviter_user_id;size:64"` - Ex string `gorm:"column:ex;size:1024"` + UserID string `bson:"user_id"` + GroupID string `bson:"group_id"` + HandleResult int32 `bson:"handle_result"` + ReqMsg string `bson:"req_msg"` + HandledMsg string `bson:"handled_msg"` + ReqTime time.Time `bson:"req_time"` + HandleUserID string `bson:"handle_user_id"` + HandledTime time.Time `bson:"handled_time"` + JoinSource int32 `bson:"join_source"` + InviterUserID string `bson:"inviter_user_id"` + Ex string `bson:"ex"` } func (GroupRequestModel) TableName() string { @@ -42,20 +57,11 @@ func (GroupRequestModel) TableName() string { } type GroupRequestModelInterface interface { - NewTx(tx any) GroupRequestModelInterface Create(ctx context.Context, groupRequests []*GroupRequestModel) (err error) Delete(ctx context.Context, groupID string, userID string) (err error) UpdateHandler(ctx context.Context, groupID string, userID string, handledMsg string, handleResult int32) (err error) Take(ctx context.Context, groupID string, userID string) (groupRequest *GroupRequestModel, err error) - FindGroupRequests(ctx context.Context, groupID string, userIDs []string) (int64, []*GroupRequestModel, error) - Page( - ctx context.Context, - userID string, - pageNumber, showNumber int32, - ) (total uint32, groups []*GroupRequestModel, err error) - PageGroup( - ctx context.Context, - groupIDs []string, - pageNumber, showNumber int32, - ) (total uint32, groups []*GroupRequestModel, err error) + FindGroupRequests(ctx context.Context, groupID string, userIDs []string) ([]*GroupRequestModel, error) + Page(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, groups []*GroupRequestModel, err error) + PageGroup(ctx context.Context, groupIDs []string, pagination pagination.Pagination) (total int64, groups []*GroupRequestModel, err error) } diff --git a/pkg/common/db/table/relation/log.go b/pkg/common/db/table/relation/log.go index 72d0fa64e..7df735676 100644 --- a/pkg/common/db/table/relation/log.go +++ b/pkg/common/db/table/relation/log.go @@ -2,24 +2,37 @@ package relation import ( "context" + "github.com/openimsdk/open-im-server/v3/pkg/common/pagination" "time" ) +//type Log struct { +// LogID string `gorm:"column:log_id;primary_key;type:char(64)"` +// Platform string `gorm:"column:platform;type:varchar(32)"` +// UserID string `gorm:"column:user_id;type:char(64)"` +// CreateTime time.Time `gorm:"index:,sort:desc"` +// Url string `gorm:"column:url;type varchar(255)"` +// FileName string `gorm:"column:filename;type varchar(255)"` +// SystemType string `gorm:"column:system_type;type varchar(255)"` +// Version string `gorm:"column:version;type varchar(255)"` +// Ex string `gorm:"column:ex;type varchar(255)"` +//} + type Log struct { - LogID string `gorm:"column:log_id;primary_key;type:char(64)"` - Platform string `gorm:"column:platform;type:varchar(32)"` - UserID string `gorm:"column:user_id;type:char(64)"` - CreateTime time.Time `gorm:"index:,sort:desc"` - Url string `gorm:"column:url;type varchar(255)"` - FileName string `gorm:"column:filename;type varchar(255)"` - SystemType string `gorm:"column:system_type;type varchar(255)"` - Version string `gorm:"column:version;type varchar(255)"` - Ex string `gorm:"column:ex;type varchar(255)"` + LogID string `bson:"log_id"` + Platform string `bson:"platform"` + UserID string `bson:"user_id"` + CreateTime time.Time `bson:"create_time"` + Url string `bson:"url"` + FileName string `bson:"file_name"` + SystemType string `bson:"system_type"` + Version string `bson:"version"` + Ex string `bson:"ex"` } type LogInterface interface { Create(ctx context.Context, log []*Log) error - Search(ctx context.Context, keyword string, start time.Time, end time.Time, pageNumber int32, showNumber int32) (uint32, []*Log, error) + Search(ctx context.Context, keyword string, start time.Time, end time.Time, pagination pagination.Pagination) (int64, []*Log, error) Delete(ctx context.Context, logID []string, userID string) error Get(ctx context.Context, logIDs []string, userID string) ([]*Log, error) } diff --git a/pkg/common/db/table/relation/object.go b/pkg/common/db/table/relation/object.go index 0ed4130a6..6259f425e 100644 --- a/pkg/common/db/table/relation/object.go +++ b/pkg/common/db/table/relation/object.go @@ -24,22 +24,35 @@ const ( ) type ObjectModel struct { - Name string `gorm:"column:name;primary_key"` - UserID string `gorm:"column:user_id"` - Hash string `gorm:"column:hash"` - Key string `gorm:"column:key"` - Size int64 `gorm:"column:size"` - ContentType string `gorm:"column:content_type"` - Cause string `gorm:"column:cause"` - CreateTime time.Time `gorm:"column:create_time"` + Name string `bson:"name"` + UserID string `bson:"user_id"` + Hash string `bson:"hash"` + Engine string `bson:"engine"` + Key string `bson:"key"` + Size int64 `bson:"size"` + ContentType string `bson:"content_type"` + Group string `bson:"group"` + CreateTime time.Time `bson:"create_time"` } +//type ObjectModel struct { +// Name string `gorm:"column:name;primary_key"` +// UserID string `gorm:"column:user_id"` +// Hash string `gorm:"column:hash"` +// Engine string `gorm:"column:engine"` +// Key string `gorm:"column:key"` +// Size int64 `gorm:"column:size"` +// ContentType string `gorm:"column:content_type"` +// Cause string `gorm:"column:cause"` +// CreateTime time.Time `gorm:"column:create_time"` +//} + func (ObjectModel) TableName() string { return ObjectInfoModelTableName } type ObjectInfoModelInterface interface { - NewTx(tx any) ObjectInfoModelInterface SetObject(ctx context.Context, obj *ObjectModel) error - Take(ctx context.Context, name string) (*ObjectModel, error) + Take(ctx context.Context, engine string, name string) (*ObjectModel, error) + Delete(ctx context.Context, engine string, name string) error } diff --git a/pkg/common/db/table/relation/user.go b/pkg/common/db/table/relation/user.go index 10a715bda..11d93b63f 100644 --- a/pkg/common/db/table/relation/user.go +++ b/pkg/common/db/table/relation/user.go @@ -16,21 +16,18 @@ package relation import ( "context" + "github.com/openimsdk/open-im-server/v3/pkg/common/pagination" "time" ) -const ( - UserModelTableName = "users" -) - type UserModel struct { - UserID string `gorm:"column:user_id;primary_key;size:64"` - Nickname string `gorm:"column:name;size:255"` - FaceURL string `gorm:"column:face_url;size:255"` - Ex string `gorm:"column:ex;size:1024"` - CreateTime time.Time `gorm:"column:create_time;index:create_time;autoCreateTime"` - AppMangerLevel int32 `gorm:"column:app_manger_level;default:1"` - GlobalRecvMsgOpt int32 `gorm:"column:global_recv_msg_opt"` + UserID string `bson:"user_id"` + Nickname string `bson:"nickname"` + FaceURL string `bson:"face_url"` + Ex string `bson:"ex"` + AppMangerLevel int32 `bson:"app_manger_level"` + GlobalRecvMsgOpt int32 `bson:"global_recv_msg_opt"` + CreateTime time.Time `bson:"create_time"` } func (u *UserModel) GetNickname() string { @@ -41,29 +38,22 @@ func (u *UserModel) GetFaceURL() string { return u.FaceURL } -func (u *UserModel) GetUserID() string { +func (u UserModel) GetUserID() string { return u.UserID } -func (u *UserModel) GetEx() string { +func (u UserModel) GetEx() string { return u.Ex } -func (UserModel) TableName() string { - return UserModelTableName -} - type UserModelInterface interface { Create(ctx context.Context, users []*UserModel) (err error) - UpdateByMap(ctx context.Context, userID string, args map[string]interface{}) (err error) - Update(ctx context.Context, user *UserModel) (err error) - // 获取指定用户信息 不存在,也不返回错误 + UpdateByMap(ctx context.Context, userID string, args map[string]any) (err error) Find(ctx context.Context, userIDs []string) (users []*UserModel, err error) - // 获取某个用户信息 不存在,则返回错误 Take(ctx context.Context, userID string) (user *UserModel, err error) - // 获取用户信息 不存在,不返回错误 - Page(ctx context.Context, pageNumber, showNumber int32) (users []*UserModel, count int64, err error) - GetAllUserID(ctx context.Context, pageNumber, showNumber int32) (userIDs []string, err error) + Page(ctx context.Context, pagination pagination.Pagination) (count int64, users []*UserModel, err error) + Exist(ctx context.Context, userID string) (exist bool, err error) + GetAllUserID(ctx context.Context, pagination pagination.Pagination) (count int64, userIDs []string, err error) GetUserGlobalRecvMsgOpt(ctx context.Context, userID string) (opt int, err error) // 获取用户总数 CountTotal(ctx context.Context, before *time.Time) (count int64, err error) diff --git a/pkg/common/db/table/unrelation/super_group.go b/pkg/common/db/table/unrelation/super_group.go index 80c3ef9c7..1fd80c67a 100644 --- a/pkg/common/db/table/unrelation/super_group.go +++ b/pkg/common/db/table/unrelation/super_group.go @@ -14,40 +14,40 @@ package unrelation -import ( - "context" -) - -const ( - CSuperGroup = "super_group" - CUserToSuperGroup = "user_to_super_group" -) - -type SuperGroupModel struct { - GroupID string `bson:"group_id" json:"groupID"` - MemberIDs []string `bson:"member_id_list" json:"memberIDList"` -} - -func (SuperGroupModel) TableName() string { - return CSuperGroup -} - -type UserToSuperGroupModel struct { - UserID string `bson:"user_id" json:"userID"` - GroupIDs []string `bson:"group_id_list" json:"groupIDList"` -} - -func (UserToSuperGroupModel) TableName() string { - return CUserToSuperGroup -} - -type SuperGroupModelInterface interface { - CreateSuperGroup(ctx context.Context, groupID string, initMemberIDs []string) error - TakeSuperGroup(ctx context.Context, groupID string) (group *SuperGroupModel, err error) - FindSuperGroup(ctx context.Context, groupIDs []string) (groups []*SuperGroupModel, err error) - AddUserToSuperGroup(ctx context.Context, groupID string, userIDs []string) error - RemoverUserFromSuperGroup(ctx context.Context, groupID string, userIDs []string) error - GetSuperGroupByUserID(ctx context.Context, userID string) (*UserToSuperGroupModel, error) - DeleteSuperGroup(ctx context.Context, groupID string) error - RemoveGroupFromUser(ctx context.Context, groupID string, userIDs []string) error -} +//import ( +// "context" +//) +// +//const ( +// CSuperGroup = "super_group" +// CUserToSuperGroup = "user_to_super_group" +//) +// +//type SuperGroupModel struct { +// GroupID string `bson:"group_id" json:"groupID"` +// MemberIDs []string `bson:"member_id_list" json:"memberIDList"` +//} +// +//func (SuperGroupModel) TableName() string { +// return CSuperGroup +//} +// +//type UserToSuperGroupModel struct { +// UserID string `bson:"user_id" json:"userID"` +// GroupIDs []string `bson:"group_id_list" json:"groupIDList"` +//} +// +//func (UserToSuperGroupModel) TableName() string { +// return CUserToSuperGroup +//} +// +//type SuperGroupModelInterface interface { +// CreateSuperGroup(ctx context.Context, groupID string, initMemberIDs []string) error +// TakeSuperGroup(ctx context.Context, groupID string) (group *SuperGroupModel, err error) +// FindSuperGroup(ctx context.Context, groupIDs []string) (groups []*SuperGroupModel, err error) +// AddUserToSuperGroup(ctx context.Context, groupID string, userIDs []string) error +// RemoverUserFromSuperGroup(ctx context.Context, groupID string, userIDs []string) error +// GetSuperGroupByUserID(ctx context.Context, userID string) (*UserToSuperGroupModel, error) +// DeleteSuperGroup(ctx context.Context, groupID string) error +// RemoveGroupFromUser(ctx context.Context, groupID string, userIDs []string) error +//} diff --git a/pkg/common/db/tx/auto.go b/pkg/common/db/tx/auto.go new file mode 100644 index 000000000..bf6817a24 --- /dev/null +++ b/pkg/common/db/tx/auto.go @@ -0,0 +1,19 @@ +package tx + +import ( + "context" + "github.com/OpenIMSDK/tools/tx" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" +) + +func NewAuto(ctx context.Context, cli *mongo.Client) (tx.CtxTx, error) { + var res map[string]any + if err := cli.Database("admin").RunCommand(ctx, bson.M{"isMaster": 1}).Decode(&res); err != nil { + return nil, err + } + if _, ok := res["setName"]; ok { + return NewMongoTx(cli), nil + } + return NewInvalidTx(), nil +} diff --git a/pkg/common/db/tx/invalid.go b/pkg/common/db/tx/invalid.go new file mode 100644 index 000000000..193972af5 --- /dev/null +++ b/pkg/common/db/tx/invalid.go @@ -0,0 +1,16 @@ +package tx + +import ( + "context" + "github.com/OpenIMSDK/tools/tx" +) + +func NewInvalidTx() tx.CtxTx { + return invalid{} +} + +type invalid struct{} + +func (m invalid) Transaction(ctx context.Context, fn func(ctx context.Context) error) error { + return fn(ctx) +} diff --git a/pkg/common/db/tx/tx.go b/pkg/common/db/tx/tx.go new file mode 100644 index 000000000..baf9a9a5d --- /dev/null +++ b/pkg/common/db/tx/tx.go @@ -0,0 +1,28 @@ +package tx + +import ( + "context" + "github.com/OpenIMSDK/tools/tx" + "go.mongodb.org/mongo-driver/mongo" +) + +func NewMongoTx(client *mongo.Client) tx.CtxTx { + return &mongoTx{ + client: client, + } +} + +type mongoTx struct { + client *mongo.Client +} + +func (m *mongoTx) Transaction(ctx context.Context, fn func(ctx context.Context) error) error { + sess, err := m.client.StartSession() + if err != nil { + return err + } + _, err = sess.WithTransaction(ctx, func(ctx mongo.SessionContext) (interface{}, error) { + return nil, fn(ctx) + }) + return err +} diff --git a/pkg/common/db/unrelation/mongo.go b/pkg/common/db/unrelation/mongo.go index 09e3e904e..38a335567 100755 --- a/pkg/common/db/unrelation/mongo.go +++ b/pkg/common/db/unrelation/mongo.go @@ -99,16 +99,6 @@ func (m *Mongo) CreateMsgIndex() error { return m.createMongoIndex(unrelation.Msg, true, "doc_id") } -func (m *Mongo) CreateSuperGroupIndex() error { - if err := m.createMongoIndex(unrelation.CSuperGroup, true, "group_id"); err != nil { - return err - } - if err := m.createMongoIndex(unrelation.CUserToSuperGroup, true, "user_id"); err != nil { - return err - } - return nil -} - func (m *Mongo) createMongoIndex(collection string, isUnique bool, keys ...string) error { db := m.db.Database(config.Config.Mongo.Database).Collection(collection) opts := options.CreateIndexes().SetMaxTime(10 * time.Second) diff --git a/pkg/common/db/unrelation/msg_convert.go b/pkg/common/db/unrelation/msg_convert.go index 810b4f419..373bc843e 100644 --- a/pkg/common/db/unrelation/msg_convert.go +++ b/pkg/common/db/unrelation/msg_convert.go @@ -48,7 +48,7 @@ func (m *MsgMongoDriver) ConvertMsgsDocLen(ctx context.Context, conversationIDs log.ZError(ctx, "convertAll delete many failed", err, "conversationID", conversationID) continue } - var newMsgDocs []interface{} + var newMsgDocs []any for _, msgDoc := range msgDocs { if int64(len(msgDoc.Msg)) == m.model.GetSingleGocMsgNum() { continue diff --git a/pkg/common/db/unrelation/super_group.go b/pkg/common/db/unrelation/super_group.go index c762140a2..6c2bb6aaf 100644 --- a/pkg/common/db/unrelation/super_group.go +++ b/pkg/common/db/unrelation/super_group.go @@ -14,149 +14,150 @@ package unrelation -import ( - "context" - - "go.mongodb.org/mongo-driver/bson" - "go.mongodb.org/mongo-driver/mongo" - "go.mongodb.org/mongo-driver/mongo/options" - - "github.com/OpenIMSDK/tools/utils" - - "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/unrelation" -) - -func NewSuperGroupMongoDriver(database *mongo.Database) unrelation.SuperGroupModelInterface { - return &SuperGroupMongoDriver{ - superGroupCollection: database.Collection(unrelation.CSuperGroup), - userToSuperGroupCollection: database.Collection(unrelation.CUserToSuperGroup), - } -} - -type SuperGroupMongoDriver struct { - superGroupCollection *mongo.Collection - userToSuperGroupCollection *mongo.Collection -} - -func (s *SuperGroupMongoDriver) CreateSuperGroup(ctx context.Context, groupID string, initMemberIDs []string) error { - _, err := s.superGroupCollection.InsertOne(ctx, &unrelation.SuperGroupModel{ - GroupID: groupID, - MemberIDs: initMemberIDs, - }) - if err != nil { - return err - } - for _, userID := range initMemberIDs { - _, err = s.userToSuperGroupCollection.UpdateOne( - ctx, - bson.M{"user_id": userID}, - bson.M{"$addToSet": bson.M{"group_id_list": groupID}}, - &options.UpdateOptions{ - Upsert: utils.ToPtr(true), - }, - ) - if err != nil { - return err - } - } - return nil -} - -func (s *SuperGroupMongoDriver) TakeSuperGroup( - ctx context.Context, - groupID string, -) (group *unrelation.SuperGroupModel, err error) { - if err := s.superGroupCollection.FindOne(ctx, bson.M{"group_id": groupID}).Decode(&group); err != nil { - return nil, utils.Wrap(err, "") - } - return group, nil -} - -func (s *SuperGroupMongoDriver) FindSuperGroup( - ctx context.Context, - groupIDs []string, -) (groups []*unrelation.SuperGroupModel, err error) { - cursor, err := s.superGroupCollection.Find(ctx, bson.M{"group_id": bson.M{ - "$in": groupIDs, - }}) - if err != nil { - return nil, err - } - defer cursor.Close(ctx) - if err := cursor.All(ctx, &groups); err != nil { - return nil, utils.Wrap(err, "") - } - return groups, nil -} - -func (s *SuperGroupMongoDriver) AddUserToSuperGroup(ctx context.Context, groupID string, userIDs []string) error { - _, err := s.superGroupCollection.UpdateOne( - ctx, - bson.M{"group_id": groupID}, - bson.M{"$addToSet": bson.M{"member_id_list": bson.M{"$each": userIDs}}}, - ) - if err != nil { - return err - } - upsert := true - opts := &options.UpdateOptions{ - Upsert: &upsert, - } - for _, userID := range userIDs { - _, err = s.userToSuperGroupCollection.UpdateOne( - ctx, - bson.M{"user_id": userID}, - bson.M{"$addToSet": bson.M{"group_id_list": groupID}}, - opts, - ) - if err != nil { - return utils.Wrap(err, "transaction failed") - } - } - return nil -} - -func (s *SuperGroupMongoDriver) RemoverUserFromSuperGroup(ctx context.Context, groupID string, userIDs []string) error { - _, err := s.superGroupCollection.UpdateOne( - ctx, - bson.M{"group_id": groupID}, - bson.M{"$pull": bson.M{"member_id_list": bson.M{"$in": userIDs}}}, - ) - if err != nil { - return err - } - err = s.RemoveGroupFromUser(ctx, groupID, userIDs) - if err != nil { - return err - } - return nil -} - -func (s *SuperGroupMongoDriver) GetSuperGroupByUserID( - ctx context.Context, - userID string, -) (*unrelation.UserToSuperGroupModel, error) { - var user unrelation.UserToSuperGroupModel - err := s.userToSuperGroupCollection.FindOne(ctx, bson.M{"user_id": userID}).Decode(&user) - return &user, utils.Wrap(err, "") -} - -func (s *SuperGroupMongoDriver) DeleteSuperGroup(ctx context.Context, groupID string) error { - group, err := s.TakeSuperGroup(ctx, groupID) - if err != nil { - return err - } - if _, err := s.superGroupCollection.DeleteOne(ctx, bson.M{"group_id": groupID}); err != nil { - return utils.Wrap(err, "") - } - return s.RemoveGroupFromUser(ctx, groupID, group.MemberIDs) -} - -func (s *SuperGroupMongoDriver) RemoveGroupFromUser(ctx context.Context, groupID string, userIDs []string) error { - _, err := s.userToSuperGroupCollection.UpdateOne( - ctx, - bson.M{"user_id": bson.M{"$in": userIDs}}, - bson.M{"$pull": bson.M{"group_id_list": groupID}}, - ) - return utils.Wrap(err, "") -} +// +//import ( +// "context" +// +// "go.mongodb.org/mongo-driver/bson" +// "go.mongodb.org/mongo-driver/mongo" +// "go.mongodb.org/mongo-driver/mongo/options" +// +// "github.com/OpenIMSDK/tools/utils" +// +// "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/unrelation" +//) +// +//func NewSuperGroupMongoDriver(database *mongo.Database) unrelation.SuperGroupModelInterface { +// return &SuperGroupMongoDriver{ +// superGroupCollection: database.Collection(unrelation.CSuperGroup), +// userToSuperGroupCollection: database.Collection(unrelation.CUserToSuperGroup), +// } +//} +// +//type SuperGroupMongoDriver struct { +// superGroupCollection *mongo.Collection +// userToSuperGroupCollection *mongo.Collection +//} +// +//func (s *SuperGroupMongoDriver) CreateSuperGroup(ctx context.Context, groupID string, initMemberIDs []string) error { +// _, err := s.superGroupCollection.InsertOne(ctx, &unrelation.SuperGroupModel{ +// GroupID: groupID, +// MemberIDs: initMemberIDs, +// }) +// if err != nil { +// return err +// } +// for _, userID := range initMemberIDs { +// _, err = s.userToSuperGroupCollection.UpdateOne( +// ctx, +// bson.M{"user_id": userID}, +// bson.M{"$addToSet": bson.M{"group_id_list": groupID}}, +// &options.UpdateOptions{ +// Upsert: utils.ToPtr(true), +// }, +// ) +// if err != nil { +// return err +// } +// } +// return nil +//} +// +//func (s *SuperGroupMongoDriver) TakeSuperGroup( +// ctx context.Context, +// groupID string, +//) (group *unrelation.SuperGroupModel, err error) { +// if err := s.superGroupCollection.FindOne(ctx, bson.M{"group_id": groupID}).Decode(&group); err != nil { +// return nil, utils.Wrap(err, "") +// } +// return group, nil +//} +// +//func (s *SuperGroupMongoDriver) FindSuperGroup( +// ctx context.Context, +// groupIDs []string, +//) (groups []*unrelation.SuperGroupModel, err error) { +// cursor, err := s.superGroupCollection.Find(ctx, bson.M{"group_id": bson.M{ +// "$in": groupIDs, +// }}) +// if err != nil { +// return nil, err +// } +// defer cursor.Close(ctx) +// if err := cursor.All(ctx, &groups); err != nil { +// return nil, utils.Wrap(err, "") +// } +// return groups, nil +//} +// +//func (s *SuperGroupMongoDriver) AddUserToSuperGroup(ctx context.Context, groupID string, userIDs []string) error { +// _, err := s.superGroupCollection.UpdateOne( +// ctx, +// bson.M{"group_id": groupID}, +// bson.M{"$addToSet": bson.M{"member_id_list": bson.M{"$each": userIDs}}}, +// ) +// if err != nil { +// return err +// } +// upsert := true +// opts := &options.UpdateOptions{ +// Upsert: &upsert, +// } +// for _, userID := range userIDs { +// _, err = s.userToSuperGroupCollection.UpdateOne( +// ctx, +// bson.M{"user_id": userID}, +// bson.M{"$addToSet": bson.M{"group_id_list": groupID}}, +// opts, +// ) +// if err != nil { +// return utils.Wrap(err, "transaction failed") +// } +// } +// return nil +//} +// +//func (s *SuperGroupMongoDriver) RemoverUserFromSuperGroup(ctx context.Context, groupID string, userIDs []string) error { +// _, err := s.superGroupCollection.UpdateOne( +// ctx, +// bson.M{"group_id": groupID}, +// bson.M{"$pull": bson.M{"member_id_list": bson.M{"$in": userIDs}}}, +// ) +// if err != nil { +// return err +// } +// err = s.RemoveGroupFromUser(ctx, groupID, userIDs) +// if err != nil { +// return err +// } +// return nil +//} +// +//func (s *SuperGroupMongoDriver) GetSuperGroupByUserID( +// ctx context.Context, +// userID string, +//) (*unrelation.UserToSuperGroupModel, error) { +// var user unrelation.UserToSuperGroupModel +// err := s.userToSuperGroupCollection.FindOne(ctx, bson.M{"user_id": userID}).Decode(&user) +// return &user, utils.Wrap(err, "") +//} +// +//func (s *SuperGroupMongoDriver) DeleteSuperGroup(ctx context.Context, groupID string) error { +// group, err := s.TakeSuperGroup(ctx, groupID) +// if err != nil { +// return err +// } +// if _, err := s.superGroupCollection.DeleteOne(ctx, bson.M{"group_id": groupID}); err != nil { +// return utils.Wrap(err, "") +// } +// return s.RemoveGroupFromUser(ctx, groupID, group.MemberIDs) +//} +// +//func (s *SuperGroupMongoDriver) RemoveGroupFromUser(ctx context.Context, groupID string, userIDs []string) error { +// _, err := s.userToSuperGroupCollection.UpdateOne( +// ctx, +// bson.M{"user_id": bson.M{"$in": userIDs}}, +// bson.M{"$pull": bson.M{"group_id_list": groupID}}, +// ) +// return utils.Wrap(err, "") +//} diff --git a/pkg/common/http/http_client.go b/pkg/common/http/http_client.go index e0cedf357..b1fdf37ef 100644 --- a/pkg/common/http/http_client.go +++ b/pkg/common/http/http_client.go @@ -58,7 +58,7 @@ func Get(url string) (response []byte, err error) { return body, nil } -func Post(ctx context.Context, url string, header map[string]string, data interface{}, timeout int) (content []byte, err error) { +func Post(ctx context.Context, url string, header map[string]string, data any, timeout int) (content []byte, err error) { if timeout > 0 { var cancel func() ctx, cancel = context.WithTimeout(ctx, time.Second*time.Duration(timeout)) @@ -97,7 +97,7 @@ func Post(ctx context.Context, url string, header map[string]string, data interf return result, nil } -func PostReturn(ctx context.Context, url string, header map[string]string, input, output interface{}, timeOutSecond int) error { +func PostReturn(ctx context.Context, url string, header map[string]string, input, output any, timeOutSecond int) error { b, err := Post(ctx, url, header, input, timeOutSecond) if err != nil { return err @@ -106,7 +106,7 @@ func PostReturn(ctx context.Context, url string, header map[string]string, input return err } -func callBackPostReturn(ctx context.Context, url, command string, input interface{}, output callbackstruct.CallbackResp, callbackConfig config.CallBackConfig) error { +func callBackPostReturn(ctx context.Context, url, command string, input any, output callbackstruct.CallbackResp, callbackConfig config.CallBackConfig) error { defer log.ZDebug(ctx, "callback", "url", url, "command", command, "input", input, "callbackConfig", callbackConfig) v := urllib.Values{} diff --git a/pkg/common/http/http_client_test.go b/pkg/common/http/http_client_test.go index 1735a3da7..5d2588673 100644 --- a/pkg/common/http/http_client_test.go +++ b/pkg/common/http/http_client_test.go @@ -54,7 +54,7 @@ func TestPost(t *testing.T) { ctx context.Context url string header map[string]string - data interface{} + data any timeout int } tests := []struct { @@ -84,8 +84,8 @@ func TestPostReturn(t *testing.T) { ctx context.Context url string header map[string]string - input interface{} - output interface{} + input any + output any timeOutSecond int } tests := []struct { @@ -109,7 +109,7 @@ func Test_callBackPostReturn(t *testing.T) { ctx context.Context url string command string - input interface{} + input any output callbackstruct.CallbackResp callbackConfig config.CallBackConfig } diff --git a/pkg/common/pagination/pagination.go b/pkg/common/pagination/pagination.go new file mode 100644 index 000000000..8e779d685 --- /dev/null +++ b/pkg/common/pagination/pagination.go @@ -0,0 +1,6 @@ +package pagination + +type Pagination interface { + GetPageNumber() int32 + GetShowNumber() int32 +} diff --git a/pkg/rpcclient/grouphash/grouphash.go b/pkg/rpcclient/grouphash/grouphash.go new file mode 100644 index 000000000..7765493fd --- /dev/null +++ b/pkg/rpcclient/grouphash/grouphash.go @@ -0,0 +1,87 @@ +package grouphash + +import ( + "context" + "crypto/md5" + "encoding/binary" + "encoding/json" + "github.com/OpenIMSDK/protocol/group" + "github.com/OpenIMSDK/protocol/sdkws" + "github.com/OpenIMSDK/tools/utils" +) + +func NewGroupHashFromGroupClient(x group.GroupClient) *GroupHash { + return &GroupHash{ + getGroupAllUserIDs: func(ctx context.Context, groupID string) ([]string, error) { + resp, err := x.GetGroupMemberUserIDs(ctx, &group.GetGroupMemberUserIDsReq{GroupID: groupID}) + if err != nil { + return nil, err + } + return resp.UserIDs, nil + }, + getGroupMemberInfo: func(ctx context.Context, groupID string, userIDs []string) ([]*sdkws.GroupMemberFullInfo, error) { + resp, err := x.GetGroupMembersInfo(ctx, &group.GetGroupMembersInfoReq{GroupID: groupID, UserIDs: userIDs}) + if err != nil { + return nil, err + } + return resp.Members, nil + }, + } +} + +func NewGroupHashFromGroupServer(x group.GroupServer) *GroupHash { + return &GroupHash{ + getGroupAllUserIDs: func(ctx context.Context, groupID string) ([]string, error) { + resp, err := x.GetGroupMemberUserIDs(ctx, &group.GetGroupMemberUserIDsReq{GroupID: groupID}) + if err != nil { + return nil, err + } + return resp.UserIDs, nil + }, + getGroupMemberInfo: func(ctx context.Context, groupID string, userIDs []string) ([]*sdkws.GroupMemberFullInfo, error) { + resp, err := x.GetGroupMembersInfo(ctx, &group.GetGroupMembersInfoReq{GroupID: groupID, UserIDs: userIDs}) + if err != nil { + return nil, err + } + return resp.Members, nil + }, + } +} + +type GroupHash struct { + getGroupAllUserIDs func(ctx context.Context, groupID string) ([]string, error) + getGroupMemberInfo func(ctx context.Context, groupID string, userIDs []string) ([]*sdkws.GroupMemberFullInfo, error) +} + +func (gh *GroupHash) GetGroupHash(ctx context.Context, groupID string) (uint64, error) { + userIDs, err := gh.getGroupAllUserIDs(ctx, groupID) + if err != nil { + return 0, err + } + var members []*sdkws.GroupMemberFullInfo + if len(userIDs) > 0 { + members, err = gh.getGroupMemberInfo(ctx, groupID, userIDs) + if err != nil { + return 0, err + } + utils.Sort(userIDs, true) + } + memberMap := utils.SliceToMap(members, func(e *sdkws.GroupMemberFullInfo) string { + return e.UserID + }) + res := make([]*sdkws.GroupMemberFullInfo, 0, len(members)) + for _, userID := range userIDs { + member, ok := memberMap[userID] + if !ok { + continue + } + member.AppMangerLevel = 0 + res = append(res, member) + } + data, err := json.Marshal(res) + if err != nil { + return 0, err + } + sum := md5.Sum(data) + return binary.BigEndian.Uint64(sum[:]), nil +} diff --git a/pkg/rpcclient/notification/group.go b/pkg/rpcclient/notification/group.go index 8e71f61c3..97e18d5ef 100755 --- a/pkg/rpcclient/notification/group.go +++ b/pkg/rpcclient/notification/group.go @@ -52,6 +52,41 @@ type GroupNotificationSender struct { db controller.GroupDatabase } +func (g *GroupNotificationSender) PopulateGroupMember(ctx context.Context, members ...*relation.GroupMemberModel) error { + if len(members) == 0 { + return nil + } + emptyUserIDs := make(map[string]struct{}) + for _, member := range members { + if member.Nickname == "" || member.FaceURL == "" { + emptyUserIDs[member.UserID] = struct{}{} + } + } + if len(emptyUserIDs) > 0 { + users, err := g.getUsersInfo(ctx, utils.Keys(emptyUserIDs)) + if err != nil { + return err + } + userMap := make(map[string]CommonUser) + for i, user := range users { + userMap[user.GetUserID()] = users[i] + } + for i, member := range members { + user, ok := userMap[member.UserID] + if !ok { + continue + } + if member.Nickname == "" { + members[i].Nickname = user.GetNickname() + } + if member.FaceURL == "" { + members[i].FaceURL = user.GetFaceURL() + } + } + } + return nil +} + func (g *GroupNotificationSender) getUser(ctx context.Context, userID string) (*sdkws.PublicUserInfo, error) { users, err := g.getUsersInfo(ctx, []string{userID}) if err != nil { @@ -103,10 +138,13 @@ func (g *GroupNotificationSender) getGroupInfo(ctx context.Context, groupID stri } func (g *GroupNotificationSender) getGroupMembers(ctx context.Context, groupID string, userIDs []string) ([]*sdkws.GroupMemberFullInfo, error) { - members, err := g.db.FindGroupMember(ctx, []string{groupID}, userIDs, nil) + members, err := g.db.FindGroupMembers(ctx, groupID, userIDs) if err != nil { return nil, err } + if err := g.PopulateGroupMember(ctx, members...); err != nil { + return nil, err + } log.ZDebug(ctx, "getGroupMembers", "members", members) users, err := g.getUsersInfoMap(ctx, userIDs) if err != nil { @@ -125,17 +163,6 @@ func (g *GroupNotificationSender) getGroupMembers(ctx context.Context, groupID s res = append(res, g.groupMemberDB2PB(member, user.AppMangerLevel)) delete(users, member.UserID) } - //for userID, info := range users { - // if info.AppMangerLevel == constant.AppAdmin { - // res = append(res, &sdkws.GroupMemberFullInfo{ - // GroupID: groupID, - // UserID: userID, - // Nickname: info.Nickname, - // FaceURL: info.FaceURL, - // AppMangerLevel: info.AppMangerLevel, - // }) - // } - //} return res, nil } @@ -163,10 +190,13 @@ func (g *GroupNotificationSender) getGroupMember(ctx context.Context, groupID st } func (g *GroupNotificationSender) getGroupOwnerAndAdminUserID(ctx context.Context, groupID string) ([]string, error) { - members, err := g.db.FindGroupMember(ctx, []string{groupID}, nil, []int32{constant.GroupOwner, constant.GroupAdmin}) + members, err := g.db.FindGroupMemberRoleLevels(ctx, groupID, []int32{constant.GroupOwner, constant.GroupAdmin}) if err != nil { return nil, err } + if err := g.PopulateGroupMember(ctx, members...); err != nil { + return nil, err + } fn := func(e *relation.GroupMemberModel) string { return e.UserID } return utils.Slice(members, fn), nil } diff --git a/test/e2e/api/token/token.go b/test/e2e/api/token/token.go index 679c0bbda..4c578e8f7 100644 --- a/test/e2e/api/token/token.go +++ b/test/e2e/api/token/token.go @@ -125,7 +125,7 @@ func RegisterUser(token, userID, nickname, faceURL string) error { return err } - var respData map[string]interface{} + var respData map[string]any if err := json.Unmarshal(respBody, &respData); err != nil { return err } diff --git a/test/e2e/api/user/user.go b/test/e2e/api/user/user.go index 66419b735..9facf76ac 100644 --- a/test/e2e/api/user/user.go +++ b/test/e2e/api/user/user.go @@ -71,7 +71,7 @@ func GetUsers(token string, pageNumber, showNumber int) error { } // sendPostRequestWithToken sends a POST request with a token in the header -func sendPostRequestWithToken(url, token string, body interface{}) error { +func sendPostRequestWithToken(url, token string, body any) error { reqBytes, err := json.Marshal(body) if err != nil { return err @@ -98,7 +98,7 @@ func sendPostRequestWithToken(url, token string, body interface{}) error { return err } - var respData map[string]interface{} + var respData map[string]any if err := json.Unmarshal(respBody, &respData); err != nil { return err } diff --git a/test/jwt/main.go b/test/jwt/main.go index a669df9d6..0ef845237 100644 --- a/test/jwt/main.go +++ b/test/jwt/main.go @@ -25,7 +25,7 @@ func main() { // Verify the token claims := &jwt.MapClaims{} - parsedT, err := jwt.ParseWithClaims(rawJWT, claims, func(token *jwt.Token) (interface{}, error) { + parsedT, err := jwt.ParseWithClaims(rawJWT, claims, func(token *jwt.Token) (any, error) { // Validate the alg is HMAC signature if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"]) diff --git a/test/typecheck/typecheck.go b/test/typecheck/typecheck.go index 0fc33597b..83e3c63ed 100644 --- a/test/typecheck/typecheck.go +++ b/test/typecheck/typecheck.go @@ -239,7 +239,7 @@ func dedup(errors []packages.Error) []string { var outMu sync.Mutex -func serialFprintf(w io.Writer, format string, a ...interface{}) (n int, err error) { +func serialFprintf(w io.Writer, format string, a ...any) (n int, err error) { outMu.Lock() defer outMu.Unlock() return fmt.Fprintf(w, format, a...) diff --git a/tools/data-conversion/openim/mysql/conversion/conversion.go b/tools/data-conversion/openim/mysql/conversion/conversion.go index 298eefb50..54cf90edf 100644 --- a/tools/data-conversion/openim/mysql/conversion/conversion.go +++ b/tools/data-conversion/openim/mysql/conversion/conversion.go @@ -3,8 +3,8 @@ package conversion import ( "github.com/OpenIMSDK/protocol/constant" - v3 "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" v2 "github.com/openimsdk/open-im-server/v3/tools/data-conversion/openim/mysql/v2" + v3 "github.com/openimsdk/open-im-server/v3/tools/data-conversion/openim/mysql/v3" "github.com/openimsdk/open-im-server/v3/tools/data-conversion/utils" ) diff --git a/tools/data-conversion/openim/mysql/v3/black.go b/tools/data-conversion/openim/mysql/v3/black.go new file mode 100644 index 000000000..59dd12122 --- /dev/null +++ b/tools/data-conversion/openim/mysql/v3/black.go @@ -0,0 +1,49 @@ +// Copyright © 2023 OpenIM. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package relation + +import ( + "context" + "time" +) + +const ( + BlackModelTableName = "blacks" +) + +type BlackModel struct { + OwnerUserID string `gorm:"column:owner_user_id;primary_key;size:64"` + BlockUserID string `gorm:"column:block_user_id;primary_key;size:64"` + CreateTime time.Time `gorm:"column:create_time"` + AddSource int32 `gorm:"column:add_source"` + OperatorUserID string `gorm:"column:operator_user_id;size:64"` + Ex string `gorm:"column:ex;size:1024"` +} + +func (BlackModel) TableName() string { + return BlackModelTableName +} + +type BlackModelInterface interface { + Create(ctx context.Context, blacks []*BlackModel) (err error) + Delete(ctx context.Context, blacks []*BlackModel) (err error) + UpdateByMap(ctx context.Context, ownerUserID, blockUserID string, args map[string]interface{}) (err error) + Update(ctx context.Context, blacks []*BlackModel) (err error) + Find(ctx context.Context, blacks []*BlackModel) (blackList []*BlackModel, err error) + Take(ctx context.Context, ownerUserID, blockUserID string) (black *BlackModel, err error) + FindOwnerBlacks(ctx context.Context, ownerUserID string, pageNumber, showNumber int32) (blacks []*BlackModel, total int64, err error) + FindOwnerBlackInfos(ctx context.Context, ownerUserID string, userIDs []string) (blacks []*BlackModel, err error) + FindBlackUserIDs(ctx context.Context, ownerUserID string) (blackUserIDs []string, err error) +} diff --git a/tools/data-conversion/openim/mysql/v3/chatlog.go b/tools/data-conversion/openim/mysql/v3/chatlog.go new file mode 100644 index 000000000..810de3db3 --- /dev/null +++ b/tools/data-conversion/openim/mysql/v3/chatlog.go @@ -0,0 +1,51 @@ +// Copyright © 2023 OpenIM. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package relation + +import ( + "time" + + pbmsg "github.com/OpenIMSDK/protocol/msg" +) + +const ( + ChatLogModelTableName = "chat_logs" +) + +type ChatLogModel struct { + ServerMsgID string `gorm:"column:server_msg_id;primary_key;type:char(64)" json:"serverMsgID"` + ClientMsgID string `gorm:"column:client_msg_id;type:char(64)" json:"clientMsgID"` + SendID string `gorm:"column:send_id;type:char(64);index:send_id,priority:2" json:"sendID"` + RecvID string `gorm:"column:recv_id;type:char(64);index:recv_id,priority:2" json:"recvID"` + SenderPlatformID int32 `gorm:"column:sender_platform_id" json:"senderPlatformID"` + SenderNickname string `gorm:"column:sender_nick_name;type:varchar(255)" json:"senderNickname"` + SenderFaceURL string `gorm:"column:sender_face_url;type:varchar(255);" json:"senderFaceURL"` + SessionType int32 `gorm:"column:session_type;index:session_type,priority:2;index:session_type_alone" json:"sessionType"` + MsgFrom int32 `gorm:"column:msg_from" json:"msgFrom"` + ContentType int32 `gorm:"column:content_type;index:content_type,priority:2;index:content_type_alone" json:"contentType"` + Content string `gorm:"column:content;type:varchar(3000)" json:"content"` + Status int32 `gorm:"column:status" json:"status"` + SendTime time.Time `gorm:"column:send_time;index:sendTime;index:content_type,priority:1;index:session_type,priority:1;index:recv_id,priority:1;index:send_id,priority:1" json:"sendTime"` + CreateTime time.Time `gorm:"column:create_time" json:"createTime"` + Ex string `gorm:"column:ex;type:varchar(1024)" json:"ex"` +} + +func (ChatLogModel) TableName() string { + return ChatLogModelTableName +} + +type ChatLogModelInterface interface { + Create(msg *pbmsg.MsgDataToMQ) error +} diff --git a/tools/data-conversion/openim/mysql/v3/conversation.go b/tools/data-conversion/openim/mysql/v3/conversation.go new file mode 100644 index 000000000..e9680873f --- /dev/null +++ b/tools/data-conversion/openim/mysql/v3/conversation.go @@ -0,0 +1,73 @@ +// Copyright © 2023 OpenIM. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package relation + +import ( + "context" + "time" +) + +const ( + conversationModelTableName = "conversations" +) + +type ConversationModel struct { + OwnerUserID string `gorm:"column:owner_user_id;primary_key;type:char(128)" json:"OwnerUserID"` + ConversationID string `gorm:"column:conversation_id;primary_key;type:char(128)" json:"conversationID"` + ConversationType int32 `gorm:"column:conversation_type" json:"conversationType"` + UserID string `gorm:"column:user_id;type:char(64)" json:"userID"` + GroupID string `gorm:"column:group_id;type:char(128)" json:"groupID"` + RecvMsgOpt int32 `gorm:"column:recv_msg_opt" json:"recvMsgOpt"` + IsPinned bool `gorm:"column:is_pinned" json:"isPinned"` + IsPrivateChat bool `gorm:"column:is_private_chat" json:"isPrivateChat"` + BurnDuration int32 `gorm:"column:burn_duration;default:30" json:"burnDuration"` + GroupAtType int32 `gorm:"column:group_at_type" json:"groupAtType"` + AttachedInfo string `gorm:"column:attached_info;type:varchar(1024)" json:"attachedInfo"` + Ex string `gorm:"column:ex;type:varchar(1024)" json:"ex"` + MaxSeq int64 `gorm:"column:max_seq" json:"maxSeq"` + MinSeq int64 `gorm:"column:min_seq" json:"minSeq"` + CreateTime time.Time `gorm:"column:create_time;index:create_time;autoCreateTime"` + IsMsgDestruct bool `gorm:"column:is_msg_destruct;default:false"` + MsgDestructTime int64 `gorm:"column:msg_destruct_time;default:604800"` + LatestMsgDestructTime time.Time `gorm:"column:latest_msg_destruct_time;autoCreateTime"` +} + +func (ConversationModel) TableName() string { + return conversationModelTableName +} + +type ConversationModelInterface interface { + Create(ctx context.Context, conversations []*ConversationModel) (err error) + Delete(ctx context.Context, groupIDs []string) (err error) + UpdateByMap(ctx context.Context, userIDs []string, conversationID string, args map[string]interface{}) (rows int64, err error) + Update(ctx context.Context, conversation *ConversationModel) (err error) + Find(ctx context.Context, ownerUserID string, conversationIDs []string) (conversations []*ConversationModel, err error) + FindUserID(ctx context.Context, userIDs []string, conversationIDs []string) ([]string, error) + FindUserIDAllConversationID(ctx context.Context, userID string) ([]string, error) + Take(ctx context.Context, userID, conversationID string) (conversation *ConversationModel, err error) + FindConversationID(ctx context.Context, userID string, conversationIDs []string) (existConversationID []string, err error) + FindUserIDAllConversations(ctx context.Context, userID string) (conversations []*ConversationModel, err error) + FindRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) ([]string, error) + GetUserRecvMsgOpt(ctx context.Context, ownerUserID, conversationID string) (opt int, err error) + FindSuperGroupRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) ([]string, error) + GetAllConversationIDs(ctx context.Context) ([]string, error) + GetAllConversationIDsNumber(ctx context.Context) (int64, error) + PageConversationIDs(ctx context.Context, pageNumber, showNumber int32) (conversationIDs []string, err error) + GetUserAllHasReadSeqs(ctx context.Context, ownerUserID string) (hashReadSeqs map[string]int64, err error) + GetConversationsByConversationID(ctx context.Context, conversationIDs []string) ([]*ConversationModel, error) + GetConversationIDsNeedDestruct(ctx context.Context) ([]*ConversationModel, error) + GetConversationNotReceiveMessageUserIDs(ctx context.Context, conversationID string) ([]string, error) + NewTx(tx any) ConversationModelInterface +} diff --git a/tools/data-conversion/openim/mysql/v3/doc.go b/tools/data-conversion/openim/mysql/v3/doc.go new file mode 100644 index 000000000..32185c8c7 --- /dev/null +++ b/tools/data-conversion/openim/mysql/v3/doc.go @@ -0,0 +1,15 @@ +// Copyright © 2023 OpenIM. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package relation // import "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" diff --git a/tools/data-conversion/openim/mysql/v3/friend.go b/tools/data-conversion/openim/mysql/v3/friend.go new file mode 100644 index 000000000..58d8d1d34 --- /dev/null +++ b/tools/data-conversion/openim/mysql/v3/friend.go @@ -0,0 +1,78 @@ +// Copyright © 2023 OpenIM. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package relation + +import ( + "context" + "time" +) + +const ( + FriendModelTableName = "friends" +) + +type FriendModel struct { + OwnerUserID string `gorm:"column:owner_user_id;primary_key;size:64"` + FriendUserID string `gorm:"column:friend_user_id;primary_key;size:64"` + Remark string `gorm:"column:remark;size:255"` + CreateTime time.Time `gorm:"column:create_time;autoCreateTime"` + AddSource int32 `gorm:"column:add_source"` + OperatorUserID string `gorm:"column:operator_user_id;size:64"` + Ex string `gorm:"column:ex;size:1024"` +} + +func (FriendModel) TableName() string { + return FriendModelTableName +} + +type FriendModelInterface interface { + // 插入多条记录 + Create(ctx context.Context, friends []*FriendModel) (err error) + // 删除ownerUserID指定的好友 + Delete(ctx context.Context, ownerUserID string, friendUserIDs []string) (err error) + // 更新ownerUserID单个好友信息 更新零值 + UpdateByMap(ctx context.Context, ownerUserID string, friendUserID string, args map[string]interface{}) (err error) + // 更新好友信息的非零值 + Update(ctx context.Context, friends []*FriendModel) (err error) + // 更新好友备注(也支持零值 ) + UpdateRemark(ctx context.Context, ownerUserID, friendUserID, remark string) (err error) + // 获取单个好友信息,如没找到 返回错误 + Take(ctx context.Context, ownerUserID, friendUserID string) (friend *FriendModel, err error) + // 查找好友关系,如果是双向关系,则都返回 + FindUserState(ctx context.Context, userID1, userID2 string) (friends []*FriendModel, err error) + // 获取 owner指定的好友列表 如果有friendUserIDs不存在,也不返回错误 + FindFriends(ctx context.Context, ownerUserID string, friendUserIDs []string) (friends []*FriendModel, err error) + // 获取哪些人添加了friendUserID 如果有ownerUserIDs不存在,也不返回错误 + FindReversalFriends( + ctx context.Context, + friendUserID string, + ownerUserIDs []string, + ) (friends []*FriendModel, err error) + // 获取ownerUserID好友列表 支持翻页 + FindOwnerFriends( + ctx context.Context, + ownerUserID string, + pageNumber, showNumber int32, + ) (friends []*FriendModel, total int64, err error) + // 获取哪些人添加了friendUserID 支持翻页 + FindInWhoseFriends( + ctx context.Context, + friendUserID string, + pageNumber, showNumber int32, + ) (friends []*FriendModel, total int64, err error) + // 获取好友UserID列表 + FindFriendUserIDs(ctx context.Context, ownerUserID string) (friendUserIDs []string, err error) + NewTx(tx any) FriendModelInterface +} diff --git a/tools/data-conversion/openim/mysql/v3/friend_request.go b/tools/data-conversion/openim/mysql/v3/friend_request.go new file mode 100644 index 000000000..51ea0ef6e --- /dev/null +++ b/tools/data-conversion/openim/mysql/v3/friend_request.go @@ -0,0 +1,66 @@ +// Copyright © 2023 OpenIM. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package relation + +import ( + "context" + "time" +) + +const FriendRequestModelTableName = "friend_requests" + +type FriendRequestModel struct { + FromUserID string `gorm:"column:from_user_id;primary_key;size:64"` + ToUserID string `gorm:"column:to_user_id;primary_key;size:64"` + HandleResult int32 `gorm:"column:handle_result"` + ReqMsg string `gorm:"column:req_msg;size:255"` + CreateTime time.Time `gorm:"column:create_time; autoCreateTime"` + HandlerUserID string `gorm:"column:handler_user_id;size:64"` + HandleMsg string `gorm:"column:handle_msg;size:255"` + HandleTime time.Time `gorm:"column:handle_time"` + Ex string `gorm:"column:ex;size:1024"` +} + +func (FriendRequestModel) TableName() string { + return FriendRequestModelTableName +} + +type FriendRequestModelInterface interface { + // 插入多条记录 + Create(ctx context.Context, friendRequests []*FriendRequestModel) (err error) + // 删除记录 + Delete(ctx context.Context, fromUserID, toUserID string) (err error) + // 更新零值 + UpdateByMap(ctx context.Context, formUserID string, toUserID string, args map[string]interface{}) (err error) + // 更新多条记录 (非零值) + Update(ctx context.Context, friendRequest *FriendRequestModel) (err error) + // 获取来指定用户的好友申请 未找到 不返回错误 + Find(ctx context.Context, fromUserID, toUserID string) (friendRequest *FriendRequestModel, err error) + Take(ctx context.Context, fromUserID, toUserID string) (friendRequest *FriendRequestModel, err error) + // 获取toUserID收到的好友申请列表 + FindToUserID( + ctx context.Context, + toUserID string, + pageNumber, showNumber int32, + ) (friendRequests []*FriendRequestModel, total int64, err error) + // 获取fromUserID发出去的好友申请列表 + FindFromUserID( + ctx context.Context, + fromUserID string, + pageNumber, showNumber int32, + ) (friendRequests []*FriendRequestModel, total int64, err error) + FindBothFriendRequests(ctx context.Context, fromUserID, toUserID string) (friends []*FriendRequestModel, err error) + NewTx(tx any) FriendRequestModelInterface +} diff --git a/tools/data-conversion/openim/mysql/v3/group.go b/tools/data-conversion/openim/mysql/v3/group.go new file mode 100644 index 000000000..6759e0d35 --- /dev/null +++ b/tools/data-conversion/openim/mysql/v3/group.go @@ -0,0 +1,66 @@ +// Copyright © 2023 OpenIM. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package relation + +import ( + "context" + "time" +) + +const ( + GroupModelTableName = "groups" +) + +type GroupModel struct { + GroupID string `gorm:"column:group_id;primary_key;size:64" json:"groupID" binding:"required"` + GroupName string `gorm:"column:name;size:255" json:"groupName"` + Notification string `gorm:"column:notification;size:255" json:"notification"` + Introduction string `gorm:"column:introduction;size:255" json:"introduction"` + FaceURL string `gorm:"column:face_url;size:255" json:"faceURL"` + CreateTime time.Time `gorm:"column:create_time;index:create_time;autoCreateTime"` + Ex string `gorm:"column:ex" json:"ex;size:1024"` + Status int32 `gorm:"column:status"` + CreatorUserID string `gorm:"column:creator_user_id;size:64"` + GroupType int32 `gorm:"column:group_type"` + NeedVerification int32 `gorm:"column:need_verification"` + LookMemberInfo int32 `gorm:"column:look_member_info" json:"lookMemberInfo"` + ApplyMemberFriend int32 `gorm:"column:apply_member_friend" json:"applyMemberFriend"` + NotificationUpdateTime time.Time `gorm:"column:notification_update_time"` + NotificationUserID string `gorm:"column:notification_user_id;size:64"` +} + +func (GroupModel) TableName() string { + return GroupModelTableName +} + +type GroupModelInterface interface { + NewTx(tx any) GroupModelInterface + Create(ctx context.Context, groups []*GroupModel) (err error) + UpdateMap(ctx context.Context, groupID string, args map[string]interface{}) (err error) + UpdateStatus(ctx context.Context, groupID string, status int32) (err error) + Find(ctx context.Context, groupIDs []string) (groups []*GroupModel, err error) + FindNotDismissedGroup(ctx context.Context, groupIDs []string) (groups []*GroupModel, err error) + Take(ctx context.Context, groupID string) (group *GroupModel, err error) + Search( + ctx context.Context, + keyword string, + pageNumber, showNumber int32, + ) (total uint32, groups []*GroupModel, err error) + GetGroupIDsByGroupType(ctx context.Context, groupType int) (groupIDs []string, err error) + // 获取群总数 + CountTotal(ctx context.Context, before *time.Time) (count int64, err error) + // 获取范围内群增量 + CountRangeEverydayTotal(ctx context.Context, start time.Time, end time.Time) (map[string]int64, error) +} diff --git a/tools/data-conversion/openim/mysql/v3/group_member.go b/tools/data-conversion/openim/mysql/v3/group_member.go new file mode 100644 index 000000000..bfde72834 --- /dev/null +++ b/tools/data-conversion/openim/mysql/v3/group_member.go @@ -0,0 +1,74 @@ +// Copyright © 2023 OpenIM. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package relation + +import ( + "context" + "time" +) + +const ( + GroupMemberModelTableName = "group_members" +) + +type GroupMemberModel struct { + GroupID string `gorm:"column:group_id;primary_key;size:64"` + UserID string `gorm:"column:user_id;primary_key;size:64"` + Nickname string `gorm:"column:nickname;size:255"` + FaceURL string `gorm:"column:user_group_face_url;size:255"` + RoleLevel int32 `gorm:"column:role_level"` + JoinTime time.Time `gorm:"column:join_time"` + JoinSource int32 `gorm:"column:join_source"` + InviterUserID string `gorm:"column:inviter_user_id;size:64"` + OperatorUserID string `gorm:"column:operator_user_id;size:64"` + MuteEndTime time.Time `gorm:"column:mute_end_time"` + Ex string `gorm:"column:ex;size:1024"` +} + +func (GroupMemberModel) TableName() string { + return GroupMemberModelTableName +} + +type GroupMemberModelInterface interface { + NewTx(tx any) GroupMemberModelInterface + Create(ctx context.Context, groupMembers []*GroupMemberModel) (err error) + Delete(ctx context.Context, groupID string, userIDs []string) (err error) + DeleteGroup(ctx context.Context, groupIDs []string) (err error) + Update(ctx context.Context, groupID string, userID string, data map[string]any) (err error) + UpdateRoleLevel(ctx context.Context, groupID string, userID string, roleLevel int32) (rowsAffected int64, err error) + Find( + ctx context.Context, + groupIDs []string, + userIDs []string, + roleLevels []int32, + ) (groupMembers []*GroupMemberModel, err error) + FindMemberUserID(ctx context.Context, groupID string) (userIDs []string, err error) + Take(ctx context.Context, groupID string, userID string) (groupMember *GroupMemberModel, err error) + TakeOwner(ctx context.Context, groupID string) (groupMember *GroupMemberModel, err error) + SearchMember( + ctx context.Context, + keyword string, + groupIDs []string, + userIDs []string, + roleLevels []int32, + pageNumber, showNumber int32, + ) (total uint32, groupList []*GroupMemberModel, err error) + MapGroupMemberNum(ctx context.Context, groupIDs []string) (count map[string]uint32, err error) + FindJoinUserID(ctx context.Context, groupIDs []string) (groupUsers map[string][]string, err error) + FindUserJoinedGroupID(ctx context.Context, userID string) (groupIDs []string, err error) + TakeGroupMemberNum(ctx context.Context, groupID string) (count int64, err error) + FindUsersJoinedGroupID(ctx context.Context, userIDs []string) (map[string][]string, error) + FindUserManagedGroupID(ctx context.Context, userID string) (groupIDs []string, err error) +} diff --git a/tools/data-conversion/openim/mysql/v3/group_request.go b/tools/data-conversion/openim/mysql/v3/group_request.go new file mode 100644 index 000000000..063b83938 --- /dev/null +++ b/tools/data-conversion/openim/mysql/v3/group_request.go @@ -0,0 +1,61 @@ +// Copyright © 2023 OpenIM. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package relation + +import ( + "context" + "time" +) + +const ( + GroupRequestModelTableName = "group_requests" +) + +type GroupRequestModel struct { + UserID string `gorm:"column:user_id;primary_key;size:64"` + GroupID string `gorm:"column:group_id;primary_key;size:64"` + HandleResult int32 `gorm:"column:handle_result"` + ReqMsg string `gorm:"column:req_msg;size:1024"` + HandledMsg string `gorm:"column:handle_msg;size:1024"` + ReqTime time.Time `gorm:"column:req_time"` + HandleUserID string `gorm:"column:handle_user_id;size:64"` + HandledTime time.Time `gorm:"column:handle_time"` + JoinSource int32 `gorm:"column:join_source"` + InviterUserID string `gorm:"column:inviter_user_id;size:64"` + Ex string `gorm:"column:ex;size:1024"` +} + +func (GroupRequestModel) TableName() string { + return GroupRequestModelTableName +} + +type GroupRequestModelInterface interface { + NewTx(tx any) GroupRequestModelInterface + Create(ctx context.Context, groupRequests []*GroupRequestModel) (err error) + Delete(ctx context.Context, groupID string, userID string) (err error) + UpdateHandler(ctx context.Context, groupID string, userID string, handledMsg string, handleResult int32) (err error) + Take(ctx context.Context, groupID string, userID string) (groupRequest *GroupRequestModel, err error) + FindGroupRequests(ctx context.Context, groupID string, userIDs []string) (int64, []*GroupRequestModel, error) + Page( + ctx context.Context, + userID string, + pageNumber, showNumber int32, + ) (total uint32, groups []*GroupRequestModel, err error) + PageGroup( + ctx context.Context, + groupIDs []string, + pageNumber, showNumber int32, + ) (total uint32, groups []*GroupRequestModel, err error) +} diff --git a/tools/data-conversion/openim/mysql/v3/log.go b/tools/data-conversion/openim/mysql/v3/log.go new file mode 100644 index 000000000..72d0fa64e --- /dev/null +++ b/tools/data-conversion/openim/mysql/v3/log.go @@ -0,0 +1,25 @@ +package relation + +import ( + "context" + "time" +) + +type Log struct { + LogID string `gorm:"column:log_id;primary_key;type:char(64)"` + Platform string `gorm:"column:platform;type:varchar(32)"` + UserID string `gorm:"column:user_id;type:char(64)"` + CreateTime time.Time `gorm:"index:,sort:desc"` + Url string `gorm:"column:url;type varchar(255)"` + FileName string `gorm:"column:filename;type varchar(255)"` + SystemType string `gorm:"column:system_type;type varchar(255)"` + Version string `gorm:"column:version;type varchar(255)"` + Ex string `gorm:"column:ex;type varchar(255)"` +} + +type LogInterface interface { + Create(ctx context.Context, log []*Log) error + Search(ctx context.Context, keyword string, start time.Time, end time.Time, pageNumber int32, showNumber int32) (uint32, []*Log, error) + Delete(ctx context.Context, logID []string, userID string) error + Get(ctx context.Context, logIDs []string, userID string) ([]*Log, error) +} diff --git a/tools/data-conversion/openim/mysql/v3/object.go b/tools/data-conversion/openim/mysql/v3/object.go new file mode 100644 index 000000000..0ed4130a6 --- /dev/null +++ b/tools/data-conversion/openim/mysql/v3/object.go @@ -0,0 +1,45 @@ +// Copyright © 2023 OpenIM. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package relation + +import ( + "context" + "time" +) + +const ( + ObjectInfoModelTableName = "object" +) + +type ObjectModel struct { + Name string `gorm:"column:name;primary_key"` + UserID string `gorm:"column:user_id"` + Hash string `gorm:"column:hash"` + Key string `gorm:"column:key"` + Size int64 `gorm:"column:size"` + ContentType string `gorm:"column:content_type"` + Cause string `gorm:"column:cause"` + CreateTime time.Time `gorm:"column:create_time"` +} + +func (ObjectModel) TableName() string { + return ObjectInfoModelTableName +} + +type ObjectInfoModelInterface interface { + NewTx(tx any) ObjectInfoModelInterface + SetObject(ctx context.Context, obj *ObjectModel) error + Take(ctx context.Context, name string) (*ObjectModel, error) +} diff --git a/tools/data-conversion/openim/mysql/v3/user.go b/tools/data-conversion/openim/mysql/v3/user.go new file mode 100644 index 000000000..10a715bda --- /dev/null +++ b/tools/data-conversion/openim/mysql/v3/user.go @@ -0,0 +1,72 @@ +// Copyright © 2023 OpenIM. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package relation + +import ( + "context" + "time" +) + +const ( + UserModelTableName = "users" +) + +type UserModel struct { + UserID string `gorm:"column:user_id;primary_key;size:64"` + Nickname string `gorm:"column:name;size:255"` + FaceURL string `gorm:"column:face_url;size:255"` + Ex string `gorm:"column:ex;size:1024"` + CreateTime time.Time `gorm:"column:create_time;index:create_time;autoCreateTime"` + AppMangerLevel int32 `gorm:"column:app_manger_level;default:1"` + GlobalRecvMsgOpt int32 `gorm:"column:global_recv_msg_opt"` +} + +func (u *UserModel) GetNickname() string { + return u.Nickname +} + +func (u *UserModel) GetFaceURL() string { + return u.FaceURL +} + +func (u *UserModel) GetUserID() string { + return u.UserID +} + +func (u *UserModel) GetEx() string { + return u.Ex +} + +func (UserModel) TableName() string { + return UserModelTableName +} + +type UserModelInterface interface { + Create(ctx context.Context, users []*UserModel) (err error) + UpdateByMap(ctx context.Context, userID string, args map[string]interface{}) (err error) + Update(ctx context.Context, user *UserModel) (err error) + // 获取指定用户信息 不存在,也不返回错误 + Find(ctx context.Context, userIDs []string) (users []*UserModel, err error) + // 获取某个用户信息 不存在,则返回错误 + Take(ctx context.Context, userID string) (user *UserModel, err error) + // 获取用户信息 不存在,不返回错误 + Page(ctx context.Context, pageNumber, showNumber int32) (users []*UserModel, count int64, err error) + GetAllUserID(ctx context.Context, pageNumber, showNumber int32) (userIDs []string, err error) + GetUserGlobalRecvMsgOpt(ctx context.Context, userID string) (opt int, err error) + // 获取用户总数 + CountTotal(ctx context.Context, before *time.Time) (count int64, err error) + // 获取范围内用户增量 + CountRangeEverydayTotal(ctx context.Context, start time.Time, end time.Time) (map[string]int64, error) +} diff --git a/tools/data-conversion/openim/mysql/v3/utils.go b/tools/data-conversion/openim/mysql/v3/utils.go new file mode 100644 index 000000000..c944eae8b --- /dev/null +++ b/tools/data-conversion/openim/mysql/v3/utils.go @@ -0,0 +1,36 @@ +// Copyright © 2023 OpenIM. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package relation + +import ( + "gorm.io/gorm" + + "github.com/OpenIMSDK/tools/utils" +) + +type BatchUpdateGroupMember struct { + GroupID string + UserID string + Map map[string]any +} + +type GroupSimpleUserID struct { + Hash uint64 + MemberNum uint32 +} + +func IsNotFound(err error) bool { + return utils.Unwrap(err) == gorm.ErrRecordNotFound +} diff --git a/tools/data-conversion/openim/proto/msg/msg.pb.go b/tools/data-conversion/openim/proto/msg/msg.pb.go index 2954a3a76..a0a6cdf02 100644 --- a/tools/data-conversion/openim/proto/msg/msg.pb.go +++ b/tools/data-conversion/openim/proto/msg/msg.pb.go @@ -2703,7 +2703,7 @@ func RegisterMsgServer(s *grpc.Server, srv MsgServer) { s.RegisterService(&_Msg_serviceDesc, srv) } -func _Msg_GetMaxAndMinSeq_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _Msg_GetMaxAndMinSeq_Handler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) { in := new(sdk_ws.GetMaxAndMinSeqReq) if err := dec(in); err != nil { return nil, err @@ -2715,13 +2715,13 @@ func _Msg_GetMaxAndMinSeq_Handler(srv interface{}, ctx context.Context, dec func Server: srv, FullMethod: "/msg.msg/GetMaxAndMinSeq", } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { + handler := func(ctx context.Context, req any) (any, error) { return srv.(MsgServer).GetMaxAndMinSeq(ctx, req.(*sdk_ws.GetMaxAndMinSeqReq)) } return interceptor(ctx, in, info, handler) } -func _Msg_PullMessageBySeqList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _Msg_PullMessageBySeqList_Handler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) { in := new(sdk_ws.PullMessageBySeqListReq) if err := dec(in); err != nil { return nil, err @@ -2733,13 +2733,13 @@ func _Msg_PullMessageBySeqList_Handler(srv interface{}, ctx context.Context, dec Server: srv, FullMethod: "/msg.msg/PullMessageBySeqList", } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { + handler := func(ctx context.Context, req any) (any, error) { return srv.(MsgServer).PullMessageBySeqList(ctx, req.(*sdk_ws.PullMessageBySeqListReq)) } return interceptor(ctx, in, info, handler) } -func _Msg_SendMsg_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _Msg_SendMsg_Handler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) { in := new(SendMsgReq) if err := dec(in); err != nil { return nil, err @@ -2751,13 +2751,13 @@ func _Msg_SendMsg_Handler(srv interface{}, ctx context.Context, dec func(interfa Server: srv, FullMethod: "/msg.msg/SendMsg", } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { + handler := func(ctx context.Context, req any) (any, error) { return srv.(MsgServer).SendMsg(ctx, req.(*SendMsgReq)) } return interceptor(ctx, in, info, handler) } -func _Msg_DelMsgList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _Msg_DelMsgList_Handler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) { in := new(sdk_ws.DelMsgListReq) if err := dec(in); err != nil { return nil, err @@ -2769,13 +2769,13 @@ func _Msg_DelMsgList_Handler(srv interface{}, ctx context.Context, dec func(inte Server: srv, FullMethod: "/msg.msg/DelMsgList", } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { + handler := func(ctx context.Context, req any) (any, error) { return srv.(MsgServer).DelMsgList(ctx, req.(*sdk_ws.DelMsgListReq)) } return interceptor(ctx, in, info, handler) } -func _Msg_DelSuperGroupMsg_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _Msg_DelSuperGroupMsg_Handler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) { in := new(DelSuperGroupMsgReq) if err := dec(in); err != nil { return nil, err @@ -2787,13 +2787,13 @@ func _Msg_DelSuperGroupMsg_Handler(srv interface{}, ctx context.Context, dec fun Server: srv, FullMethod: "/msg.msg/DelSuperGroupMsg", } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { + handler := func(ctx context.Context, req any) (any, error) { return srv.(MsgServer).DelSuperGroupMsg(ctx, req.(*DelSuperGroupMsgReq)) } return interceptor(ctx, in, info, handler) } -func _Msg_ClearMsg_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _Msg_ClearMsg_Handler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) { in := new(ClearMsgReq) if err := dec(in); err != nil { return nil, err @@ -2805,13 +2805,13 @@ func _Msg_ClearMsg_Handler(srv interface{}, ctx context.Context, dec func(interf Server: srv, FullMethod: "/msg.msg/ClearMsg", } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { + handler := func(ctx context.Context, req any) (any, error) { return srv.(MsgServer).ClearMsg(ctx, req.(*ClearMsgReq)) } return interceptor(ctx, in, info, handler) } -func _Msg_SetMsgMinSeq_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _Msg_SetMsgMinSeq_Handler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) { in := new(SetMsgMinSeqReq) if err := dec(in); err != nil { return nil, err @@ -2823,13 +2823,13 @@ func _Msg_SetMsgMinSeq_Handler(srv interface{}, ctx context.Context, dec func(in Server: srv, FullMethod: "/msg.msg/SetMsgMinSeq", } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { + handler := func(ctx context.Context, req any) (any, error) { return srv.(MsgServer).SetMsgMinSeq(ctx, req.(*SetMsgMinSeqReq)) } return interceptor(ctx, in, info, handler) } -func _Msg_SetSendMsgStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _Msg_SetSendMsgStatus_Handler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) { in := new(SetSendMsgStatusReq) if err := dec(in); err != nil { return nil, err @@ -2841,13 +2841,13 @@ func _Msg_SetSendMsgStatus_Handler(srv interface{}, ctx context.Context, dec fun Server: srv, FullMethod: "/msg.msg/SetSendMsgStatus", } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { + handler := func(ctx context.Context, req any) (any, error) { return srv.(MsgServer).SetSendMsgStatus(ctx, req.(*SetSendMsgStatusReq)) } return interceptor(ctx, in, info, handler) } -func _Msg_GetSendMsgStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _Msg_GetSendMsgStatus_Handler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) { in := new(GetSendMsgStatusReq) if err := dec(in); err != nil { return nil, err @@ -2859,13 +2859,13 @@ func _Msg_GetSendMsgStatus_Handler(srv interface{}, ctx context.Context, dec fun Server: srv, FullMethod: "/msg.msg/GetSendMsgStatus", } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { + handler := func(ctx context.Context, req any) (any, error) { return srv.(MsgServer).GetSendMsgStatus(ctx, req.(*GetSendMsgStatusReq)) } return interceptor(ctx, in, info, handler) } -func _Msg_GetSuperGroupMsg_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _Msg_GetSuperGroupMsg_Handler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) { in := new(GetSuperGroupMsgReq) if err := dec(in); err != nil { return nil, err @@ -2877,13 +2877,13 @@ func _Msg_GetSuperGroupMsg_Handler(srv interface{}, ctx context.Context, dec fun Server: srv, FullMethod: "/msg.msg/GetSuperGroupMsg", } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { + handler := func(ctx context.Context, req any) (any, error) { return srv.(MsgServer).GetSuperGroupMsg(ctx, req.(*GetSuperGroupMsgReq)) } return interceptor(ctx, in, info, handler) } -func _Msg_GetWriteDiffMsg_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _Msg_GetWriteDiffMsg_Handler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) { in := new(GetWriteDiffMsgReq) if err := dec(in); err != nil { return nil, err @@ -2895,13 +2895,13 @@ func _Msg_GetWriteDiffMsg_Handler(srv interface{}, ctx context.Context, dec func Server: srv, FullMethod: "/msg.msg/GetWriteDiffMsg", } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { + handler := func(ctx context.Context, req any) (any, error) { return srv.(MsgServer).GetWriteDiffMsg(ctx, req.(*GetWriteDiffMsgReq)) } return interceptor(ctx, in, info, handler) } -func _Msg_SetMessageReactionExtensions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _Msg_SetMessageReactionExtensions_Handler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) { in := new(SetMessageReactionExtensionsReq) if err := dec(in); err != nil { return nil, err @@ -2913,13 +2913,13 @@ func _Msg_SetMessageReactionExtensions_Handler(srv interface{}, ctx context.Cont Server: srv, FullMethod: "/msg.msg/SetMessageReactionExtensions", } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { + handler := func(ctx context.Context, req any) (any, error) { return srv.(MsgServer).SetMessageReactionExtensions(ctx, req.(*SetMessageReactionExtensionsReq)) } return interceptor(ctx, in, info, handler) } -func _Msg_GetMessageListReactionExtensions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _Msg_GetMessageListReactionExtensions_Handler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) { in := new(GetMessageListReactionExtensionsReq) if err := dec(in); err != nil { return nil, err @@ -2931,13 +2931,13 @@ func _Msg_GetMessageListReactionExtensions_Handler(srv interface{}, ctx context. Server: srv, FullMethod: "/msg.msg/GetMessageListReactionExtensions", } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { + handler := func(ctx context.Context, req any) (any, error) { return srv.(MsgServer).GetMessageListReactionExtensions(ctx, req.(*GetMessageListReactionExtensionsReq)) } return interceptor(ctx, in, info, handler) } -func _Msg_AddMessageReactionExtensions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _Msg_AddMessageReactionExtensions_Handler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) { in := new(AddMessageReactionExtensionsReq) if err := dec(in); err != nil { return nil, err @@ -2949,13 +2949,13 @@ func _Msg_AddMessageReactionExtensions_Handler(srv interface{}, ctx context.Cont Server: srv, FullMethod: "/msg.msg/AddMessageReactionExtensions", } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { + handler := func(ctx context.Context, req any) (any, error) { return srv.(MsgServer).AddMessageReactionExtensions(ctx, req.(*AddMessageReactionExtensionsReq)) } return interceptor(ctx, in, info, handler) } -func _Msg_DeleteMessageReactionExtensions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _Msg_DeleteMessageReactionExtensions_Handler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) { in := new(DeleteMessageListReactionExtensionsReq) if err := dec(in); err != nil { return nil, err @@ -2967,7 +2967,7 @@ func _Msg_DeleteMessageReactionExtensions_Handler(srv interface{}, ctx context.C Server: srv, FullMethod: "/msg.msg/DeleteMessageReactionExtensions", } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { + handler := func(ctx context.Context, req any) (any, error) { return srv.(MsgServer).DeleteMessageReactionExtensions(ctx, req.(*DeleteMessageListReactionExtensionsReq)) } return interceptor(ctx, in, info, handler) diff --git a/tools/data-conversion/openim/proto/sdk_ws/ws.pb.go b/tools/data-conversion/openim/proto/sdk_ws/ws.pb.go index 097280860..94b6f9be6 100644 --- a/tools/data-conversion/openim/proto/sdk_ws/ws.pb.go +++ b/tools/data-conversion/openim/proto/sdk_ws/ws.pb.go @@ -4156,8 +4156,8 @@ func (m *SignalReq) GetGetTokenByRoomID() *SignalGetTokenByRoomIDReq { } // XXX_OneofFuncs is for the internal use of the proto package. -func (*SignalReq) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { - return _SignalReq_OneofMarshaler, _SignalReq_OneofUnmarshaler, _SignalReq_OneofSizer, []interface{}{ +func (*SignalReq) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []any) { + return _SignalReq_OneofMarshaler, _SignalReq_OneofUnmarshaler, _SignalReq_OneofSizer, []any{ (*SignalReq_Invite)(nil), (*SignalReq_InviteInGroup)(nil), (*SignalReq_Cancel)(nil), @@ -4523,8 +4523,8 @@ func (m *SignalResp) GetGetTokenByRoomID() *SignalGetTokenByRoomIDReply { } // XXX_OneofFuncs is for the internal use of the proto package. -func (*SignalResp) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { - return _SignalResp_OneofMarshaler, _SignalResp_OneofUnmarshaler, _SignalResp_OneofSizer, []interface{}{ +func (*SignalResp) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []any) { + return _SignalResp_OneofMarshaler, _SignalResp_OneofUnmarshaler, _SignalResp_OneofSizer, []any{ (*SignalResp_Invite)(nil), (*SignalResp_InviteInGroup)(nil), (*SignalResp_Cancel)(nil),