mirror of
https://github.com/openimsdk/open-im-server.git
synced 2026-05-03 08:35:59 +08:00
feat: Remove MySQL and implement it all with Mongo (#1508)
* fix: GetUserReqApplicationList error when there is a disbanded group chat
* fix: error when querying some information about disbanded group
* fix: GetUserReqApplicationList dismissed group error
* fix: the original message referenced by the pull message processing is withdrawn
* fix: the original message referenced by the pull message processing is withdrawn
* fix: the original message referenced by the pull message processing is withdrawn
* fix: the original message referenced by the pull message processing is withdrawn
* fix: the original message referenced by the pull message processing is withdrawn
* fix: the original message referenced by the pull message processing is withdrawn
* fix: the original message referenced by the pull message processing is withdrawn
* fix: the original message referenced by the pull message processing is withdrawn
* fix: the original message referenced by the pull message processing is withdrawn
* merge
* cicd: robot automated Change
* sdkws.MsgData
* user
* interface{} -> any
* user
* third
* group
* group
* group
* group
* group
* group
* conversation
* standalone mysql db model
* tx
* s3
* group
* mongo
* group
* group
* group
* group
* group
* group
* refactor: add openim mysql to mongo refactor
Signed-off-by: Xinwei Xiong(cubxxw) <3293172751nss@gmail.com>
* refactor: add openim mysql to mongo refactor
Signed-off-by: Xinwei Xiong(cubxxw) <3293172751nss@gmail.com>
* remove mysql
* remove mysql
* friend
* friend
* friend
* friend
* friend
* friend
* group
* convert
* index
* index
* all
* all
* mysql2mongo
* data conversion
* up35
* up35
* feat: add format set
Signed-off-by: Xinwei Xiong(cubxxw) <3293172751nss@gmail.com>
* fix: fix scripts
Signed-off-by: Xinwei Xiong(cubxxw) <3293172751nss@gmail.com>
* merge main
* merge main
* Update init-config.sh
* fix: user args check
---------
Signed-off-by: Xinwei Xiong(cubxxw) <3293172751nss@gmail.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>
Co-authored-by: Xinwei Xiong(cubxxw) <3293172751nss@gmail.com>
Co-authored-by: Xinwei Xiong <3293172751@qq.com>
This commit is contained in:
@@ -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).
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
@@ -18,6 +18,8 @@ import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/OpenIMSDK/tools/pagination"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/msgprocessor"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/constant"
|
||||
@@ -31,7 +33,7 @@ import (
|
||||
|
||||
type ConversationDatabase interface {
|
||||
// UpdateUserConversationFiled 更新用户该会话的属性信息
|
||||
UpdateUsersConversationFiled(ctx context.Context, userIDs []string, conversationID string, args map[string]interface{}) error
|
||||
UpdateUsersConversationFiled(ctx context.Context, userIDs []string, conversationID string, args map[string]any) error
|
||||
// CreateConversation 创建一批新的会话
|
||||
CreateConversation(ctx context.Context, conversations []*relationtb.ConversationModel) error
|
||||
// SyncPeerUserPrivateConversation 同步对端私聊会话内部保证事务操作
|
||||
@@ -39,26 +41,26 @@ type ConversationDatabase interface {
|
||||
// FindConversations 根据会话ID获取某个用户的多个会话
|
||||
FindConversations(ctx context.Context, ownerUserID string, conversationIDs []string) ([]*relationtb.ConversationModel, error)
|
||||
// FindRecvMsgNotNotifyUserIDs 获取超级大群开启免打扰的用户ID
|
||||
FindRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) ([]string, error)
|
||||
//FindRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) ([]string, error)
|
||||
// GetUserAllConversation 获取一个用户在服务器上所有的会话
|
||||
GetUserAllConversation(ctx context.Context, ownerUserID string) ([]*relationtb.ConversationModel, error)
|
||||
// SetUserConversations 设置用户多个会话属性,如果会话不存在则创建,否则更新,内部保证原子性
|
||||
SetUserConversations(ctx context.Context, ownerUserID string, conversations []*relationtb.ConversationModel) error
|
||||
// SetUsersConversationFiledTx 设置多个用户会话关于某个字段的更新操作,如果会话不存在则创建,否则更新,内部保证事务操作
|
||||
SetUsersConversationFiledTx(ctx context.Context, userIDs []string, conversation *relationtb.ConversationModel, filedMap map[string]interface{}) error
|
||||
SetUsersConversationFiledTx(ctx context.Context, userIDs []string, conversation *relationtb.ConversationModel, filedMap map[string]any) error
|
||||
CreateGroupChatConversation(ctx context.Context, groupID string, userIDs []string) error
|
||||
GetConversationIDs(ctx context.Context, userID string) ([]string, error)
|
||||
GetUserConversationIDsHash(ctx context.Context, ownerUserID string) (hash uint64, err error)
|
||||
GetAllConversationIDs(ctx context.Context) ([]string, error)
|
||||
GetAllConversationIDsNumber(ctx context.Context) (int64, error)
|
||||
PageConversationIDs(ctx context.Context, pageNumber, showNumber int32) (conversationIDs []string, err error)
|
||||
PageConversationIDs(ctx context.Context, pagination pagination.Pagination) (conversationIDs []string, err error)
|
||||
//GetUserAllHasReadSeqs(ctx context.Context, ownerUserID string) (map[string]int64, error)
|
||||
GetConversationsByConversationID(ctx context.Context, conversationIDs []string) ([]*relationtb.ConversationModel, error)
|
||||
GetConversationIDsNeedDestruct(ctx context.Context) ([]*relationtb.ConversationModel, error)
|
||||
GetConversationNotReceiveMessageUserIDs(ctx context.Context, conversationID string) ([]string, error)
|
||||
}
|
||||
|
||||
func NewConversationDatabase(conversation relationtb.ConversationModelInterface, cache cache.ConversationCache, tx tx.Tx) ConversationDatabase {
|
||||
func NewConversationDatabase(conversation relationtb.ConversationModelInterface, cache cache.ConversationCache, tx tx.CtxTx) ConversationDatabase {
|
||||
return &conversationDatabase{
|
||||
conversationDB: conversation,
|
||||
cache: cache,
|
||||
@@ -69,22 +71,21 @@ func NewConversationDatabase(conversation relationtb.ConversationModelInterface,
|
||||
type conversationDatabase struct {
|
||||
conversationDB relationtb.ConversationModelInterface
|
||||
cache cache.ConversationCache
|
||||
tx tx.Tx
|
||||
tx tx.CtxTx
|
||||
}
|
||||
|
||||
func (c *conversationDatabase) SetUsersConversationFiledTx(ctx context.Context, userIDs []string, conversation *relationtb.ConversationModel, filedMap map[string]interface{}) (err error) {
|
||||
cache := c.cache.NewCache()
|
||||
if conversation.GroupID != "" {
|
||||
cache = cache.DelSuperGroupRecvMsgNotNotifyUserIDs(conversation.GroupID).DelSuperGroupRecvMsgNotNotifyUserIDsHash(conversation.GroupID)
|
||||
}
|
||||
if err := c.tx.Transaction(func(tx any) error {
|
||||
conversationTx := c.conversationDB.NewTx(tx)
|
||||
haveUserIDs, err := conversationTx.FindUserID(ctx, userIDs, []string{conversation.ConversationID})
|
||||
func (c *conversationDatabase) SetUsersConversationFiledTx(ctx context.Context, userIDs []string, conversation *relationtb.ConversationModel, filedMap map[string]any) (err error) {
|
||||
return c.tx.Transaction(ctx, func(ctx context.Context) error {
|
||||
cache := c.cache.NewCache()
|
||||
if conversation.GroupID != "" {
|
||||
cache = cache.DelSuperGroupRecvMsgNotNotifyUserIDs(conversation.GroupID).DelSuperGroupRecvMsgNotNotifyUserIDsHash(conversation.GroupID)
|
||||
}
|
||||
haveUserIDs, err := c.conversationDB.FindUserID(ctx, userIDs, []string{conversation.ConversationID})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(haveUserIDs) > 0 {
|
||||
_, err = conversationTx.UpdateByMap(ctx, haveUserIDs, conversation.ConversationID, filedMap)
|
||||
_, err = c.conversationDB.UpdateByMap(ctx, haveUserIDs, conversation.ConversationID, filedMap)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -112,20 +113,17 @@ func (c *conversationDatabase) SetUsersConversationFiledTx(ctx context.Context,
|
||||
conversations = append(conversations, temp)
|
||||
}
|
||||
if len(conversations) > 0 {
|
||||
err = conversationTx.Create(ctx, conversations)
|
||||
err = c.conversationDB.Create(ctx, conversations)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cache = cache.DelConversationIDs(NotUserIDs...).DelUserConversationIDsHash(NotUserIDs...).DelConversations(conversation.ConversationID, NotUserIDs...)
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return cache.ExecDel(ctx)
|
||||
return cache.ExecDel(ctx)
|
||||
})
|
||||
}
|
||||
|
||||
func (c *conversationDatabase) UpdateUsersConversationFiled(ctx context.Context, userIDs []string, conversationID string, args map[string]interface{}) error {
|
||||
func (c *conversationDatabase) UpdateUsersConversationFiled(ctx context.Context, userIDs []string, conversationID string, args map[string]any) error {
|
||||
_, err := c.conversationDB.UpdateByMap(ctx, userIDs, conversationID, args)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -153,19 +151,18 @@ func (c *conversationDatabase) CreateConversation(ctx context.Context, conversat
|
||||
}
|
||||
|
||||
func (c *conversationDatabase) SyncPeerUserPrivateConversationTx(ctx context.Context, conversations []*relationtb.ConversationModel) error {
|
||||
cache := c.cache.NewCache()
|
||||
if err := c.tx.Transaction(func(tx any) error {
|
||||
conversationTx := c.conversationDB.NewTx(tx)
|
||||
return c.tx.Transaction(ctx, func(ctx context.Context) error {
|
||||
cache := c.cache.NewCache()
|
||||
for _, conversation := range conversations {
|
||||
for _, v := range [][2]string{{conversation.OwnerUserID, conversation.UserID}, {conversation.UserID, conversation.OwnerUserID}} {
|
||||
ownerUserID := v[0]
|
||||
userID := v[1]
|
||||
haveUserIDs, err := conversationTx.FindUserID(ctx, []string{ownerUserID}, []string{conversation.ConversationID})
|
||||
haveUserIDs, err := c.conversationDB.FindUserID(ctx, []string{ownerUserID}, []string{conversation.ConversationID})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(haveUserIDs) > 0 {
|
||||
_, err := conversationTx.UpdateByMap(ctx, []string{ownerUserID}, conversation.ConversationID, map[string]interface{}{"is_private_chat": conversation.IsPrivateChat})
|
||||
_, err := c.conversationDB.UpdateByMap(ctx, []string{ownerUserID}, conversation.ConversationID, map[string]any{"is_private_chat": conversation.IsPrivateChat})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -176,18 +173,15 @@ func (c *conversationDatabase) SyncPeerUserPrivateConversationTx(ctx context.Con
|
||||
newConversation.UserID = userID
|
||||
newConversation.ConversationID = conversation.ConversationID
|
||||
newConversation.IsPrivateChat = conversation.IsPrivateChat
|
||||
if err := conversationTx.Create(ctx, []*relationtb.ConversationModel{&newConversation}); err != nil {
|
||||
if err := c.conversationDB.Create(ctx, []*relationtb.ConversationModel{&newConversation}); err != nil {
|
||||
return err
|
||||
}
|
||||
cache = cache.DelConversationIDs(ownerUserID).DelUserConversationIDsHash(ownerUserID)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return cache.ExecDel(ctx)
|
||||
return cache.ExecDel(ctx)
|
||||
})
|
||||
}
|
||||
|
||||
func (c *conversationDatabase) FindConversations(ctx context.Context, ownerUserID string, conversationIDs []string) ([]*relationtb.ConversationModel, error) {
|
||||
@@ -203,28 +197,26 @@ func (c *conversationDatabase) GetUserAllConversation(ctx context.Context, owner
|
||||
}
|
||||
|
||||
func (c *conversationDatabase) SetUserConversations(ctx context.Context, ownerUserID string, conversations []*relationtb.ConversationModel) error {
|
||||
cache := c.cache.NewCache()
|
||||
|
||||
groupIDs := utils.Distinct(utils.Filter(conversations, func(e *relationtb.ConversationModel) (string, bool) {
|
||||
return e.GroupID, e.GroupID != ""
|
||||
}))
|
||||
for _, groupID := range groupIDs {
|
||||
cache = cache.DelSuperGroupRecvMsgNotNotifyUserIDs(groupID).DelSuperGroupRecvMsgNotNotifyUserIDsHash(groupID)
|
||||
}
|
||||
if err := c.tx.Transaction(func(tx any) error {
|
||||
return c.tx.Transaction(ctx, func(ctx context.Context) error {
|
||||
cache := c.cache.NewCache()
|
||||
groupIDs := utils.Distinct(utils.Filter(conversations, func(e *relationtb.ConversationModel) (string, bool) {
|
||||
return e.GroupID, e.GroupID != ""
|
||||
}))
|
||||
for _, groupID := range groupIDs {
|
||||
cache = cache.DelSuperGroupRecvMsgNotNotifyUserIDs(groupID).DelSuperGroupRecvMsgNotNotifyUserIDsHash(groupID)
|
||||
}
|
||||
var conversationIDs []string
|
||||
for _, conversation := range conversations {
|
||||
conversationIDs = append(conversationIDs, conversation.ConversationID)
|
||||
cache = cache.DelConversations(conversation.OwnerUserID, conversation.ConversationID)
|
||||
}
|
||||
conversationTx := c.conversationDB.NewTx(tx)
|
||||
existConversations, err := conversationTx.Find(ctx, ownerUserID, conversationIDs)
|
||||
existConversations, err := c.conversationDB.Find(ctx, ownerUserID, conversationIDs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(existConversations) > 0 {
|
||||
for _, conversation := range conversations {
|
||||
err = conversationTx.Update(ctx, conversation)
|
||||
err = c.conversationDB.Update(ctx, conversation)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -246,23 +238,22 @@ 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 nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return cache.ExecDel(ctx)
|
||||
return cache.ExecDel(ctx)
|
||||
})
|
||||
}
|
||||
|
||||
func (c *conversationDatabase) FindRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) ([]string, error) {
|
||||
return c.cache.GetSuperGroupRecvMsgNotNotifyUserIDs(ctx, groupID)
|
||||
}
|
||||
//func (c *conversationDatabase) FindRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) ([]string, error) {
|
||||
// return c.cache.GetSuperGroupRecvMsgNotNotifyUserIDs(ctx, groupID)
|
||||
//}
|
||||
|
||||
func (c *conversationDatabase) CreateGroupChatConversation(ctx context.Context, groupID string, userIDs []string) error {
|
||||
cache := c.cache.NewCache()
|
||||
conversationID := msgprocessor.GetConversationIDBySessionType(constant.SuperGroupChatType, groupID)
|
||||
if err := c.tx.Transaction(func(tx any) error {
|
||||
return c.tx.Transaction(ctx, func(ctx context.Context) error {
|
||||
cache := c.cache.NewCache()
|
||||
conversationID := msgprocessor.GetConversationIDBySessionType(constant.SuperGroupChatType, groupID)
|
||||
existConversationUserIDs, err := c.conversationDB.FindUserID(ctx, userIDs, []string{conversationID})
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -281,18 +272,15 @@ func (c *conversationDatabase) CreateGroupChatConversation(ctx context.Context,
|
||||
return err
|
||||
}
|
||||
}
|
||||
_, err = c.conversationDB.UpdateByMap(ctx, existConversationUserIDs, conversationID, map[string]interface{}{"max_seq": 0})
|
||||
_, err = c.conversationDB.UpdateByMap(ctx, existConversationUserIDs, conversationID, map[string]any{"max_seq": 0})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, v := range existConversationUserIDs {
|
||||
cache = cache.DelConversations(v, conversationID)
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return cache.ExecDel(ctx)
|
||||
return c.cache.ExecDel(ctx)
|
||||
})
|
||||
}
|
||||
|
||||
func (c *conversationDatabase) GetConversationIDs(ctx context.Context, userID string) ([]string, error) {
|
||||
@@ -311,14 +299,10 @@ func (c *conversationDatabase) GetAllConversationIDsNumber(ctx context.Context)
|
||||
return c.conversationDB.GetAllConversationIDsNumber(ctx)
|
||||
}
|
||||
|
||||
func (c *conversationDatabase) PageConversationIDs(ctx context.Context, pageNumber, showNumber int32) ([]string, error) {
|
||||
return c.conversationDB.PageConversationIDs(ctx, pageNumber, showNumber)
|
||||
func (c *conversationDatabase) PageConversationIDs(ctx context.Context, pagination pagination.Pagination) ([]string, error) {
|
||||
return c.conversationDB.PageConversationIDs(ctx, pagination)
|
||||
}
|
||||
|
||||
//func (c *conversationDatabase) GetUserAllHasReadSeqs(ctx context.Context, ownerUserID string) (map[string]int64, error) {
|
||||
// return c.cache.GetUserAllHasReadSeqs(ctx, ownerUserID)
|
||||
//}
|
||||
|
||||
func (c *conversationDatabase) GetConversationsByConversationID(ctx context.Context, conversationIDs []string) ([]*relationtb.ConversationModel, error) {
|
||||
return c.conversationDB.GetConversationsByConversationID(ctx, conversationIDs)
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
m := make(map[string]interface{}, 1)
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
+157
-318
@@ -16,23 +16,18 @@ package controller
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/OpenIMSDK/tools/pagination"
|
||||
"github.com/dtm-labs/rockscache"
|
||||
"github.com/redis/go-redis/v9"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"gorm.io/gorm"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/constant"
|
||||
"github.com/OpenIMSDK/tools/tx"
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
"github.com/redis/go-redis/v9"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/relation"
|
||||
relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
unrelationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/unrelation"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation"
|
||||
)
|
||||
|
||||
type GroupDatabase interface {
|
||||
@@ -40,23 +35,26 @@ type GroupDatabase interface {
|
||||
CreateGroup(ctx context.Context, groups []*relationtb.GroupModel, groupMembers []*relationtb.GroupMemberModel) error
|
||||
TakeGroup(ctx context.Context, groupID string) (group *relationtb.GroupModel, err error)
|
||||
FindGroup(ctx context.Context, groupIDs []string) (groups []*relationtb.GroupModel, err error)
|
||||
FindNotDismissedGroup(ctx context.Context, groupIDs []string) (groups []*relationtb.GroupModel, err error)
|
||||
SearchGroup(ctx context.Context, keyword string, pageNumber, showNumber int32) (uint32, []*relationtb.GroupModel, error)
|
||||
SearchGroup(ctx context.Context, keyword string, pagination pagination.Pagination) (int64, []*relationtb.GroupModel, error)
|
||||
UpdateGroup(ctx context.Context, groupID string, data map[string]any) error
|
||||
DismissGroup(ctx context.Context, groupID string, deleteMember bool) error // 解散群,并删除群成员
|
||||
GetGroupIDsByGroupType(ctx context.Context, groupType int) (groupIDs []string, err error)
|
||||
// GroupMember
|
||||
|
||||
TakeGroupMember(ctx context.Context, groupID string, userID string) (groupMember *relationtb.GroupMemberModel, err error)
|
||||
TakeGroupOwner(ctx context.Context, groupID string) (*relationtb.GroupMemberModel, error)
|
||||
FindGroupMember(ctx context.Context, groupIDs []string, userIDs []string, roleLevels []int32) ([]*relationtb.GroupMemberModel, error)
|
||||
FindGroupMembers(ctx context.Context, groupID string, userIDs []string) (groupMembers []*relationtb.GroupMemberModel, err error) // *
|
||||
FindGroupMemberUser(ctx context.Context, groupIDs []string, userID string) (groupMembers []*relationtb.GroupMemberModel, err error) // *
|
||||
FindGroupMemberRoleLevels(ctx context.Context, groupID string, roleLevels []int32) (groupMembers []*relationtb.GroupMemberModel, err error) // *
|
||||
FindGroupMemberAll(ctx context.Context, groupID string) (groupMembers []*relationtb.GroupMemberModel, err error) // *
|
||||
FindGroupsOwner(ctx context.Context, groupIDs []string) ([]*relationtb.GroupMemberModel, error)
|
||||
FindGroupMemberUserID(ctx context.Context, groupID string) ([]string, error)
|
||||
FindGroupMemberNum(ctx context.Context, groupID string) (uint32, error)
|
||||
FindUserManagedGroupID(ctx context.Context, userID string) (groupIDs []string, err error)
|
||||
PageGroupRequest(ctx context.Context, groupIDs []string, pageNumber, showNumber int32) (uint32, []*relationtb.GroupRequestModel, error)
|
||||
PageGroupRequest(ctx context.Context, groupIDs []string, pagination pagination.Pagination) (int64, []*relationtb.GroupRequestModel, error)
|
||||
GetGroupRoleLevelMemberIDs(ctx context.Context, groupID string, roleLevel int32) ([]string, error)
|
||||
|
||||
PageGetJoinGroup(ctx context.Context, userID string, pageNumber, showNumber int32) (total uint32, totalGroupMembers []*relationtb.GroupMemberModel, err error)
|
||||
PageGetGroupMember(ctx context.Context, groupID string, pageNumber, showNumber int32) (total uint32, totalGroupMembers []*relationtb.GroupMemberModel, err error)
|
||||
SearchGroupMember(ctx context.Context, keyword string, groupIDs []string, userIDs []string, roleLevels []int32, pageNumber, showNumber int32) (uint32, []*relationtb.GroupMemberModel, error)
|
||||
PageGetJoinGroup(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, totalGroupMembers []*relationtb.GroupMemberModel, err error)
|
||||
PageGetGroupMember(ctx context.Context, groupID string, pagination pagination.Pagination) (total int64, totalGroupMembers []*relationtb.GroupMemberModel, err error)
|
||||
SearchGroupMember(ctx context.Context, keyword string, groupID string, pagination pagination.Pagination) (int64, []*relationtb.GroupMemberModel, error)
|
||||
HandlerGroupRequest(ctx context.Context, groupID string, userID string, handledMsg string, handleResult int32, member *relationtb.GroupMemberModel) error
|
||||
DeleteGroupMember(ctx context.Context, groupID string, userIDs []string) error
|
||||
MapGroupMemberUserID(ctx context.Context, groupIDs []string) (map[string]*relationtb.GroupSimpleUserID, error)
|
||||
@@ -67,15 +65,8 @@ type GroupDatabase interface {
|
||||
// GroupRequest
|
||||
CreateGroupRequest(ctx context.Context, requests []*relationtb.GroupRequestModel) error
|
||||
TakeGroupRequest(ctx context.Context, groupID string, userID string) (*relationtb.GroupRequestModel, error)
|
||||
FindGroupRequests(ctx context.Context, groupID string, userIDs []string) (int64, []*relationtb.GroupRequestModel, error)
|
||||
PageGroupRequestUser(ctx context.Context, userID string, pageNumber, showNumber int32) (uint32, []*relationtb.GroupRequestModel, error)
|
||||
// SuperGroupModelInterface
|
||||
FindSuperGroup(ctx context.Context, groupIDs []string) ([]*unrelationtb.SuperGroupModel, error)
|
||||
FindJoinSuperGroup(ctx context.Context, userID string) ([]string, error)
|
||||
CreateSuperGroup(ctx context.Context, groupID string, initMemberIDList []string) error
|
||||
DeleteSuperGroup(ctx context.Context, groupID string) error
|
||||
DeleteSuperGroupMember(ctx context.Context, groupID string, userIDs []string) error
|
||||
CreateSuperGroupMember(ctx context.Context, groupID string, userIDs []string) error
|
||||
FindGroupRequests(ctx context.Context, groupID string, userIDs []string) ([]*relationtb.GroupRequestModel, error)
|
||||
PageGroupRequestUser(ctx context.Context, userID string, pagination pagination.Pagination) (int64, []*relationtb.GroupRequestModel, error)
|
||||
|
||||
// 获取群总数
|
||||
CountTotal(ctx context.Context, before *time.Time) (count int64, err error)
|
||||
@@ -85,61 +76,91 @@ type GroupDatabase interface {
|
||||
}
|
||||
|
||||
func NewGroupDatabase(
|
||||
group relationtb.GroupModelInterface,
|
||||
member relationtb.GroupMemberModelInterface,
|
||||
request relationtb.GroupRequestModelInterface,
|
||||
tx tx.Tx,
|
||||
rdb redis.UniversalClient,
|
||||
groupDB relationtb.GroupModelInterface,
|
||||
groupMemberDB relationtb.GroupMemberModelInterface,
|
||||
groupRequestDB relationtb.GroupRequestModelInterface,
|
||||
ctxTx tx.CtxTx,
|
||||
superGroup unrelationtb.SuperGroupModelInterface,
|
||||
cache cache.GroupCache,
|
||||
groupHash cache.GroupHash,
|
||||
) GroupDatabase {
|
||||
database := &groupDatabase{
|
||||
groupDB: group,
|
||||
groupMemberDB: member,
|
||||
groupRequestDB: request,
|
||||
tx: tx,
|
||||
ctxTx: ctxTx,
|
||||
cache: cache,
|
||||
mongoDB: superGroup,
|
||||
}
|
||||
return database
|
||||
}
|
||||
|
||||
func InitGroupDatabase(db *gorm.DB, rdb redis.UniversalClient, database *mongo.Database, hashCode func(ctx context.Context, groupID string) (uint64, error)) GroupDatabase {
|
||||
rcOptions := rockscache.NewDefaultOptions()
|
||||
rcOptions.StrongConsistency = true
|
||||
rcOptions.RandomExpireAdjustment = 0.2
|
||||
return NewGroupDatabase(
|
||||
relation.NewGroupDB(db),
|
||||
relation.NewGroupMemberDB(db),
|
||||
relation.NewGroupRequest(db),
|
||||
tx.NewGorm(db),
|
||||
tx.NewMongo(database.Client()),
|
||||
unrelation.NewSuperGroupMongoDriver(database),
|
||||
cache.NewGroupCacheRedis(
|
||||
rdb,
|
||||
relation.NewGroupDB(db),
|
||||
relation.NewGroupMemberDB(db),
|
||||
relation.NewGroupRequest(db),
|
||||
unrelation.NewSuperGroupMongoDriver(database),
|
||||
hashCode,
|
||||
rcOptions,
|
||||
),
|
||||
)
|
||||
return &groupDatabase{
|
||||
groupDB: groupDB,
|
||||
groupMemberDB: groupMemberDB,
|
||||
groupRequestDB: groupRequestDB,
|
||||
ctxTx: ctxTx,
|
||||
cache: cache.NewGroupCacheRedis(rdb, groupDB, groupMemberDB, groupRequestDB, groupHash, rcOptions),
|
||||
}
|
||||
}
|
||||
|
||||
type groupDatabase struct {
|
||||
groupDB relationtb.GroupModelInterface
|
||||
groupMemberDB relationtb.GroupMemberModelInterface
|
||||
groupRequestDB relationtb.GroupRequestModelInterface
|
||||
tx tx.Tx
|
||||
ctxTx tx.CtxTx
|
||||
cache cache.GroupCache
|
||||
mongoDB unrelationtb.SuperGroupModelInterface
|
||||
}
|
||||
|
||||
func (g *groupDatabase) GetGroupIDsByGroupType(ctx context.Context, groupType int) (groupIDs []string, err error) {
|
||||
return g.groupDB.GetGroupIDsByGroupType(ctx, groupType)
|
||||
func (g *groupDatabase) FindGroupMembers(ctx context.Context, groupID string, userIDs []string) ([]*relationtb.GroupMemberModel, error) {
|
||||
return g.cache.GetGroupMembersInfo(ctx, groupID, userIDs)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) FindGroupMemberUser(ctx context.Context, groupIDs []string, userID string) ([]*relationtb.GroupMemberModel, error) {
|
||||
return g.cache.FindGroupMemberUser(ctx, groupIDs, userID)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) FindGroupMemberRoleLevels(ctx context.Context, groupID string, roleLevels []int32) ([]*relationtb.GroupMemberModel, error) {
|
||||
return g.cache.GetGroupRolesLevelMemberInfo(ctx, groupID, roleLevels)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) FindGroupMemberAll(ctx context.Context, groupID string) ([]*relationtb.GroupMemberModel, error) {
|
||||
return g.cache.GetAllGroupMembersInfo(ctx, groupID)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) FindGroupsOwner(ctx context.Context, groupIDs []string) ([]*relationtb.GroupMemberModel, error) {
|
||||
return g.cache.GetGroupsOwner(ctx, groupIDs)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) GetGroupRoleLevelMemberIDs(ctx context.Context, groupID string, roleLevel int32) ([]string, error) {
|
||||
return g.cache.GetGroupRoleLevelMemberIDs(ctx, groupID, roleLevel)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) CreateGroup(ctx context.Context, groups []*relationtb.GroupModel, groupMembers []*relationtb.GroupMemberModel) error {
|
||||
if len(groups)+len(groupMembers) == 0 {
|
||||
return nil
|
||||
}
|
||||
return g.ctxTx.Transaction(ctx, func(ctx context.Context) error {
|
||||
c := g.cache.NewCache()
|
||||
if len(groups) > 0 {
|
||||
if err := g.groupDB.Create(ctx, groups); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, group := range groups {
|
||||
c = c.DelGroupsInfo(group.GroupID).
|
||||
DelGroupMembersHash(group.GroupID).
|
||||
DelGroupMembersHash(group.GroupID).
|
||||
DelGroupsMemberNum(group.GroupID).
|
||||
DelGroupMemberIDs(group.GroupID).
|
||||
DelGroupAllRoleLevel(group.GroupID)
|
||||
}
|
||||
}
|
||||
if len(groupMembers) > 0 {
|
||||
if err := g.groupMemberDB.Create(ctx, groupMembers); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, groupMember := range groupMembers {
|
||||
c = c.DelGroupMembersHash(groupMember.GroupID).
|
||||
DelGroupsMemberNum(groupMember.GroupID).
|
||||
DelGroupMemberIDs(groupMember.GroupID).
|
||||
DelJoinedGroupID(groupMember.UserID).
|
||||
DelGroupMembersInfo(groupMember.GroupID, groupMember.UserID).
|
||||
DelGroupAllRoleLevel(groupMember.GroupID)
|
||||
}
|
||||
}
|
||||
return c.ExecDel(ctx, true)
|
||||
})
|
||||
}
|
||||
|
||||
func (g *groupDatabase) FindGroupMemberUserID(ctx context.Context, groupID string) ([]string, error) {
|
||||
@@ -154,57 +175,16 @@ func (g *groupDatabase) FindGroupMemberNum(ctx context.Context, groupID string)
|
||||
return uint32(num), nil
|
||||
}
|
||||
|
||||
func (g *groupDatabase) CreateGroup(
|
||||
ctx context.Context,
|
||||
groups []*relationtb.GroupModel,
|
||||
groupMembers []*relationtb.GroupMemberModel,
|
||||
) error {
|
||||
cache := g.cache.NewCache()
|
||||
if err := g.tx.Transaction(func(tx any) error {
|
||||
if len(groups) > 0 {
|
||||
if err := g.groupDB.NewTx(tx).Create(ctx, groups); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if len(groupMembers) > 0 {
|
||||
if err := g.groupMemberDB.NewTx(tx).Create(ctx, groupMembers); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
createGroupIDs := utils.DistinctAnyGetComparable(groups, func(group *relationtb.GroupModel) string {
|
||||
return group.GroupID
|
||||
})
|
||||
m := make(map[string]struct{})
|
||||
|
||||
for _, groupMember := range groupMembers {
|
||||
if _, ok := m[groupMember.GroupID]; !ok {
|
||||
m[groupMember.GroupID] = struct{}{}
|
||||
cache = cache.DelGroupMemberIDs(groupMember.GroupID).DelGroupMembersHash(groupMember.GroupID).DelGroupsMemberNum(groupMember.GroupID)
|
||||
}
|
||||
cache = cache.DelJoinedGroupID(groupMember.UserID).DelGroupMembersInfo(groupMember.GroupID, groupMember.UserID)
|
||||
}
|
||||
cache = cache.DelGroupsInfo(createGroupIDs...)
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return cache.ExecDel(ctx)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) TakeGroup(ctx context.Context, groupID string) (group *relationtb.GroupModel, err error) {
|
||||
func (g *groupDatabase) TakeGroup(ctx context.Context, groupID string) (*relationtb.GroupModel, error) {
|
||||
return g.cache.GetGroupInfo(ctx, groupID)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) FindGroup(ctx context.Context, groupIDs []string) (groups []*relationtb.GroupModel, err error) {
|
||||
func (g *groupDatabase) FindGroup(ctx context.Context, groupIDs []string) ([]*relationtb.GroupModel, error) {
|
||||
return g.cache.GetGroupsInfo(ctx, groupIDs)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) SearchGroup(
|
||||
ctx context.Context,
|
||||
keyword string,
|
||||
pageNumber, showNumber int32,
|
||||
) (uint32, []*relationtb.GroupModel, error) {
|
||||
return g.groupDB.Search(ctx, keyword, pageNumber, showNumber)
|
||||
func (g *groupDatabase) SearchGroup(ctx context.Context, keyword string, pagination pagination.Pagination) (int64, []*relationtb.GroupModel, error) {
|
||||
return g.groupDB.Search(ctx, keyword, pagination)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) UpdateGroup(ctx context.Context, groupID string, data map[string]any) error {
|
||||
@@ -215,166 +195,97 @@ func (g *groupDatabase) UpdateGroup(ctx context.Context, groupID string, data ma
|
||||
}
|
||||
|
||||
func (g *groupDatabase) DismissGroup(ctx context.Context, groupID string, deleteMember bool) error {
|
||||
cache := g.cache.NewCache()
|
||||
if err := g.tx.Transaction(func(tx any) error {
|
||||
if err := g.groupDB.NewTx(tx).UpdateStatus(ctx, groupID, constant.GroupStatusDismissed); err != nil {
|
||||
return g.ctxTx.Transaction(ctx, func(ctx context.Context) error {
|
||||
c := g.cache.NewCache()
|
||||
if err := g.groupDB.UpdateState(ctx, groupID, constant.GroupStatusDismissed); err != nil {
|
||||
return err
|
||||
}
|
||||
if deleteMember {
|
||||
if err := g.groupMemberDB.NewTx(tx).DeleteGroup(ctx, []string{groupID}); err != nil {
|
||||
return err
|
||||
}
|
||||
userIDs, err := g.cache.GetGroupMemberIDs(ctx, groupID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cache = cache.DelJoinedGroupID(userIDs...).DelGroupMemberIDs(groupID).DelGroupsMemberNum(groupID).DelGroupMembersHash(groupID)
|
||||
if err := g.groupMemberDB.Delete(ctx, groupID, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
c = c.DelJoinedGroupID(userIDs...).
|
||||
DelGroupMemberIDs(groupID).
|
||||
DelGroupsMemberNum(groupID).
|
||||
DelGroupMembersHash(groupID).
|
||||
DelGroupAllRoleLevel(groupID).
|
||||
DelGroupMembersInfo(groupID, userIDs...)
|
||||
}
|
||||
cache = cache.DelGroupsInfo(groupID)
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return cache.ExecDel(ctx)
|
||||
return c.DelGroupsInfo(groupID).ExecDel(ctx)
|
||||
})
|
||||
}
|
||||
|
||||
func (g *groupDatabase) TakeGroupMember(
|
||||
ctx context.Context,
|
||||
groupID string,
|
||||
userID string,
|
||||
) (groupMember *relationtb.GroupMemberModel, err error) {
|
||||
func (g *groupDatabase) TakeGroupMember(ctx context.Context, groupID string, userID string) (*relationtb.GroupMemberModel, error) {
|
||||
return g.cache.GetGroupMemberInfo(ctx, groupID, userID)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) TakeGroupOwner(ctx context.Context, groupID string) (*relationtb.GroupMemberModel, error) {
|
||||
return g.groupMemberDB.TakeOwner(ctx, groupID) // todo cache group owner
|
||||
return g.cache.GetGroupOwner(ctx, groupID)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) FindUserManagedGroupID(ctx context.Context, userID string) (groupIDs []string, err error) {
|
||||
return g.groupMemberDB.FindUserManagedGroupID(ctx, userID)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) PageGroupRequest(
|
||||
ctx context.Context,
|
||||
groupIDs []string,
|
||||
pageNumber, showNumber int32,
|
||||
) (uint32, []*relationtb.GroupRequestModel, error) {
|
||||
return g.groupRequestDB.PageGroup(ctx, groupIDs, pageNumber, showNumber)
|
||||
func (g *groupDatabase) PageGroupRequest(ctx context.Context, groupIDs []string, pagination pagination.Pagination) (int64, []*relationtb.GroupRequestModel, error) {
|
||||
return g.groupRequestDB.PageGroup(ctx, groupIDs, pagination)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) FindGroupMember(ctx context.Context, groupIDs []string, userIDs []string, roleLevels []int32) (totalGroupMembers []*relationtb.GroupMemberModel, err error) {
|
||||
if len(groupIDs) == 0 && len(roleLevels) == 0 && len(userIDs) == 1 {
|
||||
gIDs, err := g.cache.GetJoinedGroupIDs(ctx, userIDs[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var res []*relationtb.GroupMemberModel
|
||||
for _, groupID := range gIDs {
|
||||
v, err := g.cache.GetGroupMemberInfo(ctx, groupID, userIDs[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res = append(res, v)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
if len(roleLevels) == 0 {
|
||||
for _, groupID := range groupIDs {
|
||||
groupMembers, err := g.cache.GetGroupMembersInfo(ctx, groupID, userIDs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
totalGroupMembers = append(totalGroupMembers, groupMembers...)
|
||||
}
|
||||
return totalGroupMembers, nil
|
||||
}
|
||||
return g.groupMemberDB.Find(ctx, groupIDs, userIDs, roleLevels)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) PageGetJoinGroup(
|
||||
ctx context.Context,
|
||||
userID string,
|
||||
pageNumber, showNumber int32,
|
||||
) (total uint32, totalGroupMembers []*relationtb.GroupMemberModel, err error) {
|
||||
func (g *groupDatabase) PageGetJoinGroup(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, totalGroupMembers []*relationtb.GroupMemberModel, err error) {
|
||||
groupIDs, err := g.cache.GetJoinedGroupIDs(ctx, userID)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
for _, groupID := range utils.Paginate(groupIDs, int(pageNumber), int(showNumber)) {
|
||||
for _, groupID := range utils.Paginate(groupIDs, int(pagination.GetPageNumber()), int(pagination.GetShowNumber())) {
|
||||
groupMembers, err := g.cache.GetGroupMembersInfo(ctx, groupID, []string{userID})
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
totalGroupMembers = append(totalGroupMembers, groupMembers...)
|
||||
}
|
||||
return uint32(len(groupIDs)), totalGroupMembers, nil
|
||||
return int64(len(groupIDs)), totalGroupMembers, nil
|
||||
}
|
||||
|
||||
func (g *groupDatabase) PageGetGroupMember(
|
||||
ctx context.Context,
|
||||
groupID string,
|
||||
pageNumber, showNumber int32,
|
||||
) (total uint32, totalGroupMembers []*relationtb.GroupMemberModel, err error) {
|
||||
func (g *groupDatabase) PageGetGroupMember(ctx context.Context, groupID string, pagination pagination.Pagination) (total int64, totalGroupMembers []*relationtb.GroupMemberModel, err error) {
|
||||
groupMemberIDs, err := g.cache.GetGroupMemberIDs(ctx, groupID)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
pageIDs := utils.Paginate(groupMemberIDs, int(pageNumber), int(showNumber))
|
||||
pageIDs := utils.Paginate(groupMemberIDs, int(pagination.GetPageNumber()), int(pagination.GetShowNumber()))
|
||||
if len(pageIDs) == 0 {
|
||||
return uint32(len(groupMemberIDs)), nil, nil
|
||||
return int64(len(groupMemberIDs)), nil, nil
|
||||
}
|
||||
members, err := g.cache.GetGroupMembersInfo(ctx, groupID, pageIDs)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
return uint32(len(groupMemberIDs)), members, nil
|
||||
return int64(len(groupMemberIDs)), members, nil
|
||||
}
|
||||
|
||||
func (g *groupDatabase) SearchGroupMember(
|
||||
ctx context.Context,
|
||||
keyword string,
|
||||
groupIDs []string,
|
||||
userIDs []string,
|
||||
roleLevels []int32,
|
||||
pageNumber, showNumber int32,
|
||||
) (uint32, []*relationtb.GroupMemberModel, error) {
|
||||
return g.groupMemberDB.SearchMember(ctx, keyword, groupIDs, userIDs, roleLevels, pageNumber, showNumber)
|
||||
func (g *groupDatabase) SearchGroupMember(ctx context.Context, keyword string, groupID string, pagination pagination.Pagination) (int64, []*relationtb.GroupMemberModel, error) {
|
||||
return g.groupMemberDB.SearchMember(ctx, keyword, groupID, pagination)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) HandlerGroupRequest(
|
||||
ctx context.Context,
|
||||
groupID string,
|
||||
userID string,
|
||||
handledMsg string,
|
||||
handleResult int32,
|
||||
member *relationtb.GroupMemberModel,
|
||||
) error {
|
||||
//cache := g.cache.NewCache()
|
||||
//if err := g.tx.Transaction(func(tx any) error {
|
||||
// if err := g.groupRequestDB.NewTx(tx).UpdateHandler(ctx, groupID, userID, handledMsg, handleResult); err != nil {
|
||||
// return err
|
||||
// }
|
||||
// if member != nil {
|
||||
// if err := g.groupMemberDB.NewTx(tx).Create(ctx, []*relationtb.GroupMemberModel{member}); err != nil {
|
||||
// return err
|
||||
// }
|
||||
// cache = cache.DelGroupMembersHash(groupID).DelGroupMemberIDs(groupID).DelGroupsMemberNum(groupID).DelJoinedGroupID(member.UserID)
|
||||
// }
|
||||
// return nil
|
||||
//}); err != nil {
|
||||
// return err
|
||||
//}
|
||||
//return cache.ExecDel(ctx)
|
||||
|
||||
return g.tx.Transaction(func(tx any) error {
|
||||
if err := g.groupRequestDB.NewTx(tx).UpdateHandler(ctx, groupID, userID, handledMsg, handleResult); err != nil {
|
||||
func (g *groupDatabase) HandlerGroupRequest(ctx context.Context, groupID string, userID string, handledMsg string, handleResult int32, member *relationtb.GroupMemberModel) error {
|
||||
return g.ctxTx.Transaction(ctx, func(ctx context.Context) error {
|
||||
if err := g.groupRequestDB.UpdateHandler(ctx, groupID, userID, handledMsg, handleResult); err != nil {
|
||||
return err
|
||||
}
|
||||
if member != nil {
|
||||
if err := g.groupMemberDB.NewTx(tx).Create(ctx, []*relationtb.GroupMemberModel{member}); err != nil {
|
||||
if err := g.groupMemberDB.Create(ctx, []*relationtb.GroupMemberModel{member}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := g.cache.NewCache().DelGroupMembersHash(groupID).DelGroupMembersInfo(groupID, member.UserID).DelGroupMemberIDs(groupID).DelGroupsMemberNum(groupID).DelJoinedGroupID(member.UserID).ExecDel(ctx); err != nil {
|
||||
c := g.cache.DelGroupMembersHash(groupID).
|
||||
DelGroupMembersInfo(groupID, member.UserID).
|
||||
DelGroupMemberIDs(groupID).
|
||||
DelGroupsMemberNum(groupID).
|
||||
DelJoinedGroupID(member.UserID).
|
||||
DelGroupRoleLevel(groupID, []int32{member.RoleLevel})
|
||||
if err := c.ExecDel(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -391,13 +302,11 @@ func (g *groupDatabase) DeleteGroupMember(ctx context.Context, groupID string, u
|
||||
DelGroupsMemberNum(groupID).
|
||||
DelJoinedGroupID(userIDs...).
|
||||
DelGroupMembersInfo(groupID, userIDs...).
|
||||
DelGroupAllRoleLevel(groupID).
|
||||
ExecDel(ctx)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) MapGroupMemberUserID(
|
||||
ctx context.Context,
|
||||
groupIDs []string,
|
||||
) (map[string]*relationtb.GroupSimpleUserID, error) {
|
||||
func (g *groupDatabase) MapGroupMemberUserID(ctx context.Context, groupIDs []string) (map[string]*relationtb.GroupSimpleUserID, error) {
|
||||
return g.cache.GetGroupMemberHashMap(ctx, groupIDs)
|
||||
}
|
||||
|
||||
@@ -414,62 +323,54 @@ func (g *groupDatabase) MapGroupMemberNum(ctx context.Context, groupIDs []string
|
||||
}
|
||||
|
||||
func (g *groupDatabase) TransferGroupOwner(ctx context.Context, groupID string, oldOwnerUserID, newOwnerUserID string, roleLevel int32) error {
|
||||
return g.tx.Transaction(func(tx any) error {
|
||||
rowsAffected, err := g.groupMemberDB.NewTx(tx).UpdateRoleLevel(ctx, groupID, oldOwnerUserID, roleLevel)
|
||||
if err != nil {
|
||||
return g.ctxTx.Transaction(ctx, func(ctx context.Context) error {
|
||||
if err := g.groupMemberDB.UpdateRoleLevel(ctx, groupID, oldOwnerUserID, roleLevel); err != nil {
|
||||
return err
|
||||
}
|
||||
if rowsAffected != 1 {
|
||||
return utils.Wrap(fmt.Errorf("oldOwnerUserID %s rowsAffected = %d", oldOwnerUserID, rowsAffected), "")
|
||||
}
|
||||
rowsAffected, err = g.groupMemberDB.NewTx(tx).UpdateRoleLevel(ctx, groupID, newOwnerUserID, constant.GroupOwner)
|
||||
if err != nil {
|
||||
if err := g.groupMemberDB.UpdateRoleLevel(ctx, groupID, newOwnerUserID, constant.GroupOwner); err != nil {
|
||||
return err
|
||||
}
|
||||
if rowsAffected != 1 {
|
||||
return utils.Wrap(fmt.Errorf("newOwnerUserID %s rowsAffected = %d", newOwnerUserID, rowsAffected), "")
|
||||
}
|
||||
return g.cache.DelGroupMembersInfo(groupID, oldOwnerUserID, newOwnerUserID).DelGroupMembersHash(groupID).ExecDel(ctx)
|
||||
return g.cache.DelGroupMembersInfo(groupID, oldOwnerUserID, newOwnerUserID).
|
||||
DelGroupAllRoleLevel(groupID).
|
||||
DelGroupMembersHash(groupID).ExecDel(ctx)
|
||||
})
|
||||
}
|
||||
|
||||
func (g *groupDatabase) UpdateGroupMember(
|
||||
ctx context.Context,
|
||||
groupID string,
|
||||
userID string,
|
||||
data map[string]any,
|
||||
) error {
|
||||
func (g *groupDatabase) UpdateGroupMember(ctx context.Context, groupID string, userID string, data map[string]any) error {
|
||||
if err := g.groupMemberDB.Update(ctx, groupID, userID, data); err != nil {
|
||||
return err
|
||||
}
|
||||
return g.cache.DelGroupMembersInfo(groupID, userID).ExecDel(ctx)
|
||||
c := g.cache.DelGroupMembersInfo(groupID, userID)
|
||||
if g.groupMemberDB.IsUpdateRoleLevel(data) {
|
||||
c = c.DelGroupAllRoleLevel(groupID)
|
||||
}
|
||||
return c.ExecDel(ctx)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) UpdateGroupMembers(ctx context.Context, data []*relationtb.BatchUpdateGroupMember) error {
|
||||
cache := g.cache.NewCache()
|
||||
if err := g.tx.Transaction(func(tx any) error {
|
||||
return g.ctxTx.Transaction(ctx, func(ctx context.Context) error {
|
||||
c := g.cache.NewCache()
|
||||
for _, item := range data {
|
||||
if err := g.groupMemberDB.NewTx(tx).Update(ctx, item.GroupID, item.UserID, item.Map); err != nil {
|
||||
if err := g.groupMemberDB.Update(ctx, item.GroupID, item.UserID, item.Map); err != nil {
|
||||
return err
|
||||
}
|
||||
cache = cache.DelGroupMembersInfo(item.GroupID, item.UserID)
|
||||
if g.groupMemberDB.IsUpdateRoleLevel(item.Map) {
|
||||
c = c.DelGroupAllRoleLevel(item.GroupID)
|
||||
}
|
||||
c = c.DelGroupMembersInfo(item.GroupID, item.UserID).DelGroupMembersHash(item.GroupID)
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return cache.ExecDel(ctx)
|
||||
return c.ExecDel(ctx, true)
|
||||
})
|
||||
}
|
||||
|
||||
func (g *groupDatabase) CreateGroupRequest(ctx context.Context, requests []*relationtb.GroupRequestModel) error {
|
||||
return g.tx.Transaction(func(tx any) error {
|
||||
db := g.groupRequestDB.NewTx(tx)
|
||||
return g.ctxTx.Transaction(ctx, func(ctx context.Context) error {
|
||||
for _, request := range requests {
|
||||
if err := db.Delete(ctx, request.GroupID, request.UserID); err != nil {
|
||||
if err := g.groupRequestDB.Delete(ctx, request.GroupID, request.UserID); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return db.Create(ctx, requests)
|
||||
return g.groupRequestDB.Create(ctx, requests)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -481,65 +382,8 @@ func (g *groupDatabase) TakeGroupRequest(
|
||||
return g.groupRequestDB.Take(ctx, groupID, userID)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) PageGroupRequestUser(
|
||||
ctx context.Context,
|
||||
userID string,
|
||||
pageNumber, showNumber int32,
|
||||
) (uint32, []*relationtb.GroupRequestModel, error) {
|
||||
return g.groupRequestDB.Page(ctx, userID, pageNumber, showNumber)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) FindSuperGroup(
|
||||
ctx context.Context,
|
||||
groupIDs []string,
|
||||
) (models []*unrelationtb.SuperGroupModel, err error) {
|
||||
return g.cache.GetSuperGroupMemberIDs(ctx, groupIDs...)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) FindJoinSuperGroup(ctx context.Context, userID string) ([]string, error) {
|
||||
return g.cache.GetJoinedSuperGroupIDs(ctx, userID)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) CreateSuperGroup(ctx context.Context, groupID string, initMemberIDs []string) error {
|
||||
if err := g.mongoDB.CreateSuperGroup(ctx, groupID, initMemberIDs); err != nil {
|
||||
return err
|
||||
}
|
||||
return g.cache.DelSuperGroupMemberIDs(groupID).DelJoinedSuperGroupIDs(initMemberIDs...).ExecDel(ctx)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) DeleteSuperGroup(ctx context.Context, groupID string) error {
|
||||
cache := g.cache.NewCache()
|
||||
if err := g.ctxTx.Transaction(ctx, func(ctx context.Context) error {
|
||||
if err := g.mongoDB.DeleteSuperGroup(ctx, groupID); err != nil {
|
||||
return err
|
||||
}
|
||||
models, err := g.cache.GetSuperGroupMemberIDs(ctx, groupID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cache = cache.DelSuperGroupMemberIDs(groupID)
|
||||
if len(models) > 0 {
|
||||
cache = cache.DelJoinedSuperGroupIDs(models[0].MemberIDs...)
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return cache.ExecDel(ctx)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) DeleteSuperGroupMember(ctx context.Context, groupID string, userIDs []string) error {
|
||||
if err := g.mongoDB.RemoverUserFromSuperGroup(ctx, groupID, userIDs); err != nil {
|
||||
return err
|
||||
}
|
||||
return g.cache.DelSuperGroupMemberIDs(groupID).DelJoinedSuperGroupIDs(userIDs...).ExecDel(ctx)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) CreateSuperGroupMember(ctx context.Context, groupID string, userIDs []string) error {
|
||||
if err := g.mongoDB.AddUserToSuperGroup(ctx, groupID, userIDs); err != nil {
|
||||
return err
|
||||
}
|
||||
return g.cache.DelSuperGroupMemberIDs(groupID).DelJoinedSuperGroupIDs(userIDs...).ExecDel(ctx)
|
||||
func (g *groupDatabase) PageGroupRequestUser(ctx context.Context, userID string, pagination pagination.Pagination) (int64, []*relationtb.GroupRequestModel, error) {
|
||||
return g.groupRequestDB.Page(ctx, userID, pagination)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) CountTotal(ctx context.Context, before *time.Time) (count int64, err error) {
|
||||
@@ -550,14 +394,10 @@ func (g *groupDatabase) CountRangeEverydayTotal(ctx context.Context, start time.
|
||||
return g.groupDB.CountRangeEverydayTotal(ctx, start, end)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) FindGroupRequests(ctx context.Context, groupID string, userIDs []string) (int64, []*relationtb.GroupRequestModel, error) {
|
||||
func (g *groupDatabase) FindGroupRequests(ctx context.Context, groupID string, userIDs []string) ([]*relationtb.GroupRequestModel, error) {
|
||||
return g.groupRequestDB.FindGroupRequests(ctx, groupID, userIDs)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) FindNotDismissedGroup(ctx context.Context, groupIDs []string) (groups []*relationtb.GroupModel, err error) {
|
||||
return g.groupDB.FindNotDismissedGroup(ctx, groupIDs)
|
||||
}
|
||||
|
||||
func (g *groupDatabase) DeleteGroupMemberHash(ctx context.Context, groupIDs []string) error {
|
||||
if len(groupIDs) == 0 {
|
||||
return nil
|
||||
@@ -566,6 +406,5 @@ func (g *groupDatabase) DeleteGroupMemberHash(ctx context.Context, groupIDs []st
|
||||
for _, groupID := range groupIDs {
|
||||
c = c.DelGroupMembersHash(groupID)
|
||||
}
|
||||
|
||||
return c.ExecDel(ctx)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -235,7 +235,7 @@ func Test_FindBySeq(t *testing.T) {
|
||||
func TestName(t *testing.T) {
|
||||
db := GetDB()
|
||||
var seqs []int64
|
||||
for i := int64(1); i <= 4; i++ {
|
||||
for i := int64(1); i <= 50; i++ {
|
||||
seqs = append(seqs, i)
|
||||
}
|
||||
msgs, err := db.getMsgBySeqsRange(context.Background(), "4931176757", "si_3866692501_4931176757", seqs, seqs[0], seqs[len(seqs)-1])
|
||||
|
||||
@@ -72,14 +72,15 @@ func (s *s3Database) CompleteMultipartUpload(ctx context.Context, uploadID strin
|
||||
}
|
||||
|
||||
func (s *s3Database) SetObject(ctx context.Context, info *relation.ObjectModel) error {
|
||||
info.Engine = s.s3.Engine()
|
||||
if err := s.db.SetObject(ctx, info); err != nil {
|
||||
return err
|
||||
}
|
||||
return s.cache.DelObjectName(info.Name).ExecDel(ctx)
|
||||
return s.cache.DelObjectName(info.Engine, info.Name).ExecDel(ctx)
|
||||
}
|
||||
|
||||
func (s *s3Database) AccessURL(ctx context.Context, name string, expire time.Duration, opt *s3.AccessURLOption) (time.Time, string, error) {
|
||||
obj, err := s.cache.GetName(ctx, name)
|
||||
obj, err := s.cache.GetName(ctx, s.s3.Engine(), name)
|
||||
if err != nil {
|
||||
return time.Time{}, "", err
|
||||
}
|
||||
|
||||
@@ -18,10 +18,9 @@ import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
"github.com/OpenIMSDK/tools/pagination"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
||||
dbimpl "github.com/openimsdk/open-im-server/v3/pkg/common/db/relation"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
)
|
||||
|
||||
@@ -29,22 +28,15 @@ 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, pageNumber int32, showNumber int32) (uint32, []*relation.Log, error)
|
||||
GetLogs(ctx context.Context, LogIDs []string, userID string) ([]*relation.Log, error)
|
||||
FindUsers(ctx context.Context, userIDs []string) ([]*relation.UserModel, 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 {
|
||||
cache cache.MsgModel
|
||||
logdb relation.LogInterface
|
||||
userdb relation.UserModelInterface
|
||||
}
|
||||
|
||||
// FindUsers implements ThirdDatabase.
|
||||
func (t *thirdDatabase) FindUsers(ctx context.Context, userIDs []string) ([]*relation.UserModel, error) {
|
||||
return t.userdb.Find(ctx, userIDs)
|
||||
cache cache.MsgModel
|
||||
logdb relation.LogInterface
|
||||
}
|
||||
|
||||
// DeleteLogs implements ThirdDatabase.
|
||||
@@ -53,22 +45,22 @@ 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, pageNumber int32, showNumber int32) (uint32, []*relation.Log, error) {
|
||||
return t.logdb.Search(ctx, keyword, start, end, pageNumber, showNumber)
|
||||
func (t *thirdDatabase) SearchLogs(ctx context.Context, keyword string, start time.Time, end time.Time, pagination pagination.Pagination) (int64, []*relation.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)
|
||||
}
|
||||
|
||||
func NewThirdDatabase(cache cache.MsgModel, db *gorm.DB) ThirdDatabase {
|
||||
return &thirdDatabase{cache: cache, logdb: dbimpl.NewLogGorm(db), userdb: dbimpl.NewUserGorm(db)}
|
||||
func NewThirdDatabase(cache cache.MsgModel, logdb relation.LogInterface) ThirdDatabase {
|
||||
return &thirdDatabase{cache: cache, logdb: logdb}
|
||||
}
|
||||
|
||||
func (t *thirdDatabase) FcmUpdateToken(
|
||||
|
||||
@@ -18,16 +18,19 @@ 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/protocol/user"
|
||||
|
||||
unrelationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/unrelation"
|
||||
|
||||
"github.com/OpenIMSDK/tools/errs"
|
||||
"github.com/OpenIMSDK/tools/tx"
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
)
|
||||
|
||||
type UserDatabase interface {
|
||||
@@ -38,15 +41,15 @@ type UserDatabase interface {
|
||||
// Create Insert multiple external guarantees that the userID is not repeated and does not exist in the db
|
||||
Create(ctx context.Context, users []*relation.UserModel) (err error)
|
||||
// Update update (non-zero value) external guarantee userID exists
|
||||
Update(ctx context.Context, user *relation.UserModel) (err error)
|
||||
//Update(ctx context.Context, user *relation.UserModel) (err error)
|
||||
// UpdateByMap update (zero value) external guarantee userID exists
|
||||
UpdateByMap(ctx context.Context, userID string, args map[string]interface{}) (err error)
|
||||
UpdateByMap(ctx context.Context, userID string, args map[string]any) (err error)
|
||||
// Page If not found, no error is returned
|
||||
Page(ctx context.Context, pageNumber, showNumber int32) (users []*relation.UserModel, count int64, err error)
|
||||
Page(ctx context.Context, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error)
|
||||
// IsExist true as long as one exists
|
||||
IsExist(ctx context.Context, userIDs []string) (exist bool, err error)
|
||||
// GetAllUserID Get all user IDs
|
||||
GetAllUserID(ctx context.Context, pageNumber, showNumber int32) ([]string, error)
|
||||
GetAllUserID(ctx context.Context, pagination pagination.Pagination) (int64, []string, error)
|
||||
// InitOnce Inside the function, first query whether it exists in the db, if it exists, do nothing; if it does not exist, insert it
|
||||
InitOnce(ctx context.Context, users []*relation.UserModel) (err error)
|
||||
// CountTotal Get the total number of users
|
||||
@@ -68,28 +71,40 @@ type UserDatabase interface {
|
||||
}
|
||||
|
||||
type userDatabase struct {
|
||||
tx tx.CtxTx
|
||||
userDB relation.UserModelInterface
|
||||
cache cache.UserCache
|
||||
tx tx.Tx
|
||||
mongoDB unrelationtb.UserModelInterface
|
||||
}
|
||||
|
||||
func NewUserDatabase(userDB relation.UserModelInterface, cache cache.UserCache, tx tx.Tx, mongoDB unrelationtb.UserModelInterface) UserDatabase {
|
||||
func NewUserDatabase(userDB relation.UserModelInterface, cache cache.UserCache, tx tx.CtxTx, mongoDB unrelationtb.UserModelInterface) UserDatabase {
|
||||
return &userDatabase{userDB: userDB, cache: cache, tx: tx, mongoDB: mongoDB}
|
||||
}
|
||||
|
||||
func (u *userDatabase) InitOnce(ctx context.Context, users []*relation.UserModel) (err error) {
|
||||
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
|
||||
})
|
||||
result, err := u.userDB.Find(ctx, userIDs)
|
||||
|
||||
// Find existing users in the database.
|
||||
existingUsers, err := u.userDB.Find(ctx, userIDs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
miss := utils.SliceAnySub(users, result, func(e *relation.UserModel) string { return e.UserID })
|
||||
if len(miss) > 0 {
|
||||
_ = u.userDB.Create(ctx, miss)
|
||||
|
||||
// Determine which users are missing from the database.
|
||||
missingUsers := utils.SliceAnySub(users, existingUsers, func(e *relation.UserModel) string {
|
||||
return e.UserID
|
||||
})
|
||||
|
||||
// Create records for missing users.
|
||||
if len(missingUsers) > 0 {
|
||||
if err := u.userDB.Create(ctx, missingUsers); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -107,50 +122,42 @@ func (u *userDatabase) FindWithError(ctx context.Context, userIDs []string) (use
|
||||
|
||||
// Find Get the information of the specified user. If the userID is not found, no error will be returned.
|
||||
func (u *userDatabase) Find(ctx context.Context, userIDs []string) (users []*relation.UserModel, err error) {
|
||||
users, err = u.cache.GetUsersInfo(ctx, userIDs)
|
||||
return
|
||||
return u.cache.GetUsersInfo(ctx, userIDs)
|
||||
}
|
||||
|
||||
// Create Insert multiple external guarantees that the userID is not repeated and does not exist in the db.
|
||||
func (u *userDatabase) Create(ctx context.Context, users []*relation.UserModel) (err error) {
|
||||
if err := u.tx.Transaction(func(tx any) error {
|
||||
err = u.userDB.Create(ctx, users)
|
||||
if err != nil {
|
||||
return u.tx.Transaction(ctx, func(ctx context.Context) error {
|
||||
if err = u.userDB.Create(ctx, users); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
var userIDs []string
|
||||
for _, user := range users {
|
||||
userIDs = append(userIDs, user.UserID)
|
||||
}
|
||||
return u.cache.DelUsersInfo(userIDs...).ExecDel(ctx)
|
||||
return u.cache.DelUsersInfo(utils.Slice(users, func(e *relation.UserModel) string {
|
||||
return e.UserID
|
||||
})...).ExecDel(ctx)
|
||||
})
|
||||
}
|
||||
|
||||
// Update (non-zero value) externally guarantees that userID exists.
|
||||
func (u *userDatabase) Update(ctx context.Context, user *relation.UserModel) (err error) {
|
||||
if err := u.userDB.Update(ctx, user); err != nil {
|
||||
return err
|
||||
}
|
||||
return u.cache.DelUsersInfo(user.UserID).ExecDel(ctx)
|
||||
}
|
||||
//// Update (non-zero value) externally guarantees that userID exists.
|
||||
//func (u *userDatabase) Update(ctx context.Context, user *relation.UserModel) (err error) {
|
||||
// if err := u.userDB.Update(ctx, user); err != nil {
|
||||
// return err
|
||||
// }
|
||||
// return u.cache.DelUsersInfo(user.UserID).ExecDel(ctx)
|
||||
//}
|
||||
|
||||
// UpdateByMap update (zero value) externally guarantees that userID exists.
|
||||
func (u *userDatabase) UpdateByMap(ctx context.Context, userID string, args map[string]interface{}) (err error) {
|
||||
if err := u.userDB.UpdateByMap(ctx, userID, args); err != nil {
|
||||
return err
|
||||
}
|
||||
return u.cache.DelUsersInfo(userID).ExecDel(ctx)
|
||||
func (u *userDatabase) UpdateByMap(ctx context.Context, userID string, args map[string]any) (err error) {
|
||||
return u.tx.Transaction(ctx, func(ctx context.Context) error {
|
||||
if err := u.userDB.UpdateByMap(ctx, userID, args); err != nil {
|
||||
return err
|
||||
}
|
||||
return u.cache.DelUsersInfo(userID).ExecDel(ctx)
|
||||
})
|
||||
}
|
||||
|
||||
// Page Gets, returns no error if not found.
|
||||
func (u *userDatabase) Page(
|
||||
ctx context.Context,
|
||||
pageNumber, showNumber int32,
|
||||
) (users []*relation.UserModel, count int64, err error) {
|
||||
return u.userDB.Page(ctx, pageNumber, showNumber)
|
||||
func (u *userDatabase) Page(ctx context.Context, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) {
|
||||
return u.userDB.Page(ctx, pagination)
|
||||
}
|
||||
|
||||
// IsExist Does userIDs exist? As long as there is one, it will be true.
|
||||
@@ -166,8 +173,8 @@ func (u *userDatabase) IsExist(ctx context.Context, userIDs []string) (exist boo
|
||||
}
|
||||
|
||||
// GetAllUserID Get all user IDs.
|
||||
func (u *userDatabase) GetAllUserID(ctx context.Context, pageNumber, showNumber int32) (userIDs []string, err error) {
|
||||
return u.userDB.GetAllUserID(ctx, pageNumber, showNumber)
|
||||
func (u *userDatabase) GetAllUserID(ctx context.Context, pagination pagination.Pagination) (total int64, userIDs []string, err error) {
|
||||
return u.userDB.GetAllUserID(ctx, pagination)
|
||||
}
|
||||
|
||||
// CountTotal Get the total number of users.
|
||||
|
||||
Reference in New Issue
Block a user