This commit is contained in:
wangchuxiao
2023-03-23 19:02:20 +08:00
parent 3e15014e0a
commit 132e1b987c
33 changed files with 818 additions and 785 deletions
+44 -114
View File
@@ -2,7 +2,6 @@ package controller
import (
"context"
"encoding/json"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache"
@@ -12,10 +11,8 @@ import (
)
type ConversationDatabase interface {
//GetUserIDExistConversation 获取拥有该会话的的用户ID列表
GetUserIDExistConversation(ctx context.Context, userIDList []string, conversationID string) ([]string, error)
//UpdateUserConversationFiled 更新用户该会话的属性信息
UpdateUsersConversationFiled(ctx context.Context, UserIDList []string, conversationID string, args map[string]interface{}) error
UpdateUsersConversationFiled(ctx context.Context, userIDs []string, conversationID string, args map[string]interface{}) error
//CreateConversation 创建一批新的会话
CreateConversation(ctx context.Context, conversations []*relationTb.ConversationModel) error
//SyncPeerUserPrivateConversation 同步对端私聊会话内部保证事务操作
@@ -29,7 +26,7 @@ type ConversationDatabase interface {
//SetUserConversations 设置用户多个会话属性,如果会话不存在则创建,否则更新,内部保证原子性
SetUserConversations(ctx context.Context, ownerUserID string, conversations []*relationTb.ConversationModel) error
//SetUsersConversationFiledTx 设置多个用户会话关于某个字段的更新操作,如果会话不存在则创建,否则更新,内部保证事务操作
SetUsersConversationFiledTx(ctx context.Context, userIDList []string, conversation *relationTb.ConversationModel, filedMap map[string]interface{}) error
SetUsersConversationFiledTx(ctx context.Context, userIDs []string, conversation *relationTb.ConversationModel, filedMap map[string]interface{}) error
}
func NewConversationDatabase(conversation relationTb.ConversationModelInterface, cache cache.ConversationCache, tx tx.Tx) ConversationDatabase {
@@ -46,22 +43,22 @@ type ConversationDataBase struct {
tx tx.Tx
}
func (c *ConversationDataBase) SetUsersConversationFiledTx(ctx context.Context, userIDList []string, conversation *relationTb.ConversationModel, filedMap map[string]interface{}) error {
func (c *ConversationDataBase) SetUsersConversationFiledTx(ctx context.Context, userIDs []string, conversation *relationTb.ConversationModel, filedMap map[string]interface{}) error {
return c.tx.Transaction(func(tx any) error {
conversationTx := c.conversationDB.NewTx(tx)
haveUserID, err := conversationTx.FindUserID(ctx, userIDList, conversation.ConversationID)
haveUserIDs, err := conversationTx.FindUserID(ctx, userIDs, conversation.ConversationID)
if err != nil {
return err
}
if len(haveUserID) > 0 {
err = conversationTx.UpdateByMap(ctx, haveUserID, conversation.ConversationID, filedMap)
if len(haveUserIDs) > 0 {
err = conversationTx.UpdateByMap(ctx, haveUserIDs, conversation.ConversationID, filedMap)
if err != nil {
return err
}
}
NotUserID := utils.DifferenceString(haveUserID, userIDList)
NotUserIDs := utils.DifferenceString(haveUserIDs, userIDs)
var cList []*relationTb.ConversationModel
for _, v := range NotUserID {
for _, v := range NotUserIDs {
temp := new(relationTb.ConversationModel)
if err := utils.CopyStructFields(temp, conversation); err != nil {
return err
@@ -73,26 +70,17 @@ func (c *ConversationDataBase) SetUsersConversationFiledTx(ctx context.Context,
if err != nil {
return err
}
if len(NotUserID) > 0 {
err = c.cache.DelUsersConversationIDs(ctx, NotUserID)
if err != nil {
return err
}
}
err = c.cache.DelUsersConversation(ctx, haveUserID, conversation.ConversationID)
if err != nil {
return err
}
return nil
// clear cache
return c.cache.DelConversationIDs(NotUserIDs).DelUsersConversation(haveUserIDs, conversation.ConversationID).ExecDel(ctx)
})
}
func (c *ConversationDataBase) GetUserIDExistConversation(ctx context.Context, userIDList []string, conversationID string) ([]string, error) {
panic("implement me")
}
func (c *ConversationDataBase) UpdateUsersConversationFiled(ctx context.Context, UserIDList []string, conversationID string, args map[string]interface{}) error {
panic("implement me")
func (c *ConversationDataBase) UpdateUsersConversationFiled(ctx context.Context, userIDs []string, conversationID string, args map[string]interface{}) error {
err := c.conversationDB.UpdateByMap(ctx, userIDs, conversationID, args)
if err != nil {
return err
}
return c.cache.DelUsersConversation(userIDs, conversationID).ExecDel(ctx)
}
func (c *ConversationDataBase) CreateConversation(ctx context.Context, conversations []*relationTb.ConversationModel) error {
@@ -100,7 +88,6 @@ func (c *ConversationDataBase) CreateConversation(ctx context.Context, conversat
if err := c.conversationDB.NewTx(tx).Create(ctx, conversations); err != nil {
return err
}
// clear cache
return nil
})
}
@@ -109,20 +96,20 @@ func (c *ConversationDataBase) SyncPeerUserPrivateConversationTx(ctx context.Con
return c.tx.Transaction(func(tx any) error {
userIDList := []string{conversation.OwnerUserID, conversation.UserID}
conversationTx := c.conversationDB.NewTx(tx)
haveUserID, err := conversationTx.FindUserID(ctx, userIDList, conversation.ConversationID)
haveUserIDs, err := conversationTx.FindUserID(ctx, userIDList, conversation.ConversationID)
if err != nil {
return err
}
filedMap := map[string]interface{}{"is_private_chat": conversation.IsPrivateChat}
if len(haveUserID) > 0 {
err = conversationTx.UpdateByMap(ctx, haveUserID, conversation.ConversationID, filedMap)
if len(haveUserIDs) > 0 {
err = conversationTx.UpdateByMap(ctx, haveUserIDs, conversation.ConversationID, filedMap)
if err != nil {
return err
}
}
NotUserID := utils.DifferenceString(haveUserID, userIDList)
NotUserIDs := utils.DifferenceString(haveUserIDs, userIDList)
var cList []*relationTb.ConversationModel
for _, v := range NotUserID {
for _, v := range NotUserIDs {
temp := new(relationTb.ConversationModel)
if v == conversation.UserID {
temp.OwnerUserID = conversation.UserID
@@ -138,128 +125,71 @@ func (c *ConversationDataBase) SyncPeerUserPrivateConversationTx(ctx context.Con
}
cList = append(cList, temp)
}
if len(NotUserID) > 0 {
if len(NotUserIDs) > 0 {
err = c.conversationDB.Create(ctx, cList)
if err != nil {
return err
}
}
err = c.cache.DelUsersConversationIDs(ctx, NotUserID)
if err != nil {
return err
}
err = c.cache.DelUsersConversation(ctx, haveUserID, conversation.ConversationID)
if err != nil {
return err
}
return nil
// clear cache
return c.cache.DelConversationIDs(NotUserIDs).DelUsersConversation(haveUserIDs, conversation.ConversationID).ExecDel(ctx)
})
}
func (c *ConversationDataBase) FindConversations(ctx context.Context, ownerUserID string, conversationIDs []string) ([]*relationTb.ConversationModel, error) {
getConversation := func() (string, error) {
conversationList, err := c.conversationDB.Find(ctx, ownerUserID, conversationIDs)
if err != nil {
return "", utils.Wrap(err, "get failed")
}
bytes, err := json.Marshal(conversationList)
if err != nil {
return "", utils.Wrap(err, "Marshal failed")
}
return string(bytes), nil
}
return c.cache.GetConversations(ctx, ownerUserID, conversationIDs, getConversation)
return c.cache.GetConversations(ctx, ownerUserID, conversationIDs)
}
func (c *ConversationDataBase) GetConversation(ctx context.Context, ownerUserID string, conversationID string) (*relationTb.ConversationModel, error) {
getConversation := func() (string, error) {
conversationList, err := c.conversationDB.Take(ctx, ownerUserID, conversationID)
if err != nil {
return "", utils.Wrap(err, "get failed")
}
bytes, err := json.Marshal(conversationList)
if err != nil {
return "", utils.Wrap(err, "Marshal failed")
}
return string(bytes), nil
}
return c.cache.GetConversation(ctx, ownerUserID, conversationID, getConversation)
return c.cache.GetConversation(ctx, ownerUserID, conversationID)
}
func (c *ConversationDataBase) GetUserAllConversation(ctx context.Context, ownerUserID string) ([]*relationTb.ConversationModel, error) {
getConversationIDs := func() (string, error) {
conversationIDs, err := c.conversationDB.FindUserIDAllConversationID(ctx, ownerUserID)
if err != nil {
return "", utils.Wrap(err, "getConversationIDList failed")
}
bytes, err := json.Marshal(conversationIDs)
if err != nil {
return "", utils.Wrap(err, "")
}
return string(bytes), nil
}
conversationIDList, err := c.cache.GetUserConversationIDs(ctx, ownerUserID, getConversationIDs)
if err != nil {
return nil, err
}
var conversations []*relationTb.ConversationModel
for _, conversationID := range conversationIDList {
conversation, err := c.GetConversation(ctx, ownerUserID, conversationID)
if err != nil {
return nil, utils.Wrap(err, "GetConversation failed")
}
conversations = append(conversations, conversation)
}
return conversations, nil
return c.cache.GetUserAllConversations(ctx, ownerUserID)
}
func (c *ConversationDataBase) SetUserConversations(ctx context.Context, ownerUserID string, conversations []*relationTb.ConversationModel) error {
return c.tx.Transaction(func(tx any) error {
var conversationIDList []string
var conversationIDs []string
for _, conversation := range conversations {
conversationIDList = append(conversationIDList, conversation.ConversationID)
conversationIDs = append(conversationIDs, conversation.ConversationID)
}
conversationTx := c.conversationDB.NewTx(tx)
haveConversations, err := conversationTx.Find(ctx, ownerUserID, conversationIDList)
existConversations, err := conversationTx.Find(ctx, ownerUserID, conversationIDs)
if err != nil {
return err
}
if len(haveConversations) > 0 {
if len(existConversations) > 0 {
err = conversationTx.Update(ctx, conversations)
if err != nil {
return err
}
}
var haveConversationID []string
for _, conversation := range haveConversations {
haveConversationID = append(haveConversationID, conversation.ConversationID)
var existConversationIDs []string
for _, conversation := range existConversations {
existConversationIDs = append(existConversationIDs, conversation.ConversationID)
}
NotConversationID := utils.DifferenceString(haveConversationID, conversationIDList)
var NotConversations []*relationTb.ConversationModel
var notExistConversations []*relationTb.ConversationModel
for _, conversation := range conversations {
if !utils.IsContain(conversation.ConversationID, haveConversationID) {
NotConversations = append(NotConversations, conversation)
if !utils.IsContain(conversation.ConversationID, existConversationIDs) {
notExistConversations = append(notExistConversations, conversation)
}
}
if len(NotConversations) > 0 {
err = c.conversationDB.Create(ctx, NotConversations)
if len(notExistConversations) > 0 {
err = c.conversationDB.Create(ctx, notExistConversations)
if err != nil {
return err
}
}
err = c.cache.DelUsersConversationIDs(ctx, NotConversationID)
if err != nil {
return err
cache := c.cache.NewCache()
if len(notExistConversations) > 0 {
cache = cache.DelConversationIDs([]string{ownerUserID})
}
err = c.cache.DelUserConversations(ctx, ownerUserID, haveConversationID)
if err != nil {
return err
}
return nil
return cache.DelConvsersations(ownerUserID, existConversationIDs).ExecDel(ctx)
})
}
func (c *ConversationDataBase) FindRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) ([]string, error) {
return c.conversationDB.FindRecvMsgNotNotifyUserIDs(ctx, groupID)
return c.cache.GetSuperGroupRecvMsgNotNotifyUserIDs(ctx, groupID)
}