This commit is contained in:
wangchuxiao
2023-02-09 20:36:34 +08:00
parent 8a1702fcf7
commit 759432794f
216 changed files with 2299 additions and 4059 deletions
+1 -45
View File
@@ -133,7 +133,6 @@ type config struct {
OpenImPushPort []int `yaml:"openImPushPort"`
OpenImAdminCmsPort []int `yaml:"openImAdminCmsPort"`
OpenImOfficePort []int `yaml:"openImOfficePort"`
OpenImOrganizationPort []int `yaml:"openImOrganizationPort"`
OpenImConversationPort []int `yaml:"openImConversationPort"`
OpenImCachePort []int `yaml:"openImCachePort"`
OpenImRealTimeCommPort []int `yaml:"openImRealTimeCommPort"`
@@ -149,7 +148,6 @@ type config struct {
OpenImAuthName string `yaml:"openImAuthName"`
OpenImAdminCMSName string `yaml:"openImAdminCMSName"`
OpenImOfficeName string `yaml:"openImOfficeName"`
OpenImOrganizationName string `yaml:"openImOrganizationName"`
OpenImConversationName string `yaml:"openImConversationName"`
OpenImCacheName string `yaml:"openImCacheName"`
OpenImRealTimeCommName string `yaml:"openImRealTimeCommName"`
@@ -404,11 +402,6 @@ type config struct {
OfflinePush POfflinePush `yaml:"offlinePush"`
DefaultTips PDefaultTips `yaml:"defaultTips"`
} `yaml:"groupMemberSetToOrdinaryUser"`
OrganizationChanged struct {
Conversation PConversation `yaml:"conversation"`
OfflinePush POfflinePush `yaml:"offlinePush"`
DefaultTips PDefaultTips `yaml:"defaultTips"`
} `yaml:"organizationChanged"`
////////////////////////user///////////////////////
UserInfoUpdated struct {
@@ -496,44 +489,7 @@ type config struct {
} `yaml:"offlinePush"`
} `yaml:"signal"`
}
Demo struct {
Port []int `yaml:"openImDemoPort"`
ListenIP string `yaml:"listenIP"`
AliSMSVerify struct {
AccessKeyID string `yaml:"accessKeyId"`
AccessKeySecret string `yaml:"accessKeySecret"`
SignName string `yaml:"signName"`
VerificationCodeTemplateCode string `yaml:"verificationCodeTemplateCode"`
Enable bool `yaml:"enable"`
}
TencentSMS struct {
AppID string `yaml:"appID"`
Region string `yaml:"region"`
SecretID string `yaml:"secretID"`
SecretKey string `yaml:"secretKey"`
SignName string `yaml:"signName"`
VerificationCodeTemplateCode string `yaml:"verificationCodeTemplateCode"`
Enable bool `yaml:"enable"`
}
SuperCode string `yaml:"superCode"`
CodeTTL int `yaml:"codeTTL"`
UseSuperCode bool `yaml:"useSuperCode"`
Mail struct {
Title string `yaml:"title"`
SenderMail string `yaml:"senderMail"`
SenderAuthorizationCode string `yaml:"senderAuthorizationCode"`
SmtpAddr string `yaml:"smtpAddr"`
SmtpPort int `yaml:"smtpPort"`
}
TestDepartMentID string `yaml:"testDepartMentID"`
ImAPIURL string `yaml:"imAPIURL"`
NeedInvitationCode bool `yaml:"needInvitationCode"`
OnboardProcess bool `yaml:"onboardProcess"`
JoinDepartmentIDList []string `yaml:"joinDepartmentIDList"`
JoinDepartmentGroups bool `yaml:"joinDepartmentGroups"`
OaNotification bool `yaml:"oaNotification"`
CreateOrganizationUserAndJoinDepartment bool `yaml:"createOrganizationUserAndJoinDepartment"`
}
WorkMoment struct {
OnlyFriendCanSee bool `yaml:"onlyFriendCanSee"`
} `yaml:"workMoment"`
-2
View File
@@ -94,8 +94,6 @@ const (
ConversationPrivateChatNotification = 1701
ConversationUnreadNotification = 1702
OrganizationChangedNotification = 1801
WorkMomentNotificationBegin = 1900
WorkMomentNotification = 1901
+1 -1
View File
@@ -56,7 +56,7 @@ func NewConversationRedis(rcClient *rockscache.Client) *ConversationRedis {
}
func NewNewConversationRedis(rdb redis.UniversalClient, conversationDB *relation.ConversationGorm, options rockscache.Options) *ConversationRedis {
return &ConversationRedis{conversationDB: conversationDB, expireTime: conversationExpireTime, rcClient: rockscache.NewClient(rdb, options)}
return &ConversationRedis{rcClient: rockscache.NewClient(rdb, options)}
}
func (c *ConversationRedis) getConversationKey(ownerUserID, conversationID string) string {
+1 -1
View File
@@ -6,7 +6,7 @@ import (
log2 "Open_IM/pkg/common/log"
pbChat "Open_IM/pkg/proto/msg"
pbRtc "Open_IM/pkg/proto/rtc"
pbCommon "Open_IM/pkg/proto/sdk_ws"
pbCommon "Open_IM/pkg/proto/sdkws"
"Open_IM/pkg/utils"
"context"
"errors"
+1 -1
View File
@@ -3,7 +3,7 @@ package cache
import (
"Open_IM/pkg/common/constant"
pbChat "Open_IM/pkg/proto/msg"
common "Open_IM/pkg/proto/sdk_ws"
common "Open_IM/pkg/proto/sdkws"
"context"
"flag"
"fmt"
-536
View File
@@ -68,539 +68,3 @@ func (rc *RcClient) DelKeys() {
}
}
}
func (rc *Client) GetFriendIDListFromCache(ctx context.Context, userID string) (friendIDList []string, err error) {
getFriendIDList := func() (string, error) {
friendIDList, err := relation.GetFriendIDListByUserID(userID)
if err != nil {
return "", utils.Wrap(err, "")
}
bytes, err := json.Marshal(friendIDList)
if err != nil {
return "", utils.Wrap(err, "")
}
return string(bytes), nil
}
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "userID", userID, "friendIDList", friendIDList)
}()
friendIDListStr, err := db.DB.Rc.Fetch(friendRelationCache+userID, time.Second*30*60, getFriendIDList)
if err != nil {
return nil, utils.Wrap(err, "")
}
err = json.Unmarshal([]byte(friendIDListStr), &friendIDList)
return friendIDList, utils.Wrap(err, "")
}
func DelFriendIDListFromCache(ctx context.Context, userID string) (err error) {
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "userID", userID)
}()
return db.DB.Rc.TagAsDeleted(friendRelationCache + userID)
}
func GetBlackListFromCache(ctx context.Context, userID string) (blackIDs []string, err error) {
getBlackIDList := func() (string, error) {
blackIDs, err := relation.GetBlackIDListByUserID(userID)
if err != nil {
return "", utils.Wrap(err, "")
}
bytes, err := json.Marshal(blackIDs)
if err != nil {
return "", utils.Wrap(err, "")
}
return string(bytes), nil
}
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "userID", userID, "blackIDList", blackIDs)
}()
blackIDListStr, err := db.DB.Rc.Fetch(blackListCache+userID, time.Second*30*60, getBlackIDList)
if err != nil {
return nil, utils.Wrap(err, "")
}
err = json.Unmarshal([]byte(blackIDListStr), &blackIDs)
return blackIDs, utils.Wrap(err, "")
}
func DelBlackIDListFromCache(ctx context.Context, userID string) (err error) {
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "ctx", ctx)
}()
return db.DB.Rc.TagAsDeleted(blackListCache + userID)
}
func GetJoinedGroupIDListFromCache(ctx context.Context, userID string) (joinedGroupList []string, err error) {
getJoinedGroupIDList := func() (string, error) {
joinedGroupList, err := relation.GetJoinedGroupIDListByUserID(userID)
if err != nil {
return "", utils.Wrap(err, "")
}
bytes, err := json.Marshal(joinedGroupList)
if err != nil {
return "", utils.Wrap(err, "")
}
return string(bytes), nil
}
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "userID", userID, "joinedGroupList", joinedGroupList)
}()
joinedGroupIDListStr, err := db.DB.Rc.Fetch(joinedGroupListCache+userID, time.Second*30*60, getJoinedGroupIDList)
if err != nil {
return nil, utils.Wrap(err, "")
}
err = json.Unmarshal([]byte(joinedGroupIDListStr), &joinedGroupList)
return joinedGroupList, utils.Wrap(err, "")
}
func DelJoinedGroupIDListFromCache(ctx context.Context, userID string) (err error) {
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "userID", userID)
}()
return db.DB.Rc.TagAsDeleted(joinedGroupListCache + userID)
}
func GetGroupMemberIDListFromCache(ctx context.Context, groupID string) (groupMemberIDList []string, err error) {
f := func() (string, error) {
groupInfo, err := GetGroupInfoFromCache(ctx, groupID)
if err != nil {
return "", utils.Wrap(err, "GetGroupInfoFromCache failed")
}
var groupMemberIDList []string
if groupInfo.GroupType == constant.SuperGroup {
superGroup, err := db.DB.GetSuperGroup(groupID)
if err != nil {
return "", utils.Wrap(err, "")
}
groupMemberIDList = superGroup.MemberIDList
} else {
groupMemberIDList, err = relation.GetGroupMemberIDListByGroupID(groupID)
if err != nil {
return "", utils.Wrap(err, "")
}
}
bytes, err := json.Marshal(groupMemberIDList)
if err != nil {
return "", utils.Wrap(err, "")
}
return string(bytes), nil
}
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupID", groupID, "groupMemberIDList", groupMemberIDList)
}()
groupIDListStr, err := db.DB.Rc.Fetch(groupCache+groupID, time.Second*30*60, f)
if err != nil {
return nil, utils.Wrap(err, "")
}
err = json.Unmarshal([]byte(groupIDListStr), &groupMemberIDList)
return groupMemberIDList, utils.Wrap(err, "")
}
func DelGroupMemberIDListFromCache(ctx context.Context, groupID string) (err error) {
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupID", groupID)
}()
return db.DB.Rc.TagAsDeleted(groupCache + groupID)
}
func GetUserInfoFromCache(ctx context.Context, userID string) (userInfo *relation.User, err error) {
getUserInfo := func() (string, error) {
userInfo, err := relation.GetUserByUserID(userID)
if err != nil {
return "", utils.Wrap(err, "")
}
bytes, err := json.Marshal(userInfo)
if err != nil {
return "", utils.Wrap(err, "")
}
return string(bytes), nil
}
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "userID", userID, "userInfo", *userInfo)
}()
userInfoStr, err := db.DB.Rc.Fetch(userInfoCache+userID, time.Second*30*60, getUserInfo)
if err != nil {
return nil, utils.Wrap(err, "")
}
userInfo = &relation.User{}
err = json.Unmarshal([]byte(userInfoStr), userInfo)
return userInfo, utils.Wrap(err, "")
}
func GetUserInfoFromCacheBatch(ctx context.Context, userIDs []string) ([]*relation.User, error) {
var users []*relation.User
for _, userID := range userIDs {
user, err := GetUserInfoFromCache(ctx, userID)
if err != nil {
return nil, err
}
users = append(users, user)
}
return users, nil
}
func DelUserInfoFromCache(ctx context.Context, userID string) (err error) {
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "userID", userID)
}()
return db.DB.Rc.TagAsDeleted(userInfoCache + userID)
}
func GetGroupMemberInfoFromCache(ctx context.Context, groupID, userID string) (groupMember *relation.GroupMember, err error) {
getGroupMemberInfo := func() (string, error) {
groupMemberInfo, err := relation.GetGroupMemberInfoByGroupIDAndUserID(groupID, userID)
if err != nil {
return "", utils.Wrap(err, "")
}
bytes, err := json.Marshal(groupMemberInfo)
if err != nil {
return "", utils.Wrap(err, "")
}
return string(bytes), nil
}
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupID", groupID, "userID", userID, "groupMember", *groupMember)
}()
groupMemberInfoStr, err := db.DB.Rc.Fetch(groupMemberInfoCache+groupID+"-"+userID, time.Second*30*60, getGroupMemberInfo)
if err != nil {
return nil, utils.Wrap(err, "")
}
groupMember = &relation.GroupMember{}
err = json.Unmarshal([]byte(groupMemberInfoStr), groupMember)
return groupMember, utils.Wrap(err, "")
}
func DelGroupMemberInfoFromCache(ctx context.Context, groupID, userID string) (err error) {
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupID", groupID, "userID", userID)
}()
return db.DB.Rc.TagAsDeleted(groupMemberInfoCache + groupID + "-" + userID)
}
func GetGroupMembersInfoFromCache(ctx context.Context, count, offset int32, groupID string) (groupMembers []*relation.GroupMember, err error) {
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "count", count, "offset", offset, "groupID", groupID, "groupMember", groupMembers)
}()
groupMemberIDList, err := GetGroupMemberIDListFromCache(ctx, groupID)
if err != nil {
return nil, err
}
if count < 0 || offset < 0 {
return nil, nil
}
var groupMemberList []*relation.GroupMember
var start, stop int32
start = offset
stop = offset + count
l := int32(len(groupMemberIDList))
if start > stop {
return nil, nil
}
if start >= l {
return nil, nil
}
if count != 0 {
if stop >= l {
stop = l
}
groupMemberIDList = groupMemberIDList[start:stop]
} else {
if l < 1000 {
stop = l
} else {
stop = 1000
}
groupMemberIDList = groupMemberIDList[start:stop]
}
//log.NewDebug("", utils.GetSelfFuncName(), "ID list: ", groupMemberIDList)
for _, userID := range groupMemberIDList {
groupMember, err := GetGroupMemberInfoFromCache(ctx, groupID, userID)
if err != nil {
log.NewError("", utils.GetSelfFuncName(), err.Error(), groupID, userID)
continue
}
groupMembers = append(groupMembers, groupMember)
}
return groupMemberList, nil
}
func GetAllGroupMembersInfoFromCache(ctx context.Context, groupID string) (groupMembers []*relation.GroupMember, err error) {
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupID", groupID, "groupMembers", groupMembers)
}()
getGroupMemberInfo := func() (string, error) {
groupMembers, err := relation.GetGroupMemberListByGroupID(groupID)
if err != nil {
return "", utils.Wrap(err, "")
}
bytes, err := json.Marshal(groupMembers)
if err != nil {
return "", utils.Wrap(err, "")
}
return string(bytes), nil
}
groupMembersStr, err := db.DB.Rc.Fetch(groupAllMemberInfoCache+groupID, time.Second*30*60, getGroupMemberInfo)
if err != nil {
return nil, utils.Wrap(err, "")
}
err = json.Unmarshal([]byte(groupMembersStr), &groupMembers)
return groupMembers, utils.Wrap(err, "")
}
func DelAllGroupMembersInfoFromCache(ctx context.Context, groupID string) (err error) {
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupID", groupID)
}()
return db.DB.Rc.TagAsDeleted(groupAllMemberInfoCache + groupID)
}
//func GetGroupInfoFromCache(ctx context.Context, groupID string) (groupInfo *mysql.GroupGorm, err error) {
// getGroupInfo := func() (string, error) {
// groupInfo, err := mysql.GetGroupInfoByGroupID(groupID)
// if err != nil {
// return "", utils.Wrap(err, "")
// }
// bytes, err := json.Marshal(groupInfo)
// if err != nil {
// return "", utils.Wrap(err, "")
// }
// return string(bytes), nil
// }
// groupInfo = &mysql.GroupGorm{}
// defer func() {
// tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupID", groupID, "groupInfo", groupInfo)
// }()
// groupInfoStr, err := db.DB.Rc.Fetch(groupInfoCache+groupID, time.Second*30*60, getGroupInfo)
// if err != nil {
// return nil, utils.Wrap(err, "")
// }
// err = json.Unmarshal([]byte(groupInfoStr), groupInfo)
// return groupInfo, utils.Wrap(err, "")
//}
//
//func DelGroupInfoFromCache(ctx context.Context, groupID string) (err error) {
// defer func() {
// tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupID", groupID)
// }()
// return db.DB.Rc.TagAsDeleted(groupInfoCache + groupID)
//}
func GetAllFriendsInfoFromCache(ctx context.Context, userID string) (friends []*relation.Friend, err error) {
getAllFriendInfo := func() (string, error) {
friendInfoList, err := relation.GetFriendListByUserID(userID)
if err != nil {
return "", utils.Wrap(err, "")
}
bytes, err := json.Marshal(friendInfoList)
if err != nil {
return "", utils.Wrap(err, "")
}
return string(bytes), nil
}
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "userID", userID, "friends", friends)
}()
allFriendInfoStr, err := db.DB.Rc.Fetch(allFriendInfoCache+userID, time.Second*30*60, getAllFriendInfo)
if err != nil {
return nil, utils.Wrap(err, "")
}
err = json.Unmarshal([]byte(allFriendInfoStr), &friends)
return friends, utils.Wrap(err, "")
}
func DelAllFriendsInfoFromCache(ctx context.Context, userID string) (err error) {
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "userID", userID)
}()
return db.DB.Rc.TagAsDeleted(allFriendInfoCache + userID)
}
func GetJoinedSuperGroupListFromCache(ctx context.Context, userID string) (joinedSuperGroupIDs []string, err error) {
getJoinedSuperGroupIDList := func() (string, error) {
userToSuperGroup, err := db.DB.GetSuperGroupByUserID(userID)
if err != nil {
return "", utils.Wrap(err, "")
}
bytes, err := json.Marshal(userToSuperGroup.GroupIDList)
if err != nil {
return "", utils.Wrap(err, "")
}
return string(bytes), nil
}
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "userID", userID, "joinedSuperGroupIDs", joinedSuperGroupIDs)
}()
joinedSuperGroupListStr, err := db.DB.Rc.Fetch(joinedSuperGroupListCache+userID, time.Second*30*60, getJoinedSuperGroupIDList)
if err != nil {
return nil, err
}
err = json.Unmarshal([]byte(joinedSuperGroupListStr), &joinedSuperGroupIDs)
return joinedSuperGroupIDs, utils.Wrap(err, "")
}
func DelJoinedSuperGroupIDListFromCache(ctx context.Context, userID string) (err error) {
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "userID", userID)
}()
return db.DB.Rc.TagAsDeleted(joinedSuperGroupListCache + userID)
}
func GetGroupMemberListHashFromCache(ctx context.Context, groupID string) (hashCodeUint64 uint64, err error) {
generateHash := func() (string, error) {
groupInfo, err := GetGroupInfoFromCache(ctx, groupID)
if err != nil {
return "0", utils.Wrap(err, "GetGroupInfoFromCache failed")
}
if groupInfo.Status == constant.GroupStatusDismissed {
return "0", nil
}
groupMemberIDList, err := GetGroupMemberIDListFromCache(ctx, groupID)
if err != nil {
return "", utils.Wrap(err, "GetGroupMemberIDListFromCache failed")
}
sort.Strings(groupMemberIDList)
var all string
for _, v := range groupMemberIDList {
all += v
}
bi := big.NewInt(0)
bi.SetString(utils.Md5(all)[0:8], 16)
return strconv.Itoa(int(bi.Uint64())), nil
}
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupID", groupID, "hashCodeUint64", hashCodeUint64)
}()
hashCodeStr, err := db.DB.Rc.Fetch(groupMemberListHashCache+groupID, time.Second*30*60, generateHash)
if err != nil {
return 0, utils.Wrap(err, "fetch failed")
}
hashCode, err := strconv.Atoi(hashCodeStr)
return uint64(hashCode), err
}
func DelGroupMemberListHashFromCache(ctx context.Context, groupID string) (err error) {
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupID", groupID)
}()
return db.DB.Rc.TagAsDeleted(groupMemberListHashCache + groupID)
}
func GetGroupMemberNumFromCache(ctx context.Context, groupID string) (num int, err error) {
getGroupMemberNum := func() (string, error) {
num, err := relation.GetGroupMemberNumByGroupID(groupID)
if err != nil {
return "", utils.Wrap(err, "")
}
return strconv.Itoa(int(num)), nil
}
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupID", groupID, "num", num)
}()
groupMember, err := db.DB.Rc.Fetch(groupMemberNumCache+groupID, time.Second*30*60, getGroupMemberNum)
if err != nil {
return 0, utils.Wrap(err, "")
}
return strconv.Atoi(groupMember)
}
func DelGroupMemberNumFromCache(ctx context.Context, groupID string) (err error) {
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupID", groupID)
}()
return db.DB.Rc.TagAsDeleted(groupMemberNumCache + groupID)
}
func GetUserConversationIDListFromCache(ctx context.Context, userID string) (conversationIDs []string, err error) {
getConversationIDList := func() (string, error) {
conversationIDList, err := relation.GetConversationIDListByUserID(userID)
if err != nil {
return "", utils.Wrap(err, "getConversationIDList failed")
}
log.NewDebug("", utils.GetSelfFuncName(), conversationIDList)
bytes, err := json.Marshal(conversationIDList)
if err != nil {
return "", utils.Wrap(err, "")
}
return string(bytes), nil
}
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "userID", userID, "conversationIDs", conversationIDs)
}()
conversationIDListStr, err := db.DB.Rc.Fetch(conversationIDListCache+userID, time.Second*30*60, getConversationIDList)
err = json.Unmarshal([]byte(conversationIDListStr), &conversationIDs)
if err != nil {
return nil, utils.Wrap(err, "")
}
return conversationIDs, nil
}
func DelUserConversationIDListFromCache(ctx context.Context, userID string) (err error) {
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "userID", userID)
}()
return utils.Wrap(db.DB.Rc.TagAsDeleted(conversationIDListCache+userID), "DelUserConversationIDListFromCache err")
}
func GetConversationFromCache(ctx context.Context, ownerUserID, conversationID string) (conversation *relation.Conversation, err error) {
getConversation := func() (string, error) {
conversation, err := relation.GetConversation(ownerUserID, conversationID)
if err != nil {
return "", utils.Wrap(err, "get failed")
}
bytes, err := json.Marshal(conversation)
if err != nil {
return "", utils.Wrap(err, "Marshal failed")
}
return string(bytes), nil
}
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "ownerUserID", ownerUserID, "conversationID", conversationID, "conversation", *conversation)
}()
conversationStr, err := db.DB.Rc.Fetch(conversationCache+ownerUserID+":"+conversationID, time.Second*30*60, getConversation)
if err != nil {
return nil, utils.Wrap(err, "Fetch failed")
}
conversation = &relation.Conversation{}
err = json.Unmarshal([]byte(conversationStr), &conversation)
return conversation, utils.Wrap(err, "Unmarshal failed")
}
func GetConversationsFromCache(ctx context.Context, ownerUserID string, conversationIDs []string) (conversations []relation.Conversation, err error) {
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "ownerUserID", ownerUserID, "conversationIDs", conversationIDs, "conversations", conversations)
}()
for _, conversationID := range conversationIDs {
conversation, err := GetConversationFromCache(ctx, ownerUserID, conversationID)
if err != nil {
return nil, utils.Wrap(err, "GetConversationFromCache failed")
}
conversations = append(conversations, *conversation)
}
return conversations, nil
}
func GetUserAllConversationList(ctx context.Context, ownerUserID string) (conversations []relation.Conversation, err error) {
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "ownerUserID", ownerUserID, "conversations", conversations)
}()
IDList, err := GetUserConversationIDListFromCache(ctx, ownerUserID)
if err != nil {
return nil, err
}
var conversationList []relation.Conversation
log.NewDebug("", utils.GetSelfFuncName(), IDList)
for _, conversationID := range IDList {
conversation, err := GetConversationFromCache(ctx, ownerUserID, conversationID)
if err != nil {
return nil, utils.Wrap(err, "GetConversationFromCache failed")
}
conversationList = append(conversationList, *conversation)
}
return conversationList, nil
}
func DelConversationFromCache(ctx context.Context, ownerUserID, conversationID string) (err error) {
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "ownerUserID", ownerUserID, "conversationID", conversationID)
}()
return utils.Wrap(db.DB.Rc.TagAsDeleted(conversationCache+ownerUserID+":"+conversationID), "DelConversationFromCache err")
}
+14 -11
View File
@@ -19,7 +19,10 @@ const (
userGlobalRecvMsgOptKey = "USER_GLOBAL_RECV_MSG_OPT_KEY:"
)
type UserCache struct {
type UserCache interface {
}
type UserCacheRedis struct {
userDB *relation.UserGorm
expireTime time.Duration
@@ -27,8 +30,8 @@ type UserCache struct {
rcClient *rockscache.Client
}
func NewUserCache(rdb redis.UniversalClient, userDB *relation.UserGorm, options rockscache.Options) *UserCache {
return &UserCache{
func NewUserCacheRedis(rdb redis.UniversalClient, userDB *relation.UserGorm, options rockscache.Options) *UserCacheRedis {
return &UserCacheRedis{
userDB: userDB,
expireTime: userExpireTime,
redisClient: NewRedisClient(rdb),
@@ -36,15 +39,15 @@ func NewUserCache(rdb redis.UniversalClient, userDB *relation.UserGorm, options
}
}
func (u *UserCache) getUserInfoKey(userID string) string {
func (u *UserCacheRedis) getUserInfoKey(userID string) string {
return userInfoKey + userID
}
func (u *UserCache) getUserGlobalRecvMsgOptKey(userID string) string {
func (u *UserCacheRedis) getUserGlobalRecvMsgOptKey(userID string) string {
return userGlobalRecvMsgOptKey + userID
}
func (u *UserCache) GetUserInfo(ctx context.Context, userID string) (userInfo *relationTb.UserModel, err error) {
func (u *UserCacheRedis) GetUserInfo(ctx context.Context, userID string) (userInfo *relationTb.UserModel, err error) {
getUserInfo := func() (string, error) {
userInfo, err := u.userDB.Take(ctx, userID)
if err != nil {
@@ -68,7 +71,7 @@ func (u *UserCache) GetUserInfo(ctx context.Context, userID string) (userInfo *r
return userInfo, utils.Wrap(err, "")
}
func (u *UserCache) GetUsersInfo(ctx context.Context, userIDs []string) ([]*relationTb.UserModel, error) {
func (u *UserCacheRedis) GetUsersInfo(ctx context.Context, userIDs []string) ([]*relationTb.UserModel, error) {
var users []*relationTb.UserModel
for _, userID := range userIDs {
user, err := GetUserInfoFromCache(ctx, userID)
@@ -80,14 +83,14 @@ func (u *UserCache) GetUsersInfo(ctx context.Context, userIDs []string) ([]*rela
return users, nil
}
func (u *UserCache) DelUserInfo(ctx context.Context, userID string) (err error) {
func (u *UserCacheRedis) DelUserInfo(ctx context.Context, userID string) (err error) {
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "userID", userID)
}()
return u.rcClient.TagAsDeleted(u.getUserInfoKey(userID))
}
func (u *UserCache) DelUsersInfo(ctx context.Context, userIDs []string) (err error) {
func (u *UserCacheRedis) DelUsersInfo(ctx context.Context, userIDs []string) (err error) {
for _, userID := range userIDs {
if err := u.DelUserInfo(ctx, userID); err != nil {
return err
@@ -96,7 +99,7 @@ func (u *UserCache) DelUsersInfo(ctx context.Context, userIDs []string) (err err
return nil
}
func (u *UserCache) GetUserGlobalRecvMsgOpt(ctx context.Context, userID string) (opt int, err error) {
func (u *UserCacheRedis) GetUserGlobalRecvMsgOpt(ctx context.Context, userID string) (opt int, err error) {
getUserGlobalRecvMsgOpt := func() (string, error) {
userInfo, err := u.userDB.Take(ctx, userID)
if err != nil {
@@ -114,7 +117,7 @@ func (u *UserCache) GetUserGlobalRecvMsgOpt(ctx context.Context, userID string)
return strconv.Atoi(optStr)
}
func (u *UserCache) DelUserGlobalRecvMsgOpt(ctx context.Context, userID string) (err error) {
func (u *UserCacheRedis) DelUserGlobalRecvMsgOpt(ctx context.Context, userID string) (err error) {
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "userID", userID)
}()
+6 -5
View File
@@ -2,13 +2,14 @@ package controller
import (
"Open_IM/pkg/common/db/relation"
relationTb "Open_IM/pkg/common/db/table/relation"
pbMsg "Open_IM/pkg/proto/msg"
"gorm.io/gorm"
)
type ChatLogInterface interface {
CreateChatLog(msg pbMsg.MsgDataToMQ) error
GetChatLog(chatLog *relation.ChatLog, pageNumber, showNumber int32, contentTypeList []int32) (int64, []relation.ChatLog, error)
GetChatLog(chatLog *relationTb.ChatLogModel, pageNumber, showNumber int32, contentTypeList []int32) (int64, []relation.ChatLog, error)
}
func NewChatLogController(db *gorm.DB) ChatLogInterface {
@@ -23,17 +24,17 @@ func (c *ChatLogController) CreateChatLog(msg pbMsg.MsgDataToMQ) error {
return c.database.CreateChatLog(msg)
}
func (c *ChatLogController) GetChatLog(chatLog *relation.ChatLog, pageNumber, showNumber int32, contentTypeList []int32) (int64, []relation.ChatLog, error) {
func (c *ChatLogController) GetChatLog(chatLog *relationTb.ChatLogModel, pageNumber, showNumber int32, contentTypeList []int32) (int64, []relation.ChatLog, error) {
return c.database.GetChatLog(chatLog, pageNumber, showNumber, contentTypeList)
}
type ChatLogDataBaseInterface interface {
CreateChatLog(msg pbMsg.MsgDataToMQ) error
GetChatLog(chatLog *relation.ChatLog, pageNumber, showNumber int32, contentTypeList []int32) (int64, []relation.ChatLog, error)
GetChatLog(chatLog *relationTb.ChatLogModel, pageNumber, showNumber int32, contentTypeList []int32) (int64, []relation.ChatLog, error)
}
type ChatLogDataBase struct {
chatLogDB *relation.ChatLog
chatLogDB *relationTb.ChatLogModelInterface
}
func NewChatLogDataBase(db *gorm.DB) ChatLogDataBaseInterface {
@@ -44,6 +45,6 @@ func (c *ChatLogDataBase) CreateChatLog(msg pbMsg.MsgDataToMQ) error {
return c.chatLogDB.Create(msg)
}
func (c *ChatLogDataBase) GetChatLog(chatLog *relation.ChatLog, pageNumber, showNumber int32, contentTypeList []int32) (int64, []relation.ChatLog, error) {
func (c *ChatLogDataBase) GetChatLog(chatLog *relationTb.ChatLogModel, pageNumber, showNumber int32, contentTypeList []int32) (int64, []relation.ChatLog, error) {
return c.chatLogDB.GetChatLog(chatLog, pageNumber, showNumber, contentTypeList)
}
+2 -2
View File
@@ -4,7 +4,7 @@ import (
"Open_IM/pkg/common/constant"
"Open_IM/pkg/common/db/table/relation"
pbMsg "Open_IM/pkg/proto/msg"
server_api_params "Open_IM/pkg/proto/sdk_ws"
sdkws "Open_IM/pkg/proto/sdkws"
"Open_IM/pkg/utils"
"fmt"
"github.com/golang/protobuf/jsonpb"
@@ -31,7 +31,7 @@ func (c *ChatLogGorm) Create(msg pbMsg.MsgDataToMQ) error {
chatLog.RecvID = msg.MsgData.RecvID
}
if msg.MsgData.ContentType >= constant.NotificationBegin && msg.MsgData.ContentType <= constant.NotificationEnd {
var tips server_api_params.TipsComm
var tips sdkws.TipsComm
_ = proto.Unmarshal(msg.MsgData.Content, &tips)
marshaler := jsonpb.Marshaler{
OrigName: true,
@@ -1,7 +1,7 @@
package unrelation
import (
common "Open_IM/pkg/proto/sdk_ws"
common "Open_IM/pkg/proto/sdkws"
"context"
"strconv"
"strings"
+65
View File
@@ -0,0 +1,65 @@
package unrelation
import "strconv"
const (
singleGocMsgNum = 5000
CChat = "msg"
)
type UserChatModel struct {
UID string `bson:"uid"`
Msg []MsgInfoModel `bson:"msg"`
}
type MsgInfoModel struct {
SendTime int64 `bson:"sendtime"`
Msg []byte `bson:"msg"`
}
func (UserChatModel) TableName() string {
return CChat
}
func (UserChatModel) GetSingleGocMsgNum() int {
return singleGocMsgNum
}
func (u UserChatModel) getSeqUid(uid string, seq uint32) string {
seqSuffix := seq / singleGocMsgNum
return u.indexGen(uid, seqSuffix)
}
func (u UserChatModel) getSeqUserIDList(userID string, maxSeq uint32) []string {
seqMaxSuffix := maxSeq / singleGocMsgNum
var seqUserIDList []string
for i := 0; i <= int(seqMaxSuffix); i++ {
seqUserID := u.indexGen(userID, uint32(i))
seqUserIDList = append(seqUserIDList, seqUserID)
}
return seqUserIDList
}
func (UserChatModel) getSeqSuperGroupID(groupID string, seq uint32) string {
seqSuffix := seq / singleGocMsgNum
return superGroupIndexGen(groupID, seqSuffix)
}
func (u UserChatModel) GetSeqUid(uid string, seq uint32) string {
return u.getSeqUid(uid, seq)
}
func (UserChatModel) getMsgIndex(seq uint32) int {
seqSuffix := seq / singleGocMsgNum
var index uint32
if seqSuffix == 0 {
index = (seq - seqSuffix*singleGocMsgNum) - 1
} else {
index = seq - seqSuffix*singleGocMsgNum
}
return int(index)
}
func (UserChatModel) indexGen(uid string, seqSuffix uint32) string {
return uid + ":" + strconv.FormatInt(int64(seqSuffix), 10)
}
+4 -10
View File
@@ -2,6 +2,7 @@ package unrelation
import (
"context"
"strconv"
)
const (
@@ -37,13 +38,6 @@ type SuperGroupModelInterface interface {
RemoveGroupFromUser(ctx context.Context, groupID string, userIDs []string, tx ...any) error
}
//type SuperGroupModelInterface interface {
// // tx is your transaction object
// CreateSuperGroup(ctx context.Context, groupID string, initMemberIDs []string, tx ...interface{}) error
// FindSuperGroup(ctx context.Context, groupIDs []string, tx ...interface{}) ([]*SuperGroupModel, error)
// //GetSuperGroup(ctx context.Context, groupID string) (SuperGroupModel, error)
// AddUserToSuperGroup(ctx context.Context, groupID string, userIDs []string, tx ...interface{}) error
// RemoverUserFromSuperGroup(ctx context.Context, groupID string, userIDs []string, tx ...interface{}) error
// GetSuperGroupByUserID(ctx context.Context, userID string, tx ...interface{}) (*UserToSuperGroupModel, error)
// DeleteSuperGroup(ctx context.Context, groupID string, tx ...interface{}) error
//}
func superGroupIndexGen(groupID string, seqSuffix uint32) string {
return "super_group_" + groupID + ":" + strconv.FormatInt(int64(seqSuffix), 10)
}
@@ -2,7 +2,7 @@ package unrelation
import (
"Open_IM/pkg/common/db/table/unrelation"
server_api_params "Open_IM/pkg/proto/sdk_ws"
"Open_IM/pkg/proto/sdkws"
"Open_IM/pkg/utils"
"context"
"errors"
@@ -99,7 +99,7 @@ func (e *ExtendMsgSetMongoDriver) InsertExtendMsg(ctx context.Context, sourceID
}
// insert or update
func (e *ExtendMsgSetMongoDriver) InsertOrUpdateReactionExtendMsgSet(ctx context.Context, sourceID string, sessionType int32, clientMsgID string, msgFirstModifyTime int64, reactionExtensionList map[string]*server_api_params.KeyValue) error {
func (e *ExtendMsgSetMongoDriver) InsertOrUpdateReactionExtendMsgSet(ctx context.Context, sourceID string, sessionType int32, clientMsgID string, msgFirstModifyTime int64, reactionExtensionList map[string]*sdkws.KeyValue) error {
var updateBson = bson.M{}
for _, v := range reactionExtensionList {
updateBson[fmt.Sprintf("extend_msgs.%s.%s", clientMsgID, v.TypeKey)] = v
@@ -120,7 +120,7 @@ func (e *ExtendMsgSetMongoDriver) InsertOrUpdateReactionExtendMsgSet(ctx context
}
// delete TypeKey
func (e *ExtendMsgSetMongoDriver) DeleteReactionExtendMsgSet(ctx context.Context, sourceID string, sessionType int32, clientMsgID string, msgFirstModifyTime int64, reactionExtensionList map[string]*server_api_params.KeyValue) error {
func (e *ExtendMsgSetMongoDriver) DeleteReactionExtendMsgSet(ctx context.Context, sourceID string, sessionType int32, clientMsgID string, msgFirstModifyTime int64, reactionExtensionList map[string]*sdkws.KeyValue) error {
var updateBson = bson.M{}
for _, v := range reactionExtensionList {
updateBson[fmt.Sprintf("extend_msgs.%s.%s", clientMsgID, v.TypeKey)] = ""
File diff suppressed because it is too large Load Diff
+582
View File
@@ -0,0 +1,582 @@
package unrelation
import (
"Open_IM/pkg/common/constant"
"Open_IM/pkg/common/db/table/unrelation"
"Open_IM/pkg/proto/sdkws"
"Open_IM/pkg/utils"
"context"
"errors"
"github.com/go-redis/redis/v8"
"github.com/gogo/protobuf/sortkeys"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"sync"
"time"
)
var ErrMsgListNotExist = errors.New("user not have msg in mongoDB")
type MsgMongoDriver struct {
mgoDB *mongo.Database
MsgCollection *mongo.Collection
}
func NewMsgMongoDriver(mgoDB *mongo.Database) *MsgMongoDriver {
return &MsgMongoDriver{mgoDB: mgoDB, MsgCollection: mgoDB.Collection(unrelation.CChat)}
}
func (m *MsgMongoDriver) DelMsgBySeqList(ctx context.Context, userID string, seqList []uint32) (totalUnExistSeqList []uint32, err error) {
sortkeys.Uint32s(seqList)
suffixUserID2SubSeqList := func(uid string, seqList []uint32) map[string][]uint32 {
t := make(map[string][]uint32)
for i := 0; i < len(seqList); i++ {
seqUid := getSeqUid(uid, seqList[i])
if value, ok := t[seqUid]; !ok {
var temp []uint32
t[seqUid] = append(temp, seqList[i])
} else {
t[seqUid] = append(value, seqList[i])
}
}
return t
}(userID, seqList)
lock := sync.Mutex{}
var wg sync.WaitGroup
wg.Add(len(suffixUserID2SubSeqList))
for k, v := range suffixUserID2SubSeqList {
go func(suffixUserID string, subSeqList []uint32) {
defer wg.Done()
unexistSeqList, err := m.DelMsgBySeqListInOneDoc(ctx, suffixUserID, subSeqList)
if err != nil {
return
}
lock.Lock()
totalUnExistSeqList = append(totalUnExistSeqList, unexistSeqList...)
lock.Unlock()
}(k, v)
}
return totalUnExistSeqList, nil
}
func (m *MsgMongoDriver) DelMsgBySeqListInOneDoc(ctx context.Context, suffixUserID string, seqList []uint32) ([]uint32, error) {
seqMsgList, indexList, unexistSeqList, err := m.GetMsgAndIndexBySeqListInOneMongo2(suffixUserID, seqList)
if err != nil {
return nil, utils.Wrap(err, "")
}
for i, v := range seqMsgList {
if err := m.ReplaceMsgByIndex(suffixUserID, v, operationID, indexList[i]); err != nil {
return nil, utils.Wrap(err, "")
}
}
return unexistSeqList, nil
}
func (m *MsgMongoDriver) DelMsgLogic(ctx context.Context, uid string, seqList []uint32) error {
sortkeys.Uint32s(seqList)
seqMsgs, err := d.GetMsgBySeqListMongo2(ctx, uid, seqList)
if err != nil {
return utils.Wrap(err, "")
}
for _, seqMsg := range seqMsgs {
seqMsg.Status = constant.MsgDeleted
if err = d.ReplaceMsgBySeq(ctx, uid, seqMsg); err != nil {
log.NewError(operationID, utils.GetSelfFuncName(), "ReplaceMsgListBySeq error", err.Error())
}
}
return nil
}
func (m *MsgMongoDriver) ReplaceMsgByIndex(ctx context.Context, suffixUserID string, msg *sdkws.MsgData, seqIndex int) error {
log.NewInfo(operationID, utils.GetSelfFuncName(), suffixUserID, *msg)
ctx, _ := context.WithTimeout(context.Background(), time.Duration(config.Config.Mongo.DBTimeout)*time.Second)
c := d.mongoClient.Database(config.Config.Mongo.DBDatabase).Collection(cChat)
s := fmt.Sprintf("msg.%d.msg", seqIndex)
log.NewDebug(operationID, utils.GetSelfFuncName(), seqIndex, s)
msg.Status = constant.MsgDeleted
bytes, err := proto.Marshal(msg)
if err != nil {
log.NewError(operationID, utils.GetSelfFuncName(), "proto marshal failed ", err.Error(), msg.String())
return utils.Wrap(err, "")
}
updateResult, err := c.UpdateOne(ctx, bson.M{"uid": suffixUserID}, bson.M{"$set": bson.M{s: bytes}})
log.NewInfo(operationID, utils.GetSelfFuncName(), updateResult)
if err != nil {
log.NewError(operationID, utils.GetSelfFuncName(), "UpdateOne", err.Error())
return utils.Wrap(err, "")
}
return nil
}
func (d *db.DataBases) ReplaceMsgBySeq(uid string, msg *open_im_sdk.MsgData, operationID string) error {
log.NewInfo(operationID, utils.GetSelfFuncName(), uid, *msg)
ctx, _ := context.WithTimeout(context.Background(), time.Duration(config.Config.Mongo.DBTimeout)*time.Second)
c := d.mongoClient.Database(config.Config.Mongo.DBDatabase).Collection(cChat)
uid = getSeqUid(uid, msg.Seq)
seqIndex := getMsgIndex(msg.Seq)
s := fmt.Sprintf("msg.%d.msg", seqIndex)
log.NewDebug(operationID, utils.GetSelfFuncName(), seqIndex, s)
bytes, err := proto.Marshal(msg)
if err != nil {
log.NewError(operationID, utils.GetSelfFuncName(), "proto marshal", err.Error())
return utils.Wrap(err, "")
}
updateResult, err := c.UpdateOne(
ctx, bson.M{"uid": uid},
bson.M{"$set": bson.M{s: bytes}})
log.NewInfo(operationID, utils.GetSelfFuncName(), updateResult)
if err != nil {
log.NewError(operationID, utils.GetSelfFuncName(), "UpdateOne", err.Error())
return utils.Wrap(err, "")
}
return nil
}
func (d *db.DataBases) UpdateOneMsgList(msg *UserChat) error {
ctx, _ := context.WithTimeout(context.Background(), time.Duration(config.Config.Mongo.DBTimeout)*time.Second)
c := d.mongoClient.Database(config.Config.Mongo.DBDatabase).Collection(cChat)
_, err := c.UpdateOne(ctx, bson.M{"uid": msg.UID}, bson.M{"$set": bson.M{"msg": msg.Msg}})
return err
}
func (d *db.DataBases) GetMsgBySeqList(uid string, seqList []uint32, operationID string) (seqMsg []*open_im_sdk.MsgData, err error) {
log.NewInfo(operationID, utils.GetSelfFuncName(), uid, seqList)
var hasSeqList []uint32
singleCount := 0
session := d.mgoSession.Clone()
if session == nil {
return nil, errors.New("session == nil")
}
defer session.Close()
c := session.DB(config.Config.Mongo.DBDatabase).C(cChat)
m := func(uid string, seqList []uint32) map[string][]uint32 {
t := make(map[string][]uint32)
for i := 0; i < len(seqList); i++ {
seqUid := getSeqUid(uid, seqList[i])
if value, ok := t[seqUid]; !ok {
var temp []uint32
t[seqUid] = append(temp, seqList[i])
} else {
t[seqUid] = append(value, seqList[i])
}
}
return t
}(uid, seqList)
sChat := UserChat{}
for seqUid, value := range m {
if err = c.Find(bson.M{"uid": seqUid}).One(&sChat); err != nil {
log.NewError(operationID, "not find seqUid", seqUid, value, uid, seqList, err.Error())
continue
}
singleCount = 0
for i := 0; i < len(sChat.Msg); i++ {
msg := new(open_im_sdk.MsgData)
if err = proto.Unmarshal(sChat.Msg[i].Msg, msg); err != nil {
log.NewError(operationID, "Unmarshal err", seqUid, value, uid, seqList, err.Error())
return nil, err
}
if isContainInt32(msg.Seq, value) {
seqMsg = append(seqMsg, msg)
hasSeqList = append(hasSeqList, msg.Seq)
singleCount++
if singleCount == len(value) {
break
}
}
}
}
if len(hasSeqList) != len(seqList) {
var diff []uint32
diff = utils.Difference(hasSeqList, seqList)
exceptionMSg := genExceptionMessageBySeqList(diff)
seqMsg = append(seqMsg, exceptionMSg...)
}
return seqMsg, nil
}
func (d *db.DataBases) GetUserMsgListByIndex(ID string, index int64) (*UserChat, error) {
ctx, _ := context.WithTimeout(context.Background(), time.Duration(config.Config.Mongo.DBTimeout)*time.Second)
c := d.mongoClient.Database(config.Config.Mongo.DBDatabase).Collection(cChat)
regex := fmt.Sprintf("^%s", ID)
findOpts := options.Find().SetLimit(1).SetSkip(index).SetSort(bson.M{"uid": 1})
var msgs []UserChat
//primitive.Regex{Pattern: regex}
cursor, err := c.Find(ctx, bson.M{"uid": primitive.Regex{Pattern: regex}}, findOpts)
if err != nil {
return nil, utils.Wrap(err, "")
}
err = cursor.All(context.Background(), &msgs)
if err != nil {
return nil, utils.Wrap(err, fmt.Sprintf("cursor is %s", cursor.Current.String()))
}
if len(msgs) > 0 {
return &msgs[0], nil
} else {
return nil, ErrMsgListNotExist
}
}
func (d *db.DataBases) DelMongoMsgs(IDList []string) error {
ctx, _ := context.WithTimeout(context.Background(), time.Duration(config.Config.Mongo.DBTimeout)*time.Second)
c := d.mongoClient.Database(config.Config.Mongo.DBDatabase).Collection(cChat)
_, err := c.DeleteMany(ctx, bson.M{"uid": bson.M{"$in": IDList}})
return err
}
func (d *db.DataBases) ReplaceMsgToBlankByIndex(suffixID string, index int) (replaceMaxSeq uint32, err error) {
ctx, _ := context.WithTimeout(context.Background(), time.Duration(config.Config.Mongo.DBTimeout)*time.Second)
c := d.mongoClient.Database(config.Config.Mongo.DBDatabase).Collection(cChat)
userChat := &UserChat{}
err = c.FindOne(ctx, bson.M{"uid": suffixID}).Decode(&userChat)
if err != nil {
return 0, err
}
for i, msg := range userChat.Msg {
if i <= index {
msgPb := &open_im_sdk.MsgData{}
if err = proto.Unmarshal(msg.Msg, msgPb); err != nil {
continue
}
newMsgPb := &open_im_sdk.MsgData{Seq: msgPb.Seq}
bytes, err := proto.Marshal(newMsgPb)
if err != nil {
continue
}
msg.Msg = bytes
msg.SendTime = 0
replaceMaxSeq = msgPb.Seq
}
}
_, err = c.UpdateOne(ctx, bson.M{"uid": suffixID}, bson.M{"$set": bson.M{"msg": userChat.Msg}})
return replaceMaxSeq, err
}
func (d *db.DataBases) GetNewestMsg(ID string) (msg *open_im_sdk.MsgData, err error) {
ctx, _ := context.WithTimeout(context.Background(), time.Duration(config.Config.Mongo.DBTimeout)*time.Second)
c := d.mongoClient.Database(config.Config.Mongo.DBDatabase).Collection(cChat)
regex := fmt.Sprintf("^%s", ID)
findOpts := options.Find().SetLimit(1).SetSort(bson.M{"uid": -1})
var userChats []UserChat
cursor, err := c.Find(ctx, bson.M{"uid": bson.M{"$regex": regex}}, findOpts)
if err != nil {
return nil, err
}
err = cursor.All(ctx, &userChats)
if err != nil {
return nil, utils.Wrap(err, "")
}
if len(userChats) > 0 {
if len(userChats[0].Msg) > 0 {
msgPb := &open_im_sdk.MsgData{}
err = proto.Unmarshal(userChats[0].Msg[len(userChats[0].Msg)-1].Msg, msgPb)
if err != nil {
return nil, utils.Wrap(err, "")
}
return msgPb, nil
}
return nil, errors.New("len(userChats[0].Msg) < 0")
}
return nil, nil
}
func (d *db.DataBases) GetOldestMsg(ID string) (msg *open_im_sdk.MsgData, err error) {
ctx, _ := context.WithTimeout(context.Background(), time.Duration(config.Config.Mongo.DBTimeout)*time.Second)
c := d.mongoClient.Database(config.Config.Mongo.DBDatabase).Collection(cChat)
regex := fmt.Sprintf("^%s", ID)
findOpts := options.Find().SetLimit(1).SetSort(bson.M{"uid": 1})
var userChats []UserChat
cursor, err := c.Find(ctx, bson.M{"uid": bson.M{"$regex": regex}}, findOpts)
if err != nil {
return nil, err
}
err = cursor.All(ctx, &userChats)
if err != nil {
return nil, utils.Wrap(err, "")
}
var oldestMsg []byte
if len(userChats) > 0 {
for _, v := range userChats[0].Msg {
if v.SendTime != 0 {
oldestMsg = v.Msg
break
}
}
if len(oldestMsg) == 0 {
oldestMsg = userChats[0].Msg[len(userChats[0].Msg)-1].Msg
}
msgPb := &open_im_sdk.MsgData{}
err = proto.Unmarshal(oldestMsg, msgPb)
if err != nil {
return nil, utils.Wrap(err, "")
}
return msgPb, nil
}
return nil, nil
}
func (d *db.DataBases) GetMsgBySeqListMongo2(uid string, seqList []uint32, operationID string) (seqMsg []*open_im_sdk.MsgData, err error) {
var hasSeqList []uint32
singleCount := 0
ctx, _ := context.WithTimeout(context.Background(), time.Duration(config.Config.Mongo.DBTimeout)*time.Second)
c := d.mongoClient.Database(config.Config.Mongo.DBDatabase).Collection(cChat)
m := func(uid string, seqList []uint32) map[string][]uint32 {
t := make(map[string][]uint32)
for i := 0; i < len(seqList); i++ {
seqUid := getSeqUid(uid, seqList[i])
if value, ok := t[seqUid]; !ok {
var temp []uint32
t[seqUid] = append(temp, seqList[i])
} else {
t[seqUid] = append(value, seqList[i])
}
}
return t
}(uid, seqList)
sChat := UserChat{}
for seqUid, value := range m {
if err = c.FindOne(ctx, bson.M{"uid": seqUid}).Decode(&sChat); err != nil {
log.NewError(operationID, "not find seqUid", seqUid, value, uid, seqList, err.Error())
continue
}
singleCount = 0
for i := 0; i < len(sChat.Msg); i++ {
msg := new(open_im_sdk.MsgData)
if err = proto.Unmarshal(sChat.Msg[i].Msg, msg); err != nil {
log.NewError(operationID, "Unmarshal err", seqUid, value, uid, seqList, err.Error())
return nil, err
}
if isContainInt32(msg.Seq, value) {
seqMsg = append(seqMsg, msg)
hasSeqList = append(hasSeqList, msg.Seq)
singleCount++
if singleCount == len(value) {
break
}
}
}
}
if len(hasSeqList) != len(seqList) {
var diff []uint32
diff = utils.Difference(hasSeqList, seqList)
exceptionMSg := genExceptionMessageBySeqList(diff)
seqMsg = append(seqMsg, exceptionMSg...)
}
return seqMsg, nil
}
func (d *db.DataBases) GetSuperGroupMsgBySeqListMongo(groupID string, seqList []uint32, operationID string) (seqMsg []*open_im_sdk.MsgData, err error) {
var hasSeqList []uint32
singleCount := 0
ctx, _ := context.WithTimeout(context.Background(), time.Duration(config.Config.Mongo.DBTimeout)*time.Second)
c := d.mongoClient.Database(config.Config.Mongo.DBDatabase).Collection(cChat)
m := func(uid string, seqList []uint32) map[string][]uint32 {
t := make(map[string][]uint32)
for i := 0; i < len(seqList); i++ {
seqUid := getSeqUid(uid, seqList[i])
if value, ok := t[seqUid]; !ok {
var temp []uint32
t[seqUid] = append(temp, seqList[i])
} else {
t[seqUid] = append(value, seqList[i])
}
}
return t
}(groupID, seqList)
sChat := UserChat{}
for seqUid, value := range m {
if err = c.FindOne(ctx, bson.M{"uid": seqUid}).Decode(&sChat); err != nil {
log.NewError(operationID, "not find seqGroupID", seqUid, value, groupID, seqList, err.Error())
continue
}
singleCount = 0
for i := 0; i < len(sChat.Msg); i++ {
msg := new(open_im_sdk.MsgData)
if err = proto.Unmarshal(sChat.Msg[i].Msg, msg); err != nil {
log.NewError(operationID, "Unmarshal err", seqUid, value, groupID, seqList, err.Error())
return nil, err
}
if isContainInt32(msg.Seq, value) {
seqMsg = append(seqMsg, msg)
hasSeqList = append(hasSeqList, msg.Seq)
singleCount++
if singleCount == len(value) {
break
}
}
}
}
if len(hasSeqList) != len(seqList) {
var diff []uint32
diff = utils.Difference(hasSeqList, seqList)
exceptionMSg := genExceptionSuperGroupMessageBySeqList(diff, groupID)
seqMsg = append(seqMsg, exceptionMSg...)
}
return seqMsg, nil
}
func (d *db.DataBases) GetMsgAndIndexBySeqListInOneMongo2(suffixUserID string, seqList []uint32, operationID string) (seqMsg []*open_im_sdk.MsgData, indexList []int, unexistSeqList []uint32, err error) {
ctx, _ := context.WithTimeout(context.Background(), time.Duration(config.Config.Mongo.DBTimeout)*time.Second)
c := d.mongoClient.Database(config.Config.Mongo.DBDatabase).Collection(cChat)
sChat := UserChat{}
if err = c.FindOne(ctx, bson.M{"uid": suffixUserID}).Decode(&sChat); err != nil {
log.NewError(operationID, "not find seqUid", suffixUserID, err.Error())
return nil, nil, nil, utils.Wrap(err, "")
}
singleCount := 0
var hasSeqList []uint32
for i := 0; i < len(sChat.Msg); i++ {
msg := new(open_im_sdk.MsgData)
if err = proto.Unmarshal(sChat.Msg[i].Msg, msg); err != nil {
log.NewError(operationID, "Unmarshal err", msg.String(), err.Error())
return nil, nil, nil, err
}
if isContainInt32(msg.Seq, seqList) {
indexList = append(indexList, i)
seqMsg = append(seqMsg, msg)
hasSeqList = append(hasSeqList, msg.Seq)
singleCount++
if singleCount == len(seqList) {
break
}
}
}
for _, i := range seqList {
if isContainInt32(i, hasSeqList) {
continue
}
unexistSeqList = append(unexistSeqList, i)
}
return seqMsg, indexList, unexistSeqList, nil
}
func genExceptionMessageBySeqList(seqList []uint32) (exceptionMsg []*open_im_sdk.MsgData) {
for _, v := range seqList {
msg := new(open_im_sdk.MsgData)
msg.Seq = v
exceptionMsg = append(exceptionMsg, msg)
}
return exceptionMsg
}
func genExceptionSuperGroupMessageBySeqList(seqList []uint32, groupID string) (exceptionMsg []*open_im_sdk.MsgData) {
for _, v := range seqList {
msg := new(open_im_sdk.MsgData)
msg.Seq = v
msg.GroupID = groupID
msg.SessionType = constant.SuperGroupChatType
exceptionMsg = append(exceptionMsg, msg)
}
return exceptionMsg
}
func (d *db.DataBases) SaveUserChatMongo2(uid string, sendTime int64, m *pbMsg.MsgDataToDB) error {
ctx, _ := context.WithTimeout(context.Background(), time.Duration(config.Config.Mongo.DBTimeout)*time.Second)
c := d.mongoClient.Database(config.Config.Mongo.DBDatabase).Collection(cChat)
newTime := getCurrentTimestampByMill()
operationID := ""
seqUid := getSeqUid(uid, m.MsgData.Seq)
filter := bson.M{"uid": seqUid}
var err error
sMsg := MsgInfo{}
sMsg.SendTime = sendTime
if sMsg.Msg, err = proto.Marshal(m.MsgData); err != nil {
return utils.Wrap(err, "")
}
err = c.FindOneAndUpdate(ctx, filter, bson.M{"$push": bson.M{"msg": sMsg}}).Err()
log.NewWarn(operationID, "get mgoSession cost time", getCurrentTimestampByMill()-newTime)
if err != nil {
sChat := UserChat{}
sChat.UID = seqUid
sChat.Msg = append(sChat.Msg, sMsg)
if _, err = c.InsertOne(ctx, &sChat); err != nil {
log.NewDebug(operationID, "InsertOne failed", filter)
return utils.Wrap(err, "")
}
} else {
log.NewDebug(operationID, "FindOneAndUpdate ok", filter)
}
log.NewDebug(operationID, "find mgo uid cost time", getCurrentTimestampByMill()-newTime)
return nil
}
func (d *db.DataBases) SaveUserChat(uid string, sendTime int64, m *pbMsg.MsgDataToDB) error {
var seqUid string
newTime := getCurrentTimestampByMill()
session := d.mgoSession.Clone()
if session == nil {
return errors.New("session == nil")
}
defer session.Close()
log.NewDebug("", "get mgoSession cost time", getCurrentTimestampByMill()-newTime)
c := session.DB(config.Config.Mongo.DBDatabase).C(cChat)
seqUid = getSeqUid(uid, m.MsgData.Seq)
n, err := c.Find(bson.M{"uid": seqUid}).Count()
if err != nil {
return err
}
log.NewDebug("", "find mgo uid cost time", getCurrentTimestampByMill()-newTime)
sMsg := MsgInfo{}
sMsg.SendTime = sendTime
if sMsg.Msg, err = proto.Marshal(m.MsgData); err != nil {
return err
}
if n == 0 {
sChat := UserChat{}
sChat.UID = seqUid
sChat.Msg = append(sChat.Msg, sMsg)
err = c.Insert(&sChat)
if err != nil {
return err
}
} else {
err = c.Update(bson.M{"uid": seqUid}, bson.M{"$push": bson.M{"msg": sMsg}})
if err != nil {
return err
}
}
log.NewDebug("", "insert mgo data cost time", getCurrentTimestampByMill()-newTime)
return nil
}
func (d *db.DataBases) DelUserChatMongo2(uid string) error {
ctx, _ := context.WithTimeout(context.Background(), time.Duration(config.Config.Mongo.DBTimeout)*time.Second)
c := d.mongoClient.Database(config.Config.Mongo.DBDatabase).Collection(cChat)
filter := bson.M{"uid": uid}
delTime := time.Now().Unix() - int64(config.Config.Mongo.DBRetainChatRecords)*24*3600
if _, err := c.UpdateOne(ctx, filter, bson.M{"$pull": bson.M{"msg": bson.M{"sendtime": bson.M{"$lte": delTime}}}}); err != nil {
return utils.Wrap(err, "")
}
return nil
}
func (d *db.DataBases) MgoSkipUID(count int) (string, error) {
return "", nil
}
func (d *db.DataBases) CleanUpUserMsgFromMongo(userID string, operationID string) error {
ctx := context.Background()
c := d.mongoClient.Database(config.Config.Mongo.DBDatabase).Collection(cChat)
maxSeq, err := d.GetUserMaxSeq(userID)
if err == redis.Nil {
return nil
}
if err != nil {
return utils.Wrap(err, "")
}
seqUsers := getSeqUserIDList(userID, uint32(maxSeq))
log.Error(operationID, "getSeqUserIDList", seqUsers)
_, err = c.DeleteMany(ctx, bson.M{"uid": bson.M{"$in": seqUsers}})
if err == mongo.ErrNoDocuments {
return nil
}
return utils.Wrap(err, "")
}
-14
View File
@@ -111,20 +111,6 @@ type SuperGroupMongoDriver struct {
// panic("implement me")
// }
func (s *SuperGroupMongoDriver) Transaction(ctx context.Context, fn func(s unrelation.SuperGroupModelInterface, tx any) error) error {
sess, err := s.MgoClient.StartSession()
if err != nil {
return err
}
txCtx := mongo.NewSessionContext(ctx, sess)
defer sess.EndSession(txCtx)
if err := fn(s, txCtx); err != nil {
_ = sess.AbortTransaction(txCtx)
return err
}
return utils.Wrap(sess.CommitTransaction(txCtx), "")
}
func (s *SuperGroupMongoDriver) getTxCtx(ctx context.Context, tx []any) context.Context {
if len(tx) > 0 {
if ctx, ok := tx[0].(mongo.SessionContext); ok {
+7
View File
@@ -7,6 +7,9 @@ import (
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"math/rand"
"strconv"
"time"
)
type TagMongoDriver struct {
@@ -19,6 +22,10 @@ func NewTagMongoDriver(mgoDB *mongo.Database) *TagMongoDriver {
return &TagMongoDriver{mgoDB: mgoDB, TagCollection: mgoDB.Collection(unrelation.CTag), TagSendLogCollection: mgoDB.Collection(unrelation.CSendLog)}
}
func (db *TagMongoDriver) generateTagID(tagName, userID string) string {
return utils.Md5(tagName + userID + strconv.Itoa(rand.Int()) + time.Now().String())
}
func (db *TagMongoDriver) GetUserTags(ctx context.Context, userID string) ([]unrelation.TagModel, error) {
var tags []unrelation.TagModel
cursor, err := db.TagCollection.Find(ctx, bson.M{"user_id": userID})
+12 -1
View File
@@ -4,10 +4,13 @@ import (
"Open_IM/pkg/common/config"
"Open_IM/pkg/common/constant"
"Open_IM/pkg/common/db/table/unrelation"
"Open_IM/pkg/utils"
"context"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"math/rand"
"strconv"
"time"
)
@@ -20,8 +23,16 @@ func NewWorkMomentMongoDriver(mgoDB *mongo.Database) *WorkMomentMongoDriver {
return &WorkMomentMongoDriver{mgoDB: mgoDB, WorkMomentCollection: mgoDB.Collection(unrelation.CWorkMoment)}
}
func (db *WorkMomentMongoDriver) generateWorkMomentID(userID string) string {
return utils.Md5(userID + strconv.Itoa(rand.Int()) + time.Now().String())
}
func (db *WorkMomentMongoDriver) generateWorkMomentCommentID(workMomentID string) string {
return utils.Md5(workMomentID + strconv.Itoa(rand.Int()) + time.Now().String())
}
func (db *WorkMomentMongoDriver) CreateOneWorkMoment(ctx context.Context, workMoment *unrelation.WorkMoment) error {
workMomentID := generateWorkMomentID(workMoment.UserID)
workMomentID := db.generateWorkMomentID(workMoment.UserID)
workMoment.WorkMomentID = workMomentID
workMoment.CreateTime = int32(time.Now().Unix())
_, err := db.WorkMomentCollection.InsertOne(ctx, workMoment)