diff --git a/go.mod b/go.mod index ae884a5aa..52b1bb4e9 100644 --- a/go.mod +++ b/go.mod @@ -38,7 +38,7 @@ require github.com/google/uuid v1.3.1 require ( github.com/IBM/sarama v1.41.3 github.com/OpenIMSDK/protocol v0.0.31 - github.com/OpenIMSDK/tools v0.0.17 + github.com/OpenIMSDK/tools v0.0.18 github.com/aliyun/aliyun-oss-go-sdk v2.2.9+incompatible github.com/go-redis/redis v6.15.9+incompatible github.com/go-sql-driver/mysql v1.7.1 diff --git a/internal/msgtransfer/init.go b/internal/msgtransfer/init.go index 8436317ee..a8d10799f 100644 --- a/internal/msgtransfer/init.go +++ b/internal/msgtransfer/init.go @@ -17,21 +17,20 @@ package msgtransfer import ( "errors" "fmt" + "log" + "net/http" + "sync" + "github.com/OpenIMSDK/tools/mw" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/collectors" "github.com/prometheus/client_golang/prometheus/promhttp" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" - "log" - "net/http" - "sync" "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/common/db/unrelation" kdisc "github.com/openimsdk/open-im-server/v3/pkg/common/discoveryregister" "github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics" @@ -39,20 +38,12 @@ import ( ) type MsgTransfer struct { - persistentCH *PersistentConsumerHandler // 聊天记录持久化到mysql的消费者 订阅的topic: ws2ms_chat historyCH *OnlineHistoryRedisConsumerHandler // 这个消费者聚合消息, 订阅的topic:ws2ms_chat, 修改通知发往msg_to_modify topic, 消息存入redis后Incr Redis, 再发消息到ms2pschat topic推送, 发消息到msg_to_mongo topic持久化 historyMongoCH *OnlineHistoryMongoConsumerHandler // mongoDB批量插入, 成功后删除redis中消息,以及处理删除通知消息删除的 订阅的topic: msg_to_mongo // modifyCH *ModifyMsgConsumerHandler // 负责消费修改消息通知的consumer, 订阅的topic: msg_to_modify } func StartTransfer(prometheusPort int) error { - db, err := relation.NewGormDB() - if err != nil { - return err - } - if err := db.AutoMigrate(&relationtb.ChatLogModel{}); err != nil { - fmt.Printf("gorm: AutoMigrate ChatLogModel err: %v\n", err) - } rdb, err := cache.NewRedis() if err != nil { return err @@ -78,21 +69,16 @@ func StartTransfer(prometheusPort int) error { client.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials())) msgModel := cache.NewMsgCacheModel(rdb) msgDocModel := unrelation.NewMsgMongoDriver(mongo.GetDatabase()) - msgMysModel := relation.NewChatLogGorm(db) - chatLogDatabase := controller.NewChatLogDatabase(msgMysModel) msgDatabase := controller.NewCommonMsgDatabase(msgDocModel, msgModel) conversationRpcClient := rpcclient.NewConversationRpcClient(client) groupRpcClient := rpcclient.NewGroupRpcClient(client) - msgTransfer := NewMsgTransfer(chatLogDatabase, msgDatabase, &conversationRpcClient, &groupRpcClient) + msgTransfer := NewMsgTransfer(msgDatabase, &conversationRpcClient, &groupRpcClient) return msgTransfer.Start(prometheusPort) } -func NewMsgTransfer(chatLogDatabase controller.ChatLogDatabase, - msgDatabase controller.CommonMsgDatabase, - conversationRpcClient *rpcclient.ConversationRpcClient, groupRpcClient *rpcclient.GroupRpcClient, -) *MsgTransfer { +func NewMsgTransfer(msgDatabase controller.CommonMsgDatabase, conversationRpcClient *rpcclient.ConversationRpcClient, groupRpcClient *rpcclient.GroupRpcClient) *MsgTransfer { return &MsgTransfer{ - persistentCH: NewPersistentConsumerHandler(chatLogDatabase), historyCH: NewOnlineHistoryRedisConsumerHandler(msgDatabase, conversationRpcClient, groupRpcClient), + historyCH: NewOnlineHistoryRedisConsumerHandler(msgDatabase, conversationRpcClient, groupRpcClient), historyMongoCH: NewOnlineHistoryMongoConsumerHandler(msgDatabase), } } diff --git a/internal/msgtransfer/persistent_msg_handler.go b/internal/msgtransfer/persistent_msg_handler.go deleted file mode 100644 index d105de2fe..000000000 --- a/internal/msgtransfer/persistent_msg_handler.go +++ /dev/null @@ -1,119 +0,0 @@ -// 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 msgtransfer - -import ( - "context" - - "github.com/OpenIMSDK/protocol/constant" - pbmsg "github.com/OpenIMSDK/protocol/msg" - "github.com/OpenIMSDK/tools/log" - "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/controller" - kfk "github.com/openimsdk/open-im-server/v3/pkg/common/kafka" - - "github.com/IBM/sarama" - "google.golang.org/protobuf/proto" -) - -type PersistentConsumerHandler struct { - persistentConsumerGroup *kfk.MConsumerGroup - chatLogDatabase controller.ChatLogDatabase -} - -func NewPersistentConsumerHandler(database controller.ChatLogDatabase) *PersistentConsumerHandler { - return &PersistentConsumerHandler{ - persistentConsumerGroup: kfk.NewMConsumerGroup(&kfk.MConsumerGroupConfig{ - KafkaVersion: sarama.V2_0_0_0, - OffsetsInitial: sarama.OffsetNewest, IsReturnErr: false, - }, []string{config.Config.Kafka.LatestMsgToRedis.Topic}, - config.Config.Kafka.Addr, config.Config.Kafka.ConsumerGroupID.MsgToMySql), - chatLogDatabase: database, - } -} - -func (pc *PersistentConsumerHandler) handleChatWs2Mysql( - ctx context.Context, - cMsg *sarama.ConsumerMessage, - msgKey string, - _ sarama.ConsumerGroupSession, -) { - msg := cMsg.Value - var tag bool - msgFromMQ := pbmsg.MsgDataToMQ{} - err := proto.Unmarshal(msg, &msgFromMQ) - if err != nil { - log.ZError(ctx, "msg_transfer Unmarshal msg err", err) - return - } - - log.ZDebug(ctx, "handleChatWs2Mysql", "msg", msgFromMQ.MsgData) - // Control whether to store history messages (mysql) - isPersist := utils.GetSwitchFromOptions(msgFromMQ.MsgData.Options, constant.IsPersistent) - // Only process receiver data - if isPersist { - switch msgFromMQ.MsgData.SessionType { - case constant.SingleChatType, constant.NotificationChatType: - if msgKey == msgFromMQ.MsgData.RecvID { - tag = true - } - case constant.GroupChatType: - if msgKey == msgFromMQ.MsgData.SendID { - tag = true - } - case constant.SuperGroupChatType: - tag = true - } - if tag { - log.ZInfo(ctx, "msg_transfer msg persisting", "msg", string(msg)) - if err = pc.chatLogDatabase.CreateChatLog(&msgFromMQ); err != nil { - log.ZError(ctx, "Message insert failed", err, "msg", msgFromMQ.String()) - return - } - } - } -} -func (PersistentConsumerHandler) Setup(_ sarama.ConsumerGroupSession) error { return nil } -func (PersistentConsumerHandler) Cleanup(_ sarama.ConsumerGroupSession) error { return nil } - -func (pc *PersistentConsumerHandler) ConsumeClaim( - sess sarama.ConsumerGroupSession, - claim sarama.ConsumerGroupClaim, -) error { - for msg := range claim.Messages() { - ctx := pc.persistentConsumerGroup.GetContextFromMsg(msg) - log.ZDebug( - ctx, - "kafka get info to mysql", - "msgTopic", - msg.Topic, - "msgPartition", - msg.Partition, - "msg", - string(msg.Value), - "key", - string(msg.Key), - ) - if len(msg.Value) != 0 { - pc.handleChatWs2Mysql(ctx, msg, string(msg.Key), sess) - } else { - log.ZError(ctx, "msg get from kafka but is nil", nil, "key", msg.Key) - } - sess.MarkMessage(msg, "") - } - return nil -} diff --git a/internal/rpc/conversation/conversaion.go b/internal/rpc/conversation/conversaion.go index 12e3e96fd..88c9ff7ff 100644 --- a/internal/rpc/conversation/conversaion.go +++ b/internal/rpc/conversation/conversaion.go @@ -17,8 +17,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/tools/tx" + + "github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo" "github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation" "google.golang.org/grpc" @@ -53,11 +55,7 @@ func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) e if err != nil { return err } - tx, err := tx2.NewAuto(context.Background(), mongo.GetClient()) - if err != nil { - return err - } - conversationDB, err := newmgo.NewConversationMongo(mongo.GetDatabase()) + conversationDB, err := mgo.NewConversationMongo(mongo.GetDatabase()) if err != nil { return err } @@ -66,7 +64,7 @@ func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) e pbconversation.RegisterConversationServer(server, &conversationServer{ conversationNotificationSender: notification.NewConversationNotificationSender(&msgRpcClient), groupRpcClient: &groupRpcClient, - conversationDatabase: controller.NewConversationDatabase(conversationDB, cache.NewConversationRedis(rdb, cache.GetDefaultOpt(), conversationDB), tx), + conversationDatabase: controller.NewConversationDatabase(conversationDB, cache.NewConversationRedis(rdb, cache.GetDefaultOpt(), conversationDB), tx.NewMongo(mongo.GetClient())), }) return nil } diff --git a/internal/rpc/friend/black.go b/internal/rpc/friend/black.go index fee2d5480..54cdbb2cc 100644 --- a/internal/rpc/friend/black.go +++ b/internal/rpc/friend/black.go @@ -27,19 +27,11 @@ import ( "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" ) -func (s *friendServer) GetPaginationBlacks( - ctx context.Context, - req *pbfriend.GetPaginationBlacksReq, -) (resp *pbfriend.GetPaginationBlacksResp, err error) { +func (s *friendServer) GetPaginationBlacks(ctx context.Context, req *pbfriend.GetPaginationBlacksReq) (resp *pbfriend.GetPaginationBlacksResp, err error) { if err := s.userRpcClient.Access(ctx, req.UserID); err != nil { return nil, err } - var pageNumber, showNumber int32 - if req.Pagination != nil { - pageNumber = req.Pagination.PageNumber - showNumber = req.Pagination.ShowNumber - } - blacks, total, err := s.blackDatabase.FindOwnerBlacks(ctx, req.UserID, pageNumber, showNumber) + total, blacks, err := s.blackDatabase.FindOwnerBlacks(ctx, req.UserID, req.Pagination) if err != nil { return nil, err } @@ -63,10 +55,7 @@ func (s *friendServer) IsBlack(ctx context.Context, req *pbfriend.IsBlackReq) (* return resp, nil } -func (s *friendServer) RemoveBlack( - ctx context.Context, - req *pbfriend.RemoveBlackReq, -) (*pbfriend.RemoveBlackResp, error) { +func (s *friendServer) RemoveBlack(ctx context.Context, req *pbfriend.RemoveBlackReq) (*pbfriend.RemoveBlackResp, error) { if err := s.userRpcClient.Access(ctx, req.OwnerUserID); err != nil { return nil, err } @@ -74,9 +63,6 @@ func (s *friendServer) RemoveBlack( return nil, err } s.notificationSender.BlackDeletedNotification(ctx, req) - if err := CallbackAfterRemoveBlack(ctx, req); err != nil { - return nil, err - } return &pbfriend.RemoveBlackResp{}, nil } @@ -88,9 +74,6 @@ func (s *friendServer) AddBlack(ctx context.Context, req *pbfriend.AddBlackReq) if err != nil { return nil, err } - if err := CallbackBeforeAddBlack(ctx, req); err != nil { - return nil, err - } black := relation.BlackModel{ OwnerUserID: req.OwnerUserID, BlockUserID: req.BlackUserID, diff --git a/internal/rpc/friend/friend.go b/internal/rpc/friend/friend.go index 5c80d7f00..a8db9f721 100644 --- a/internal/rpc/friend/friend.go +++ b/internal/rpc/friend/friend.go @@ -17,6 +17,8 @@ package friend import ( "context" + "github.com/OpenIMSDK/tools/tx" + "github.com/OpenIMSDK/protocol/sdkws" "github.com/openimsdk/open-im-server/v3/pkg/authverify" @@ -32,12 +34,11 @@ import ( pbfriend "github.com/OpenIMSDK/protocol/friend" registry "github.com/OpenIMSDK/tools/discoveryregistry" "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/controller" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/newmgo" + "github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo" 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" @@ -65,17 +66,17 @@ func Start(client registry.SvcDiscoveryRegistry, server *grpc.Server) error { return err } - friendMongoDB, err := newmgo.NewFriendMongo(mongo.GetDatabase()) + friendMongoDB, err := mgo.NewFriendMongo(mongo.GetDatabase()) if err != nil { return err } - friendRequestMongoDB, err := newmgo.NewFriendRequestMongo(mongo.GetDatabase()) + friendRequestMongoDB, err := mgo.NewFriendRequestMongo(mongo.GetDatabase()) if err != nil { return err } - blackMongoDB, err := newmgo.NewBlackMongo(mongo.GetDatabase()) + blackMongoDB, err := mgo.NewBlackMongo(mongo.GetDatabase()) if err != nil { return err } @@ -89,7 +90,6 @@ func Start(client registry.SvcDiscoveryRegistry, server *grpc.Server) error { &msgRpcClient, notification.WithRpcFunc(userRpcClient.GetUsersInfo), ) - // Register Friend server with refactored MongoDB and Redis integrations pbfriend.RegisterFriendServer(server, &friendServer{ friendDatabase: controller.NewFriendDatabase( @@ -311,15 +311,12 @@ func (s *friendServer) GetDesignatedFriendsApply(ctx context.Context, } // ok 获取接收到的好友申请(即别人主动申请的). -func (s *friendServer) GetPaginationFriendsApplyTo( - ctx context.Context, - req *pbfriend.GetPaginationFriendsApplyToReq, -) (resp *pbfriend.GetPaginationFriendsApplyToResp, err error) { +func (s *friendServer) GetPaginationFriendsApplyTo(ctx context.Context, req *pbfriend.GetPaginationFriendsApplyToReq) (resp *pbfriend.GetPaginationFriendsApplyToResp, err error) { defer log.ZInfo(ctx, utils.GetFuncName()+" Return") if err := s.userRpcClient.Access(ctx, req.UserID); err != nil { return nil, err } - friendRequests, total, err := s.friendDatabase.PageFriendRequestToMe(ctx, req.UserID, req.Pagination.PageNumber, req.Pagination.ShowNumber) + total, friendRequests, err := s.friendDatabase.PageFriendRequestToMe(ctx, req.UserID, req.Pagination) if err != nil { return nil, err } @@ -333,16 +330,13 @@ func (s *friendServer) GetPaginationFriendsApplyTo( } // ok 获取主动发出去的好友申请列表. -func (s *friendServer) GetPaginationFriendsApplyFrom( - ctx context.Context, - req *pbfriend.GetPaginationFriendsApplyFromReq, -) (resp *pbfriend.GetPaginationFriendsApplyFromResp, err error) { +func (s *friendServer) GetPaginationFriendsApplyFrom(ctx context.Context, req *pbfriend.GetPaginationFriendsApplyFromReq) (resp *pbfriend.GetPaginationFriendsApplyFromResp, err error) { defer log.ZInfo(ctx, utils.GetFuncName()+" Return") resp = &pbfriend.GetPaginationFriendsApplyFromResp{} if err := s.userRpcClient.Access(ctx, req.UserID); err != nil { return nil, err } - friendRequests, total, err := s.friendDatabase.PageFriendRequestFromMe(ctx, req.UserID, req.Pagination.PageNumber, req.Pagination.ShowNumber) + total, friendRequests, err := s.friendDatabase.PageFriendRequestFromMe(ctx, req.UserID, req.Pagination) if err != nil { return nil, err } @@ -355,10 +349,7 @@ func (s *friendServer) GetPaginationFriendsApplyFrom( } // ok. -func (s *friendServer) IsFriend( - ctx context.Context, - req *pbfriend.IsFriendReq, -) (resp *pbfriend.IsFriendResp, err error) { +func (s *friendServer) IsFriend(ctx context.Context, req *pbfriend.IsFriendReq) (resp *pbfriend.IsFriendResp, err error) { defer log.ZInfo(ctx, utils.GetFuncName()+" Return") resp = &pbfriend.IsFriendResp{} resp.InUser1Friends, resp.InUser2Friends, err = s.friendDatabase.CheckIn(ctx, req.UserID1, req.UserID2) @@ -368,15 +359,12 @@ func (s *friendServer) IsFriend( return resp, nil } -func (s *friendServer) GetPaginationFriends( - ctx context.Context, - req *pbfriend.GetPaginationFriendsReq, -) (resp *pbfriend.GetPaginationFriendsResp, err error) { +func (s *friendServer) GetPaginationFriends(ctx context.Context, req *pbfriend.GetPaginationFriendsReq) (resp *pbfriend.GetPaginationFriendsResp, err error) { defer log.ZInfo(ctx, utils.GetFuncName()+" Return") if err := s.userRpcClient.Access(ctx, req.UserID); err != nil { return nil, err } - friends, total, err := s.friendDatabase.PageOwnerFriends(ctx, req.UserID, req.Pagination.PageNumber, req.Pagination.ShowNumber) + total, friends, err := s.friendDatabase.PageOwnerFriends(ctx, req.UserID, req.Pagination) if err != nil { return nil, err } @@ -389,10 +377,7 @@ func (s *friendServer) GetPaginationFriends( return resp, nil } -func (s *friendServer) GetFriendIDs( - ctx context.Context, - req *pbfriend.GetFriendIDsReq, -) (resp *pbfriend.GetFriendIDsResp, err error) { +func (s *friendServer) GetFriendIDs(ctx context.Context, req *pbfriend.GetFriendIDsReq) (resp *pbfriend.GetFriendIDsResp, err error) { defer log.ZInfo(ctx, utils.GetFuncName()+" Return") if err := s.userRpcClient.Access(ctx, req.UserID); err != nil { return nil, err diff --git a/internal/rpc/group/group.go b/internal/rpc/group/group.go index 1254f2dd8..5992ed031 100644 --- a/internal/rpc/group/group.go +++ b/internal/rpc/group/group.go @@ -17,18 +17,19 @@ package group import ( "context" "fmt" - pbconversation "github.com/OpenIMSDK/protocol/conversation" - "github.com/OpenIMSDK/protocol/wrapperspb" - "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" + "github.com/openimsdk/open-im-server/v3/pkg/callbackstruct" "math/big" "math/rand" "strconv" "strings" "time" - "github.com/openimsdk/open-im-server/v3/pkg/callbackstruct" + pbconversation "github.com/OpenIMSDK/protocol/conversation" + "github.com/OpenIMSDK/protocol/wrapperspb" + "github.com/OpenIMSDK/tools/tx" + + "github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo" + "github.com/openimsdk/open-im-server/v3/pkg/rpcclient/grouphash" "github.com/openimsdk/open-im-server/v3/pkg/authverify" "github.com/openimsdk/open-im-server/v3/pkg/msgprocessor" @@ -53,19 +54,11 @@ 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" relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" "github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation" ) func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error { - db, err := relation.NewGormDB() - if err != nil { - return err - } - if err := db.AutoMigrate(&relationtb.GroupModel{}, &relationtb.GroupMemberModel{}, &relationtb.GroupRequestModel{}); err != nil { - return err - } mongo, err := unrelation.NewMongo() if err != nil { return err @@ -74,27 +67,23 @@ func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) e if err != nil { return err } - groupDB, err := newmgo.NewGroupMongo(mongo.GetDatabase()) + groupDB, err := mgo.NewGroupMongo(mongo.GetDatabase()) if err != nil { return err } - groupMemberDB, err := newmgo.NewGroupMember(mongo.GetDatabase()) + groupMemberDB, err := mgo.NewGroupMember(mongo.GetDatabase()) if err != nil { return err } - groupRequestDB, err := newmgo.NewGroupRequestMgo(mongo.GetDatabase()) + groupRequestDB, err := mgo.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.NewGroupDatabase(rdb, groupDB, groupMemberDB, groupRequestDB, tx, grouphash.NewGroupHashFromGroupServer(&gs)) + database := controller.NewGroupDatabase(rdb, groupDB, groupMemberDB, groupRequestDB, tx.NewMongo(mongo.GetClient()), 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) { diff --git a/internal/rpc/third/log.go b/internal/rpc/third/log.go index 30d95e26b..57d4f536e 100644 --- a/internal/rpc/third/log.go +++ b/internal/rpc/third/log.go @@ -32,11 +32,11 @@ func genLogID() string { } func (t *thirdServer) UploadLogs(ctx context.Context, req *third.UploadLogsReq) (*third.UploadLogsResp, error) { - var DBlogs []*relationtb.Log + var DBlogs []*relationtb.LogModel userID := ctx.Value(constant.OpUserID).(string) platform := constant.PlatformID2Name[int(req.Platform)] for _, fileURL := range req.FileURLs { - log := relationtb.Log{ + log := relationtb.LogModel{ Version: req.Version, SystemType: req.SystemType, Platform: platform, @@ -57,7 +57,7 @@ func (t *thirdServer) UploadLogs(ctx context.Context, req *third.UploadLogsReq) } } if log.LogID == "" { - return nil, errs.ErrData.Wrap("Log id gen error") + return nil, errs.ErrData.Wrap("LogModel id gen error") } DBlogs = append(DBlogs, &log) } @@ -92,8 +92,8 @@ func (t *thirdServer) DeleteLogs(ctx context.Context, req *third.DeleteLogsReq) return &third.DeleteLogsResp{}, nil } -func dbToPbLogInfos(logs []*relationtb.Log) []*third.LogInfo { - db2pbForLogInfo := func(log *relationtb.Log) *third.LogInfo { +func dbToPbLogInfos(logs []*relationtb.LogModel) []*third.LogInfo { + db2pbForLogInfo := func(log *relationtb.LogModel) *third.LogInfo { return &third.LogInfo{ Filename: log.FileName, UserID: log.UserID, diff --git a/internal/rpc/third/third.go b/internal/rpc/third/third.go index f285790b3..7a63d3526 100644 --- a/internal/rpc/third/third.go +++ b/internal/rpc/third/third.go @@ -17,17 +17,17 @@ 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" + "github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo" + "github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation" + "github.com/openimsdk/open-im-server/v3/pkg/common/db/s3" "github.com/openimsdk/open-im-server/v3/pkg/common/db/s3/cos" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/s3/kodo" "github.com/openimsdk/open-im-server/v3/pkg/common/db/s3/minio" "github.com/openimsdk/open-im-server/v3/pkg/common/db/s3/oss" + "google.golang.org/grpc" "github.com/OpenIMSDK/protocol/third" @@ -44,11 +44,11 @@ func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) e if err != nil { return err } - logdb, err := newmgo.NewLogMongo(mongo.GetDatabase()) + logdb, err := mgo.NewLogMongo(mongo.GetDatabase()) if err != nil { return err } - s3db, err := newmgo.NewS3Mongo(mongo.GetDatabase()) + s3db, err := mgo.NewS3Mongo(mongo.GetDatabase()) if err != nil { return err } @@ -77,8 +77,6 @@ func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) e o, err = cos.NewCos() case "oss": o, err = oss.NewOSS() - case "kodo": - o, err = kodo.NewKodo() default: err = fmt.Errorf("invalid object enable: %s", enable) } diff --git a/internal/rpc/user/user.go b/internal/rpc/user/user.go index 69d7bd318..176bc91a9 100644 --- a/internal/rpc/user/user.go +++ b/internal/rpc/user/user.go @@ -17,11 +17,13 @@ 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" + "github.com/OpenIMSDK/tools/tx" + + "github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo" + "github.com/OpenIMSDK/protocol/constant" "github.com/OpenIMSDK/protocol/sdkws" "github.com/OpenIMSDK/tools/errs" @@ -70,17 +72,13 @@ 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, err := newmgo.NewUserMongo(mongo.GetDatabase()) - if err != nil { - return err - } - tx, err := tx2.NewAuto(context.Background(), mongo.GetClient()) + userDB, err := mgo.NewUserMongo(mongo.GetDatabase()) if err != nil { return err } cache := cache.NewUserCacheRedis(rdb, userDB, cache.GetDefaultOpt()) userMongoDB := unrelation.NewUserMongoDriver(mongo.GetDatabase()) - database := controller.NewUserDatabase(userDB, cache, tx, userMongoDB) + database := controller.NewUserDatabase(userDB, cache, tx.NewMongo(mongo.GetClient()), userMongoDB) friendRpcClient := rpcclient.NewFriendRpcClient(client) groupRpcClient := rpcclient.NewGroupRpcClient(client) msgRpcClient := rpcclient.NewMessageRpcClient(client) diff --git a/internal/tools/msg.go b/internal/tools/msg.go index bf0231786..97bb2988e 100644 --- a/internal/tools/msg.go +++ b/internal/tools/msg.go @@ -17,11 +17,13 @@ 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/OpenIMSDK/protocol/sdkws" + "github.com/OpenIMSDK/tools/tx" + + "github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo" + "github.com/redis/go-redis/v9" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" @@ -78,43 +80,40 @@ func InitMsgTool() (*MsgTool, error) { return nil, err } 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()) + userDB, err := mgo.NewUserMongo(mongo.GetDatabase()) if err != nil { return nil, err } msgDatabase := controller.InitCommonMsgDatabase(rdb, mongo.GetDatabase()) userMongoDB := unrelation.NewUserMongoDriver(mongo.GetDatabase()) + ctxTx := tx.NewMongo(mongo.GetClient()) userDatabase := controller.NewUserDatabase( userDB, cache.NewUserCacheRedis(rdb, userDB, cache.GetDefaultOpt()), - tx, + ctxTx, userMongoDB, ) - groupDB, err := newmgo.NewGroupMongo(mongo.GetDatabase()) + groupDB, err := mgo.NewGroupMongo(mongo.GetDatabase()) if err != nil { return nil, err } - groupMemberDB, err := newmgo.NewGroupMember(mongo.GetDatabase()) + groupMemberDB, err := mgo.NewGroupMember(mongo.GetDatabase()) if err != nil { return nil, err } - groupRequestDB, err := newmgo.NewGroupRequestMgo(mongo.GetDatabase()) + groupRequestDB, err := mgo.NewGroupRequestMgo(mongo.GetDatabase()) if err != nil { return nil, err } - conversationDB, err := newmgo.NewConversationMongo(mongo.GetDatabase()) + conversationDB, err := mgo.NewConversationMongo(mongo.GetDatabase()) if err != nil { return nil, err } - groupDatabase := controller.NewGroupDatabase(rdb, groupDB, groupMemberDB, groupRequestDB, tx, nil) + groupDatabase := controller.NewGroupDatabase(rdb, groupDB, groupMemberDB, groupRequestDB, ctxTx, nil) conversationDatabase := controller.NewConversationDatabase( conversationDB, cache.NewConversationRedis(rdb, cache.GetDefaultOpt(), conversationDB), - tx, + ctxTx, ) msgRpcClient := rpcclient.NewMessageRpcClient(discov) msgNotificationSender := notification.NewMsgNotificationSender(rpcclient.WithRpcClient(&msgRpcClient)) diff --git a/pkg/common/db/cache/group.go b/pkg/common/db/cache/group.go index b45cfd091..603d8e534 100644 --- a/pkg/common/db/cache/group.go +++ b/pkg/common/db/cache/group.go @@ -17,11 +17,12 @@ package cache import ( "context" "fmt" - "github.com/OpenIMSDK/protocol/constant" - "github.com/OpenIMSDK/tools/errs" "strconv" "time" + "github.com/OpenIMSDK/protocol/constant" + "github.com/OpenIMSDK/tools/errs" + "github.com/OpenIMSDK/tools/log" "github.com/dtm-labs/rockscache" @@ -318,7 +319,12 @@ 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 diff --git a/pkg/common/db/cache/msg.go b/pkg/common/db/cache/msg.go index 45dee3950..5cd3cb22c 100644 --- a/pkg/common/db/cache/msg.go +++ b/pkg/common/db/cache/msg.go @@ -173,20 +173,7 @@ func (c *msgCache) getSeqs(ctx context.Context, items []string, getkey func(s st } func (c *msgCache) SetMaxSeq(ctx context.Context, conversationID string, maxSeq int64) error { - var retErr error - for { - select { - case <-ctx.Done(): - return errs.Wrap(retErr, "SetMaxSeq redis retry too many amount") - default: - retErr = c.setSeq(ctx, conversationID, maxSeq, c.getMaxSeqKey) - if retErr != nil { - time.Sleep(time.Second * 2) - continue - } - return nil - } - } + return c.setSeq(ctx, conversationID, maxSeq, c.getMaxSeqKey) } func (c *msgCache) GetMaxSeqs(ctx context.Context, conversationIDs []string) (m map[string]int64, err error) { @@ -194,21 +181,7 @@ func (c *msgCache) GetMaxSeqs(ctx context.Context, conversationIDs []string) (m } func (c *msgCache) GetMaxSeq(ctx context.Context, conversationID string) (int64, error) { - var retErr error - var retData int64 - for { - select { - case <-ctx.Done(): - return -1, errs.Wrap(retErr, "GetMaxSeq redis retry too many amount") - default: - retData, retErr = c.getSeq(ctx, conversationID, c.getMaxSeqKey) - if retErr != nil && errs.Unwrap(retErr) != redis.Nil { - time.Sleep(time.Second * 2) - continue - } - return retData, retErr - } - } + return c.getSeq(ctx, conversationID, c.getMaxSeqKey) } func (c *msgCache) SetMinSeq(ctx context.Context, conversationID string, minSeq int64) error { @@ -672,35 +645,19 @@ func (c *msgCache) PipeDeleteMessages(ctx context.Context, conversationID string } func (c *msgCache) CleanUpOneConversationAllMsg(ctx context.Context, conversationID string) error { - var ( - cursor uint64 - keys []string - err error - - key = c.allMessageCacheKey(conversationID) - ) - - for { - // scan up to 10000 at a time, the count (10000) param refers to the number of scans on redis server. - // if the count is too small, needs to be run scan on redis frequently. - var limit int64 = 10000 - keys, cursor, err = c.rdb.Scan(ctx, cursor, key, limit).Result() - if err != nil { + vals, err := c.rdb.Keys(ctx, c.allMessageCacheKey(conversationID)).Result() + if errors.Is(err, redis.Nil) { + return nil + } + if err != nil { + return errs.Wrap(err) + } + for _, v := range vals { + if err := c.rdb.Del(ctx, v).Err(); err != nil { return errs.Wrap(err) } - - for _, key := range keys { - err := c.rdb.Del(ctx, key).Err() - if err != nil { - return errs.Wrap(err) - } - } - - // scan end - if cursor == 0 { - return nil - } } + return nil } func (c *msgCache) DelMsgFromCache(ctx context.Context, userID string, seqs []int64) error { diff --git a/pkg/common/db/cache/msg_test.go b/pkg/common/db/cache/msg_test.go index a5be018ed..3fddf5965 100644 --- a/pkg/common/db/cache/msg_test.go +++ b/pkg/common/db/cache/msg_test.go @@ -385,50 +385,3 @@ func testParallelDeleteMessagesMix(t *testing.T, cid string, seqs []int64, input assert.EqualValues(t, 1, val) // exists } } - -func TestCleanUpOneConversationAllMsg(t *testing.T) { - rdb := redis.NewClient(&redis.Options{}) - defer rdb.Close() - - cacher := msgCache{rdb: rdb} - count := 1000 - prefix := fmt.Sprintf("%v", rand.Int63()) - - ids := []string{} - for i := 0; i < count; i++ { - id := fmt.Sprintf("%v-cid-%v", prefix, rand.Int63()) - ids = append(ids, id) - - key := cacher.allMessageCacheKey(id) - rdb.Set(context.Background(), key, "openim", 0) - } - - // delete 100 keys with scan. - for i := 0; i < 100; i++ { - pickedKey := ids[i] - err := cacher.CleanUpOneConversationAllMsg(context.Background(), pickedKey) - assert.Nil(t, err) - - ls, err := rdb.Keys(context.Background(), pickedKey).Result() - assert.Nil(t, err) - assert.Equal(t, 0, len(ls)) - - rcode, err := rdb.Exists(context.Background(), pickedKey).Result() - assert.Nil(t, err) - assert.EqualValues(t, 0, rcode) // non-exists - } - - sid := fmt.Sprintf("%v-cid-*", prefix) - ls, err := rdb.Keys(context.Background(), cacher.allMessageCacheKey(sid)).Result() - assert.Nil(t, err) - assert.Equal(t, count-100, len(ls)) - - // delete fuzzy matching keys. - err = cacher.CleanUpOneConversationAllMsg(context.Background(), sid) - assert.Nil(t, err) - - // don't contains keys matched `{prefix}-cid-{random}` on redis - ls, err = rdb.Keys(context.Background(), cacher.allMessageCacheKey(sid)).Result() - assert.Nil(t, err) - assert.Equal(t, 0, len(ls)) -} diff --git a/pkg/common/db/cache/user.go b/pkg/common/db/cache/user.go index e0f22b2f7..979bd06e4 100644 --- a/pkg/common/db/cache/user.go +++ b/pkg/common/db/cache/user.go @@ -18,11 +18,12 @@ import ( "context" "encoding/json" "errors" - relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" "hash/crc32" "strconv" "time" + relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" + "github.com/OpenIMSDK/tools/log" "github.com/OpenIMSDK/protocol/constant" diff --git a/pkg/common/db/controller/black.go b/pkg/common/db/controller/black.go index 70e942a77..e68d06b01 100644 --- a/pkg/common/db/controller/black.go +++ b/pkg/common/db/controller/black.go @@ -17,6 +17,8 @@ package controller import ( "context" + "github.com/OpenIMSDK/tools/pagination" + "github.com/OpenIMSDK/tools/log" "github.com/OpenIMSDK/tools/utils" @@ -30,12 +32,7 @@ type BlackDatabase interface { // Delete 删除黑名单 Delete(ctx context.Context, blacks []*relation.BlackModel) (err error) // FindOwnerBlacks 获取黑名单列表 - FindOwnerBlacks( - ctx context.Context, - ownerUserID string, - pageNumber, showNumber int32, - ) (blacks []*relation.BlackModel, total int64, err error) - FindBlackIDs(ctx context.Context, ownerUserID string) (blackIDs []string, err error) + FindOwnerBlacks(ctx context.Context, ownerUserID string, pagination pagination.Pagination) (total int64, blacks []*relation.BlackModel, err error) FindBlackInfos(ctx context.Context, ownerUserID string, userIDs []string) (blacks []*relation.BlackModel, err error) // CheckIn 检查user2是否在user1的黑名单列表中(inUser1Blacks==true) 检查user1是否在user2的黑名单列表中(inUser2Blacks==true) CheckIn(ctx context.Context, userID1, userID2 string) (inUser1Blacks bool, inUser2Blacks bool, err error) @@ -75,12 +72,8 @@ func (b *blackDatabase) deleteBlackIDsCache(ctx context.Context, blacks []*relat } // FindOwnerBlacks 获取黑名单列表. -func (b *blackDatabase) FindOwnerBlacks( - ctx context.Context, - ownerUserID string, - pageNumber, showNumber int32, -) (blacks []*relation.BlackModel, total int64, err error) { - return b.black.FindOwnerBlacks(ctx, ownerUserID, pageNumber, showNumber) +func (b *blackDatabase) FindOwnerBlacks(ctx context.Context, ownerUserID string, pagination pagination.Pagination) (total int64, blacks []*relation.BlackModel, err error) { + return b.black.FindOwnerBlacks(ctx, ownerUserID, pagination) } // CheckIn 检查user2是否在user1的黑名单列表中(inUser1Blacks==true) 检查user1是否在user2的黑名单列表中(inUser2Blacks==true). diff --git a/pkg/common/db/controller/chatlog.go b/pkg/common/db/controller/chatlog.go deleted file mode 100644 index def490265..000000000 --- a/pkg/common/db/controller/chatlog.go +++ /dev/null @@ -1,37 +0,0 @@ -// 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 controller - -import ( - pbmsg "github.com/OpenIMSDK/protocol/msg" - - relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" -) - -type ChatLogDatabase interface { - CreateChatLog(msg *pbmsg.MsgDataToMQ) error -} - -func NewChatLogDatabase(chatLogModelInterface relationtb.ChatLogModelInterface) ChatLogDatabase { - return &chatLogDatabase{chatLogModel: chatLogModelInterface} -} - -type chatLogDatabase struct { - chatLogModel relationtb.ChatLogModelInterface -} - -func (c *chatLogDatabase) CreateChatLog(msg *pbmsg.MsgDataToMQ) error { - return c.chatLogModel.Create(msg) -} diff --git a/pkg/common/db/controller/conversation.go b/pkg/common/db/controller/conversation.go index 6f7b8acb1..2a0cb63e4 100644 --- a/pkg/common/db/controller/conversation.go +++ b/pkg/common/db/controller/conversation.go @@ -16,9 +16,10 @@ package controller import ( "context" - "github.com/openimsdk/open-im-server/v3/pkg/common/pagination" "time" + "github.com/OpenIMSDK/tools/pagination" + "github.com/openimsdk/open-im-server/v3/pkg/msgprocessor" "github.com/OpenIMSDK/protocol/constant" @@ -237,7 +238,9 @@ func (c *conversationDatabase) SetUserConversations(ctx context.Context, ownerUs if err != nil { return err } - cache = cache.DelConversationIDs(ownerUserID).DelUserConversationIDsHash(ownerUserID).DelConversationNotReceiveMessageUserIDs(utils.Slice(notExistConversations, func(e *relationtb.ConversationModel) string { return e.ConversationID })...) + cache = cache.DelConversationIDs(ownerUserID). + DelUserConversationIDsHash(ownerUserID). + DelConversationNotReceiveMessageUserIDs(utils.Slice(notExistConversations, func(e *relationtb.ConversationModel) string { return e.ConversationID })...) } return cache.ExecDel(ctx) }) diff --git a/pkg/common/db/controller/friend.go b/pkg/common/db/controller/friend.go index 5d1c2617f..29b2ef9b1 100644 --- a/pkg/common/db/controller/friend.go +++ b/pkg/common/db/controller/friend.go @@ -18,7 +18,7 @@ import ( "context" "time" - "gorm.io/gorm" + "github.com/OpenIMSDK/tools/pagination" "github.com/OpenIMSDK/protocol/constant" "github.com/OpenIMSDK/tools/errs" @@ -47,35 +47,15 @@ type FriendDatabase interface { // 更新好友备注 UpdateRemark(ctx context.Context, ownerUserID, friendUserID, remark string) (err error) // 获取ownerUserID的好友列表 - PageOwnerFriends( - ctx context.Context, - ownerUserID string, - pageNumber, showNumber int32, - ) (friends []*relation.FriendModel, total int64, err error) + PageOwnerFriends(ctx context.Context, ownerUserID string, pagination pagination.Pagination) (total int64, friends []*relation.FriendModel, err error) // friendUserID在哪些人的好友列表中 - PageInWhoseFriends( - ctx context.Context, - friendUserID string, - pageNumber, showNumber int32, - ) (friends []*relation.FriendModel, total int64, err error) + PageInWhoseFriends(ctx context.Context, friendUserID string, pagination pagination.Pagination) (total int64, friends []*relation.FriendModel, err error) // 获取我发出去的好友申请 - PageFriendRequestFromMe( - ctx context.Context, - userID string, - pageNumber, showNumber int32, - ) (friends []*relation.FriendRequestModel, total int64, err error) + PageFriendRequestFromMe(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, friends []*relation.FriendRequestModel, err error) // 获取我收到的的好友申请 - PageFriendRequestToMe( - ctx context.Context, - userID string, - pageNumber, showNumber int32, - ) (friends []*relation.FriendRequestModel, total int64, err error) + PageFriendRequestToMe(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, friends []*relation.FriendRequestModel, err error) // 获取某人指定好友的信息 - FindFriendsWithError( - ctx context.Context, - ownerUserID string, - friendUserIDs []string, - ) (friends []*relation.FriendModel, err error) + FindFriendsWithError(ctx context.Context, ownerUserID string, friendUserIDs []string) (friends []*relation.FriendModel, err error) FindFriendUserIDs(ctx context.Context, ownerUserID string) (friendUserIDs []string, err error) FindBothFriendRequests(ctx context.Context, fromUserID, toUserID string) (friends []*relation.FriendRequestModel, err error) } @@ -83,24 +63,16 @@ type FriendDatabase interface { type friendDatabase struct { friend relation.FriendModelInterface friendRequest relation.FriendRequestModelInterface - tx tx.Tx + tx tx.CtxTx cache cache.FriendCache } -func NewFriendDatabase( - friend relation.FriendModelInterface, - friendRequest relation.FriendRequestModelInterface, - cache cache.FriendCache, - tx tx.Tx, -) FriendDatabase { +func NewFriendDatabase(friend relation.FriendModelInterface, friendRequest relation.FriendRequestModelInterface, cache cache.FriendCache, tx tx.CtxTx) FriendDatabase { return &friendDatabase{friend: friend, friendRequest: friendRequest, cache: cache, tx: tx} } // ok 检查user2是否在user1的好友列表中(inUser1Friends==true) 检查user1是否在user2的好友列表中(inUser2Friends==true). -func (f *friendDatabase) CheckIn( - ctx context.Context, - userID1, userID2 string, -) (inUser1Friends bool, inUser2Friends bool, err error) { +func (f *friendDatabase) CheckIn(ctx context.Context, userID1, userID2 string) (inUser1Friends bool, inUser2Friends bool, err error) { userID1FriendIDs, err := f.cache.GetFriendIDs(ctx, userID1) if err != nil { return @@ -113,50 +85,35 @@ func (f *friendDatabase) CheckIn( } // 增加或者更新好友申请 如果之前有记录则更新,没有记录则新增. -func (f *friendDatabase) AddFriendRequest( - ctx context.Context, - fromUserID, toUserID string, - reqMsg string, - ex string, -) (err error) { - return f.tx.Transaction(func(tx any) error { - _, err := f.friendRequest.NewTx(tx).Take(ctx, fromUserID, toUserID) - // 有db错误 - if err != nil && errs.Unwrap(err) != gorm.ErrRecordNotFound { - return err - } - // 无错误 则更新 - if err == nil { +func (f *friendDatabase) AddFriendRequest(ctx context.Context, fromUserID, toUserID string, reqMsg string, ex string) (err error) { + return f.tx.Transaction(ctx, func(ctx context.Context) error { + _, err := f.friendRequest.Take(ctx, fromUserID, toUserID) + switch { + case err == nil: m := make(map[string]any, 1) m["handle_result"] = 0 m["handle_msg"] = "" m["req_msg"] = reqMsg m["ex"] = ex m["create_time"] = time.Now() - if err := f.friendRequest.NewTx(tx).UpdateByMap(ctx, fromUserID, toUserID, m); err != nil { - return err - } - return nil - } - // gorm.ErrRecordNotFound 错误,则新增 - if err := f.friendRequest.NewTx(tx).Create(ctx, []*relation.FriendRequestModel{{FromUserID: fromUserID, ToUserID: toUserID, ReqMsg: reqMsg, Ex: ex, CreateTime: time.Now(), HandleTime: time.Unix(0, 0)}}); err != nil { + return f.friendRequest.UpdateByMap(ctx, fromUserID, toUserID, m) + case relation.IsNotFound(err): + return f.friendRequest.Create( + ctx, + []*relation.FriendRequestModel{{FromUserID: fromUserID, ToUserID: toUserID, ReqMsg: reqMsg, Ex: ex, CreateTime: time.Now(), HandleTime: time.Unix(0, 0)}}, + ) + default: return err } - return nil }) } // (1)先判断是否在好友表 (在不在都不返回错误) (2)对于不在好友列表的 插入即可. -func (f *friendDatabase) BecomeFriends( - ctx context.Context, - ownerUserID string, - friendUserIDs []string, - addSource int32, -) (err error) { - cache := f.cache.NewCache() - if err := f.tx.Transaction(func(tx any) error { +func (f *friendDatabase) BecomeFriends(ctx context.Context, ownerUserID string, friendUserIDs []string, addSource int32) (err error) { + return f.tx.Transaction(ctx, func(ctx context.Context) error { + cache := f.cache.NewCache() // 先find 找出重复的 去掉重复的 - fs1, err := f.friend.NewTx(tx).FindFriends(ctx, ownerUserID, friendUserIDs) + fs1, err := f.friend.FindFriends(ctx, ownerUserID, friendUserIDs) if err != nil { return err } @@ -168,11 +125,11 @@ func (f *friendDatabase) BecomeFriends( return e.FriendUserID }) - err = f.friend.NewTx(tx).Create(ctx, fs11) + err = f.friend.Create(ctx, fs11) if err != nil { return err } - fs2, err := f.friend.NewTx(tx).FindReversalFriends(ctx, ownerUserID, friendUserIDs) + fs2, err := f.friend.FindReversalFriends(ctx, ownerUserID, friendUserIDs) if err != nil { return err } @@ -184,24 +141,19 @@ func (f *friendDatabase) BecomeFriends( fs22 := utils.DistinctAny(fs2, func(e *relation.FriendModel) string { return e.OwnerUserID }) - err = f.friend.NewTx(tx).Create(ctx, fs22) + err = f.friend.Create(ctx, fs22) if err != nil { return err } newFriendIDs = append(newFriendIDs, ownerUserID) cache = cache.DelFriendIDs(newFriendIDs...) - return nil - }); err != nil { - return nil - } - return cache.ExecDel(ctx) + return cache.ExecDel(ctx) + + }) } // 拒绝好友申请 (1)检查是否有申请记录且为未处理状态 (没有记录返回错误) (2)修改申请记录 已拒绝. -func (f *friendDatabase) RefuseFriendRequest( - ctx context.Context, - friendRequest *relation.FriendRequestModel, -) (err error) { +func (f *friendDatabase) RefuseFriendRequest(ctx context.Context, friendRequest *relation.FriendRequestModel) (err error) { fr, err := f.friendRequest.Take(ctx, friendRequest.FromUserID, friendRequest.ToUserID) if err != nil { return err @@ -220,14 +172,11 @@ func (f *friendDatabase) RefuseFriendRequest( } // AgreeFriendRequest 同意好友申请 (1)检查是否有申请记录且为未处理状态 (没有记录返回错误) (2)检查是否好友(不返回错误) (3) 建立双向好友关系(存在的忽略). -func (f *friendDatabase) AgreeFriendRequest( - ctx context.Context, - friendRequest *relation.FriendRequestModel, -) (err error) { - return f.tx.Transaction(func(tx any) error { +func (f *friendDatabase) AgreeFriendRequest(ctx context.Context, friendRequest *relation.FriendRequestModel) (err error) { + return f.tx.Transaction(ctx, func(ctx context.Context) error { defer log.ZDebug(ctx, "return line") now := time.Now() - fr, err := f.friendRequest.NewTx(tx).Take(ctx, friendRequest.FromUserID, friendRequest.ToUserID) + fr, err := f.friendRequest.Take(ctx, friendRequest.FromUserID, friendRequest.ToUserID) if err != nil { return err } @@ -237,25 +186,25 @@ func (f *friendDatabase) AgreeFriendRequest( friendRequest.HandlerUserID = mcontext.GetOpUserID(ctx) friendRequest.HandleResult = constant.FriendResponseAgree friendRequest.HandleTime = now - err = f.friendRequest.NewTx(tx).Update(ctx, friendRequest) + err = f.friendRequest.Update(ctx, friendRequest) if err != nil { return err } - fr2, err := f.friendRequest.NewTx(tx).Take(ctx, friendRequest.ToUserID, friendRequest.FromUserID) + fr2, err := f.friendRequest.Take(ctx, friendRequest.ToUserID, friendRequest.FromUserID) if err == nil && fr2.HandleResult == constant.FriendResponseNotHandle { fr2.HandlerUserID = mcontext.GetOpUserID(ctx) fr2.HandleResult = constant.FriendResponseAgree fr2.HandleTime = now - err = f.friendRequest.NewTx(tx).Update(ctx, fr2) + err = f.friendRequest.Update(ctx, fr2) if err != nil { return err } - } else if err != nil && errs.Unwrap(err) != gorm.ErrRecordNotFound { + } else if err != nil && (!relation.IsNotFound(err)) { return err } - exists, err := f.friend.NewTx(tx).FindUserState(ctx, friendRequest.FromUserID, friendRequest.ToUserID) + exists, err := f.friend.FindUserState(ctx, friendRequest.FromUserID, friendRequest.ToUserID) if err != nil { return err } @@ -286,7 +235,7 @@ func (f *friendDatabase) AgreeFriendRequest( ) } if len(adds) > 0 { - if err := f.friend.NewTx(tx).Create(ctx, adds); err != nil { + if err := f.friend.Create(ctx, adds); err != nil { return err } } @@ -311,47 +260,27 @@ func (f *friendDatabase) UpdateRemark(ctx context.Context, ownerUserID, friendUs } // 获取ownerUserID的好友列表 无结果不返回错误. -func (f *friendDatabase) PageOwnerFriends( - ctx context.Context, - ownerUserID string, - pageNumber, showNumber int32, -) (friends []*relation.FriendModel, total int64, err error) { - return f.friend.FindOwnerFriends(ctx, ownerUserID, pageNumber, showNumber) +func (f *friendDatabase) PageOwnerFriends(ctx context.Context, ownerUserID string, pagination pagination.Pagination) (total int64, friends []*relation.FriendModel, err error) { + return f.friend.FindOwnerFriends(ctx, ownerUserID, pagination) } // friendUserID在哪些人的好友列表中. -func (f *friendDatabase) PageInWhoseFriends( - ctx context.Context, - friendUserID string, - pageNumber, showNumber int32, -) (friends []*relation.FriendModel, total int64, err error) { - return f.friend.FindInWhoseFriends(ctx, friendUserID, pageNumber, showNumber) +func (f *friendDatabase) PageInWhoseFriends(ctx context.Context, friendUserID string, pagination pagination.Pagination) (total int64, friends []*relation.FriendModel, err error) { + return f.friend.FindInWhoseFriends(ctx, friendUserID, pagination) } // 获取我发出去的好友申请 无结果不返回错误. -func (f *friendDatabase) PageFriendRequestFromMe( - ctx context.Context, - userID string, - pageNumber, showNumber int32, -) (friends []*relation.FriendRequestModel, total int64, err error) { - return f.friendRequest.FindFromUserID(ctx, userID, pageNumber, showNumber) +func (f *friendDatabase) PageFriendRequestFromMe(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, friends []*relation.FriendRequestModel, err error) { + return f.friendRequest.FindFromUserID(ctx, userID, pagination) } // 获取我收到的的好友申请 无结果不返回错误. -func (f *friendDatabase) PageFriendRequestToMe( - ctx context.Context, - userID string, - pageNumber, showNumber int32, -) (friends []*relation.FriendRequestModel, total int64, err error) { - return f.friendRequest.FindToUserID(ctx, userID, pageNumber, showNumber) +func (f *friendDatabase) PageFriendRequestToMe(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, friends []*relation.FriendRequestModel, err error) { + return f.friendRequest.FindToUserID(ctx, userID, pagination) } // 获取某人指定好友的信息 如果有好友不存在,也返回错误. -func (f *friendDatabase) FindFriendsWithError( - ctx context.Context, - ownerUserID string, - friendUserIDs []string, -) (friends []*relation.FriendModel, err error) { +func (f *friendDatabase) FindFriendsWithError(ctx context.Context, ownerUserID string, friendUserIDs []string) (friends []*relation.FriendModel, err error) { friends, err = f.friend.FindFriends(ctx, ownerUserID, friendUserIDs) if err != nil { return @@ -362,10 +291,7 @@ func (f *friendDatabase) FindFriendsWithError( return } -func (f *friendDatabase) FindFriendUserIDs( - ctx context.Context, - ownerUserID string, -) (friendUserIDs []string, err error) { +func (f *friendDatabase) FindFriendUserIDs(ctx context.Context, ownerUserID string) (friendUserIDs []string, err error) { return f.cache.GetFriendIDs(ctx, ownerUserID) } diff --git a/pkg/common/db/controller/group.go b/pkg/common/db/controller/group.go index 0df0383e8..4147d59c0 100644 --- a/pkg/common/db/controller/group.go +++ b/pkg/common/db/controller/group.go @@ -16,10 +16,11 @@ package controller import ( "context" - "github.com/dtm-labs/rockscache" - "github.com/openimsdk/open-im-server/v3/pkg/common/pagination" "time" + "github.com/OpenIMSDK/tools/pagination" + "github.com/dtm-labs/rockscache" + "github.com/OpenIMSDK/protocol/constant" "github.com/OpenIMSDK/tools/tx" "github.com/OpenIMSDK/tools/utils" @@ -74,7 +75,14 @@ type GroupDatabase interface { DeleteGroupMemberHash(ctx context.Context, groupIDs []string) error } -func NewGroupDatabase(rdb redis.UniversalClient, groupDB relationtb.GroupModelInterface, groupMemberDB relationtb.GroupMemberModelInterface, groupRequestDB relationtb.GroupRequestModelInterface, ctxTx tx.CtxTx, groupHash cache.GroupHash) 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 diff --git a/pkg/common/db/controller/msg.go b/pkg/common/db/controller/msg.go index cba0a6bbd..fb0a9c702 100644 --- a/pkg/common/db/controller/msg.go +++ b/pkg/common/db/controller/msg.go @@ -357,9 +357,7 @@ func (db *commonMsgDatabase) DelUserDeleteMsgsList(ctx context.Context, conversa } func (db *commonMsgDatabase) BatchInsertChat2Cache(ctx context.Context, conversationID string, msgs []*sdkws.MsgData) (seq int64, isNew bool, err error) { - cancelCtx, cancel := context.WithTimeout(ctx, 1*time.Minute) - defer cancel() - currentMaxSeq, err := db.cache.GetMaxSeq(cancelCtx, conversationID) + currentMaxSeq, err := db.cache.GetMaxSeq(ctx, conversationID) if err != nil && errs.Unwrap(err) != redis.Nil { log.ZError(ctx, "db.cache.GetMaxSeq", err) return 0, false, err @@ -386,21 +384,19 @@ func (db *commonMsgDatabase) BatchInsertChat2Cache(ctx context.Context, conversa prommetrics.MsgInsertRedisFailedCounter.Add(float64(failedNum)) log.ZError(ctx, "setMessageToCache error", err, "len", len(msgs), "conversationID", conversationID) } else { - prommetrics.MsgInsertRedisSuccessCounter.Add(float64(len(msgs))) + prommetrics.MsgInsertRedisSuccessCounter.Inc() } - cancelCtx, cancel = context.WithTimeout(ctx, 1*time.Minute) - defer cancel() - err = db.cache.SetMaxSeq(cancelCtx, conversationID, currentMaxSeq) + err = db.cache.SetMaxSeq(ctx, conversationID, currentMaxSeq) if err != nil { log.ZError(ctx, "db.cache.SetMaxSeq error", err, "conversationID", conversationID) prommetrics.SeqSetFailedCounter.Inc() } err2 := db.cache.SetHasReadSeqs(ctx, conversationID, userSeqMap) - if err2 != nil { + if err != nil { log.ZError(ctx, "SetHasReadSeqs error", err2, "userSeqMap", userSeqMap, "conversationID", conversationID) prommetrics.SeqSetFailedCounter.Inc() } - return lastMaxSeq, isNew, errs.Wrap(err, "redis SetMaxSeq error") + return lastMaxSeq, isNew, utils.Wrap(err, "") } func (db *commonMsgDatabase) getMsgBySeqs(ctx context.Context, userID, conversationID string, seqs []int64) (totalMsgs []*sdkws.MsgData, err error) { @@ -658,26 +654,16 @@ func (db *commonMsgDatabase) GetMsgBySeqsRange(ctx context.Context, userID strin func (db *commonMsgDatabase) GetMsgBySeqs(ctx context.Context, userID string, conversationID string, seqs []int64) (int64, int64, []*sdkws.MsgData, error) { userMinSeq, err := db.cache.GetConversationUserMinSeq(ctx, conversationID, userID) - if err != nil { - log.ZError(ctx, "cache.GetConversationUserMinSeq error", err) - if errs.Unwrap(err) != redis.Nil { - return 0, 0, nil, err - } + if err != nil && errs.Unwrap(err) != redis.Nil { + return 0, 0, nil, err } minSeq, err := db.cache.GetMinSeq(ctx, conversationID) - if err != nil { - log.ZError(ctx, "cache.GetMinSeq error", err) - if errs.Unwrap(err) != redis.Nil { - return 0, 0, nil, err - } + if err != nil && errs.Unwrap(err) != redis.Nil { + return 0, 0, nil, err } maxSeq, err := db.cache.GetMaxSeq(ctx, conversationID) - if err != nil { - log.ZError(ctx, "cache.GetMaxSeq error", err) - if errs.Unwrap(err) != redis.Nil { - return 0, 0, nil, err - } - + if err != nil && errs.Unwrap(err) != redis.Nil { + return 0, 0, nil, err } if userMinSeq < minSeq { minSeq = userMinSeq @@ -690,16 +676,34 @@ func (db *commonMsgDatabase) GetMsgBySeqs(ctx context.Context, userID string, co } successMsgs, failedSeqs, err := db.cache.GetMessagesBySeq(ctx, conversationID, newSeqs) if err != nil { - log.ZError(ctx, "get message from redis exception", err, "failedSeqs", failedSeqs, "conversationID", conversationID) + if err != redis.Nil { + log.ZError(ctx, "get message from redis exception", err, "failedSeqs", failedSeqs, "conversationID", conversationID) + } } - log.ZInfo(ctx, "db.cache.GetMessagesBySeq", "userID", userID, "conversationID", conversationID, "seqs", seqs, "successMsgs", - len(successMsgs), "failedSeqs", failedSeqs, "conversationID", conversationID) + log.ZInfo( + ctx, + "db.cache.GetMessagesBySeq", + "userID", + userID, + "conversationID", + conversationID, + "seqs", + seqs, + "successMsgs", + len(successMsgs), + "failedSeqs", + failedSeqs, + "conversationID", + conversationID, + ) if len(failedSeqs) > 0 { mongoMsgs, err := db.getMsgBySeqs(ctx, userID, conversationID, failedSeqs) if err != nil { + return 0, 0, nil, err } + successMsgs = append(successMsgs, mongoMsgs...) } return minSeq, maxSeq, successMsgs, nil diff --git a/pkg/common/db/controller/third.go b/pkg/common/db/controller/third.go index 27481f78d..fb5b0ccbe 100644 --- a/pkg/common/db/controller/third.go +++ b/pkg/common/db/controller/third.go @@ -16,9 +16,10 @@ package controller import ( "context" - "github.com/openimsdk/open-im-server/v3/pkg/common/pagination" "time" + "github.com/OpenIMSDK/tools/pagination" + "github.com/openimsdk/open-im-server/v3/pkg/common/db/cache" "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" ) @@ -27,10 +28,10 @@ type ThirdDatabase interface { FcmUpdateToken(ctx context.Context, account string, platformID int, fcmToken string, expireTime int64) error SetAppBadge(ctx context.Context, userID string, value int) error // about log for debug - UploadLogs(ctx context.Context, logs []*relation.Log) error + UploadLogs(ctx context.Context, logs []*relation.LogModel) error DeleteLogs(ctx context.Context, logID []string, userID string) 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) + SearchLogs(ctx context.Context, keyword string, start time.Time, end time.Time, pagination pagination.Pagination) (int64, []*relation.LogModel, error) + GetLogs(ctx context.Context, LogIDs []string, userID string) ([]*relation.LogModel, error) } type thirdDatabase struct { @@ -44,17 +45,17 @@ func (t *thirdDatabase) DeleteLogs(ctx context.Context, logID []string, userID s } // GetLogs implements ThirdDatabase. -func (t *thirdDatabase) GetLogs(ctx context.Context, LogIDs []string, userID string) ([]*relation.Log, error) { +func (t *thirdDatabase) GetLogs(ctx context.Context, LogIDs []string, userID string) ([]*relation.LogModel, error) { return t.logdb.Get(ctx, LogIDs, userID) } // SearchLogs implements ThirdDatabase. -func (t *thirdDatabase) SearchLogs(ctx context.Context, keyword string, start time.Time, end time.Time, pagination pagination.Pagination) (int64, []*relation.Log, error) { +func (t *thirdDatabase) SearchLogs(ctx context.Context, keyword string, start time.Time, end time.Time, pagination pagination.Pagination) (int64, []*relation.LogModel, error) { return t.logdb.Search(ctx, keyword, start, end, pagination) } // UploadLogs implements ThirdDatabase. -func (t *thirdDatabase) UploadLogs(ctx context.Context, logs []*relation.Log) error { +func (t *thirdDatabase) UploadLogs(ctx context.Context, logs []*relation.LogModel) error { return t.logdb.Create(ctx, logs) } diff --git a/pkg/common/db/controller/user.go b/pkg/common/db/controller/user.go index 6299e7e87..ca703b729 100644 --- a/pkg/common/db/controller/user.go +++ b/pkg/common/db/controller/user.go @@ -16,10 +16,12 @@ package controller import ( "context" + "time" + + "github.com/OpenIMSDK/tools/pagination" "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" @@ -79,35 +81,33 @@ func NewUserDatabase(userDB relation.UserModelInterface, cache cache.UserCache, return &userDatabase{userDB: userDB, cache: cache, tx: tx, mongoDB: mongoDB} } - 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 - }) + // 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 - } + // 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 - }) + // 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 - } - } + // Create records for missing users. + if len(missingUsers) > 0 { + if err := u.userDB.Create(ctx, missingUsers); err != nil { + return err + } + } - return nil + 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) diff --git a/pkg/common/db/mgo/black.go b/pkg/common/db/mgo/black.go new file mode 100644 index 000000000..6235639aa --- /dev/null +++ b/pkg/common/db/mgo/black.go @@ -0,0 +1,91 @@ +package mgo + +import ( + "context" + + "github.com/OpenIMSDK/tools/mgoutil" + "github.com/OpenIMSDK/tools/pagination" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" + + "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" +) + +func NewBlackMongo(db *mongo.Database) (relation.BlackModelInterface, error) { + coll := db.Collection("black") + _, err := coll.Indexes().CreateOne(context.Background(), mongo.IndexModel{ + Keys: bson.D{ + {Key: "owner_user_id", Value: 1}, + {Key: "block_user_id", Value: 1}, + }, + Options: options.Index().SetUnique(true), + }) + if err != nil { + return nil, err + } + return &BlackMgo{coll: coll}, nil +} + +type BlackMgo struct { + coll *mongo.Collection +} + +func (b *BlackMgo) blackFilter(ownerUserID, blockUserID string) bson.M { + return bson.M{ + "owner_user_id": ownerUserID, + "block_user_id": blockUserID, + } +} + +func (b *BlackMgo) blacksFilter(blacks []*relation.BlackModel) bson.M { + if len(blacks) == 0 { + return nil + } + or := make(bson.A, 0, len(blacks)) + for _, black := range blacks { + or = append(or, b.blackFilter(black.OwnerUserID, black.BlockUserID)) + } + return bson.M{"$or": or} +} + +func (b *BlackMgo) Create(ctx context.Context, blacks []*relation.BlackModel) (err error) { + return mgoutil.InsertMany(ctx, b.coll, blacks) +} + +func (b *BlackMgo) Delete(ctx context.Context, blacks []*relation.BlackModel) (err error) { + if len(blacks) == 0 { + return nil + } + return mgoutil.DeleteMany(ctx, b.coll, b.blacksFilter(blacks)) +} + +func (b *BlackMgo) UpdateByMap(ctx context.Context, ownerUserID, blockUserID string, args map[string]any) (err error) { + if len(args) == 0 { + return nil + } + return mgoutil.UpdateOne(ctx, b.coll, b.blackFilter(ownerUserID, blockUserID), bson.M{"$set": args}, false) +} + +func (b *BlackMgo) Find(ctx context.Context, blacks []*relation.BlackModel) (blackList []*relation.BlackModel, err error) { + return mgoutil.Find[*relation.BlackModel](ctx, b.coll, b.blacksFilter(blacks)) +} + +func (b *BlackMgo) Take(ctx context.Context, ownerUserID, blockUserID string) (black *relation.BlackModel, err error) { + return mgoutil.FindOne[*relation.BlackModel](ctx, b.coll, b.blackFilter(ownerUserID, blockUserID)) +} + +func (b *BlackMgo) FindOwnerBlacks(ctx context.Context, ownerUserID string, pagination pagination.Pagination) (total int64, blacks []*relation.BlackModel, err error) { + return mgoutil.FindPage[*relation.BlackModel](ctx, b.coll, bson.M{"owner_user_id": ownerUserID}, pagination) +} + +func (b *BlackMgo) FindOwnerBlackInfos(ctx context.Context, ownerUserID string, userIDs []string) (blacks []*relation.BlackModel, err error) { + if len(userIDs) == 0 { + return mgoutil.Find[*relation.BlackModel](ctx, b.coll, bson.M{"owner_user_id": ownerUserID}) + } + return mgoutil.Find[*relation.BlackModel](ctx, b.coll, bson.M{"owner_user_id": ownerUserID, "block_user_id": bson.M{"$in": userIDs}}) +} + +func (b *BlackMgo) FindBlackUserIDs(ctx context.Context, ownerUserID string) (blackUserIDs []string, err error) { + return mgoutil.Find[string](ctx, b.coll, bson.M{"owner_user_id": ownerUserID}, options.Find().SetProjection(bson.M{"_id": 0, "block_user_id": 1})) +} diff --git a/pkg/common/db/newmgo/conversation.go b/pkg/common/db/mgo/conversation.go similarity index 70% rename from pkg/common/db/newmgo/conversation.go rename to pkg/common/db/mgo/conversation.go index cfa22d08f..72d04ebb3 100644 --- a/pkg/common/db/newmgo/conversation.go +++ b/pkg/common/db/mgo/conversation.go @@ -1,21 +1,32 @@ -package newmgo +package mgo import ( "context" + "time" + "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" + "github.com/OpenIMSDK/tools/mgoutil" + "github.com/OpenIMSDK/tools/pagination" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" - "time" + + "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" ) func NewConversationMongo(db *mongo.Database) (*ConversationMgo, error) { - return &ConversationMgo{ - coll: db.Collection("conversation"), - }, nil + coll := db.Collection("conversation") + _, err := coll.Indexes().CreateOne(context.Background(), mongo.IndexModel{ + Keys: bson.D{ + {Key: "owner_user_id", Value: 1}, + {Key: "conversation_id", Value: 1}, + }, + Options: options.Index().SetUnique(true), + }) + if err != nil { + return nil, err + } + return &ConversationMgo{coll: coll}, nil } type ConversationMgo struct { @@ -23,15 +34,15 @@ type ConversationMgo struct { } func (c *ConversationMgo) Create(ctx context.Context, conversations []*relation.ConversationModel) (err error) { - return mgotool.InsertMany(ctx, c.coll, conversations) + return mgoutil.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}}) + return mgoutil.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}) + res, err := mgoutil.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 } @@ -39,50 +50,55 @@ func (c *ConversationMgo) UpdateByMap(ctx context.Context, userIDs []string, con } 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) + return mgoutil.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}}) + return mgoutil.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})) + return mgoutil.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})) + return mgoutil.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}) + return mgoutil.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})) + return mgoutil.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}) + return mgoutil.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})) + return mgoutil.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})) + return mgoutil.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{ + return mgoutil.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{ + counts, err := mgoutil.Aggregate[int64](ctx, c.coll, []bson.M{ {"$group": bson.M{"_id": "$conversation_id"}}, {"$project": bson.M{"_id": 0, "conversation_id": "$_id"}}, }) @@ -96,16 +112,16 @@ func (c *ConversationMgo) GetAllConversationIDsNumber(ctx context.Context) (int6 } 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})) + return mgoutil.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}}) + return mgoutil.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{ + return mgoutil.Find[*relation.ConversationModel](ctx, c.coll, bson.M{ "is_msg_destruct": 1, "msg_destruct_time": bson.M{"$ne": 0}, "$or": []bson.M{ @@ -125,5 +141,10 @@ func (c *ConversationMgo) GetConversationIDsNeedDestruct(ctx context.Context) ([ } 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})) + return mgoutil.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/mgo/friend.go similarity index 63% rename from pkg/common/db/newmgo/friend.go rename to pkg/common/db/mgo/friend.go index b02cff7c0..aa9cb0301 100644 --- a/pkg/common/db/newmgo/friend.go +++ b/pkg/common/db/mgo/friend.go @@ -1,13 +1,16 @@ -package newmgo +package mgo 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" + "github.com/OpenIMSDK/tools/mgoutil" + "github.com/OpenIMSDK/tools/pagination" + "go.mongodb.org/mongo-driver/mongo/options" + "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" + + "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" ) // FriendMgo implements FriendModelInterface using MongoDB as the storage backend. @@ -17,14 +20,23 @@ type FriendMgo struct { // 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 + coll := db.Collection("friend") + _, err := coll.Indexes().CreateOne(context.Background(), mongo.IndexModel{ + Keys: bson.D{ + {Key: "owner_user_id", Value: 1}, + {Key: "friend_user_id", Value: 1}, + }, + Options: options.Index().SetUnique(true), + }) + if err != nil { + return nil, err + } + return &FriendMgo{coll: coll}, nil } // Create inserts multiple friend records. func (f *FriendMgo) Create(ctx context.Context, friends []*relation.FriendModel) error { - return mgotool.InsertMany(ctx, f.coll, friends) + return mgoutil.InsertMany(ctx, f.coll, friends) } // Delete removes specified friends of the owner user. @@ -33,11 +45,7 @@ func (f *FriendMgo) Delete(ctx context.Context, ownerUserID string, friendUserID "owner_user_id": ownerUserID, "friend_user_id": bson.M{"$in": friendUserIDs}, } - _, err := f.coll.DeleteMany(ctx, filter) - if err != nil { - return err - } - return nil + return mgoutil.DeleteOne(ctx, f.coll, filter) } // UpdateByMap updates specific fields of a friend document using a map. @@ -49,12 +57,7 @@ func (f *FriendMgo) UpdateByMap(ctx context.Context, ownerUserID string, friendU "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 + return mgoutil.UpdateOne(ctx, f.coll, filter, bson.M{"$set": args}, true) } // Update modifies multiple friend documents. @@ -68,8 +71,7 @@ func (f *FriendMgo) UpdateByMap(ctx context.Context, ownerUserID string, friendU // 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) + return f.UpdateByMap(ctx, ownerUserID, friendUserID, map[string]any{"remark": remark}) } // Take retrieves a single friend document. Returns an error if not found. @@ -78,11 +80,7 @@ func (f *FriendMgo) Take(ctx context.Context, ownerUserID, friendUserID string) "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 + return mgoutil.FindOne[*relation.FriendModel](ctx, f.coll, filter) } // FindUserState finds the friendship status between two users. @@ -93,11 +91,7 @@ func (f *FriendMgo) FindUserState(ctx context.Context, userID1, userID2 string) {"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 + return mgoutil.Find[*relation.FriendModel](ctx, f.coll, filter) } // FindFriends retrieves a list of friends for a given owner. Missing friends do not cause an error. @@ -106,11 +100,7 @@ func (f *FriendMgo) FindFriends(ctx context.Context, ownerUserID string, friendU "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 + return mgoutil.Find[*relation.FriendModel](ctx, f.coll, filter) } // FindReversalFriends finds users who have added the specified user as a friend. @@ -119,51 +109,23 @@ func (f *FriendMgo) FindReversalFriends(ctx context.Context, friendUserID string "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 + return mgoutil.Find[*relation.FriendModel](ctx, f.coll, filter) } // 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) { +func (f *FriendMgo) FindOwnerFriends(ctx context.Context, ownerUserID string, pagination pagination.Pagination) (int64, []*relation.FriendModel, 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 + return mgoutil.FindPage[*relation.FriendModel](ctx, f.coll, filter, pagination) } // 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) { +func (f *FriendMgo) FindInWhoseFriends(ctx context.Context, friendUserID string, pagination pagination.Pagination) (int64, []*relation.FriendModel, 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 + return mgoutil.FindPage[*relation.FriendModel](ctx, f.coll, filter, pagination) } // 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 + return mgoutil.Find[string](ctx, f.coll, filter, options.Find().SetProjection(bson.M{"_id": 0, "friend_user_id": 1})) } diff --git a/pkg/common/db/mgo/friend_request.go b/pkg/common/db/mgo/friend_request.go new file mode 100644 index 000000000..c1be87ca2 --- /dev/null +++ b/pkg/common/db/mgo/friend_request.go @@ -0,0 +1,99 @@ +package mgo + +import ( + "context" + + "github.com/OpenIMSDK/tools/mgoutil" + "github.com/OpenIMSDK/tools/pagination" + "go.mongodb.org/mongo-driver/mongo/options" + + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" + + "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" +) + +func NewFriendRequestMongo(db *mongo.Database) (relation.FriendRequestModelInterface, error) { + coll := db.Collection("friend_request") + _, err := coll.Indexes().CreateOne(context.Background(), mongo.IndexModel{ + Keys: bson.D{ + {Key: "from_user_id", Value: 1}, + {Key: "to_user_id", Value: 1}, + }, + Options: options.Index().SetUnique(true), + }) + if err != nil { + return nil, err + } + return &FriendRequestMgo{coll: coll}, nil +} + +type FriendRequestMgo struct { + coll *mongo.Collection +} + +func (f *FriendRequestMgo) FindToUserID(ctx context.Context, toUserID string, pagination pagination.Pagination) (total int64, friendRequests []*relation.FriendRequestModel, err error) { + return mgoutil.FindPage[*relation.FriendRequestModel](ctx, f.coll, bson.M{"to_user_id": toUserID}, pagination) +} + +func (f *FriendRequestMgo) FindFromUserID(ctx context.Context, fromUserID string, pagination pagination.Pagination) (total int64, friendRequests []*relation.FriendRequestModel, err error) { + return mgoutil.FindPage[*relation.FriendRequestModel](ctx, f.coll, bson.M{"from_user_id": fromUserID}, pagination) +} + +func (f *FriendRequestMgo) FindBothFriendRequests(ctx context.Context, fromUserID, toUserID string) (friends []*relation.FriendRequestModel, err error) { + filter := bson.M{"$or": []bson.M{ + {"from_user_id": fromUserID, "to_user_id": toUserID}, + {"from_user_id": toUserID, "to_user_id": fromUserID}, + }} + return mgoutil.Find[*relation.FriendRequestModel](ctx, f.coll, filter) +} + +func (f *FriendRequestMgo) Create(ctx context.Context, friendRequests []*relation.FriendRequestModel) error { + return mgoutil.InsertMany(ctx, f.coll, friendRequests) +} + +func (f *FriendRequestMgo) Delete(ctx context.Context, fromUserID, toUserID string) (err error) { + return mgoutil.DeleteOne(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 mgoutil.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) { + updater := bson.M{} + if friendRequest.HandleResult != 0 { + updater["handle_result"] = friendRequest.HandleResult + } + if friendRequest.ReqMsg != "" { + updater["req_msg"] = friendRequest.ReqMsg + } + if friendRequest.HandlerUserID != "" { + updater["handler_user_id"] = friendRequest.HandlerUserID + } + if friendRequest.HandleMsg != "" { + updater["handle_msg"] = friendRequest.HandleMsg + } + if !friendRequest.HandleTime.IsZero() { + updater["handle_time"] = friendRequest.HandleTime + } + if friendRequest.Ex != "" { + updater["ex"] = friendRequest.Ex + } + if len(updater) == 0 { + return nil + } + filter := bson.M{"from_user_id": friendRequest.FromUserID, "to_user_id": friendRequest.ToUserID} + return mgoutil.UpdateOne(ctx, f.coll, filter, bson.M{"$set": updater}, true) +} + +func (f *FriendRequestMgo) Find(ctx context.Context, fromUserID, toUserID string) (friendRequest *relation.FriendRequestModel, err error) { + return mgoutil.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/mgo/group.go similarity index 50% rename from pkg/common/db/newmgo/group.go rename to pkg/common/db/mgo/group.go index ff5807c0d..3553b6b56 100644 --- a/pkg/common/db/newmgo/group.go +++ b/pkg/common/db/mgo/group.go @@ -1,19 +1,30 @@ -package newmgo +package mgo 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" + "time" + + "github.com/OpenIMSDK/tools/mgoutil" + "github.com/OpenIMSDK/tools/pagination" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" - "time" + "go.mongodb.org/mongo-driver/mongo/options" + + "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" ) func NewGroupMongo(db *mongo.Database) (relation.GroupModelInterface, error) { - return &GroupMgo{ - coll: db.Collection("group"), - }, nil + coll := db.Collection("group") + _, err := coll.Indexes().CreateOne(context.Background(), mongo.IndexModel{ + Keys: bson.D{ + {Key: "group_id", Value: 1}, + }, + Options: options.Index().SetUnique(true), + }) + if err != nil { + return nil, err + } + return &GroupMgo{coll: coll}, nil } type GroupMgo struct { @@ -21,7 +32,7 @@ type GroupMgo struct { } func (g *GroupMgo) Create(ctx context.Context, groups []*relation.GroupModel) (err error) { - return mgotool.InsertMany(ctx, g.coll, groups) + return mgoutil.InsertMany(ctx, g.coll, groups) } func (g *GroupMgo) UpdateState(ctx context.Context, groupID string, state int32) (err error) { @@ -32,29 +43,63 @@ func (g *GroupMgo) UpdateMap(ctx context.Context, groupID string, args map[strin if len(args) == 0 { return nil } - return mgotool.UpdateOne(ctx, g.coll, bson.M{"group_id": groupID}, bson.M{"$set": args}, true) + return mgoutil.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}}) + return mgoutil.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}) + return mgoutil.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) + return mgoutil.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 mgoutil.Count(ctx, g.coll, bson.M{}) } - return mgotool.Count(ctx, g.coll, bson.M{"create_time": bson.M{"$lt": before}}) + return mgoutil.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") + pipeline := bson.A{ + bson.M{ + "$match": bson.M{ + "create_time": bson.M{ + "$gte": start, + "$lt": end, + }, + }, + }, + bson.M{ + "$group": bson.M{ + "_id": bson.M{ + "$dateToString": bson.M{ + "format": "%Y-%m-%d", + "date": "$create_time", + }, + }, + "count": bson.M{ + "$sum": 1, + }, + }, + }, + } + type Item struct { + Date string `bson:"_id"` + Count int64 `bson:"count"` + } + items, err := mgoutil.Aggregate[Item](ctx, g.coll, pipeline) + if err != nil { + return nil, err + } + res := make(map[string]int64, len(items)) + for _, item := range items { + res[item.Date] = item.Count + } + return res, nil } diff --git a/pkg/common/db/newmgo/group_member.go b/pkg/common/db/mgo/group_member.go similarity index 74% rename from pkg/common/db/newmgo/group_member.go rename to pkg/common/db/mgo/group_member.go index dbc774e80..ed09a028b 100644 --- a/pkg/common/db/newmgo/group_member.go +++ b/pkg/common/db/mgo/group_member.go @@ -1,18 +1,31 @@ -package newmgo +package mgo 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" + "github.com/OpenIMSDK/tools/mgoutil" + "github.com/OpenIMSDK/tools/pagination" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" + + "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" ) func NewGroupMember(db *mongo.Database) (relation.GroupMemberModelInterface, error) { - return &GroupMemberMgo{coll: db.Collection("group_member")}, nil + coll := db.Collection("group_member") + _, err := coll.Indexes().CreateOne(context.Background(), mongo.IndexModel{ + Keys: bson.D{ + {Key: "group_id", Value: 1}, + {Key: "user_id", Value: 1}, + }, + Options: options.Index().SetUnique(true), + }) + if err != nil { + return nil, err + } + return &GroupMemberMgo{coll: coll}, nil } type GroupMemberMgo struct { @@ -20,11 +33,11 @@ type GroupMemberMgo struct { } func (g *GroupMemberMgo) Create(ctx context.Context, groupMembers []*relation.GroupMemberModel) (err error) { - return mgotool.InsertMany(ctx, g.coll, groupMembers) + return mgoutil.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}}) + return mgoutil.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 { @@ -32,7 +45,7 @@ func (g *GroupMemberMgo) UpdateRoleLevel(ctx context.Context, groupID string, us } 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) + return mgoutil.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) { @@ -41,19 +54,19 @@ func (g *GroupMemberMgo) Find(ctx context.Context, groupIDs []string, userIDs [] } 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})) + return mgoutil.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}) + return mgoutil.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}) + return mgoutil.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})) + return mgoutil.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) { @@ -62,11 +75,11 @@ func (g *GroupMemberMgo) SearchMember(ctx context.Context, keyword string, group } 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})) + return mgoutil.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}) + return mgoutil.Count(ctx, g.coll, bson.M{"group_id": groupID}) } func (g *GroupMemberMgo) FindUserManagedGroupID(ctx context.Context, userID string) (groupIDs []string, err error) { @@ -76,7 +89,7 @@ func (g *GroupMemberMgo) FindUserManagedGroupID(ctx context.Context, userID stri "$in": []int{constant.GroupOwner, constant.GroupAdmin}, }, } - return mgotool.Find[string](ctx, g.coll, filter, options.Find().SetProjection(bson.M{"_id": 0, "group_id": 1})) + return mgoutil.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 { diff --git a/pkg/common/db/newmgo/group_request.go b/pkg/common/db/mgo/group_request.go similarity index 64% rename from pkg/common/db/newmgo/group_request.go rename to pkg/common/db/mgo/group_request.go index ea367b653..e88a39bf5 100644 --- a/pkg/common/db/newmgo/group_request.go +++ b/pkg/common/db/mgo/group_request.go @@ -1,16 +1,30 @@ -package newmgo +package mgo 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" + + "github.com/OpenIMSDK/tools/mgoutil" + "github.com/OpenIMSDK/tools/pagination" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" + + "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" ) func NewGroupRequestMgo(db *mongo.Database) (relation.GroupRequestModelInterface, error) { - return &GroupRequestMgo{coll: db.Collection("group_request")}, nil + coll := db.Collection("group_request") + _, err := coll.Indexes().CreateOne(context.Background(), mongo.IndexModel{ + Keys: bson.D{ + {Key: "group_id", Value: 1}, + {Key: "user_id", Value: 1}, + }, + Options: options.Index().SetUnique(true), + }) + if err != nil { + return nil, err + } + return &GroupRequestMgo{coll: coll}, nil } type GroupRequestMgo struct { @@ -18,29 +32,29 @@ type GroupRequestMgo struct { } func (g *GroupRequestMgo) Create(ctx context.Context, groupRequests []*relation.GroupRequestModel) (err error) { - return mgotool.InsertMany(ctx, g.coll, groupRequests) + return mgoutil.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}) + return mgoutil.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) + return mgoutil.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}) + return mgoutil.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}}) + return mgoutil.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) + return mgoutil.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) + return mgoutil.FindPage[*relation.GroupRequestModel](ctx, g.coll, bson.M{"group_id": bson.M{"$in": groupIDs}}, pagination) } diff --git a/pkg/common/db/mgo/log.go b/pkg/common/db/mgo/log.go new file mode 100644 index 000000000..aa280fcf2 --- /dev/null +++ b/pkg/common/db/mgo/log.go @@ -0,0 +1,70 @@ +package mgo + +import ( + "context" + "time" + + "github.com/OpenIMSDK/tools/mgoutil" + "github.com/OpenIMSDK/tools/pagination" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" + + "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" +) + +func NewLogMongo(db *mongo.Database) (relation.LogInterface, error) { + coll := db.Collection("log") + _, err := coll.Indexes().CreateMany(context.Background(), []mongo.IndexModel{ + { + Keys: bson.D{ + {Key: "log_id", Value: 1}, + }, + Options: options.Index().SetUnique(true), + }, + { + Keys: bson.D{ + {Key: "user_id", Value: 1}, + }, + }, + { + Keys: bson.D{ + {Key: "create_time", Value: -1}, + }, + }, + }) + if err != nil { + return nil, err + } + return &LogMgo{coll: coll}, nil +} + +type LogMgo struct { + coll *mongo.Collection +} + +func (l *LogMgo) Create(ctx context.Context, log []*relation.LogModel) error { + return mgoutil.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.LogModel, error) { + filter := bson.M{"create_time": bson.M{"$gte": start, "$lte": end}} + if keyword != "" { + filter["user_id"] = bson.M{"$regex": keyword} + } + return mgoutil.FindPage[*relation.LogModel](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 mgoutil.DeleteMany(ctx, l.coll, bson.M{"log_id": bson.M{"$in": logID}}) + } + return mgoutil.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.LogModel, error) { + if userID == "" { + return mgoutil.Find[*relation.LogModel](ctx, l.coll, bson.M{"log_id": bson.M{"$in": logIDs}}) + } + return mgoutil.Find[*relation.LogModel](ctx, l.coll, bson.M{"log_id": bson.M{"$in": logIDs}, "user_id": userID}) +} diff --git a/pkg/common/db/newmgo/object.go b/pkg/common/db/mgo/object.go similarity index 64% rename from pkg/common/db/newmgo/object.go rename to pkg/common/db/mgo/object.go index 32e3daa4f..5976b2d28 100644 --- a/pkg/common/db/newmgo/object.go +++ b/pkg/common/db/mgo/object.go @@ -1,18 +1,28 @@ -package newmgo +package mgo 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/tools/mgoutil" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" + + "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" ) func NewS3Mongo(db *mongo.Database) (relation.ObjectInfoModelInterface, error) { - return &S3Mongo{ - coll: db.Collection("s3"), - }, nil + coll := db.Collection("s3") + _, err := coll.Indexes().CreateOne(context.Background(), mongo.IndexModel{ + Keys: bson.D{ + {Key: "name", Value: 1}, + }, + Options: options.Index().SetUnique(true), + }) + if err != nil { + return nil, err + } + return &S3Mongo{coll: coll}, nil } type S3Mongo struct { @@ -30,16 +40,16 @@ func (o *S3Mongo) SetObject(ctx context.Context, obj *relation.ObjectModel) erro "group": obj.Group, "create_time": obj.CreateTime, } - return mgotool.UpdateOne(ctx, o.coll, filter, bson.M{"$set": update}, false, options.Update().SetUpsert(true)) + return mgoutil.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 mgoutil.FindOne[*relation.ObjectModel](ctx, o.coll, bson.M{"name": name}) } - return mgotool.FindOne[*relation.ObjectModel](ctx, o.coll, bson.M{"name": name, "engine": engine}) + return mgoutil.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}) + return mgoutil.DeleteOne(ctx, o.coll, bson.M{"name": name, "engine": engine}) } diff --git a/pkg/common/db/newmgo/user.go b/pkg/common/db/mgo/user.go similarity index 50% rename from pkg/common/db/newmgo/user.go rename to pkg/common/db/mgo/user.go index 6a9975dff..4a53cb3c4 100644 --- a/pkg/common/db/newmgo/user.go +++ b/pkg/common/db/mgo/user.go @@ -1,20 +1,30 @@ -package newmgo +package mgo 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" + "time" + + "github.com/OpenIMSDK/tools/mgoutil" + "github.com/OpenIMSDK/tools/pagination" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" - "time" + + "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" ) func NewUserMongo(db *mongo.Database) (relation.UserModelInterface, error) { - return &UserMgo{ - coll: db.Collection("user"), - }, nil + coll := db.Collection("user") + _, err := coll.Indexes().CreateOne(context.Background(), mongo.IndexModel{ + Keys: bson.D{ + {Key: "user_id", Value: 1}, + }, + Options: options.Index().SetUnique(true), + }) + if err != nil { + return nil, err + } + return &UserMgo{coll: coll}, nil } type UserMgo struct { @@ -22,50 +32,82 @@ type UserMgo struct { } func (u *UserMgo) Create(ctx context.Context, users []*relation.UserModel) error { - return mgotool.InsertMany(ctx, u.coll, users) + return mgoutil.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) + return mgoutil.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}}) + return mgoutil.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}) + return mgoutil.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) + return mgoutil.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})) + return mgoutil.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}) + return mgoutil.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})) + return mgoutil.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}}) + if before == nil { + return mgoutil.Count(ctx, u.coll, bson.M{}) + } + return mgoutil.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 + pipeline := bson.A{ + bson.M{ + "$match": bson.M{ + "create_time": bson.M{ + "$gte": start, + "$lt": end, + }, + }, + }, + bson.M{ + "$group": bson.M{ + "_id": bson.M{ + "$dateToString": bson.M{ + "format": "%Y-%m-%d", + "date": "$create_time", + }, + }, + "count": bson.M{ + "$sum": 1, + }, + }, + }, + } + type Item struct { + Date string `bson:"_id"` + Count int64 `bson:"count"` + } + items, err := mgoutil.Aggregate[Item](ctx, u.coll, pipeline) + if err != nil { + return nil, err + } + res := make(map[string]int64, len(items)) + for _, item := range items { + res[item.Date] = item.Count + } + return res, nil } diff --git a/pkg/common/db/newmgo/friend_request.go b/pkg/common/db/newmgo/friend_request.go deleted file mode 100644 index 99f4dff56..000000000 --- a/pkg/common/db/newmgo/friend_request.go +++ /dev/null @@ -1,48 +0,0 @@ -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/log.go b/pkg/common/db/newmgo/log.go deleted file mode 100644 index f42588745..000000000 --- a/pkg/common/db/newmgo/log.go +++ /dev/null @@ -1,49 +0,0 @@ -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 deleted file mode 100644 index c2c05949c..000000000 --- a/pkg/common/db/newmgo/mgotool/tool.go +++ /dev/null @@ -1,198 +0,0 @@ -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/relation/black_model.go b/pkg/common/db/relation/black_model.go deleted file mode 100644 index 458012d15..000000000 --- a/pkg/common/db/relation/black_model.go +++ /dev/null @@ -1,111 +0,0 @@ -// 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" - - "github.com/OpenIMSDK/tools/errs" - - "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 BlackGorm struct { - *MetaDB -} - -func NewBlackGorm(db *gorm.DB) relation.BlackModelInterface { - return &BlackGorm{NewMetaDB(db, &relation.BlackModel{})} -} - -func (b *BlackGorm) Create(ctx context.Context, blacks []*relation.BlackModel) (err error) { - return utils.Wrap(b.db(ctx).Create(&blacks).Error, "") -} - -func (b *BlackGorm) Delete(ctx context.Context, blacks []*relation.BlackModel) (err error) { - return utils.Wrap(b.db(ctx).Delete(blacks).Error, "") -} - -func (b *BlackGorm) UpdateByMap( - ctx context.Context, - ownerUserID, blockUserID string, - 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, - "", - ) -} - -func (b *BlackGorm) Update(ctx context.Context, blacks []*relation.BlackModel) (err error) { - return utils.Wrap(b.db(ctx).Updates(&blacks).Error, "") -} - -func (b *BlackGorm) Find( - ctx context.Context, - blacks []*relation.BlackModel, -) (blackList []*relation.BlackModel, err error) { - var where [][]any - for _, black := range blacks { - 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, - "", - ) -} - -func (b *BlackGorm) Take(ctx context.Context, ownerUserID, blockUserID string) (black *relation.BlackModel, err error) { - black = &relation.BlackModel{} - return black, utils.Wrap( - b.db(ctx).Where("owner_user_id = ? and block_user_id = ?", ownerUserID, blockUserID).Take(black).Error, - "", - ) -} - -func (b *BlackGorm) FindOwnerBlacks( - ctx context.Context, - ownerUserID string, - pageNumber, showNumber int32, -) (blacks []*relation.BlackModel, total int64, err error) { - err = b.db(ctx).Count(&total).Error - if err != nil { - return nil, 0, utils.Wrap(err, "") - } - totalUint32, blacks, err := ormutil.GormPage[relation.BlackModel]( - b.db(ctx).Where("owner_user_id = ?", ownerUserID), - pageNumber, - showNumber, - ) - total = int64(totalUint32) - return -} - -func (b *BlackGorm) FindBlackUserIDs(ctx context.Context, ownerUserID string) (blackUserIDs []string, err error) { - return blackUserIDs, utils.Wrap( - b.db(ctx).Where("owner_user_id = ?", ownerUserID).Pluck("block_user_id", &blackUserIDs).Error, - "", - ) -} - -func (b *BlackGorm) FindOwnerBlackInfos(ctx context.Context, ownerUserID string, userIDs []string) (blacks []*relation.BlackModel, err error) { - return blacks, errs.Wrap(b.db(ctx).Where("owner_user_id = ? and block_user_id in ?", ownerUserID, userIDs).Find(&blacks).Error) -} diff --git a/pkg/common/db/relation/chat_log_model.go b/pkg/common/db/relation/chat_log_model.go deleted file mode 100644 index f183a543f..000000000 --- a/pkg/common/db/relation/chat_log_model.go +++ /dev/null @@ -1,63 +0,0 @@ -// 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/golang/protobuf/jsonpb" - "github.com/jinzhu/copier" - "google.golang.org/protobuf/proto" - "gorm.io/gorm" - - "github.com/OpenIMSDK/protocol/constant" - pbmsg "github.com/OpenIMSDK/protocol/msg" - sdkws "github.com/OpenIMSDK/protocol/sdkws" - "github.com/OpenIMSDK/tools/utils" - - "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" -) - -type ChatLogGorm struct { - *MetaDB -} - -func NewChatLogGorm(db *gorm.DB) relation.ChatLogModelInterface { - return &ChatLogGorm{NewMetaDB(db, &relation.ChatLogModel{})} -} - -func (c *ChatLogGorm) Create(msg *pbmsg.MsgDataToMQ) error { - chatLog := new(relation.ChatLogModel) - copier.Copy(chatLog, msg.MsgData) - switch msg.MsgData.SessionType { - case constant.GroupChatType, constant.SuperGroupChatType: - chatLog.RecvID = msg.MsgData.GroupID - case constant.SingleChatType: - chatLog.RecvID = msg.MsgData.RecvID - } - if msg.MsgData.ContentType >= constant.NotificationBegin && msg.MsgData.ContentType <= constant.NotificationEnd { - var tips sdkws.TipsComm - _ = proto.Unmarshal(msg.MsgData.Content, &tips) - marshaler := jsonpb.Marshaler{ - OrigName: true, - EnumsAsInts: false, - EmitDefaults: false, - } - chatLog.Content, _ = marshaler.MarshalToString(&tips) - } else { - chatLog.Content = string(msg.MsgData.Content) - } - chatLog.CreateTime = utils.UnixMillSecondToTime(msg.MsgData.CreateTime) - chatLog.SendTime = utils.UnixMillSecondToTime(msg.MsgData.SendTime) - return c.DB.Create(chatLog).Error -} diff --git a/pkg/common/db/relation/conversation_model.go b/pkg/common/db/relation/conversation_model.go deleted file mode 100644 index 73cf1a80e..000000000 --- a/pkg/common/db/relation/conversation_model.go +++ /dev/null @@ -1,244 +0,0 @@ -// 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" -// -// "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/doc.go b/pkg/common/db/relation/doc.go deleted file mode 100644 index 41135ac97..000000000 --- a/pkg/common/db/relation/doc.go +++ /dev/null @@ -1,15 +0,0 @@ -// 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/relation" diff --git a/pkg/common/db/relation/friend_model.go b/pkg/common/db/relation/friend_model.go deleted file mode 100644 index 50f4451b5..000000000 --- a/pkg/common/db/relation/friend_model.go +++ /dev/null @@ -1,193 +0,0 @@ -// 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" - - "gorm.io/gorm" - - "github.com/OpenIMSDK/tools/utils" - - "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" -) - -type FriendGorm struct { - *MetaDB -} - -func NewFriendGorm(db *gorm.DB) relation.FriendModelInterface { - return &FriendGorm{NewMetaDB(db, &relation.FriendModel{})} -} - -func (f *FriendGorm) NewTx(tx any) relation.FriendModelInterface { - return &FriendGorm{NewMetaDB(tx.(*gorm.DB), &relation.FriendModel{})} -} - -// 插入多条记录. -func (f *FriendGorm) Create(ctx context.Context, friends []*relation.FriendModel) (err error) { - return utils.Wrap(f.db(ctx).Create(&friends).Error, "") -} - -// 删除ownerUserID指定的好友. -func (f *FriendGorm) Delete(ctx context.Context, ownerUserID string, friendUserIDs []string) (err error) { - err = utils.Wrap( - f.db(ctx). - Where("owner_user_id = ? AND friend_user_id in ( ?)", ownerUserID, friendUserIDs). - Delete(&relation.FriendModel{}). - Error, - "", - ) - return err -} - -// 更新ownerUserID单个好友信息 更新零值. -func (f *FriendGorm) UpdateByMap( - ctx context.Context, - ownerUserID string, - friendUserID string, - 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, - "", - ) -} - -// 更新好友信息的非零值. -func (f *FriendGorm) Update(ctx context.Context, friends []*relation.FriendModel) (err error) { - return utils.Wrap(f.db(ctx).Updates(&friends).Error, "") -} - -// 更新好友备注(也支持零值 ). -func (f *FriendGorm) UpdateRemark(ctx context.Context, ownerUserID, friendUserID, remark string) (err error) { - if remark != "" { - return utils.Wrap( - f.db(ctx). - Where("owner_user_id = ? and friend_user_id = ?", ownerUserID, friendUserID). - Update("remark", remark). - Error, - "", - ) - } - m := make(map[string]any, 1) - m["remark"] = "" - return utils.Wrap(f.db(ctx).Where("owner_user_id = ?", ownerUserID).Updates(m).Error, "") -} - -// 获取单个好友信息,如没找到 返回错误. -func (f *FriendGorm) Take( - ctx context.Context, - ownerUserID, friendUserID string, -) (friend *relation.FriendModel, err error) { - friend = &relation.FriendModel{} - return friend, utils.Wrap( - f.db(ctx).Where("owner_user_id = ? and friend_user_id", ownerUserID, friendUserID).Take(friend).Error, - "", - ) -} - -// 查找好友关系,如果是双向关系,则都返回. -func (f *FriendGorm) FindUserState( - ctx context.Context, - userID1, userID2 string, -) (friends []*relation.FriendModel, err error) { - return friends, utils.Wrap( - f.db(ctx). - Where("(owner_user_id = ? and friend_user_id = ?) or (owner_user_id = ? and friend_user_id = ?)", userID1, userID2, userID2, userID1). - Find(&friends). - Error, - "", - ) -} - -// 获取 owner指定的好友列表 如果有friendUserIDs不存在,也不返回错误. -func (f *FriendGorm) FindFriends( - ctx context.Context, - ownerUserID string, - friendUserIDs []string, -) (friends []*relation.FriendModel, err error) { - return friends, utils.Wrap( - f.db(ctx).Where("owner_user_id = ? AND friend_user_id in (?)", ownerUserID, friendUserIDs).Find(&friends).Error, - "", - ) -} - -// 获取哪些人添加了friendUserID 如果有ownerUserIDs不存在,也不返回错误. -func (f *FriendGorm) FindReversalFriends( - ctx context.Context, - friendUserID string, - ownerUserIDs []string, -) (friends []*relation.FriendModel, err error) { - return friends, utils.Wrap( - f.db(ctx).Where("friend_user_id = ? AND owner_user_id in (?)", friendUserID, ownerUserIDs).Find(&friends).Error, - "", - ) -} - -// 获取ownerUserID好友列表 支持翻页. -func (f *FriendGorm) FindOwnerFriends( - ctx context.Context, - ownerUserID string, - pageNumber, showNumber int32, -) (friends []*relation.FriendModel, total int64, err error) { - err = f.DB.Model(&relation.FriendModel{}).Where("owner_user_id = ? ", ownerUserID).Count(&total).Error - if err != nil { - return nil, 0, utils.Wrap(err, "") - } - err = utils.Wrap( - f.db(ctx). - Where("owner_user_id = ? ", ownerUserID). - Limit(int(showNumber)). - Offset(int((pageNumber-1)*showNumber)). - Find(&friends). - Error, - "", - ) - return -} - -// 获取哪些人添加了friendUserID 支持翻页. -func (f *FriendGorm) FindInWhoseFriends( - ctx context.Context, - friendUserID string, - pageNumber, showNumber int32, -) (friends []*relation.FriendModel, total int64, err error) { - err = f.DB.Model(&relation.FriendModel{}).Where("friend_user_id = ? ", friendUserID).Count(&total).Error - if err != nil { - return nil, 0, utils.Wrap(err, "") - } - err = utils.Wrap( - f.db(ctx). - Where("friend_user_id = ? ", friendUserID). - Limit(int(showNumber)). - Offset(int((pageNumber-1)*showNumber)). - Find(&friends). - Error, - "", - ) - return -} - -func (f *FriendGorm) FindFriendUserIDs(ctx context.Context, ownerUserID string) (friendUserIDs []string, err error) { - return friendUserIDs, utils.Wrap( - f.db(ctx). - Model(&relation.FriendModel{}). - Where("owner_user_id = ? ", ownerUserID). - Pluck("friend_user_id", &friendUserIDs). - Error, - "", - ) -} diff --git a/pkg/common/db/relation/friend_request_model.go b/pkg/common/db/relation/friend_request_model.go deleted file mode 100644 index e215f8850..000000000 --- a/pkg/common/db/relation/friend_request_model.go +++ /dev/null @@ -1,154 +0,0 @@ -// 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 - -// 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 deleted file mode 100644 index 93885760c..000000000 --- a/pkg/common/db/relation/group_member_model.go +++ /dev/null @@ -1,198 +0,0 @@ -// 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" -// -// "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 deleted file mode 100644 index 1b07a4072..000000000 --- a/pkg/common/db/relation/group_model.go +++ /dev/null @@ -1,106 +0,0 @@ -// 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" -// -// "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 deleted file mode 100644 index aa601aaba..000000000 --- a/pkg/common/db/relation/group_request_model.go +++ /dev/null @@ -1,119 +0,0 @@ -// 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" -// -// "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 deleted file mode 100644 index f5d8a9fae..000000000 --- a/pkg/common/db/relation/log_model.go +++ /dev/null @@ -1,49 +0,0 @@ -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} -//} diff --git a/pkg/common/db/relation/meta_db.go b/pkg/common/db/relation/meta_db.go deleted file mode 100644 index 6ab980120..000000000 --- a/pkg/common/db/relation/meta_db.go +++ /dev/null @@ -1,38 +0,0 @@ -// 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" - - "gorm.io/gorm" -) - -type MetaDB struct { - DB *gorm.DB - table any -} - -func NewMetaDB(db *gorm.DB, table any) *MetaDB { - return &MetaDB{ - DB: db, - table: table, - } -} - -func (g *MetaDB) db(ctx context.Context) *gorm.DB { - db := g.DB.WithContext(ctx).Model(g.table) - return db -} diff --git a/pkg/common/db/relation/mysql_init.go b/pkg/common/db/relation/mysql_init.go deleted file mode 100644 index 41399d5ca..000000000 --- a/pkg/common/db/relation/mysql_init.go +++ /dev/null @@ -1,157 +0,0 @@ -// 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 ( - "fmt" - "time" - - "github.com/OpenIMSDK/tools/errs" - "github.com/OpenIMSDK/tools/log" - "github.com/OpenIMSDK/tools/mw/specialerror" - mysqldriver "github.com/go-sql-driver/mysql" - "gorm.io/driver/mysql" - "gorm.io/gorm" - "gorm.io/gorm/logger" - - "github.com/openimsdk/open-im-server/v3/pkg/common/config" -) - -const ( - maxRetry = 100 // number of retries -) - -type option struct { - Username string - Password string - Address []string - Database string - LogLevel int - SlowThreshold int - MaxLifeTime int - MaxOpenConn int - MaxIdleConn int - Connect func(dsn string, maxRetry int) (*gorm.DB, error) -} - -// newMysqlGormDB Initialize the database connection. -func newMysqlGormDB(o *option) (*gorm.DB, error) { - err := maybeCreateTable(o) - if err != nil { - return nil, err - } - dsn := fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8mb4&parseTime=true&loc=Local", - o.Username, o.Password, o.Address[0], o.Database) - sqlLogger := log.NewSqlLogger( - logger.LogLevel(o.LogLevel), - true, - time.Duration(o.SlowThreshold)*time.Millisecond, - ) - db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{ - Logger: sqlLogger, - }) - if err != nil { - return nil, err - } - sqlDB, err := db.DB() - if err != nil { - return nil, err - } - sqlDB.SetConnMaxLifetime(time.Second * time.Duration(o.MaxLifeTime)) - sqlDB.SetMaxOpenConns(o.MaxOpenConn) - sqlDB.SetMaxIdleConns(o.MaxIdleConn) - return db, nil -} - -// maybeCreateTable creates a database if it does not exists. -func maybeCreateTable(o *option) error { - dsn := fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8mb4&parseTime=true&loc=Local", - o.Username, o.Password, o.Address[0], "mysql") - - var db *gorm.DB - var err error - if f := o.Connect; f != nil { - db, err = f(dsn, maxRetry) - } else { - db, err = connectToDatabase(dsn, maxRetry) - } - if err != nil { - panic(err.Error() + " Open failed " + dsn) - } - - sqlDB, err := db.DB() - if err != nil { - return err - } - defer sqlDB.Close() - sql := fmt.Sprintf( - "CREATE DATABASE IF NOT EXISTS `%s` default charset utf8mb4 COLLATE utf8mb4_unicode_ci", - o.Database, - ) - err = db.Exec(sql).Error - if err != nil { - return fmt.Errorf("init db %w", err) - } - return nil -} - -// connectToDatabase Connection retry for mysql. -func connectToDatabase(dsn string, maxRetry int) (*gorm.DB, error) { - var db *gorm.DB - var err error - for i := 0; i <= maxRetry; i++ { - db, err = gorm.Open(mysql.Open(dsn), nil) - if err == nil { - return db, nil - } - if mysqlErr, ok := err.(*mysqldriver.MySQLError); ok && mysqlErr.Number == 1045 { - return nil, err - } - time.Sleep(time.Duration(1) * time.Second) - } - return nil, err -} - -// NewGormDB gorm mysql. -func NewGormDB() (*gorm.DB, error) { - specialerror.AddReplace(gorm.ErrRecordNotFound, errs.ErrRecordNotFound) - specialerror.AddErrHandler(replaceDuplicateKey) - - return newMysqlGormDB(&option{ - Username: config.Config.Mysql.Username, - Password: config.Config.Mysql.Password, - Address: config.Config.Mysql.Address, - Database: config.Config.Mysql.Database, - LogLevel: config.Config.Mysql.LogLevel, - SlowThreshold: config.Config.Mysql.SlowThreshold, - MaxLifeTime: config.Config.Mysql.MaxLifeTime, - MaxOpenConn: config.Config.Mysql.MaxOpenConn, - MaxIdleConn: config.Config.Mysql.MaxIdleConn, - }) -} - -func replaceDuplicateKey(err error) errs.CodeError { - if IsMysqlDuplicateKey(err) { - return errs.ErrDuplicateKey - } - return nil -} - -func IsMysqlDuplicateKey(err error) bool { - if mysqlErr, ok := err.(*mysqldriver.MySQLError); ok { - return mysqlErr.Number == 1062 - } - return false -} diff --git a/pkg/common/db/relation/mysql_init_test.go b/pkg/common/db/relation/mysql_init_test.go deleted file mode 100644 index c321dfd9f..000000000 --- a/pkg/common/db/relation/mysql_init_test.go +++ /dev/null @@ -1,121 +0,0 @@ -package relation - -import ( - "context" - "database/sql" - "database/sql/driver" - "errors" - "fmt" - "reflect" - "testing" - - "gorm.io/driver/mysql" - "gorm.io/gorm" - "gorm.io/gorm/logger" -) - -func TestMaybeCreateTable(t *testing.T) { - t.Run("normal", func(t *testing.T) { - err := maybeCreateTable(&option{ - Username: "root", - Password: "openIM123", - Address: []string{"172.28.0.1:13306"}, - Database: "openIM_v3", - LogLevel: 4, - SlowThreshold: 500, - MaxOpenConn: 1000, - MaxIdleConn: 100, - MaxLifeTime: 60, - Connect: connect(expectExec{ - query: "CREATE DATABASE IF NOT EXISTS `openIM_v3` default charset utf8mb4 COLLATE utf8mb4_unicode_ci", - args: nil, - }), - }) - if err != nil { - t.Fatal(err) - } - }) - - t.Run("im-db", func(t *testing.T) { - err := maybeCreateTable(&option{ - Username: "root", - Password: "openIM123", - Address: []string{"172.28.0.1:13306"}, - Database: "im-db", - LogLevel: 4, - SlowThreshold: 500, - MaxOpenConn: 1000, - MaxIdleConn: 100, - MaxLifeTime: 60, - Connect: connect(expectExec{ - query: "CREATE DATABASE IF NOT EXISTS `im-db` default charset utf8mb4 COLLATE utf8mb4_unicode_ci", - args: nil, - }), - }) - if err != nil { - t.Fatal(err) - } - }) - - t.Run("err", func(t *testing.T) { - e := errors.New("e") - err := maybeCreateTable(&option{ - Username: "root", - Password: "openIM123", - Address: []string{"172.28.0.1:13306"}, - Database: "openIM_v3", - LogLevel: 4, - SlowThreshold: 500, - MaxOpenConn: 1000, - MaxIdleConn: 100, - MaxLifeTime: 60, - Connect: connect(expectExec{ - err: e, - }), - }) - if !errors.Is(err, e) { - t.Fatalf("err not is e: %v", err) - } - }) -} - -func connect(e expectExec) func(string, int) (*gorm.DB, error) { - return func(string, int) (*gorm.DB, error) { - return gorm.Open(mysql.New(mysql.Config{ - SkipInitializeWithVersion: true, - Conn: sql.OpenDB(e), - }), &gorm.Config{ - Logger: logger.Discard, - }) - } -} - -type expectExec struct { - err error - query string - args []driver.NamedValue -} - -func (c expectExec) ExecContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Result, error) { - if c.err != nil { - return nil, c.err - } - if query != c.query { - return nil, fmt.Errorf("query mismatch. expect: %s, got: %s", c.query, query) - } - if reflect.DeepEqual(args, c.args) { - return nil, fmt.Errorf("args mismatch. expect: %v, got: %v", c.args, args) - } - return noEffectResult{}, nil -} - -func (e expectExec) Connect(context.Context) (driver.Conn, error) { return e, nil } -func (expectExec) Driver() driver.Driver { panic("not implemented") } -func (expectExec) Prepare(query string) (driver.Stmt, error) { panic("not implemented") } -func (expectExec) Close() (e error) { return } -func (expectExec) Begin() (driver.Tx, error) { panic("not implemented") } - -type noEffectResult struct{} - -func (noEffectResult) LastInsertId() (i int64, e error) { return } -func (noEffectResult) RowsAffected() (i int64, e error) { return } diff --git a/pkg/common/db/relation/object_model.go b/pkg/common/db/relation/object_model.go deleted file mode 100644 index 67b59969b..000000000 --- a/pkg/common/db/relation/object_model.go +++ /dev/null @@ -1,54 +0,0 @@ -// 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" -// -// "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 deleted file mode 100644 index 100bfcf13..000000000 --- a/pkg/common/db/relation/user_model.go +++ /dev/null @@ -1,138 +0,0 @@ -// 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" -// -// "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/kodo/internal.go b/pkg/common/db/s3/kodo/internal.go deleted file mode 100644 index 3a4943e62..000000000 --- a/pkg/common/db/s3/kodo/internal.go +++ /dev/null @@ -1 +0,0 @@ -package kodo diff --git a/pkg/common/db/s3/kodo/kodo.go b/pkg/common/db/s3/kodo/kodo.go deleted file mode 100644 index d73220b3b..000000000 --- a/pkg/common/db/s3/kodo/kodo.go +++ /dev/null @@ -1,323 +0,0 @@ -package kodo - -import ( - "context" - "errors" - "fmt" - "net/http" - "net/url" - "strconv" - "strings" - "time" - - "github.com/aws/aws-sdk-go-v2/aws" - awss3config "github.com/aws/aws-sdk-go-v2/config" - "github.com/aws/aws-sdk-go-v2/credentials" - awss3 "github.com/aws/aws-sdk-go-v2/service/s3" - awss3types "github.com/aws/aws-sdk-go-v2/service/s3/types" - "github.com/openimsdk/open-im-server/v3/pkg/common/config" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/s3" - "github.com/qiniu/go-sdk/v7/auth" - "github.com/qiniu/go-sdk/v7/storage" -) - -const ( - minPartSize = 1024 * 1024 * 1 // 1MB - maxPartSize = 1024 * 1024 * 1024 * 5 // 5GB - maxNumSize = 10000 -) - -type Kodo struct { - AccessKey string - SecretKey string - Region string - Token string - Endpoint string - BucketURL string - Auth *auth.Credentials - Client *awss3.Client - PresignClient *awss3.PresignClient -} - -func NewKodo() (s3.Interface, error) { - conf := config.Config.Object.Kodo - //init client - cfg, err := awss3config.LoadDefaultConfig(context.TODO(), - awss3config.WithRegion(conf.Bucket), - awss3config.WithEndpointResolverWithOptions( - aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) { - return aws.Endpoint{URL: conf.Endpoint}, nil - })), - awss3config.WithCredentialsProvider(credentials.NewStaticCredentialsProvider( - conf.AccessKeyID, - conf.AccessKeySecret, - conf.SessionToken), - ), - ) - if err != nil { - panic(err) - } - client := awss3.NewFromConfig(cfg) - presignClient := awss3.NewPresignClient(client) - - return &Kodo{ - AccessKey: conf.AccessKeyID, - SecretKey: conf.AccessKeySecret, - Region: conf.Bucket, - BucketURL: conf.BucketURL, - Auth: auth.New(conf.AccessKeyID, conf.AccessKeySecret), - Client: client, - PresignClient: presignClient, - }, nil -} - -func (k Kodo) Engine() string { - return "kodo" -} - -func (k Kodo) PartLimit() *s3.PartLimit { - return &s3.PartLimit{ - MinPartSize: minPartSize, - MaxPartSize: maxPartSize, - MaxNumSize: maxNumSize, - } -} - -func (k Kodo) InitiateMultipartUpload(ctx context.Context, name string) (*s3.InitiateMultipartUploadResult, error) { - result, err := k.Client.CreateMultipartUpload(ctx, &awss3.CreateMultipartUploadInput{ - Bucket: aws.String(k.Region), - Key: aws.String(name), - }) - if err != nil { - return nil, err - } - return &s3.InitiateMultipartUploadResult{ - UploadID: aws.ToString(result.UploadId), - Bucket: aws.ToString(result.Bucket), - Key: aws.ToString(result.Key), - }, nil -} - -func (k Kodo) CompleteMultipartUpload(ctx context.Context, uploadID string, name string, parts []s3.Part) (*s3.CompleteMultipartUploadResult, error) { - kodoParts := make([]awss3types.CompletedPart, len(parts)) - for i, part := range parts { - kodoParts[i] = awss3types.CompletedPart{ - PartNumber: aws.Int32(int32(part.PartNumber)), - ETag: aws.String(part.ETag), - } - } - result, err := k.Client.CompleteMultipartUpload(ctx, &awss3.CompleteMultipartUploadInput{ - Bucket: aws.String(k.Region), - Key: aws.String(name), - UploadId: aws.String(uploadID), - MultipartUpload: &awss3types.CompletedMultipartUpload{Parts: kodoParts}, - }) - if err != nil { - return nil, err - } - return &s3.CompleteMultipartUploadResult{ - Location: aws.ToString(result.Location), - Bucket: aws.ToString(result.Bucket), - Key: aws.ToString(result.Key), - ETag: strings.ToLower(strings.ReplaceAll(aws.ToString(result.ETag), `"`, ``)), - }, nil -} - -func (k Kodo) PartSize(ctx context.Context, size int64) (int64, error) { - if size <= 0 { - return 0, errors.New("size must be greater than 0") - } - if size > maxPartSize*maxNumSize { - return 0, fmt.Errorf("size must be less than %db", maxPartSize*maxNumSize) - } - if size <= minPartSize*maxNumSize { - return minPartSize, nil - } - partSize := size / maxNumSize - if size%maxNumSize != 0 { - partSize++ - } - return partSize, nil -} - -func (k Kodo) AuthSign(ctx context.Context, uploadID string, name string, expire time.Duration, partNumbers []int) (*s3.AuthSignResult, error) { - result := s3.AuthSignResult{ - URL: k.BucketURL + "/" + name, - Query: url.Values{"uploadId": {uploadID}}, - Header: make(http.Header), - Parts: make([]s3.SignPart, len(partNumbers)), - } - for i, partNumber := range partNumbers { - part, _ := k.PresignClient.PresignUploadPart(ctx, &awss3.UploadPartInput{ - Bucket: aws.String(k.Region), - UploadId: aws.String(uploadID), - Key: aws.String(name), - PartNumber: aws.Int32(int32(partNumber)), - }) - result.Parts[i] = s3.SignPart{ - PartNumber: partNumber, - URL: part.URL, - Header: part.SignedHeader, - } - } - return &result, nil - -} - -func (k Kodo) PresignedPutObject(ctx context.Context, name string, expire time.Duration) (string, error) { - object, err := k.PresignClient.PresignPutObject(ctx, &awss3.PutObjectInput{ - Bucket: aws.String(k.Region), - Key: aws.String(name), - }, func(po *awss3.PresignOptions) { - po.Expires = expire - }) - return object.URL, err - -} - -func (k Kodo) DeleteObject(ctx context.Context, name string) error { - _, err := k.Client.DeleteObject(ctx, &awss3.DeleteObjectInput{ - Bucket: aws.String(k.Region), - Key: aws.String(name), - }) - return err -} - -func (k Kodo) CopyObject(ctx context.Context, src string, dst string) (*s3.CopyObjectInfo, error) { - result, err := k.Client.CopyObject(ctx, &awss3.CopyObjectInput{ - Bucket: aws.String(k.Region), - CopySource: aws.String(k.Region + "/" + src), - Key: aws.String(dst), - }) - if err != nil { - return nil, err - } - return &s3.CopyObjectInfo{ - Key: dst, - ETag: strings.ToLower(strings.ReplaceAll(aws.ToString(result.CopyObjectResult.ETag), `"`, ``)), - }, nil -} - -func (k Kodo) StatObject(ctx context.Context, name string) (*s3.ObjectInfo, error) { - info, err := k.Client.HeadObject(ctx, &awss3.HeadObjectInput{ - Bucket: aws.String(k.Region), - Key: aws.String(name), - }) - if err != nil { - return nil, err - } - res := &s3.ObjectInfo{Key: name} - res.Size = aws.ToInt64(info.ContentLength) - res.ETag = strings.ToLower(strings.ReplaceAll(aws.ToString(info.ETag), `"`, ``)) - return res, nil -} - -func (k Kodo) IsNotFound(err error) bool { - return true -} - -func (k Kodo) AbortMultipartUpload(ctx context.Context, uploadID string, name string) error { - _, err := k.Client.AbortMultipartUpload(ctx, &awss3.AbortMultipartUploadInput{ - UploadId: aws.String(uploadID), - Bucket: aws.String(k.Region), - Key: aws.String(name), - }) - return err -} - -func (k Kodo) ListUploadedParts(ctx context.Context, uploadID string, name string, partNumberMarker int, maxParts int) (*s3.ListUploadedPartsResult, error) { - result, err := k.Client.ListParts(ctx, &awss3.ListPartsInput{ - Key: aws.String(name), - UploadId: aws.String(uploadID), - Bucket: aws.String(k.Region), - MaxParts: aws.Int32(int32(maxParts)), - PartNumberMarker: aws.String(strconv.Itoa(partNumberMarker)), - }) - if err != nil { - return nil, err - } - res := &s3.ListUploadedPartsResult{ - Key: aws.ToString(result.Key), - UploadID: aws.ToString(result.UploadId), - MaxParts: int(aws.ToInt32(result.MaxParts)), - UploadedParts: make([]s3.UploadedPart, len(result.Parts)), - } - // int to string - NextPartNumberMarker, err := strconv.Atoi(aws.ToString(result.NextPartNumberMarker)) - if err != nil { - return nil, err - } - res.NextPartNumberMarker = NextPartNumberMarker - for i, part := range result.Parts { - res.UploadedParts[i] = s3.UploadedPart{ - PartNumber: int(aws.ToInt32(part.PartNumber)), - LastModified: aws.ToTime(part.LastModified), - ETag: aws.ToString(part.ETag), - Size: aws.ToInt64(part.Size), - } - } - return res, nil -} - -func (k Kodo) AccessURL(ctx context.Context, name string, expire time.Duration, opt *s3.AccessURLOption) (string, error) { - //get object head - info, err := k.Client.HeadObject(ctx, &awss3.HeadObjectInput{ - Bucket: aws.String(k.Region), - Key: aws.String(name), - }) - if err != nil { - return "", errors.New("AccessURL object not found") - } - if opt != nil { - if opt.ContentType != aws.ToString(info.ContentType) { - //修改文件类型 - err := k.SetObjectContentType(ctx, name, opt.ContentType) - if err != nil { - return "", errors.New("AccessURL setContentType error") - } - } - } - imageMogr := "" - //image dispose - if opt != nil { - if opt.Image != nil { - //https://developer.qiniu.com/dora/8255/the-zoom - process := "" - if opt.Image.Width > 0 { - process += strconv.Itoa(opt.Image.Width) + "x" - } - if opt.Image.Height > 0 { - if opt.Image.Width > 0 { - process += strconv.Itoa(opt.Image.Height) - } else { - process += "x" + strconv.Itoa(opt.Image.Height) - } - } - imageMogr = "imageMogr2/thumbnail/" + process - } - } - //expire - deadline := time.Now().Add(time.Second * expire).Unix() - domain := k.BucketURL - query := url.Values{} - if opt != nil && opt.Filename != "" { - query.Add("attname", opt.Filename) - } - privateURL := storage.MakePrivateURLv2WithQuery(k.Auth, domain, name, query, deadline) - if imageMogr != "" { - privateURL += "&" + imageMogr - } - return privateURL, nil -} - -func (k *Kodo) SetObjectContentType(ctx context.Context, name string, contentType string) error { - //set object content-type - _, err := k.Client.CopyObject(ctx, &awss3.CopyObjectInput{ - Bucket: aws.String(k.Region), - CopySource: aws.String(k.Region + "/" + name), - Key: aws.String(name), - ContentType: aws.String(contentType), - MetadataDirective: awss3types.MetadataDirectiveReplace, - }) - return err -} diff --git a/pkg/common/db/s3/oss/oss.go b/pkg/common/db/s3/oss/oss.go old mode 100755 new mode 100644 diff --git a/pkg/common/db/table/relation/black.go b/pkg/common/db/table/relation/black.go index 1697eaec6..50499054c 100644 --- a/pkg/common/db/table/relation/black.go +++ b/pkg/common/db/table/relation/black.go @@ -17,33 +17,27 @@ package relation import ( "context" "time" -) -const ( - BlackModelTableName = "blacks" + "github.com/OpenIMSDK/tools/pagination" ) 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 + OwnerUserID string `bson:"owner_user_id"` + BlockUserID string `bson:"block_user_id"` + CreateTime time.Time `bson:"create_time"` + AddSource int32 `bson:"add_source"` + OperatorUserID string `bson:"operator_user_id"` + Ex string `bson:"ex"` } 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]any) (err error) - Update(ctx context.Context, blacks []*BlackModel) (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) - FindOwnerBlacks(ctx context.Context, ownerUserID string, pageNumber, showNumber int32) (blacks []*BlackModel, total int64, err error) + FindOwnerBlacks(ctx context.Context, ownerUserID string, pagination pagination.Pagination) (total int64, blacks []*BlackModel, 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/pkg/common/db/table/relation/chatlog.go b/pkg/common/db/table/relation/chatlog.go deleted file mode 100644 index 810de3db3..000000000 --- a/pkg/common/db/table/relation/chatlog.go +++ /dev/null @@ -1,51 +0,0 @@ -// 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/pkg/common/db/table/relation/conversation.go b/pkg/common/db/table/relation/conversation.go index ffc82f244..e0a5268ca 100644 --- a/pkg/common/db/table/relation/conversation.go +++ b/pkg/common/db/table/relation/conversation.go @@ -16,35 +16,11 @@ package relation import ( "context" - "github.com/openimsdk/open-im-server/v3/pkg/common/pagination" "time" -) -const ( - conversationModelTableName = "conversations" + "github.com/OpenIMSDK/tools/pagination" ) -//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 `bson:"owner_user_id"` ConversationID string `bson:"conversation_id"` @@ -66,10 +42,6 @@ type ConversationModel struct { LatestMsgDestructTime time.Time `bson:"latest_msg_destruct_time"` } -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) @@ -83,11 +55,9 @@ 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) GetAllConversationIDs(ctx context.Context) ([]string, error) GetAllConversationIDsNumber(ctx context.Context) (int64, 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) diff --git a/pkg/common/db/table/relation/doc.go b/pkg/common/db/table/relation/doc.go deleted file mode 100644 index 32185c8c7..000000000 --- a/pkg/common/db/table/relation/doc.go +++ /dev/null @@ -1,15 +0,0 @@ -// 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/pkg/common/db/table/relation/friend.go b/pkg/common/db/table/relation/friend.go index 481b23525..75dbea850 100644 --- a/pkg/common/db/table/relation/friend.go +++ b/pkg/common/db/table/relation/friend.go @@ -18,36 +18,18 @@ import ( "context" "time" - "go.mongodb.org/mongo-driver/bson/primitive" + "github.com/OpenIMSDK/tools/pagination" ) -const ( - 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 { - 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"` -} - -// CollectionName returns the name of the MongoDB collection. -func (FriendModel) CollectionName() string { - return FriendModelCollectionName + 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"` } // FriendModelInterface defines the operations for managing friends in MongoDB. @@ -58,9 +40,7 @@ type FriendModelInterface interface { Delete(ctx context.Context, ownerUserID string, friendUserIDs []string) (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 modify remarks. 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) @@ -71,11 +51,9 @@ type FriendModelInterface interface { // 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) + FindOwnerFriends(ctx context.Context, ownerUserID string, pagination pagination.Pagination) (total int64, friends []*FriendModel, 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) + FindInWhoseFriends(ctx context.Context, friendUserID string, pagination pagination.Pagination) (total int64, friends []*FriendModel, 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 90d4a7b72..8dceb0778 100644 --- a/pkg/common/db/table/relation/friend_request.go +++ b/pkg/common/db/table/relation/friend_request.go @@ -18,26 +18,19 @@ import ( "context" "time" - "go.mongodb.org/mongo-driver/bson/primitive" + "github.com/OpenIMSDK/tools/pagination" ) -const FriendRequestModelCollectionName = "friend_requests" - type FriendRequestModel struct { - 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) CollectionName() string { - return FriendRequestModelCollectionName + 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"` } type FriendRequestModelInterface interface { @@ -53,11 +46,8 @@ type FriendRequestModelInterface interface { Find(ctx context.Context, fromUserID, toUserID string) (friendRequest *FriendRequestModel, err error) Take(ctx context.Context, fromUserID, toUserID string) (friendRequest *FriendRequestModel, 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) + FindToUserID(ctx context.Context, toUserID string, pagination pagination.Pagination) (total int64, friendRequests []*FriendRequestModel, 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) + FindFromUserID(ctx context.Context, fromUserID string, pagination pagination.Pagination) (total int64, friendRequests []*FriendRequestModel, 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 f9afc06b0..bb1ddd878 100644 --- a/pkg/common/db/table/relation/group.go +++ b/pkg/common/db/table/relation/group.go @@ -16,32 +16,11 @@ package relation import ( "context" - "github.com/openimsdk/open-im-server/v3/pkg/common/pagination" "time" -) -const ( - GroupModelTableName = "groups" + "github.com/OpenIMSDK/tools/pagination" ) -//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 `bson:"group_id"` GroupName string `bson:"group_name"` @@ -60,10 +39,6 @@ type GroupModel struct { NotificationUserID string `bson:"notification_user_id"` } -func (GroupModel) TableName() string { - return GroupModelTableName -} - type GroupModelInterface interface { Create(ctx context.Context, groups []*GroupModel) (err error) UpdateMap(ctx context.Context, groupID string, args map[string]any) (err error) diff --git a/pkg/common/db/table/relation/group_member.go b/pkg/common/db/table/relation/group_member.go index e35f2dd84..88ab87739 100644 --- a/pkg/common/db/table/relation/group_member.go +++ b/pkg/common/db/table/relation/group_member.go @@ -16,28 +16,11 @@ package relation import ( "context" - "github.com/openimsdk/open-im-server/v3/pkg/common/pagination" "time" -) -const ( - GroupMemberModelTableName = "group_members" + "github.com/OpenIMSDK/tools/pagination" ) -//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 `bson:"group_id"` UserID string `bson:"user_id"` @@ -52,10 +35,6 @@ type GroupMemberModel struct { Ex string `bson:"ex"` } -func (GroupMemberModel) TableName() string { - return GroupMemberModelTableName -} - type GroupMemberModelInterface interface { //NewTx(tx any) GroupMemberModelInterface Create(ctx context.Context, groupMembers []*GroupMemberModel) (err error) diff --git a/pkg/common/db/table/relation/group_request.go b/pkg/common/db/table/relation/group_request.go index 83c0cf5bd..39999d799 100644 --- a/pkg/common/db/table/relation/group_request.go +++ b/pkg/common/db/table/relation/group_request.go @@ -16,28 +16,11 @@ package relation import ( "context" - "github.com/openimsdk/open-im-server/v3/pkg/common/pagination" "time" -) -const ( - GroupRequestModelTableName = "group_requests" + "github.com/OpenIMSDK/tools/pagination" ) -//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 `bson:"user_id"` GroupID string `bson:"group_id"` @@ -52,10 +35,6 @@ type GroupRequestModel struct { Ex string `bson:"ex"` } -func (GroupRequestModel) TableName() string { - return GroupRequestModelTableName -} - type GroupRequestModelInterface interface { Create(ctx context.Context, groupRequests []*GroupRequestModel) (err error) Delete(ctx context.Context, groupID string, userID string) (err error) diff --git a/pkg/common/db/table/relation/log.go b/pkg/common/db/table/relation/log.go index 7df735676..f690ff8aa 100644 --- a/pkg/common/db/table/relation/log.go +++ b/pkg/common/db/table/relation/log.go @@ -2,23 +2,12 @@ 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)"` -//} + "github.com/OpenIMSDK/tools/pagination" +) -type Log struct { +type LogModel struct { LogID string `bson:"log_id"` Platform string `bson:"platform"` UserID string `bson:"user_id"` @@ -31,8 +20,8 @@ type Log struct { } type LogInterface interface { - Create(ctx context.Context, log []*Log) error - Search(ctx context.Context, keyword string, start time.Time, end time.Time, pagination pagination.Pagination) (int64, []*Log, error) + Create(ctx context.Context, log []*LogModel) error + Search(ctx context.Context, keyword string, start time.Time, end time.Time, pagination pagination.Pagination) (int64, []*LogModel, error) Delete(ctx context.Context, logID []string, userID string) error - Get(ctx context.Context, logIDs []string, userID string) ([]*Log, error) + Get(ctx context.Context, logIDs []string, userID string) ([]*LogModel, error) } diff --git a/pkg/common/db/table/relation/object.go b/pkg/common/db/table/relation/object.go index 6259f425e..678fddcfd 100644 --- a/pkg/common/db/table/relation/object.go +++ b/pkg/common/db/table/relation/object.go @@ -19,10 +19,6 @@ import ( "time" ) -const ( - ObjectInfoModelTableName = "object" -) - type ObjectModel struct { Name string `bson:"name"` UserID string `bson:"user_id"` @@ -35,22 +31,6 @@ type ObjectModel struct { 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 { SetObject(ctx context.Context, obj *ObjectModel) error Take(ctx context.Context, engine string, name string) (*ObjectModel, error) diff --git a/pkg/common/db/table/relation/user.go b/pkg/common/db/table/relation/user.go index 11d93b63f..1f26d751f 100644 --- a/pkg/common/db/table/relation/user.go +++ b/pkg/common/db/table/relation/user.go @@ -16,8 +16,9 @@ package relation import ( "context" - "github.com/openimsdk/open-im-server/v3/pkg/common/pagination" "time" + + "github.com/OpenIMSDK/tools/pagination" ) type UserModel struct { diff --git a/pkg/common/db/table/relation/utils.go b/pkg/common/db/table/relation/utils.go index c944eae8b..380f2410e 100644 --- a/pkg/common/db/table/relation/utils.go +++ b/pkg/common/db/table/relation/utils.go @@ -15,9 +15,8 @@ package relation import ( - "gorm.io/gorm" - "github.com/OpenIMSDK/tools/utils" + "go.mongodb.org/mongo-driver/mongo" ) type BatchUpdateGroupMember struct { @@ -32,5 +31,5 @@ type GroupSimpleUserID struct { } func IsNotFound(err error) bool { - return utils.Unwrap(err) == gorm.ErrRecordNotFound + return utils.Unwrap(err) == mongo.ErrNoDocuments } diff --git a/pkg/common/db/tx/auto.go b/pkg/common/db/tx/auto.go deleted file mode 100644 index bf6817a24..000000000 --- a/pkg/common/db/tx/auto.go +++ /dev/null @@ -1,19 +0,0 @@ -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 deleted file mode 100644 index 193972af5..000000000 --- a/pkg/common/db/tx/invalid.go +++ /dev/null @@ -1,16 +0,0 @@ -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 deleted file mode 100644 index baf9a9a5d..000000000 --- a/pkg/common/db/tx/tx.go +++ /dev/null @@ -1,28 +0,0 @@ -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 old mode 100755 new mode 100644 diff --git a/pkg/common/db/unrelation/msg.go b/pkg/common/db/unrelation/msg.go old mode 100755 new mode 100644 diff --git a/pkg/common/db/unrelation/user.go b/pkg/common/db/unrelation/user.go old mode 100755 new mode 100644